aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/video
diff options
context:
space:
mode:
authorLajos Molnar <molnar@ti.com>2011-06-15 23:51:41 -0500
committerRebecca Schultz Zavin <rebecca@android.com>2011-07-11 17:00:32 -0700
commit0844e594b7b884a4c41c56faeca2723e516ca7e7 (patch)
treef2854167eae795f15d41bcabfb725d99a9525a21 /drivers/video
parentb77e0f19fe564ec32287a6a3a1183fe6713d0f91 (diff)
downloadkernel_samsung_tuna-0844e594b7b884a4c41c56faeca2723e516ca7e7.zip
kernel_samsung_tuna-0844e594b7b884a4c41c56faeca2723e516ca7e7.tar.gz
kernel_samsung_tuna-0844e594b7b884a4c41c56faeca2723e516ca7e7.tar.bz2
OMAP:DSSCOMP: Added dsscomp_delayed_apply()
We may want to delay apply() as it is blocking. However, we will not get the error code if the apply failed, only an ECLIPSED_SET callback. This should be enough to handle the lifecycle of this composition. dsscomp_gralloc_queue() now calls delayed apply. Change-Id: I494073a338b75fc85d570a7f030a9bb73dcec6a3 Signed-off-by: Lajos Molnar <molnar@ti.com>
Diffstat (limited to 'drivers/video')
-rw-r--r--drivers/video/omap2/dsscomp/gralloc.c2
-rw-r--r--drivers/video/omap2/dsscomp/queue.c35
2 files changed, 36 insertions, 1 deletions
diff --git a/drivers/video/omap2/dsscomp/gralloc.c b/drivers/video/omap2/dsscomp/gralloc.c
index fbce18f..8b66c5b 100644
--- a/drivers/video/omap2/dsscomp/gralloc.c
+++ b/drivers/video/omap2/dsscomp/gralloc.c
@@ -194,7 +194,7 @@ int dsscomp_gralloc_queue(struct dsscomp_setup_mgr_data *d,
comp->extra_cb = dsscomp_gralloc_cb;
comp->gralloc_cb_fn = cb_fn;
comp->gralloc_cb_arg = cb_arg;
- r = dsscomp_apply(comp);
+ r = dsscomp_delayed_apply(comp);
if (r)
dev_err(DEV(cdev), "failed to apply comp (%d)\n", r);
}
diff --git a/drivers/video/omap2/dsscomp/queue.c b/drivers/video/omap2/dsscomp/queue.c
index 8ab98a4..9b885d9 100644
--- a/drivers/video/omap2/dsscomp/queue.c
+++ b/drivers/video/omap2/dsscomp/queue.c
@@ -57,6 +57,7 @@ static struct {
u32 ovl_qmask; /* overlays queued to this display */
} mgrq[MAX_MANAGERS];
+static struct workqueue_struct *wkq; /* work queue */
static struct dsscomp_dev *cdev;
/*
@@ -91,6 +92,11 @@ int dsscomp_queue_init(struct dsscomp_dev *cdev_)
mgrq[i].ovl_mask |= 1 << j;
}
}
+
+ wkq = create_workqueue("dsscomp");
+ if (!wkq)
+ return -EFAULT;
+
return 0;
}
@@ -606,6 +612,8 @@ int dsscomp_apply(dsscomp_t comp)
r = r ? : set_dss_mgr_info(&d->mgr);
if (r) {
dev_err(DEV(cdev), "[%p] set failed %d\n", comp, r);
+ /* FIXME: this only needs to be called for delayed apply */
+ dsscomp_mgr_callback(comp, -1, DSS_COMPLETION_ECLIPSED_SET);
dsscomp_drop(comp);
change = true;
goto done;
@@ -670,6 +678,32 @@ done:
}
EXPORT_SYMBOL(dsscomp_apply);
+struct dsscomp_apply_work {
+ struct work_struct work;
+ dsscomp_t comp;
+};
+
+static void dsscomp_do_apply(struct work_struct *work)
+{
+ struct dsscomp_apply_work *wk = container_of(work, typeof(*wk), work);
+ /* complete compositions that failed to apply */
+ if (dsscomp_apply(wk->comp))
+ dsscomp_mgr_callback(wk->comp, -1, DSS_COMPLETION_ECLIPSED_SET);
+ kfree(wk);
+}
+
+int dsscomp_delayed_apply(dsscomp_t comp)
+{
+ /* don't block in case we are called from interrupt context */
+ struct dsscomp_apply_work *wk = kzalloc(sizeof(*wk), GFP_NOWAIT);
+ if (!wk)
+ return -ENOMEM;
+ wk->comp = comp;
+ INIT_WORK(&wk->work, dsscomp_do_apply);
+ return queue_work(wkq, &wk->work) ? 0 : -EBUSY;
+}
+EXPORT_SYMBOL(dsscomp_delayed_apply);
+
/*
* ===========================================================================
* WAIT OPERATIONS
@@ -745,6 +779,7 @@ void dsscomp_queue_exit(void)
list_for_each_entry_safe(c, c2, &mgrq[i].q_ci, q)
dsscomp_drop(c);
}
+ destroy_workqueue(wkq);
cdev = NULL;
}
}