From 812ecb2d99fe27a9a096ac26c50e30a82008d18f Mon Sep 17 00:00:00 2001 From: Danny Nold Date: Mon, 20 Jun 2011 21:51:03 -0500 Subject: [PATCH] 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 --- drivers/video/mxc/mxc_epdc_fb.c | 20 ++++++++++++++++---- 1 file 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 @@ -2297,6 +2297,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 */ -- 2.39.2