summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMaciej Socha <maciej.socha@stericsson.com>2011-12-06 12:39:36 +0100
committerPhilippe Langlais <philippe.langlais@stericsson.com>2012-05-22 11:04:22 +0200
commitb5478f54d905e5c81680d1974e3a5fae1ca8941d (patch)
tree9db1d797768aca1a1360d8b3972e7c91ffef325b
parenta5c5d89cfaee85c040e12de7c3f8007cc76969ae (diff)
misc: compdev added
This driver is needed to support new display composition cases in HC/ICS. The driver is similar to the dispdev driver but not the same. ST-Ericsson ID: 350337 ST-Ericsson FOSS-OUT ID: NA Change-Id: Ide63b6f3994dece44259ac25da26b06a2fcca832 Signed-off-by: Jörgen Nilsson <jorgen.nilsson@stericsson.com> Reviewed-on: http://gerrit.lud.stericsson.com/gerrit/42890 Reviewed-by: Per-Daniel OLSSON <per-daniel.olsson@stericsson.com> Tested-by: Per-Daniel OLSSON <per-daniel.olsson@stericsson.com> Reviewed-by: Jonas ABERG <jonas.aberg@stericsson.com>
-rw-r--r--arch/arm/mach-ux500/board-mop500-mcde.c17
-rw-r--r--drivers/misc/Kconfig9
-rw-r--r--drivers/misc/Makefile1
-rw-r--r--drivers/misc/compdev/Makefile1
-rw-r--r--drivers/misc/compdev/compdev.c481
-rw-r--r--include/linux/compdev.h106
6 files changed, 614 insertions, 1 deletions
diff --git a/arch/arm/mach-ux500/board-mop500-mcde.c b/arch/arm/mach-ux500/board-mop500-mcde.c
index 470302b6809..8b9e0b5a9c2 100644
--- a/arch/arm/mach-ux500/board-mop500-mcde.c
+++ b/arch/arm/mach-ux500/board-mop500-mcde.c
@@ -13,6 +13,7 @@
#include <linux/mfd/ab8500/denc.h>
#include <linux/workqueue.h>
#include <linux/dispdev.h>
+#include <linux/compdev.h>
#include <asm/mach-types.h>
#include <linux/clk.h>
#include <mach/devices.h>
@@ -348,7 +349,7 @@ static int display_postregistered_callback(struct notifier_block *nb,
u16 virtual_height;
u32 rotate = FB_ROTATE_UR;
struct fb_info *fbi;
-#ifdef CONFIG_DISPDEV
+#if defined(CONFIG_DISPDEV) || defined(CONFIG_COMPDEV)
struct mcde_fb *mfb;
#endif
@@ -397,6 +398,20 @@ static int display_postregistered_callback(struct notifier_block *nb,
}
#endif
+#ifdef CONFIG_COMPDEV
+ mfb = to_mcde_fb(fbi);
+ /* Create a compdev overlay for this display */
+ if (compdev_create(ddev, mfb->ovlys[0]) < 0) {
+ dev_warn(&ddev->dev,
+ "Failed to create compdev for display %s\n",
+ ddev->name);
+ goto display_postregistered_callback_err;
+ } else {
+ dev_info(&ddev->dev, "compdev created for (%s)\n",
+ ddev->name);
+ }
+#endif
+
out:
return 0;
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index 1b3e2b1ae2c..c7c7114859f 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -470,6 +470,15 @@ config DISPDEV
addition to the framebuffer). The device allows for registration of
userspace buffers to be used with the overlay.
+config COMPDEV
+ bool "Display composition device"
+ depends on FB_MCDE && HWMEM
+ default n
+ help
+ This driver provides a way to use several overlays for a display.
+ This driver replaces the use of the framebuffer The device allows
+ for posting userspace buffers to be used with the overlays.
+
config PCH_PHUB
tristate "Intel EG20T PCH/LAPIS Semicon IOH(ML7213/ML7223/ML7831) PHUB"
depends on PCI
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index 2868ec61bc5..6f925aafbd5 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -47,6 +47,7 @@ obj-$(CONFIG_AB8500_PWM) += ab8500-pwm.o
obj-y += lis3lv02d/
obj-y += carma/
obj-$(CONFIG_DISPDEV) += dispdev/
+obj-$(CONFIG_COMPDEV) += compdev/
obj-$(CONFIG_USB_SWITCH_FSA9480) += fsa9480.o
obj-$(CONFIG_ALTERA_STAPL) +=altera-stapl/
obj-$(CONFIG_MAX8997_MUIC) += max8997-muic.o
diff --git a/drivers/misc/compdev/Makefile b/drivers/misc/compdev/Makefile
new file mode 100644
index 00000000000..8d5cd14dc36
--- /dev/null
+++ b/drivers/misc/compdev/Makefile
@@ -0,0 +1 @@
+obj-$(CONFIG_DISPDEV) += compdev.o
diff --git a/drivers/misc/compdev/compdev.c b/drivers/misc/compdev/compdev.c
new file mode 100644
index 00000000000..7e840a59d9c
--- /dev/null
+++ b/drivers/misc/compdev/compdev.c
@@ -0,0 +1,481 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * Display overlay compositer device driver
+ *
+ * Author: Anders Bauer <anders.bauer@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * Modified: Per-Daniel Olsson <per-daniel.olsson@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#include <linux/kernel.h>
+#include <linux/fs.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/miscdevice.h>
+#include <linux/uaccess.h>
+#include <linux/list.h>
+#include <linux/mutex.h>
+#include <linux/ioctl.h>
+
+#include <linux/compdev.h>
+#include <linux/hwmem.h>
+#include <video/mcde_dss.h>
+
+static LIST_HEAD(dev_list);
+static DEFINE_MUTEX(dev_list_lock);
+
+struct compdev_buffer {
+ struct hwmem_alloc *alloc;
+ enum compdev_ptr_type type;
+ u32 size;
+ u32 paddr; /* if pinned */
+};
+
+struct compdev {
+ bool open;
+ struct mutex lock;
+ struct miscdevice mdev;
+ struct list_head list;
+ struct mcde_display_device *ddev;
+ struct mcde_overlay *ovly[NUM_COMPDEV_BUFS];
+ struct compdev_buffer ovly_buffer[NUM_COMPDEV_BUFS];
+ struct compdev_size phy_size;
+};
+
+static int compdev_open(struct inode *inode, struct file *file)
+{
+ struct compdev *cd = NULL;
+
+ mutex_lock(&dev_list_lock);
+ list_for_each_entry(cd, &dev_list, list)
+ if (cd->mdev.minor == iminor(inode))
+ break;
+
+ if (&cd->list == &dev_list) {
+ mutex_unlock(&dev_list_lock);
+ return -ENODEV;
+ }
+
+ if (cd->open) {
+ mutex_unlock(&dev_list_lock);
+ return -EBUSY;
+ }
+
+ cd->open = true;
+
+ mutex_unlock(&dev_list_lock);
+
+ file->private_data = cd;
+
+ return 0;
+}
+
+static int disable_overlay(struct mcde_overlay *ovly)
+{
+ struct mcde_overlay_info info;
+
+ mcde_dss_get_overlay_info(ovly, &info);
+ if (info.paddr != 0) {
+ /* Set the pointer to zero to disable the overlay */
+ info.paddr = 0;
+ mcde_dss_apply_overlay(ovly, &info);
+ }
+ return 0;
+}
+
+static int compdev_release(struct inode *inode, struct file *file)
+{
+ struct compdev *cd = NULL;
+ int i;
+
+ mutex_lock(&dev_list_lock);
+ list_for_each_entry(cd, &dev_list, list)
+ if (cd->mdev.minor == iminor(inode))
+ break;
+ mutex_unlock(&dev_list_lock);
+
+ if (&cd->list == &dev_list)
+ return -ENODEV;
+
+ for (i = 0; i < NUM_COMPDEV_BUFS; i++) {
+ disable_overlay(cd->ovly[i]);
+ if (cd->ovly_buffer[i].paddr &&
+ cd->ovly_buffer[i].type ==
+ COMPDEV_PTR_HWMEM_BUF_NAME_OFFSET)
+ hwmem_unpin(cd->ovly_buffer[i].alloc);
+
+ cd->ovly_buffer[i].alloc = NULL;
+ cd->ovly_buffer[i].size = 0;
+ cd->ovly_buffer[i].paddr = 0;
+ }
+
+ cd->open = false;
+ return 0;
+}
+
+static enum mcde_ovly_pix_fmt get_ovly_fmt(enum compdev_fmt fmt)
+{
+ switch (fmt) {
+ default:
+ case COMPDEV_FMT_RGB565:
+ return MCDE_OVLYPIXFMT_RGB565;
+ case COMPDEV_FMT_RGB888:
+ return MCDE_OVLYPIXFMT_RGB888;
+ case COMPDEV_FMT_RGBA8888:
+ return MCDE_OVLYPIXFMT_RGBA8888;
+ case COMPDEV_FMT_RGBX8888:
+ return MCDE_OVLYPIXFMT_RGBX8888;
+ case COMPDEV_FMT_YUV422:
+ return MCDE_OVLYPIXFMT_YCbCr422;
+ }
+}
+
+static int compdev_setup_ovly(struct compdev_img *img,
+ struct compdev_buffer *buffer,
+ struct mcde_overlay *ovly,
+ int z_order,
+ struct compdev *cd)
+{
+ int ret = 0;
+ enum hwmem_mem_type memtype;
+ enum hwmem_access access;
+ struct hwmem_mem_chunk mem_chunk;
+ size_t mem_chunk_length = 1;
+ struct hwmem_region rgn = { .offset = 0, .count = 1, .start = 0 };
+ struct mcde_overlay_info info;
+
+ if (img->buf.type == COMPDEV_PTR_HWMEM_BUF_NAME_OFFSET) {
+ buffer->type = COMPDEV_PTR_HWMEM_BUF_NAME_OFFSET;
+ buffer->alloc = hwmem_resolve_by_name(img->buf.hwmem_buf_name);
+ if (IS_ERR(buffer->alloc)) {
+ ret = PTR_ERR(buffer->alloc);
+ dev_warn(cd->mdev.this_device,
+ "HWMEM resolve failed, %d\n", ret);
+ goto resolve_failed;
+ }
+
+ hwmem_get_info(buffer->alloc, &buffer->size, &memtype,
+ &access);
+
+ if (!(access & HWMEM_ACCESS_READ) ||
+ memtype != HWMEM_MEM_CONTIGUOUS_SYS) {
+ ret = -EACCES;
+ dev_warn(cd->mdev.this_device,
+ "Invalid_mem overlay, %d\n", ret);
+ goto invalid_mem;
+ }
+ ret = hwmem_pin(buffer->alloc, &mem_chunk, &mem_chunk_length);
+ if (ret) {
+ dev_warn(cd->mdev.this_device,
+ "Pin failed, %d\n", ret);
+ goto pin_failed;
+ }
+
+ rgn.size = rgn.end = buffer->size;
+ ret = hwmem_set_domain(buffer->alloc, HWMEM_ACCESS_READ,
+ HWMEM_DOMAIN_SYNC, &rgn);
+ if (ret)
+ dev_warn(cd->mdev.this_device,
+ "Set domain failed, %d\n", ret);
+
+ buffer->paddr = mem_chunk.paddr;
+ } else if (img->buf.type == COMPDEV_PTR_PHYSICAL) {
+ buffer->type = COMPDEV_PTR_PHYSICAL;
+ buffer->alloc = NULL;
+ buffer->size = img->buf.len;
+ buffer->paddr = img->buf.offset;
+ }
+
+ info.stride = img->pitch;
+ info.fmt = get_ovly_fmt(img->fmt);
+ info.src_x = 0;
+ info.src_y = 0;
+ info.dst_x = img->dst_rect.x;
+ info.dst_y = img->dst_rect.y;
+ info.dst_z = z_order;
+ info.w = img->dst_rect.width;
+ info.h = img->dst_rect.height;
+ info.dirty.x = 0;
+ info.dirty.y = 0;
+ info.dirty.w = cd->phy_size.width;
+ info.dirty.h = cd->phy_size.height;
+ info.paddr = buffer->paddr;
+ mcde_dss_apply_overlay(ovly, &info);
+ return ret;
+
+pin_failed:
+invalid_mem:
+ buffer->alloc = NULL;
+ buffer->size = 0;
+ buffer->paddr = 0;
+
+resolve_failed:
+ return ret;
+}
+
+static int release_prev_frame(struct compdev *cd)
+{
+ int ret = 0;
+ int i;
+
+ /* Handle unpin of previous buffers */
+ for (i = 0; i < NUM_COMPDEV_BUFS; i++) {
+ if (cd->ovly_buffer[i].type ==
+ COMPDEV_PTR_HWMEM_BUF_NAME_OFFSET &&
+ cd->ovly_buffer[i].paddr != 0) {
+ hwmem_unpin(cd->ovly_buffer[i].alloc);
+ hwmem_release(cd->ovly_buffer[i].alloc);
+ }
+ cd->ovly_buffer[i].alloc = NULL;
+ cd->ovly_buffer[i].size = 0;
+ cd->ovly_buffer[i].paddr = 0;
+ }
+ return ret;
+
+}
+
+static void check_buffer(struct compdev *cd,
+ struct compdev_buffer *overlay_buffer,
+ struct compdev_buf *posted_buffer)
+{
+ if (overlay_buffer->type == COMPDEV_PTR_PHYSICAL &&
+ posted_buffer->type == COMPDEV_PTR_PHYSICAL &&
+ overlay_buffer->paddr == posted_buffer->offset &&
+ overlay_buffer->paddr != 0)
+ dev_warn(cd->mdev.this_device, "The same FB pointer!!\n");
+}
+
+static int compdev_post_buffers(struct compdev *cd,
+ struct compdev_post_buffers_req *req)
+{
+ int ret = 0;
+ int i, j;
+
+ for (i = 0; i < NUM_COMPDEV_BUFS; i++)
+ for (j = 0; j < NUM_COMPDEV_BUFS; j++)
+ check_buffer(cd, &cd->ovly_buffer[i],
+ &req->img_buffers[j].buf);
+
+ /* Unpin the previous frame */
+ release_prev_frame(cd);
+
+ /* Validate buffer count */
+ if (req->buffer_count > NUM_COMPDEV_BUFS || req->buffer_count == 0) {
+ dev_warn(cd->mdev.this_device,
+ "Illegal buffer count, will be clamped to %d\n",
+ NUM_COMPDEV_BUFS);
+ req->buffer_count = NUM_COMPDEV_BUFS;
+ }
+
+ /* Handle buffers */
+ for (i = 0; i < req->buffer_count; i++) {
+ int overlay_index = req->buffer_count - i - 1;
+ ret = compdev_setup_ovly(&req->img_buffers[i],
+ &cd->ovly_buffer[i], cd->ovly[overlay_index], i, cd);
+ if (ret)
+ dev_warn(cd->mdev.this_device,
+ "Failed to setup overlay[%d], %d\n", i, ret);
+ }
+
+ for (i = NUM_COMPDEV_BUFS; i > req->buffer_count; i--)
+ disable_overlay(cd->ovly[i-1]);
+
+ /* Do the display update */
+ if (req->buffer_count > 0)
+ mcde_dss_update_overlay(cd->ovly[0], false);
+ else
+ dev_warn(cd->mdev.this_device, "No overlays requested\n");
+ return ret;
+}
+
+static long compdev_ioctl(struct file *file,
+ unsigned int cmd,
+ unsigned long arg)
+{
+ int ret;
+ struct compdev *cd = (struct compdev *)file->private_data;
+ struct compdev_post_buffers_req req;
+
+ mutex_lock(&cd->lock);
+
+ switch (cmd) {
+ case COMPDEV_GET_SIZE_IOC:
+ ret = copy_to_user((void __user *)arg, &cd->phy_size,
+ sizeof(cd->phy_size));
+ if (ret)
+ ret = -EFAULT;
+ break;
+ case COMPDEV_POST_BUFFERS_IOC:
+ /* arg is user pointer to struct compdev_post_buffers_req */
+
+ /* Initialize the structure */
+ memset(&req, 0, sizeof(req));
+
+ /*
+ * The user request is a sub structure of the
+ * kernel request structure.
+ */
+
+ /* Get the user data */
+ if (copy_from_user(&req, (void *)arg, sizeof(req))) {
+ dev_warn(cd->mdev.this_device,
+ "%s: copy_from_user failed\n",
+ __func__);
+ mutex_unlock(&cd->lock);
+ return -EFAULT;
+ }
+
+ ret = compdev_post_buffers(cd, &req);
+
+ break;
+ default:
+ ret = -ENOSYS;
+ }
+
+ mutex_unlock(&cd->lock);
+
+ return ret;
+}
+
+static const struct file_operations compdev_fops = {
+ .open = compdev_open,
+ .release = compdev_release,
+ .unlocked_ioctl = compdev_ioctl,
+};
+
+static void init_compdev(struct compdev *cd, struct mcde_display_device *ddev,
+ const char *name)
+{
+ mutex_init(&cd->lock);
+ INIT_LIST_HEAD(&cd->list);
+ cd->ddev = ddev;
+ cd->mdev.minor = MISC_DYNAMIC_MINOR;
+ cd->mdev.name = name;
+ cd->mdev.fops = &compdev_fops;
+}
+
+int compdev_create(struct mcde_display_device *ddev,
+ struct mcde_overlay *parent_ovly)
+{
+ int ret = 0;
+ int i;
+ struct compdev *cd;
+ struct mcde_video_mode vmode;
+ struct mcde_overlay_info info;
+
+ static int counter;
+ char name[10];
+
+ cd = kzalloc(sizeof(struct compdev), GFP_KERNEL);
+ if (!cd)
+ return -ENOMEM;
+
+ snprintf(name, sizeof(name), "%s%d", COMPDEV_DEFAULT_DEVICE_PREFIX,
+ counter++);
+ init_compdev(cd, ddev, name);
+ mcde_dss_get_video_mode(ddev, &vmode);
+
+ cd->ovly[0] = parent_ovly;
+ if (!cd->ovly[0]) {
+ ret = -ENOMEM;
+ goto fail_create_ovly;
+ }
+
+ for (i = 1; i < NUM_COMPDEV_BUFS; i++) {
+ cd->ovly[i] = mcde_dss_create_overlay(ddev, &info);
+ if (!cd->ovly[i]) {
+ ret = -ENOMEM;
+ goto fail_create_ovly;
+ }
+ mcde_dss_enable_overlay(cd->ovly[i]);
+ disable_overlay(cd->ovly[i]);
+ }
+
+ mcde_dss_get_native_resolution(ddev, &cd->phy_size.width,
+ &cd->phy_size.height);
+
+ ret = misc_register(&cd->mdev);
+ if (ret)
+ goto fail_register_misc;
+ mutex_lock(&dev_list_lock);
+ list_add_tail(&cd->list, &dev_list);
+ mutex_unlock(&dev_list_lock);
+
+ goto out;
+
+fail_register_misc:
+fail_create_ovly:
+ for (i = 0; i < NUM_COMPDEV_BUFS; i++) {
+ if (cd->ovly[i])
+ mcde_dss_destroy_overlay(cd->ovly[i]);
+ }
+ kfree(cd);
+out:
+ return ret;
+}
+
+void compdev_destroy(struct mcde_display_device *ddev)
+{
+ struct compdev *cd;
+ struct compdev *tmp;
+ int i;
+
+ mutex_lock(&dev_list_lock);
+ list_for_each_entry_safe(cd, tmp, &dev_list, list) {
+ if (cd->ddev == ddev) {
+ list_del(&cd->list);
+ misc_deregister(&cd->mdev);
+ for (i = 0; i < NUM_COMPDEV_BUFS; i++)
+ mcde_dss_destroy_overlay(cd->ovly[i]);
+ kfree(cd);
+ break;
+ }
+ }
+ mutex_unlock(&dev_list_lock);
+}
+
+static void compdev_destroy_all(void)
+{
+ struct compdev *cd;
+ struct compdev *tmp;
+ int i;
+
+ mutex_lock(&dev_list_lock);
+ list_for_each_entry_safe(cd, tmp, &dev_list, list) {
+ list_del(&cd->list);
+ misc_deregister(&cd->mdev);
+ for (i = 0; i < NUM_COMPDEV_BUFS; i++)
+ mcde_dss_destroy_overlay(cd->ovly[i]);
+ kfree(cd);
+ }
+ mutex_unlock(&dev_list_lock);
+
+ mutex_destroy(&dev_list_lock);
+}
+
+static int __init compdev_init(void)
+{
+ pr_info("%s\n", __func__);
+
+ mutex_init(&dev_list_lock);
+
+ return 0;
+}
+module_init(compdev_init);
+
+static void __exit compdev_exit(void)
+{
+ compdev_destroy_all();
+ pr_info("%s\n", __func__);
+}
+module_exit(compdev_exit);
+
+MODULE_AUTHOR("Anders Bauer <anders.bauer@stericsson.com>");
+MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Display overlay device driver");
+
diff --git a/include/linux/compdev.h b/include/linux/compdev.h
new file mode 100644
index 00000000000..9e707c7b770
--- /dev/null
+++ b/include/linux/compdev.h
@@ -0,0 +1,106 @@
+/*
+ * Copyright (C) ST-Ericsson SA 2011
+ *
+ * ST-Ericsson Display overlay compositer device driver
+ *
+ * Author: Anders Bauer <anders.bauer@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * Modified: Per-Daniel Olsson <per-daniel.olsson@stericsson.com>
+ * for ST-Ericsson.
+ *
+ * License terms: GNU General Public License (GPL), version 2.
+ */
+
+#ifndef _COMPDEV_H_
+#define _COMPDEV_H_
+
+#if !defined(__KERNEL__) && !defined(_KERNEL)
+#include <stdint.h>
+#else
+#include <linux/types.h>
+#include <video/mcde.h>
+#endif
+
+#if defined(__KERNEL__) || defined(_KERNEL)
+#include <linux/mm_types.h>
+#include <linux/bitops.h>
+#else
+#define BIT(nr) (1UL << (nr))
+#endif
+
+#define COMPDEV_DEFAULT_DEVICE_PREFIX "comp"
+#define NUM_COMPDEV_BUFS 2
+
+enum compdev_fmt {
+ COMPDEV_FMT_RGB565,
+ COMPDEV_FMT_RGB888,
+ COMPDEV_FMT_RGBX8888,
+ COMPDEV_FMT_RGBA8888,
+ COMPDEV_FMT_YUV422,
+};
+
+struct compdev_size {
+ uint16_t width;
+ uint16_t height;
+};
+
+/* Display rotation */
+enum compdev_rotation {
+ COMPDEV_ROT_0 = 0,
+ COMPDEV_ROT_90_CCW = 90,
+ COMPDEV_ROT_180_CCW = 180,
+ COMPDEV_ROT_270_CCW = 270,
+ COMPDEV_ROT_90_CW = COMPDEV_ROT_270_CCW,
+ COMPDEV_ROT_180_CW = COMPDEV_ROT_180_CCW,
+ COMPDEV_ROT_270_CW = COMPDEV_ROT_90_CCW,
+};
+
+enum compdev_ptr_type {
+ COMPDEV_PTR_PHYSICAL,
+ COMPDEV_PTR_HWMEM_BUF_NAME_OFFSET,
+};
+
+struct compdev_rect {
+ __s32 x;
+ __s32 y;
+ __s32 width;
+ __s32 height;
+};
+
+struct compdev_buf {
+ enum compdev_ptr_type type;
+ __s32 hwmem_buf_name;
+ __s32 fd;
+ __u32 offset;
+ __u32 len;
+};
+
+struct compdev_img {
+ enum compdev_fmt fmt;
+ struct compdev_buf buf;
+ __s32 width;
+ __s32 height;
+ __u32 pitch;
+ struct compdev_rect dst_rect;
+};
+
+struct compdev_post_buffers_req {
+ enum compdev_rotation rotation;
+ struct compdev_img img_buffers[NUM_COMPDEV_BUFS];
+ __u8 buffer_count;
+};
+
+#define COMPDEV_GET_SIZE_IOC _IOR('D', 1, struct compdev_size)
+#define COMPDEV_POST_BUFFERS_IOC _IOW('D', 2, struct compdev_post_buffers_req)
+
+#ifdef __KERNEL__
+
+int compdev_create(struct mcde_display_device *ddev,
+ struct mcde_overlay *parent_ovly);
+void compdev_destroy(struct mcde_display_device *ddev);
+
+#endif /* __KERNEL__ */
+
+#endif /* _COMPDEV_H_ */
+