From 1f6daacebe0358bdfb78a35186cbb308ca117b8a Mon Sep 17 00:00:00 2001 From: Jamie Nicol Date: Fri, 22 Aug 2014 17:08:47 +0100 Subject: [PATCH] FROMLIST: fb: add dma-buf support 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 Signed-off-by: Mark Yao (am from https://patchwork.linuxtv.org/patch/12980) --- drivers/video/fbdev/core/fbmem.c | 36 ++++++++++++++++++++++++++++++++ include/linux/fb.h | 3 +++ include/uapi/linux/fb.h | 5 +++++ 3 files changed, 44 insertions(+) diff --git a/drivers/video/fbdev/core/fbmem.c b/drivers/video/fbdev/core/fbmem.c index 0705d8883ede..bf348a6e6517 100644 --- a/drivers/video/fbdev/core/fbmem.c +++ b/drivers/video/fbdev/core/fbmem.c @@ -28,6 +28,7 @@ #include #include #include +#include #include #include #include @@ -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); diff --git a/include/linux/fb.h b/include/linux/fb.h index 3d003805aac3..33564b062803 100644 --- a/include/linux/fb.h +++ b/include/linux/fb.h @@ -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 diff --git a/include/uapi/linux/fb.h b/include/uapi/linux/fb.h index fb795c3b3c17..39c48cde02ec 100644 --- a/include/uapi/linux/fb.h +++ b/include/uapi/linux/fb.h @@ -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 */ -- 2.34.1