diff options
author | Danny Nold <dannynold@freescale.com> | 2011-06-20 21:51:03 -0500 |
---|---|---|
committer | Danny Nold <dannynold@freescale.com> | 2011-06-21 15:09:39 -0500 |
commit | ece8a7a1f38080b27757ca46f5893a7897a749df (patch) | |
tree | 85039c8ebf3d4dbf01fa51e84e6a46bb4b57f767 /drivers | |
parent | d5719ce72c327511dc3b20ac0dae9c3c4204bf2d (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.c | 20 |
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 */ |