summaryrefslogtreecommitdiff
path: root/drivers
diff options
context:
space:
mode:
authorDanny Nold <dannynold@freescale.com>2011-06-20 21:51:03 -0500
committerDanny Nold <dannynold@freescale.com>2011-06-21 15:09:39 -0500
commitece8a7a1f38080b27757ca46f5893a7897a749df (patch)
tree85039c8ebf3d4dbf01fa51e84e6a46bb4b57f767 /drivers
parentd5719ce72c327511dc3b20ac0dae9c3c4204bf2d (diff)
ENGR00151822 - EPDC fb: Prevent endless collision by managing FULL mode updates
When using SNAPSHOT update scheme, submitting FULL mode updates can easily lead to an endlessly looping sequence of collisions if any updates are active when the new FULL mode update is submitted. Thus, we must first flush any updates out before submitting a new FULL mode update. Signed-off-by: Danny Nold <dannynold@freescale.com>
Diffstat (limited to 'drivers')
-rw-r--r--drivers/video/mxc/mxc_epdc_fb.c20
1 files changed, 16 insertions, 4 deletions
diff --git a/drivers/video/mxc/mxc_epdc_fb.c b/drivers/video/mxc/mxc_epdc_fb.c
index a28e57092698..35b028e95e19 100644
--- a/drivers/video/mxc/mxc_epdc_fb.c
+++ b/drivers/video/mxc/mxc_epdc_fb.c
@@ -2298,6 +2298,19 @@ int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
if (fb_data->upd_scheme == UPDATE_SCHEME_SNAPSHOT) {
/*
+ * If next update is a FULL mode update, then we must
+ * ensure that all pending & active updates are complete
+ * before submitting the update. Otherwise, the FULL
+ * mode update may cause an endless collision loop with
+ * other updates. Block here until updates are flushed.
+ */
+ if (upd_data->update_mode == UPDATE_MODE_FULL) {
+ spin_unlock_irqrestore(&fb_data->queue_lock, flags);
+ mxc_epdc_fb_flush_updates(fb_data);
+ spin_lock_irqsave(&fb_data->queue_lock, flags);
+ }
+
+ /*
* Get available intermediate (PxP output) buffer to hold
* processed update region
*/
@@ -2371,12 +2384,12 @@ int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
/* Snapshot update scheme processing */
- spin_unlock_irqrestore(&fb_data->queue_lock, flags);
-
/* Set descriptor for current update, delete from pending list */
upd_data_list->update_desc = upd_desc;
list_del_init(&upd_desc->list);
+ spin_unlock_irqrestore(&fb_data->queue_lock, flags);
+
/*
* Hold on to original screen update region, which we
* will ultimately use when telling EPDC where to update on panel
@@ -2513,8 +2526,7 @@ int mxc_epdc_fb_wait_update_complete(u32 update_marker, struct fb_info *info)
if (!ret) {
dev_err(fb_data->dev,
"Timed out waiting for update completion\n");
- list_del_init(&next_marker->full_list);
- ret = -ETIMEDOUT;
+ return -ETIMEDOUT;
}
/* Free update marker object */