diff options
author | Robert Morell <rmorell@nvidia.com> | 2011-03-03 13:04:00 -0800 |
---|---|---|
committer | Dan Willemsen <dwillemsen@nvidia.com> | 2011-11-30 21:48:11 -0800 |
commit | 4d785e53437e27a0bbf57f26c66dcad3bacd35f0 (patch) | |
tree | 59ec45c90e9462c8298ec504107588880a9a198f /drivers/video/tegra/dc | |
parent | 6964bbc3358ef35caf426fc06490a9359a91ab6b (diff) |
video: tegra: Add skeleton support for extensions
This adds the infrasturcture for an enhanced driver interface to program
extended capabilities of the Tegra display controller.
It exposes a new set of device nodes for userspace clients distinct from
the traditional fbdev device nodes. This is necessary due to
limitations in the fbdev infrastructure that don't allow drivers to
store file-private data.
bug 818525
Original-Change-Id: I06cecf894792b9904c73f9ebcdeb746ff7455f6e
Signed-off-by: Robert Morell <rmorell@nvidia.com>
Reviewed-on: http://git-master/r/40512
Reviewed-by: Jonathan Mayo <jmayo@nvidia.com>
Rebase-Id: Rfa3969804d7f52c841be1ff96305c9463077e1c5
Diffstat (limited to 'drivers/video/tegra/dc')
-rw-r--r-- | drivers/video/tegra/dc/Makefile | 1 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc.c | 12 | ||||
-rw-r--r-- | drivers/video/tegra/dc/dc_priv.h | 4 | ||||
-rw-r--r-- | drivers/video/tegra/dc/ext/Makefile | 1 | ||||
-rw-r--r-- | drivers/video/tegra/dc/ext/dev.c | 141 | ||||
-rw-r--r-- | drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h | 33 |
6 files changed, 192 insertions, 0 deletions
diff --git a/drivers/video/tegra/dc/Makefile b/drivers/video/tegra/dc/Makefile index 63044cafd638..90b03892673c 100644 --- a/drivers/video/tegra/dc/Makefile +++ b/drivers/video/tegra/dc/Makefile @@ -7,3 +7,4 @@ obj-y += nvsd.o obj-y += dsi.o obj-y += dc_sysfs.o obj-$(CONFIG_TEGRA_OVERLAY) += overlay.o +obj-$(CONFIG_TEGRA_DC_EXTENSIONS) += ext/ diff --git a/drivers/video/tegra/dc/dc.c b/drivers/video/tegra/dc/dc.c index f6488ad7699e..a0e8c45098ef 100644 --- a/drivers/video/tegra/dc/dc.c +++ b/drivers/video/tegra/dc/dc.c @@ -2371,6 +2371,12 @@ static int tegra_dc_probe(struct nvhost_device *ndev) if (dc->out && dc->out->hotplug_init) dc->out->hotplug_init(); + dc->ext = tegra_dc_ext_register(ndev, dc); + if (IS_ERR_OR_NULL(dc->ext)) { + dev_warn(&ndev->dev, "Failed to enable Tegra DC extensions.\n"); + dc->ext = NULL; + } + if (dc->out_ops && dc->out_ops->detect) dc->out_ops->detect(dc); @@ -2413,6 +2419,8 @@ static int tegra_dc_remove(struct nvhost_device *ndev) release_resource(dc->fb_mem); } + if (dc->ext) + tegra_dc_ext_unregister(dc->ext); if (dc->enabled) _tegra_dc_disable(dc); @@ -2522,12 +2530,16 @@ struct nvhost_driver tegra_dc_driver = { static int __init tegra_dc_module_init(void) { + int ret = tegra_dc_ext_module_init(); + if (ret) + return ret; return nvhost_driver_register(&tegra_dc_driver); } static void __exit tegra_dc_module_exit(void) { nvhost_driver_unregister(&tegra_dc_driver); + tegra_dc_ext_module_exit(); } module_exit(tegra_dc_module_exit); diff --git a/drivers/video/tegra/dc/dc_priv.h b/drivers/video/tegra/dc/dc_priv.h index ebd339c489c2..4bf429f7e68c 100644 --- a/drivers/video/tegra/dc/dc_priv.h +++ b/drivers/video/tegra/dc/dc_priv.h @@ -28,6 +28,8 @@ #include "../host/dev.h" #include "../host/t20/syncpt_t20.h" +#include <mach/tegra_dc_ext.h> + #define WIN_IS_TILED(win) ((win)->flags & TEGRA_WIN_FLAG_TILED) #define WIN_IS_ENABLED(win) ((win)->flags & TEGRA_WIN_FLAG_ENABLED) #define WIN_USE_V_FILTER(win) ((win)->flags & TEGRA_WIN_FLAG_V_FILTER) @@ -121,6 +123,8 @@ struct tegra_dc { unsigned underflows_c; } stats; + struct tegra_dc_ext *ext; + #ifdef CONFIG_DEBUG_FS struct dentry *debugdir; #endif diff --git a/drivers/video/tegra/dc/ext/Makefile b/drivers/video/tegra/dc/ext/Makefile new file mode 100644 index 000000000000..44c52311b4e3 --- /dev/null +++ b/drivers/video/tegra/dc/ext/Makefile @@ -0,0 +1 @@ +obj-y += dev.o diff --git a/drivers/video/tegra/dc/ext/dev.c b/drivers/video/tegra/dc/ext/dev.c new file mode 100644 index 000000000000..6fe778896241 --- /dev/null +++ b/drivers/video/tegra/dc/ext/dev.c @@ -0,0 +1,141 @@ +/* + * drivers/video/tegra/dc/dev.c + * + * Copyright (C) 2011, NVIDIA Corporation + * + * Author: Robert Morell <rmorell@nvidia.com> + * Some code based on fbdev extensions written by: + * Erik Gilling <konkers@android.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#include <linux/file.h> +#include <linux/fs.h> +#include <linux/slab.h> + +#include <mach/dc.h> +#include <mach/tegra_dc_ext.h> + +#include "tegra_dc_ext_priv.h" + +static int tegra_dc_ext_devno; +static struct class *tegra_dc_ext_class; + +static int tegra_dc_release(struct inode *inode, struct file *filp) +{ + struct tegra_dc_ext_user *user = filp->private_data; + + kfree(user); + + return 0; +} + +static int tegra_dc_open(struct inode *inode, struct file *filp) +{ + struct tegra_dc_ext_user *user; + + user = kzalloc(sizeof(*user), GFP_KERNEL); + if (!user) + return -ENOMEM; + + filp->private_data = user; + + return 0; +} + +static long tegra_dc_ioctl(struct file *filp, unsigned int cmd, + unsigned long arg) +{ + return 0; +} + +static const struct file_operations tegra_dc_devops = { + .owner = THIS_MODULE, + .open = tegra_dc_open, + .release = tegra_dc_release, + .unlocked_ioctl = tegra_dc_ioctl, +}; + +struct tegra_dc_ext *tegra_dc_ext_register(struct nvhost_device *ndev, + struct tegra_dc *dc) +{ + int ret; + struct tegra_dc_ext *ext; + + ext = kzalloc(sizeof(*ext), GFP_KERNEL); + if (!ext) + return ERR_PTR(-ENOMEM); + + BUG_ON(!tegra_dc_ext_devno); + cdev_init(&ext->cdev, &tegra_dc_devops); + ext->cdev.owner = THIS_MODULE; + ret = cdev_add(&ext->cdev, tegra_dc_ext_devno, 1); + if (ret) { + dev_err(&ndev->dev, "Failed to create character device\n"); + goto cleanup_alloc; + } + + ext->dev = device_create(tegra_dc_ext_class, + &ndev->dev, + tegra_dc_ext_devno, + NULL, + "tegra_dc_%d", + ndev->id); + + if (IS_ERR(ext->dev)) { + ret = PTR_ERR(ext->dev); + goto cleanup_cdev; + } + + tegra_dc_ext_devno++; + + return ext; + +cleanup_cdev: + cdev_del(&ext->cdev); + +cleanup_alloc: + kfree(ext); + + return ERR_PTR(ret); +} + +void tegra_dc_ext_unregister(struct tegra_dc_ext *ext) +{ + cdev_del(&ext->cdev); + kfree(ext); +} + +int __init tegra_dc_ext_module_init(void) +{ + int ret; + + tegra_dc_ext_class = class_create(THIS_MODULE, "tegra_dc_ext"); + if (!tegra_dc_ext_class) { + printk(KERN_ERR "tegra_dc_ext: failed to create class\n"); + return -ENOMEM; + } + + ret = alloc_chrdev_region(&tegra_dc_ext_devno, + 0, TEGRA_MAX_DC, + "tegra_dc_ext"); + if (ret) + class_destroy(tegra_dc_ext_class); + + return ret; +} + +void __exit tegra_dc_ext_module_exit(void) +{ + unregister_chrdev_region(tegra_dc_ext_devno, TEGRA_MAX_DC); + class_destroy(tegra_dc_ext_class); +} diff --git a/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h b/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h new file mode 100644 index 000000000000..387af543c511 --- /dev/null +++ b/drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h @@ -0,0 +1,33 @@ +/* + * drivers/video/tegra/dc/ext/tegra_dc_ext_priv.h + * + * Copyright (C) 2011, NVIDIA Corporation + * + * Author: Robert Morell <rmorell@nvidia.com> + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License as published by + * the Free Software Foundation; either version 2 of the License, or + * (at your option) any later version. + * + * This program is distributed in the hope that it will be useful, but WITHOUT + * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or + * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License for + * more details. + */ + +#ifndef __TEGRA_DC_EXT_PRIV_H +#define __TEGRA_DC_EXT_PRIV_H + +#include <linux/cdev.h> + +struct tegra_dc_ext { + struct cdev cdev; + struct device *dev; +}; + +struct tegra_dc_ext_user { + +}; + +#endif /* __TEGRA_DC_EXT_PRIV_H */ |