drm/fb_cma_helper: Add support for the fbdev dma-buf API

Add support for the new semi-standard fbdev API for dma-buf exports to
user space.

Change-Id: I8df10b2d214bb75a0c3f42f4c6ce58da9e9573b8
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
Reviewed-by: Liviu Dudau <liviu.dudau@arm.com>
[Ported to gem5's 4.9 kernel. Fix incorrect ref count.]
Signed-off-by: Andreas Sandberg <andreas.sandberg@arm.com>
diff --git a/drivers/gpu/drm/drm_fb_cma_helper.c b/drivers/gpu/drm/drm_fb_cma_helper.c
index f2ee883..21769e5 100644
--- a/drivers/gpu/drm/drm_fb_cma_helper.c
+++ b/drivers/gpu/drm/drm_fb_cma_helper.c
@@ -251,8 +251,31 @@
 	.fb_copyarea	= drm_fb_helper_sys_copyarea,
 	.fb_imageblit	= drm_fb_helper_sys_imageblit,
 	.fb_mmap	= drm_fb_cma_mmap,
+	.fb_dmabuf_export	= drm_fb_cma_get_dmabuf,
 };
 
+struct dma_buf *drm_fb_cma_get_dmabuf(struct fb_info *info)
+{
+	struct dma_buf *buf = NULL;
+	struct drm_fb_helper *helper = info->par;
+	struct drm_device *dev = helper->dev;
+	struct drm_gem_cma_object *cma_obj;
+
+	if (!dev->driver->gem_prime_export)
+		return NULL;
+
+	cma_obj = drm_fb_cma_get_gem_obj(helper->fb, 0);
+	buf = dev->driver->gem_prime_export(dev, &cma_obj->base,
+					    O_RDWR);
+	if (IS_ERR_OR_NULL(buf))
+		return buf;
+
+	drm_gem_object_reference(&cma_obj->base);
+
+	return buf;
+}
+EXPORT_SYMBOL_GPL(drm_fb_cma_get_dmabuf);
+
 static int drm_fbdev_cma_deferred_io_mmap(struct fb_info *info,
 					  struct vm_area_struct *vma)
 {
diff --git a/include/drm/drm_fb_cma_helper.h b/include/drm/drm_fb_cma_helper.h
index 1df291d..e8c09d4 100644
--- a/include/drm/drm_fb_cma_helper.h
+++ b/include/drm/drm_fb_cma_helper.h
@@ -55,5 +55,7 @@
 int drm_fb_cma_debugfs_show(struct seq_file *m, void *arg);
 #endif
 
+struct dma_buf *drm_fb_cma_get_dmabuf(struct fb_info *info);
+
 #endif