FROMLIST: fb: add dma-buf support
authorJamie Nicol <jamie.nicol@arm.com>
Fri, 22 Aug 2014 16:08:47 +0000 (17:08 +0100)
committerHuang, Tao <huangtao@rock-chips.com>
Wed, 21 Jun 2017 07:13:01 +0000 (15:13 +0800)
Add support for the dma-buf exporter role to the frame buffer API. The
importer role isn't meaningful for frame buffer devices, as the frame
buffer device model doesn't allow using externally allocated memory.

taken from an RFC on the linaro-mm-sig mailing list:
http://lists.linaro.org/pipermail/linaro-mm-sig/2012-June/002167.html

Fixes by Mark Yao:
  add FBIOGET_DMABUF to compat_ioctl.

Change-Id: I39c9bbdd6b88c6d5ba7524abfc5b560dceb4633e
Signed-off-by: Guillaume Tucker <guillaume.tucker@arm.com>
Signed-off-by: Mark Yao <mark.yao@rock-chips.com>
(am from https://patchwork.linuxtv.org/patch/12980)

drivers/video/fbdev/core/fbmem.c
include/linux/fb.h
include/uapi/linux/fb.h

index 0705d8883edecc785a72f4ef256b9894e4d0e950..bf348a6e651739385702a3874e3802da80ff3d35 100644 (file)
@@ -28,6 +28,7 @@
 #include <linux/seq_file.h>
 #include <linux/console.h>
 #include <linux/kmod.h>
+#include <linux/dma-buf.h>
 #include <linux/err.h>
 #include <linux/device.h>
 #include <linux/efi.h>
@@ -1084,6 +1085,24 @@ fb_blank(struct fb_info *info, int blank)
 }
 EXPORT_SYMBOL(fb_blank);
 
+int fb_get_dmabuf(struct fb_info *info, int flags)
+{
+#ifdef CONFIG_DMA_SHARED_BUFFER
+       struct dma_buf *dmabuf;
+
+       if (!info->fbops->fb_dmabuf_export)
+               return -ENOTTY;
+
+       dmabuf = info->fbops->fb_dmabuf_export(info);
+       if (IS_ERR(dmabuf))
+               return PTR_ERR(dmabuf);
+
+       return dma_buf_fd(dmabuf, flags);
+#else
+       return -ENOTTY;
+#endif
+}
+
 static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
                        unsigned long arg)
 {
@@ -1094,6 +1113,7 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
        struct fb_cmap cmap_from;
        struct fb_cmap_user cmap;
        struct fb_event event;
+       struct fb_dmabuf_export dmaexp;
        void __user *argp = (void __user *)arg;
        long ret = 0;
 
@@ -1211,6 +1231,21 @@ static long do_fb_ioctl(struct fb_info *info, unsigned int cmd,
                unlock_fb_info(info);
                console_unlock();
                break;
+       case FBIOGET_DMABUF:
+               if (copy_from_user(&dmaexp, argp, sizeof(dmaexp)))
+                       return -EFAULT;
+
+               if (!lock_fb_info(info))
+                       return -ENODEV;
+               ret = fb_get_dmabuf(info, dmaexp.flags);
+               unlock_fb_info(info);
+
+               if (ret < 0)
+                       return ret;
+               dmaexp.fd = ret;
+
+               ret = copy_to_user(argp, &dmaexp, sizeof(dmaexp)) ? -EFAULT : 0;
+               break;
        default:
                if (!lock_fb_info(info))
                        return -ENODEV;
@@ -1365,6 +1400,7 @@ static long fb_compat_ioctl(struct file *file, unsigned int cmd,
        case FBIOPAN_DISPLAY:
        case FBIOGET_CON2FBMAP:
        case FBIOPUT_CON2FBMAP:
+       case FBIOGET_DMABUF:
                arg = (unsigned long) compat_ptr(arg);
        case FBIOBLANK:
                ret = do_fb_ioctl(info, cmd, arg);
index 3d003805aac32ab1880c432cf556da8c5c29e14c..33564b062803eca64ff2b2107fad117fdadaa167 100644 (file)
@@ -305,6 +305,9 @@ struct fb_ops {
        /* called at KDB enter and leave time to prepare the console */
        int (*fb_debug_enter)(struct fb_info *info);
        int (*fb_debug_leave)(struct fb_info *info);
+
+       /* Export the frame buffer as a dmabuf object */
+       struct dma_buf *(*fb_dmabuf_export)(struct fb_info *info);
 };
 
 #ifdef CONFIG_FB_TILEBLITTING
index fb795c3b3c178ad3cd7c9e9e4547ffd492bac181..39c48cde02ec86629e930420f5232524d32cc385 100644 (file)
@@ -34,6 +34,7 @@
 #define FBIOPUT_MODEINFO        0x4617
 #define FBIOGET_DISPINFO        0x4618
 #define FBIO_WAITFORVSYNC      _IOW('F', 0x20, __u32)
+#define FBIOGET_DMABUF         _IOR('F', 0x21, struct fb_dmabuf_export)
 
 #define FB_TYPE_PACKED_PIXELS          0       /* Packed Pixels        */
 #define FB_TYPE_PLANES                 1       /* Non interleaved planes */
@@ -398,5 +399,9 @@ struct fb_cursor {
 #define FB_BACKLIGHT_MAX       0xFF
 #endif
 
+struct fb_dmabuf_export {
+       __u32 fd;
+       __u32 flags;
+};
 
 #endif /* _UAPI_LINUX_FB_H */