aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/video/omap2/dsscomp/device.c4
-rw-r--r--drivers/video/omap2/dsscomp/dsscomp.h3
-rw-r--r--drivers/video/omap2/dsscomp/queue.c36
3 files changed, 40 insertions, 3 deletions
diff --git a/drivers/video/omap2/dsscomp/device.c b/drivers/video/omap2/dsscomp/device.c
index eb57c4a..773931a 100644
--- a/drivers/video/omap2/dsscomp/device.c
+++ b/drivers/video/omap2/dsscomp/device.c
@@ -369,6 +369,10 @@ static void fill_cache(struct dsscomp_dev *cdev)
cdev->displays[i] = dssdev;
dev_dbg(DEV(cdev), "display%lu=%s\n", i, dssdev->driver_name);
+
+ cdev->state_notifiers[i].notifier_call = dsscomp_state_notifier;
+ blocking_notifier_chain_register(&dssdev->state_notifiers,
+ cdev->state_notifiers + i);
}
dev_info(DEV(cdev), "found %d displays and %d overlays\n",
cdev->num_displays, cdev->num_ovls);
diff --git a/drivers/video/omap2/dsscomp/dsscomp.h b/drivers/video/omap2/dsscomp/dsscomp.h
index 6deeda0..82e50cd 100644
--- a/drivers/video/omap2/dsscomp/dsscomp.h
+++ b/drivers/video/omap2/dsscomp/dsscomp.h
@@ -59,6 +59,7 @@ struct dsscomp_dev {
struct omap_overlay_manager *mgrs[MAX_MANAGERS];
u32 num_displays;
struct omap_dss_device *displays[MAX_DISPLAYS];
+ struct notifier_block state_notifiers[MAX_DISPLAYS];
};
extern int debug;
@@ -112,6 +113,8 @@ void dsscomp_gralloc_exit(void);
int dsscomp_gralloc_queue_ioctl(struct dsscomp_setup_dispc_data *d);
int dsscomp_wait(struct dsscomp_sync_obj *sync, enum dsscomp_wait_phase phase,
int timeout);
+int dsscomp_state_notifier(struct notifier_block *nb,
+ unsigned long arg, void *ptr);
/* basic operation - if not using queues */
int set_dss_ovl_info(struct dss2_ovl_info *oi);
diff --git a/drivers/video/omap2/dsscomp/queue.c b/drivers/video/omap2/dsscomp/queue.c
index 3616ccd..0f8c8a6 100644
--- a/drivers/video/omap2/dsscomp/queue.c
+++ b/drivers/video/omap2/dsscomp/queue.c
@@ -23,6 +23,7 @@
#include <linux/vmalloc.h>
#include <linux/sched.h>
#include <linux/slab.h>
+#include <linux/ratelimit.h>
#include <video/omapdss.h>
#include <video/dsscomp.h>
@@ -44,6 +45,7 @@ static struct {
u32 ovl_mask; /* overlays used on this display */
struct maskref ovl_qmask; /* overlays queued to this display */
+ bool blanking;
} mgrq[MAX_MANAGERS];
static struct workqueue_struct *cb_wkq; /* callback work queue */
@@ -545,9 +547,17 @@ skip_ovl_set:
if (!d->win.h && !d->win.y)
d->win.h = dssdev->panel.timings.y_res - d->win.y;
- r = mgr->apply(mgr);
- if (r)
- dev_err(DEV(cdev), "failed while applying %d", r);
+ mutex_lock(&mtx);
+ if (mgrq[comp->ix].blanking) {
+ pr_info_ratelimited("ignoring apply mgr(%s) while blanking\n",
+ mgr->name);
+ r = -ENODEV;
+ } else {
+ r = mgr->apply(mgr);
+ if (r)
+ dev_err(DEV(cdev), "failed while applying %d", r);
+ }
+ mutex_unlock(&mtx);
/* ignore this error if callback has already been registered */
if (!mgr->info_dirty)
@@ -576,6 +586,26 @@ struct dsscomp_apply_work {
dsscomp_t comp;
};
+int dsscomp_state_notifier(struct notifier_block *nb,
+ unsigned long arg, void *ptr)
+{
+ struct omap_dss_device *dssdev = ptr;
+ enum omap_dss_display_state state = arg;
+ struct omap_overlay_manager *mgr = dssdev->manager;
+ if (mgr) {
+ mutex_lock(&mtx);
+ if (state == OMAP_DSS_DISPLAY_DISABLED) {
+ mgr->blank(mgr, false);
+ mgrq[mgr->id].blanking = true;
+ } else if (state == OMAP_DSS_DISPLAY_ACTIVE) {
+ mgrq[mgr->id].blanking = false;
+ }
+ mutex_unlock(&mtx);
+ }
+ return 0;
+}
+
+
static void dsscomp_do_apply(struct work_struct *work)
{
struct dsscomp_apply_work *wk = container_of(work, typeof(*wk), work);