diff options
author | Rob Clark <rob@ti.com> | 2010-08-24 18:30:32 -0500 |
---|---|---|
committer | Mayuresh Janorkar <mayur@ti.com> | 2010-08-25 21:20:38 +0530 |
commit | cad4d0cbccef79a4dffef7b37fc485eb5cba7952 (patch) | |
tree | 583f5ca9ef72566669da164752e9854658b1249c /drivers | |
parent | d4baddaaf0f9bac6f5100f992d06b7805b895599 (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-x | drivers/video/omap2/dss/core.c | 3 | ||||
-rw-r--r-- | drivers/video/omap2/dss/display.c | 55 | ||||
-rw-r--r-- | drivers/video/omap2/dss/hdmi.c | 2 |
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 */ |