]> rtime.felk.cvut.cz Git - sojka/nv-tegra/linux-3.10.git/commitdiff
dmabuf: Support driver data
authorArto Merilainen <amerilainen@nvidia.com>
Sun, 16 Feb 2014 13:22:50 +0000 (15:22 +0200)
committerTerje Bergstrom <tbergstrom@nvidia.com>
Thu, 27 Feb 2014 06:35:21 +0000 (22:35 -0800)
Occassionally we need to store driver/device specific data of a device
that survives over attach/detach sequence. This patch adds support for
defining drvdata inside dmabuf.

Bug 1450489

Change-Id: I840d415657a07ef86476e32bcac4e13a8706ece4
Signed-off-by: Arto Merilainen <amerilainen@nvidia.com>
Reviewed-on: http://git-master/r/368139
Reviewed-by: Krishna Reddy <vdumpa@nvidia.com>
Reviewed-by: Terje Bergstrom <tbergstrom@nvidia.com>
drivers/base/dma-buf.c
include/linux/dma-buf.h

index 08fe897c0b4cfcdc4c2eed939870cf46ddf57735..f98d1ad2ded7dbe56d7cfb163c093a7826c87395 100644 (file)
@@ -39,6 +39,56 @@ struct dma_buf_list {
 
 static struct dma_buf_list db_list;
 
+/**
+ * dma_buf_set_drvdata - Set driver specific data to dmabuf. The data
+ * will remain even if the device is detached from the device. This is useful
+ * if the device requires some buffer specific parameters that should be
+ * available when the buffer is accessed next time.
+ *
+ * The exporter calls the destroy callback:
+ *  - the buffer is freed
+ *  - the device/driver is removed
+ *  - new device private data is set
+ *
+ * @dmabuf     [in]    Buffer object
+ * @device     [in]    Device to which the data is related to.
+ * @priv       [in]    Private data
+ * @destroy    [in]    Function callback to destroy function. Called when the
+ *                     data is not needed anymore (device or dmabuf is
+ *                     removed)
+ *
+ * The function returns 0 on success. Otherwise the function returns a negative
+ * errorcode
+ */
+int dma_buf_set_drvdata(struct dma_buf * dmabuf, struct device *device,
+                       void *priv, void (*destroy)(void *))
+{
+       if (!(dmabuf && dmabuf->ops && dmabuf->ops->set_drvdata))
+               return -ENOSYS;
+
+       return dmabuf->ops->set_drvdata(dmabuf, device, priv, destroy);
+}
+EXPORT_SYMBOL(dma_buf_set_drvdata);
+
+/**
+ * dma_buf_get_drvdata - Get driver specific data to dmabuf.
+ *
+ * @dmabuf     [in]    Buffer object
+ * @device     [in]    Device to which the data is related to.
+ *
+ * The function returns the user data structure on success. Otherwise NULL
+ * is returned.
+ */
+void *dma_buf_get_drvdata(struct dma_buf *dmabuf, struct device *device)
+{
+       if (!(dmabuf && dmabuf->ops && dmabuf->ops->get_drvdata))
+               return ERR_PTR(-ENOSYS);
+
+       return dmabuf->ops->get_drvdata(dmabuf, device);
+}
+EXPORT_SYMBOL(dma_buf_get_drvdata);
+
+
 static int dma_buf_release(struct inode *inode, struct file *file)
 {
        struct dma_buf *dmabuf;
index dfac5ed311205d2469628273b161e4008fcfcbfb..cf1f03f69a47678a9b9f5effcb3d7e1574052273 100644 (file)
@@ -104,6 +104,10 @@ struct dma_buf_ops {
 
        void *(*vmap)(struct dma_buf *);
        void (*vunmap)(struct dma_buf *, void *vaddr);
+
+       void *(*get_drvdata)(struct dma_buf *, struct device *);
+       int (*set_drvdata)(struct dma_buf *, struct device *, void *priv,
+                          void (*)(void *));
 };
 
 /**
@@ -177,6 +181,10 @@ int dma_buf_fd(struct dma_buf *dmabuf, int flags);
 struct dma_buf *dma_buf_get(int fd);
 void dma_buf_put(struct dma_buf *dmabuf);
 
+int dma_buf_set_drvdata(struct dma_buf *, struct device *,
+                       void *, void (*destroy)(void *));
+void *dma_buf_get_drvdata(struct dma_buf *, struct device *);
+
 struct sg_table *dma_buf_map_attachment(struct dma_buf_attachment *,
                                        enum dma_data_direction);
 void dma_buf_unmap_attachment(struct dma_buf_attachment *, struct sg_table *,