summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorRob Clark <rob@ti.com>2010-08-24 18:30:32 -0500
committerMayuresh Janorkar <mayur@ti.com>2010-08-25 21:20:38 +0530
commitcad4d0cbccef79a4dffef7b37fc485eb5cba7952 (patch)
tree583f5ca9ef72566669da164752e9854658b1249c /drivers
parentd4baddaaf0f9bac6f5100f992d06b7805b895599 (diff)
OMAP4:DSS: add generic notifier mechanism
A callback can be registered by the dssdev client in order to be notified of resolution changes, for example an external monitor that is hot-plugged. Multiple clients can now register for notification from one dssdev, and the notification mechanism can be extended in the future to add other events. Note that this patch supersedes the "OMAP4:DSS: add callback to notify client of resolution change" patch.
Diffstat (limited to 'drivers')
-rwxr-xr-xdrivers/video/omap2/dss/core.c3
-rw-r--r--drivers/video/omap2/dss/display.c55
-rw-r--r--drivers/video/omap2/dss/hdmi.c2
3 files changed, 33 insertions, 27 deletions
diff --git a/drivers/video/omap2/dss/core.c b/drivers/video/omap2/dss/core.c
index 00f68cb5f293..854be93f4c4a 100755
--- a/drivers/video/omap2/dss/core.c
+++ b/drivers/video/omap2/dss/core.c
@@ -1111,6 +1111,9 @@ int omap_dss_register_device(struct omap_dss_device *dssdev)
dssdev->dev.parent = &dss_bus;
dssdev->dev.release = omap_dss_dev_release;
dev_set_name(&dssdev->dev, "display%d", dev_num++);
+
+ BLOCKING_INIT_NOTIFIER_HEAD(&dssdev->notifier);
+
return device_register(&dssdev->dev);
}
diff --git a/drivers/video/omap2/dss/display.c b/drivers/video/omap2/dss/display.c
index 94e4ce0d7450..443cf1109d3b 100644
--- a/drivers/video/omap2/dss/display.c
+++ b/drivers/video/omap2/dss/display.c
@@ -709,44 +709,47 @@ EXPORT_SYMBOL(omap_dss_stop_device);
/* since omap_dss_update_size can be called in irq context, schedule work from
* work-queue to deliver notification to client..
*/
-struct update_size_work {
+struct notify_work {
struct work_struct work;
struct omap_dss_device *dssdev;
- int w, h;
+ enum omap_dss_event evt;
};
-static void update_size_worker(struct work_struct *work)
+static void notify_worker(struct work_struct *work)
{
- struct update_size_work *usw =
- container_of(work, struct update_size_work, work);
- if (usw->dssdev->size_notify) {
- usw->dssdev->size_notify(usw->dssdev->size_notify_arg, usw->w, usw->h);
- }
+ struct notify_work *nw =
+ container_of(work, struct notify_work, work);
+ struct omap_dss_device *dssdev = nw->dssdev;
+ blocking_notifier_call_chain(&dssdev->notifier, nw->evt, dssdev);
kfree(work);
}
/**
- * Called by lower level driver to notify about a change in resolution, for
- * example in response to a hot-plug event..
+ * Called by lower level driver to notify about a change in resolution, etc.
*/
-void omap_dss_update_size(struct omap_dss_device *dssdev, int w, int h)
-{
- struct update_size_work *usw =
- kmalloc(sizeof(struct update_size_work), GFP_KERNEL);
- if (usw) {
- INIT_WORK(&usw->work, update_size_worker);
- usw->dssdev = dssdev;
- usw->w = w;
- usw->h = h;
- schedule_work(&usw->work);
+void omap_dss_notify(struct omap_dss_device *dssdev, enum omap_dss_event evt)
+{
+ struct notify_work *nw =
+ kmalloc(sizeof(struct notify_work), GFP_KERNEL);
+ if (nw) {
+ INIT_WORK(&nw->work, notify_worker);
+ nw->dssdev = dssdev;
+ nw->evt = evt;
+ schedule_work(&nw->work);
}
}
-EXPORT_SYMBOL(omap_dss_update_size);
+EXPORT_SYMBOL(omap_dss_notify);
+
+void omap_dss_add_notify(struct omap_dss_device *dssdev,
+ struct notifier_block *nb)
+{
+ blocking_notifier_chain_register(&dssdev->notifier, nb);
+}
+EXPORT_SYMBOL(omap_dss_add_notify);
-void omap_dss_set_size_notify(struct omap_dss_device *dssdev,
- void (*notify)(void *arg, int w, int h), void *arg)
+void omap_dss_remove_notify(struct omap_dss_device *dssdev,
+ struct notifier_block *nb)
{
- dssdev->size_notify_arg = arg;
- dssdev->size_notify = notify;
+ blocking_notifier_chain_unregister(&dssdev->notifier, nb);
}
-EXPORT_SYMBOL(omap_dss_set_size_notify);
+EXPORT_SYMBOL(omap_dss_remove_notify);
diff --git a/drivers/video/omap2/dss/hdmi.c b/drivers/video/omap2/dss/hdmi.c
index 04e16033d175..b820f4d30eeb 100644
--- a/drivers/video/omap2/dss/hdmi.c
+++ b/drivers/video/omap2/dss/hdmi.c
@@ -705,7 +705,7 @@ static int hdmi_power_on(struct omap_dss_device *dssdev)
dispc_enable_digit_out(0);
if (dirty) {
- omap_dss_update_size(dssdev, p->x_res, p->y_res);
+ omap_dss_notify(dssdev, OMAP_DSS_SIZE_CHANGE);
}
/* config the PLL and PHY first */