summaryrefslogtreecommitdiffstats
path: root/drivers/video/fbdev/omap2/dss/output.c
diff options
context:
space:
mode:
authorArnd Bergmann <arnd@arndb.de>2014-04-24 23:46:58 +0200
committerArnd Bergmann <arnd@arndb.de>2014-04-24 23:46:58 +0200
commit1fc52762e33cc905331681364d79424d921f60f2 (patch)
treed7347407cbbdb7a0565e3b4d09aaf40f0705491a /drivers/video/fbdev/omap2/dss/output.c
parent9ef1af9ea28c23d0eaed97f7f5142788b6cf570a (diff)
parentcf2e0a73ca9ad376825c013ebaa145608abc27d7 (diff)
downloadop-kernel-dev-1fc52762e33cc905331681364d79424d921f60f2.zip
op-kernel-dev-1fc52762e33cc905331681364d79424d921f60f2.tar.gz
Merge tag 'vexpress/fixes-for-3.15' of git://git.linaro.org/people/pawel.moll/linux into fixes
ARM Versatile Express fixes for 3.15 This series contains straight-forward fixes for different Versatile Express infrastructure drivers: - NULL pointer dereference on the error path in the clk driver - out of boundary array access in the dcscb driver - broken restart/power off implementation - mis-interpreted voltage unit in the spc driver * tag 'vexpress/fixes-for-3.15' of git://git.linaro.org/people/pawel.moll/linux: ARM: vexpress/TC2: Convert OPP voltage to uV before storing power/reset: vexpress: Fix restart/power off operation arm/mach-vexpress: array accessed out of bounds clk: vexpress: NULL dereference on error path Includes an update to 3.15-rc2 Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Diffstat (limited to 'drivers/video/fbdev/omap2/dss/output.c')
-rw-r--r--drivers/video/fbdev/omap2/dss/output.c254
1 files changed, 254 insertions, 0 deletions
diff --git a/drivers/video/fbdev/omap2/dss/output.c b/drivers/video/fbdev/omap2/dss/output.c
new file mode 100644
index 0000000..2ab3afa
--- /dev/null
+++ b/drivers/video/fbdev/omap2/dss/output.c
@@ -0,0 +1,254 @@
+/*
+ * Copyright (C) 2012 Texas Instruments Ltd
+ * Author: Archit Taneja <archit@ti.com>
+ *
+ * This program is free software; you can redistribute it and/or modify it
+ * under the terms of the GNU General Public License version 2 as published by
+ * the Free Software Foundation.
+ *
+ * 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.
+ *
+ * You should have received a copy of the GNU General Public License along with
+ * this program. If not, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+#include <video/omapdss.h>
+
+#include "dss.h"
+
+static LIST_HEAD(output_list);
+static DEFINE_MUTEX(output_lock);
+
+int omapdss_output_set_device(struct omap_dss_device *out,
+ struct omap_dss_device *dssdev)
+{
+ int r;
+
+ mutex_lock(&output_lock);
+
+ if (out->dst) {
+ DSSERR("output already has device %s connected to it\n",
+ out->dst->name);
+ r = -EINVAL;
+ goto err;
+ }
+
+ if (out->output_type != dssdev->type) {
+ DSSERR("output type and display type don't match\n");
+ r = -EINVAL;
+ goto err;
+ }
+
+ out->dst = dssdev;
+ dssdev->src = out;
+
+ mutex_unlock(&output_lock);
+
+ return 0;
+err:
+ mutex_unlock(&output_lock);
+
+ return r;
+}
+EXPORT_SYMBOL(omapdss_output_set_device);
+
+int omapdss_output_unset_device(struct omap_dss_device *out)
+{
+ int r;
+
+ mutex_lock(&output_lock);
+
+ if (!out->dst) {
+ DSSERR("output doesn't have a device connected to it\n");
+ r = -EINVAL;
+ goto err;
+ }
+
+ if (out->dst->state != OMAP_DSS_DISPLAY_DISABLED) {
+ DSSERR("device %s is not disabled, cannot unset device\n",
+ out->dst->name);
+ r = -EINVAL;
+ goto err;
+ }
+
+ out->dst->src = NULL;
+ out->dst = NULL;
+
+ mutex_unlock(&output_lock);
+
+ return 0;
+err:
+ mutex_unlock(&output_lock);
+
+ return r;
+}
+EXPORT_SYMBOL(omapdss_output_unset_device);
+
+int omapdss_register_output(struct omap_dss_device *out)
+{
+ list_add_tail(&out->list, &output_list);
+ return 0;
+}
+EXPORT_SYMBOL(omapdss_register_output);
+
+void omapdss_unregister_output(struct omap_dss_device *out)
+{
+ list_del(&out->list);
+}
+EXPORT_SYMBOL(omapdss_unregister_output);
+
+struct omap_dss_device *omap_dss_get_output(enum omap_dss_output_id id)
+{
+ struct omap_dss_device *out;
+
+ list_for_each_entry(out, &output_list, list) {
+ if (out->id == id)
+ return out;
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(omap_dss_get_output);
+
+struct omap_dss_device *omap_dss_find_output(const char *name)
+{
+ struct omap_dss_device *out;
+
+ list_for_each_entry(out, &output_list, list) {
+ if (strcmp(out->name, name) == 0)
+ return omap_dss_get_device(out);
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(omap_dss_find_output);
+
+struct omap_dss_device *omap_dss_find_output_by_node(struct device_node *node)
+{
+ struct omap_dss_device *out;
+
+ list_for_each_entry(out, &output_list, list) {
+ if (out->dev->of_node == node)
+ return omap_dss_get_device(out);
+ }
+
+ return NULL;
+}
+EXPORT_SYMBOL(omap_dss_find_output_by_node);
+
+struct omap_dss_device *omapdss_find_output_from_display(struct omap_dss_device *dssdev)
+{
+ while (dssdev->src)
+ dssdev = dssdev->src;
+
+ if (dssdev->id != 0)
+ return omap_dss_get_device(dssdev);
+
+ return NULL;
+}
+EXPORT_SYMBOL(omapdss_find_output_from_display);
+
+struct omap_overlay_manager *omapdss_find_mgr_from_display(struct omap_dss_device *dssdev)
+{
+ struct omap_dss_device *out;
+ struct omap_overlay_manager *mgr;
+
+ out = omapdss_find_output_from_display(dssdev);
+
+ if (out == NULL)
+ return NULL;
+
+ mgr = out->manager;
+
+ omap_dss_put_device(out);
+
+ return mgr;
+}
+EXPORT_SYMBOL(omapdss_find_mgr_from_display);
+
+static const struct dss_mgr_ops *dss_mgr_ops;
+
+int dss_install_mgr_ops(const struct dss_mgr_ops *mgr_ops)
+{
+ if (dss_mgr_ops)
+ return -EBUSY;
+
+ dss_mgr_ops = mgr_ops;
+
+ return 0;
+}
+EXPORT_SYMBOL(dss_install_mgr_ops);
+
+void dss_uninstall_mgr_ops(void)
+{
+ dss_mgr_ops = NULL;
+}
+EXPORT_SYMBOL(dss_uninstall_mgr_ops);
+
+int dss_mgr_connect(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *dst)
+{
+ return dss_mgr_ops->connect(mgr, dst);
+}
+EXPORT_SYMBOL(dss_mgr_connect);
+
+void dss_mgr_disconnect(struct omap_overlay_manager *mgr,
+ struct omap_dss_device *dst)
+{
+ dss_mgr_ops->disconnect(mgr, dst);
+}
+EXPORT_SYMBOL(dss_mgr_disconnect);
+
+void dss_mgr_set_timings(struct omap_overlay_manager *mgr,
+ const struct omap_video_timings *timings)
+{
+ dss_mgr_ops->set_timings(mgr, timings);
+}
+EXPORT_SYMBOL(dss_mgr_set_timings);
+
+void dss_mgr_set_lcd_config(struct omap_overlay_manager *mgr,
+ const struct dss_lcd_mgr_config *config)
+{
+ dss_mgr_ops->set_lcd_config(mgr, config);
+}
+EXPORT_SYMBOL(dss_mgr_set_lcd_config);
+
+int dss_mgr_enable(struct omap_overlay_manager *mgr)
+{
+ return dss_mgr_ops->enable(mgr);
+}
+EXPORT_SYMBOL(dss_mgr_enable);
+
+void dss_mgr_disable(struct omap_overlay_manager *mgr)
+{
+ dss_mgr_ops->disable(mgr);
+}
+EXPORT_SYMBOL(dss_mgr_disable);
+
+void dss_mgr_start_update(struct omap_overlay_manager *mgr)
+{
+ dss_mgr_ops->start_update(mgr);
+}
+EXPORT_SYMBOL(dss_mgr_start_update);
+
+int dss_mgr_register_framedone_handler(struct omap_overlay_manager *mgr,
+ void (*handler)(void *), void *data)
+{
+ return dss_mgr_ops->register_framedone_handler(mgr, handler, data);
+}
+EXPORT_SYMBOL(dss_mgr_register_framedone_handler);
+
+void dss_mgr_unregister_framedone_handler(struct omap_overlay_manager *mgr,
+ void (*handler)(void *), void *data)
+{
+ dss_mgr_ops->unregister_framedone_handler(mgr, handler, data);
+}
+EXPORT_SYMBOL(dss_mgr_unregister_framedone_handler);
OpenPOWER on IntegriCloud