summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDanny Nold <dannynold@freescale.com>2011-03-03 15:37:57 -0600
committerDanny Nold <dannynold@freescale.com>2011-03-03 15:37:59 -0600
commitb74d7147b961d3de15c6f12421754bddf2896e6a (patch)
treebf4093544da616f0dcd1c855e2332858b8e539b7
parent39abbad4b453f707b2c3d07233876efe018943c4 (diff)
ENGR00139919 - EPDC fb: Allows merging of 2 updates with markers
- Create new per-update list of markers instead of just one marker per update. - Allow updates with markers to merge and compile all markers onto a per-update list. - Changed full marker list member variable to a list_head to reduce memory allocations and wasted memory. - Also redefined buffer queue objects as list_head objects Signed-off-by: Danny Nold <dannynold@freescale.com>
-rw-r--r--drivers/video/mxc/mxc_epdc_fb.c262
1 files changed, 139 insertions, 123 deletions
diff --git a/drivers/video/mxc/mxc_epdc_fb.c b/drivers/video/mxc/mxc_epdc_fb.c
index dd0cb5f0b59c..c7f28133850f 100644
--- a/drivers/video/mxc/mxc_epdc_fb.c
+++ b/drivers/video/mxc/mxc_epdc_fb.c
@@ -79,7 +79,8 @@
static unsigned long default_bpp = 16;
struct update_marker_data {
- struct list_head list;
+ struct list_head full_list;
+ struct list_head upd_list;
u32 update_marker;
struct completion update_completion;
int lut_num;
@@ -90,7 +91,7 @@ struct update_desc_list {
struct list_head list;
struct mxcfb_update_data upd_data;/* Update parameters */
u32 epdc_offs; /* Added to buffer ptr to resolve alignment */
- struct update_marker_data *upd_marker_data;
+ struct list_head upd_marker_list; /* List of markers for this update */
u32 update_order; /* Numeric ordering value for update */
};
@@ -142,10 +143,10 @@ struct mxc_epdc_fb_data {
bool waiting_for_idle;
u32 auto_mode;
u32 upd_scheme;
- struct update_desc_list *upd_pending_list;
- struct update_data_list *upd_buf_queue;
- struct update_data_list *upd_buf_free_list;
- struct update_data_list *upd_buf_collision_list;
+ struct list_head upd_pending_list;
+ struct list_head upd_buf_queue;
+ struct list_head upd_buf_free_list;
+ struct list_head upd_buf_collision_list;
struct update_data_list *cur_update;
spinlock_t queue_lock;
int trt_entries;
@@ -159,7 +160,7 @@ struct mxc_epdc_fb_data {
u32 working_buffer_phys;
u32 working_buffer_size;
u32 order_cnt;
- struct update_marker_data *update_marker_list;
+ struct list_head full_marker_list;
u32 lut_update_order[EPDC_NUM_LUTS];
struct completion updates_done;
struct delayed_work epdc_done_work;
@@ -365,9 +366,9 @@ static void dump_collision_list(struct mxc_epdc_fb_data *fb_data)
struct update_data_list *plist;
dev_info(fb_data->dev, "Collision List:\n");
- if (list_empty(&fb_data->upd_buf_collision_list->list))
+ if (list_empty(&fb_data->upd_buf_collision_list))
dev_info(fb_data->dev, "Empty");
- list_for_each_entry(plist, &fb_data->upd_buf_collision_list->list, list) {
+ list_for_each_entry(plist, &fb_data->upd_buf_collision_list, list) {
dev_info(fb_data->dev, "Virt Addr = 0x%x, Phys Addr = 0x%x ",
(u32)plist->virt_addr, plist->phys_addr);
dump_update_data(fb_data->dev, plist);
@@ -379,9 +380,9 @@ static void dump_free_list(struct mxc_epdc_fb_data *fb_data)
struct update_data_list *plist;
dev_info(fb_data->dev, "Free List:\n");
- if (list_empty(&fb_data->upd_buf_free_list->list))
+ if (list_empty(&fb_data->upd_buf_free_list))
dev_info(fb_data->dev, "Empty");
- list_for_each_entry(plist, &fb_data->upd_buf_free_list->list, list) {
+ list_for_each_entry(plist, &fb_data->upd_buf_free_list, list) {
dev_info(fb_data->dev, "Virt Addr = 0x%x, Phys Addr = 0x%x ",
(u32)plist->virt_addr, plist->phys_addr);
dump_update_data(fb_data->dev, plist);
@@ -393,9 +394,9 @@ static void dump_queue(struct mxc_epdc_fb_data *fb_data)
struct update_data_list *plist;
dev_info(fb_data->dev, "Queue:\n");
- if (list_empty(&fb_data->upd_buf_queue->list))
+ if (list_empty(&fb_data->upd_buf_queue))
dev_info(fb_data->dev, "Empty");
- list_for_each_entry(plist, &fb_data->upd_buf_queue->list, list) {
+ list_for_each_entry(plist, &fb_data->upd_buf_queue, list) {
dev_info(fb_data->dev, "Virt Addr = 0x%x, Phys Addr = 0x%x ",
(u32)plist->virt_addr, plist->phys_addr);
dump_update_data(fb_data->dev, plist);
@@ -421,9 +422,9 @@ static void dump_pending_list(struct mxc_epdc_fb_data *fb_data)
struct update_desc_list *plist;
dev_info(fb_data->dev, "Queue:\n");
- if (list_empty(&fb_data->upd_pending_list->list))
+ if (list_empty(&fb_data->upd_pending_list))
dev_info(fb_data->dev, "Empty");
- list_for_each_entry(plist, &fb_data->upd_pending_list->list, list)
+ list_for_each_entry(plist, &fb_data->upd_pending_list, list)
dump_desc_data(fb_data->dev, plist);
}
@@ -1826,8 +1827,7 @@ static int epdc_submit_merge(struct update_desc_list *upd_desc_list,
arect->left > (brect->left + brect->width) ||
brect->left > (arect->left + arect->width) ||
arect->top > (brect->top + brect->height) ||
- brect->top > (arect->top + arect->height) ||
- (b->update_marker != 0 && a->update_marker != 0))
+ brect->top > (arect->top + arect->height))
return MERGE_FAIL;
combine.left = arect->left < brect->left ? arect->left : brect->left;
@@ -1847,12 +1847,9 @@ static int epdc_submit_merge(struct update_desc_list *upd_desc_list,
if (use_flags)
a->flags = b->flags;
- /* Preserve marker value for merged update */
- if (b->update_marker != 0) {
- a->update_marker = b->update_marker;
- upd_desc_list->upd_marker_data =
- update_to_merge->upd_marker_data;
- }
+ /* Merge markers */
+ list_splice_tail(&update_to_merge->upd_marker_list,
+ &upd_desc_list->upd_marker_list);
/* Merged update should take on the earliest order */
upd_desc_list->update_order =
@@ -1865,17 +1862,15 @@ static int epdc_submit_merge(struct update_desc_list *upd_desc_list,
static void epdc_submit_work_func(struct work_struct *work)
{
int temp_index;
- struct update_data_list *next_update;
- struct update_data_list *temp_update;
- struct update_desc_list *next_desc;
- struct update_desc_list *temp_desc;
+ struct update_data_list *next_update, *temp_update;
+ struct update_desc_list *next_desc, *temp_desc;
+ struct update_marker_data *next_marker, *temp_marker;
unsigned long flags;
struct mxc_epdc_fb_data *fb_data =
container_of(work, struct mxc_epdc_fb_data, epdc_submit_work);
struct update_data_list *upd_data_list = NULL;
struct mxcfb_rect adj_update_region;
bool end_merge = false;
- struct update_data_list *buf_free_list = fb_data->upd_buf_free_list;
/* Protect access to buffer queues and to update HW */
spin_lock_irqsave(&fb_data->queue_lock, flags);
@@ -1886,7 +1881,7 @@ static void epdc_submit_work_func(struct work_struct *work)
* if the collision mask has been fully cleared
*/
list_for_each_entry_safe(next_update, temp_update,
- &fb_data->upd_buf_collision_list->list, list) {
+ &fb_data->upd_buf_collision_list, list) {
if (next_update->collision_mask != 0)
continue;
@@ -1915,7 +1910,7 @@ static void epdc_submit_work_func(struct work_struct *work)
list_del_init(&next_update->list);
/* Add to free buffer list */
list_add_tail(&next_update->list,
- &buf_free_list->list);
+ &fb_data->upd_buf_free_list);
break;
case MERGE_FAIL:
dev_dbg(fb_data->dev,
@@ -1951,21 +1946,21 @@ static void epdc_submit_work_func(struct work_struct *work)
* already have a collision update selected)
*/
if (!upd_data_list &&
- list_empty(&fb_data->upd_buf_free_list->list)) {
+ list_empty(&fb_data->upd_buf_free_list)) {
spin_unlock_irqrestore(&fb_data->queue_lock, flags);
return;
}
list_for_each_entry_safe(next_desc, temp_desc,
- &fb_data->upd_pending_list->list, list) {
+ &fb_data->upd_pending_list, list) {
dev_dbg(fb_data->dev, "Found a pending update!\n");
if (!upd_data_list) {
- if (list_empty(&buf_free_list->list))
+ if (list_empty(&fb_data->upd_buf_free_list))
break;
upd_data_list =
- list_entry(buf_free_list->list.next,
+ list_entry(fb_data->upd_buf_free_list.next,
struct update_data_list, list);
list_del_init(&upd_data_list->list);
upd_data_list->update_desc = next_desc;
@@ -2015,7 +2010,8 @@ static void epdc_submit_work_func(struct work_struct *work)
kfree(upd_data_list->update_desc);
upd_data_list->update_desc = NULL;
/* Add to free buffer list */
- list_add_tail(&upd_data_list->list, &buf_free_list->list);
+ list_add_tail(&upd_data_list->list,
+ &fb_data->upd_buf_free_list);
/* Release buffer queues */
spin_unlock_irqrestore(&fb_data->queue_lock, flags);
return;
@@ -2073,9 +2069,9 @@ static void epdc_submit_work_func(struct work_struct *work)
upd_data_list->lut_num = epdc_get_next_lut();
/* Associate LUT with update marker */
- if (upd_data_list->update_desc->upd_marker_data)
- upd_data_list->update_desc->upd_marker_data->lut_num =
- fb_data->cur_update->lut_num;
+ list_for_each_entry_safe(next_marker, temp_marker,
+ &upd_data_list->update_desc->upd_marker_list, upd_list)
+ next_marker->lut_num = fb_data->cur_update->lut_num;
/* Mark LUT with order */
fb_data->lut_update_order[upd_data_list->lut_num] =
@@ -2117,7 +2113,7 @@ int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
int temp_index;
int ret;
struct update_desc_list *upd_desc;
- struct update_marker_data *marker_data;
+ struct update_marker_data *marker_data, *next_marker, *temp_marker;
/* Has EPDC HW been initialized? */
if (!fb_data->hw_ready) {
@@ -2176,7 +2172,7 @@ int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
* Get available intermediate (PxP output) buffer to hold
* processed update region
*/
- if (list_empty(&fb_data->upd_buf_free_list->list)) {
+ if (list_empty(&fb_data->upd_buf_free_list)) {
dev_err(fb_data->dev,
"No free intermediate buffers available.\n");
spin_unlock_irqrestore(&fb_data->queue_lock, flags);
@@ -2185,7 +2181,7 @@ int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
/* Grab first available buffer and delete from the free list */
upd_data_list =
- list_entry(fb_data->upd_buf_free_list->list.next,
+ list_entry(fb_data->upd_buf_free_list.next,
struct update_data_list, list);
list_del_init(&upd_data_list->list);
@@ -2201,14 +2197,16 @@ int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
"Insufficient system memory for update! Aborting.\n");
if (fb_data->upd_scheme == UPDATE_SCHEME_SNAPSHOT) {
list_add(&upd_data_list->list,
- &fb_data->upd_buf_free_list->list);
+ &fb_data->upd_buf_free_list);
}
spin_unlock_irqrestore(&fb_data->queue_lock, flags);
return -EPERM;
}
+ /* Initialize per-update marker list */
+ INIT_LIST_HEAD(&upd_desc->upd_marker_list);
upd_desc->upd_data = *upd_data;
upd_desc->update_order = fb_data->order_cnt++;
- list_add_tail(&upd_desc->list, &fb_data->upd_pending_list->list);
+ list_add_tail(&upd_desc->list, &fb_data->upd_pending_list);
/* If marker specified, associate it with a completion */
if (upd_data->update_marker != 0) {
@@ -2220,13 +2218,14 @@ int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
spin_unlock_irqrestore(&fb_data->queue_lock, flags);
return -ENOMEM;
}
- upd_desc->upd_marker_data = marker_data;
+ list_add_tail(&marker_data->upd_list,
+ &upd_desc->upd_marker_list);
marker_data->update_marker = upd_data->update_marker;
marker_data->lut_num = INVALID_LUT;
init_completion(&marker_data->update_completion);
- /* Add marker to marker list */
- list_add_tail(&marker_data->list,
- &fb_data->update_marker_list->list);
+ /* Add marker to master marker list */
+ list_add_tail(&marker_data->full_list,
+ &fb_data->full_marker_list);
}
if (fb_data->upd_scheme != UPDATE_SCHEME_SNAPSHOT) {
@@ -2278,8 +2277,7 @@ int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
*/
if ((fb_data->cur_update != NULL) || !epdc_any_luts_available()) {
/* Add processed Y buffer to update list */
- list_add_tail(&upd_data_list->list,
- &fb_data->upd_buf_queue->list);
+ list_add_tail(&upd_data_list->list, &fb_data->upd_buf_queue);
/* Return and allow the update to be submitted by the ISR. */
spin_unlock_irqrestore(&fb_data->queue_lock, flags);
@@ -2293,9 +2291,9 @@ int mxc_epdc_fb_send_update(struct mxcfb_update_data *upd_data,
upd_data_list->lut_num = epdc_get_next_lut();
/* Associate LUT with update marker */
- if (upd_data_list->update_desc->upd_marker_data)
- upd_data_list->update_desc->upd_marker_data->lut_num =
- upd_data_list->lut_num;
+ list_for_each_entry_safe(next_marker, temp_marker,
+ &upd_data_list->update_desc->upd_marker_list, upd_list)
+ next_marker->lut_num = upd_data_list->lut_num;
/* Mark LUT as containing new update */
fb_data->lut_update_order[upd_data_list->lut_num] =
@@ -2350,7 +2348,7 @@ int mxc_epdc_fb_wait_update_complete(u32 update_marker, struct fb_info *info)
spin_lock_irqsave(&fb_data->queue_lock, flags);
list_for_each_entry_safe(next_marker, temp,
- &fb_data->update_marker_list->list, list) {
+ &fb_data->full_marker_list, full_list) {
if (next_marker->update_marker == update_marker) {
dev_dbg(fb_data->dev, "Waiting for marker %d\n",
update_marker);
@@ -2374,7 +2372,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->list);
+ list_del_init(&next_marker->full_list);
ret = -ETIMEDOUT;
}
@@ -2557,7 +2555,7 @@ void mxc_epdc_fb_flush_updates(struct mxc_epdc_fb_data *fb_data)
* 3) Active updates to panel - We can key off of EPDC
* power state to know if we have active updates.
*/
- if (!list_empty(&fb_data->upd_pending_list->list) ||
+ if (!list_empty(&fb_data->upd_pending_list) ||
!is_free_list_full(fb_data) ||
((fb_data->power_state == POWER_STATE_ON) &&
!fb_data->powering_down)) {
@@ -2677,7 +2675,7 @@ static bool is_free_list_full(struct mxc_epdc_fb_data *fb_data)
struct update_data_list *plist;
/* Count buffers in free buffer list */
- list_for_each_entry(plist, &fb_data->upd_buf_free_list->list, list)
+ list_for_each_entry(plist, &fb_data->upd_buf_free_list, list)
count++;
/* Check to see if all buffers are in this list */
@@ -2723,6 +2721,8 @@ static irqreturn_t mxc_epdc_irq_handler(int irq, void *dev_id)
u32 lut;
bool ignore_collision = false;
int i;
+ bool wb_lut_done = false;
+ bool free_update = true;
/*
* If we just completed one-time panel init, bypass
@@ -2773,8 +2773,7 @@ static irqreturn_t mxc_epdc_irq_handler(int irq, void *dev_id)
* the completed LUT.
*/
list_for_each_entry(collision_update,
- &fb_data->upd_buf_collision_list->
- list, list) {
+ &fb_data->upd_buf_collision_list, list) {
collision_update->collision_mask =
collision_update->collision_mask & ~(1 << i);
}
@@ -2791,27 +2790,35 @@ static irqreturn_t mxc_epdc_irq_handler(int irq, void *dev_id)
fb_data->waiting_for_lut = false;
}
+ /* Detect race condition where WB and its LUT complete
+ (i.e. full update completes) in one swoop */
+ if (fb_data->cur_update &&
+ (i == fb_data->cur_update->lut_num))
+ wb_lut_done = true;
+
/* Signal completion if anyone waiting on this LUT */
- list_for_each_entry_safe(next_marker, temp,
- &fb_data->update_marker_list->list, list) {
- if (next_marker->lut_num != i)
- continue;
+ if (!wb_lut_done)
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->full_marker_list,
+ full_list) {
+ if (next_marker->lut_num != i)
+ continue;
- /* Found marker to signal - remove from marker list */
- list_del_init(&next_marker->list);
+ /* Found marker to signal - remove from list */
+ list_del_init(&next_marker->full_list);
- /* Signal completion of update */
- dev_dbg(fb_data->dev, "Signaling marker %d\n",
- next_marker->update_marker);
- if (next_marker->waiting)
- complete(&next_marker->update_completion);
- else
- kfree(next_marker);
- }
+ /* Signal completion of update */
+ dev_dbg(fb_data->dev, "Signaling marker %d\n",
+ next_marker->update_marker);
+ if (next_marker->waiting)
+ complete(&next_marker->update_completion);
+ else
+ kfree(next_marker);
+ }
}
/* Check to see if all updates have completed */
- if (list_empty(&fb_data->upd_pending_list->list) &&
+ if (list_empty(&fb_data->upd_pending_list) &&
is_free_list_full(fb_data) &&
(fb_data->cur_update == NULL) &&
!epdc_any_luts_active()) {
@@ -2862,8 +2869,7 @@ static irqreturn_t mxc_epdc_irq_handler(int irq, void *dev_id)
* - No collision reported with current active updates
*/
list_for_each_entry(collision_update,
- &fb_data->upd_buf_collision_list->list,
- list)
+ &fb_data->upd_buf_collision_list, list)
if (do_updates_overlap(collision_update,
fb_data->cur_update))
missed_coll_mask |=
@@ -2912,27 +2918,52 @@ static irqreturn_t mxc_epdc_irq_handler(int irq, void *dev_id)
}
}
- if (ignore_collision) {
- /* Add to free buffer list */
- list_add_tail(&fb_data->cur_update->list,
- &fb_data->upd_buf_free_list->list);
- } else {
+ if (!ignore_collision) {
+ free_update = false;
/*
- * If update has a marker, clear the LUT, since
- * we don't want to signal that it is complete.
+ * If update has markers, clear the LUTs to
+ * avoid signalling that they have completed.
*/
- if (fb_data->cur_update->update_desc->upd_marker_data)
- fb_data->cur_update->update_desc->upd_marker_data->lut_num = INVALID_LUT;
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->cur_update->update_desc->upd_marker_list,
+ upd_list)
+ next_marker->lut_num = INVALID_LUT;
/* Move to collision list */
list_add_tail(&fb_data->cur_update->list,
- &fb_data->upd_buf_collision_list->list);
+ &fb_data->upd_buf_collision_list);
}
- } else {
+ }
+
+ if (free_update) {
+ /* Handle condition where WB & LUT are both complete */
+ if (wb_lut_done)
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->cur_update->update_desc->upd_marker_list,
+ upd_list) {
+
+ /* Del from per-update & full list */
+ list_del_init(&next_marker->upd_list);
+ list_del_init(&next_marker->full_list);
+
+ /* Signal completion of update */
+ dev_dbg(fb_data->dev,
+ "Signaling marker %d\n",
+ next_marker->update_marker);
+ if (next_marker->waiting)
+ complete(&next_marker->update_completion);
+ else
+ kfree(next_marker);
+ }
+
+ /* Free marker list and update descriptor */
+ kfree(fb_data->cur_update->update_desc);
+
/* Add to free buffer list */
list_add_tail(&fb_data->cur_update->list,
- &fb_data->upd_buf_free_list->list);
+ &fb_data->upd_buf_free_list);
}
+
/* Clear current update */
fb_data->cur_update = NULL;
@@ -2970,7 +3001,7 @@ static irqreturn_t mxc_epdc_irq_handler(int irq, void *dev_id)
* if the collision mask has been fully cleared
*/
list_for_each_entry(collision_update,
- &fb_data->upd_buf_collision_list->list, list) {
+ &fb_data->upd_buf_collision_list, list) {
if (collision_update->collision_mask != 0)
continue;
@@ -2991,7 +3022,7 @@ static irqreturn_t mxc_epdc_irq_handler(int irq, void *dev_id)
*/
if (fb_data->cur_update == NULL) {
/* Is update list empty? */
- if (list_empty(&fb_data->upd_buf_queue->list)) {
+ if (list_empty(&fb_data->upd_buf_queue)) {
dev_dbg(fb_data->dev, "No pending updates.\n");
/* No updates pending, so we are done */
@@ -3002,7 +3033,7 @@ static irqreturn_t mxc_epdc_irq_handler(int irq, void *dev_id)
/* Process next item in update list */
fb_data->cur_update =
- list_entry(fb_data->upd_buf_queue->list.next,
+ list_entry(fb_data->upd_buf_queue.next,
struct update_data_list, list);
list_del_init(&fb_data->cur_update->list);
}
@@ -3011,10 +3042,10 @@ static irqreturn_t mxc_epdc_irq_handler(int irq, void *dev_id)
/* LUTs are available, so we get one here */
fb_data->cur_update->lut_num = epdc_get_next_lut();
- /* Associate LUT with update marker */
- if (fb_data->cur_update->update_desc->upd_marker_data)
- fb_data->cur_update->update_desc->upd_marker_data->lut_num =
- fb_data->cur_update->lut_num;
+ /* Associate LUT with update markers */
+ list_for_each_entry_safe(next_marker, temp,
+ &fb_data->cur_update->update_desc->upd_marker_list, upd_list)
+ next_marker->lut_num = fb_data->cur_update->lut_num;
/* Mark LUT as containing new update */
fb_data->lut_update_order[fb_data->cur_update->lut_num] =
@@ -3513,32 +3544,15 @@ int __devinit mxc_epdc_fb_probe(struct platform_device *pdev)
fb_data->epdc_fb_var = *var_info;
fb_data->fb_offset = 0;
- /* Allocate head objects for our lists */
- fb_data->upd_pending_list =
- kzalloc(sizeof(struct update_desc_list), GFP_KERNEL);
- fb_data->upd_buf_queue =
- kzalloc(sizeof(struct update_data_list), GFP_KERNEL);
- fb_data->upd_buf_collision_list =
- kzalloc(sizeof(struct update_data_list), GFP_KERNEL);
- fb_data->upd_buf_free_list =
- kzalloc(sizeof(struct update_data_list), GFP_KERNEL);
- if ((fb_data->upd_pending_list == NULL) ||
- (fb_data->upd_buf_queue == NULL) ||
- (fb_data->upd_buf_free_list == NULL) ||
- (fb_data->upd_buf_collision_list == NULL)) {
- ret = -ENOMEM;
- goto out_dma_fb;
- }
-
/*
* Initialize lists for pending updates,
* active update requests, update collisions,
* and available update (PxP output) buffers
*/
- INIT_LIST_HEAD(&fb_data->upd_pending_list->list);
- INIT_LIST_HEAD(&fb_data->upd_buf_queue->list);
- INIT_LIST_HEAD(&fb_data->upd_buf_free_list->list);
- INIT_LIST_HEAD(&fb_data->upd_buf_collision_list->list);
+ INIT_LIST_HEAD(&fb_data->upd_pending_list);
+ INIT_LIST_HEAD(&fb_data->upd_buf_queue);
+ INIT_LIST_HEAD(&fb_data->upd_buf_free_list);
+ INIT_LIST_HEAD(&fb_data->upd_buf_collision_list);
/* Allocate update buffers and add them to the list */
for (i = 0; i < EPDC_MAX_NUM_UPDATES; i++) {
@@ -3565,7 +3579,7 @@ int __devinit mxc_epdc_fb_probe(struct platform_device *pdev)
}
/* Add newly allocated buffer to free list */
- list_add(&upd_list->list, &fb_data->upd_buf_free_list->list);
+ list_add(&upd_list->list, &fb_data->upd_buf_free_list);
dev_dbg(fb_data->info.device, "allocated %d bytes @ 0x%08X\n",
upd_list->size, upd_list->phys_addr);
@@ -3627,9 +3641,7 @@ int __devinit mxc_epdc_fb_probe(struct platform_device *pdev)
fb_data->wv_modes.mode_gc32 = 2;
/* Initialize marker list */
- fb_data->update_marker_list =
- kzalloc(sizeof(struct update_marker_data), GFP_KERNEL);
- INIT_LIST_HEAD(&fb_data->update_marker_list->list);
+ INIT_LIST_HEAD(&fb_data->full_marker_list);
/* Initialize all LUTs to inactive */
for (i = 0; i < EPDC_NUM_LUTS; i++)
@@ -3831,9 +3843,11 @@ out_dma_work_buf:
if (fb_data->pdata->put_pins)
fb_data->pdata->put_pins();
out_upd_buffers:
- list_for_each_entry_safe(plist, temp_list, &fb_data->upd_buf_free_list->list, list) {
+ list_for_each_entry_safe(plist, temp_list, &fb_data->upd_buf_free_list,
+ list) {
list_del(&plist->list);
- dma_free_writecombine(&pdev->dev, plist->size, plist->virt_addr,
+ dma_free_writecombine(&pdev->dev, plist->size,
+ plist->virt_addr,
plist->phys_addr);
dma_free_writecombine(&pdev->dev, plist->size*2,
plist->virt_addr_copybuf,
@@ -3877,9 +3891,11 @@ static int mxc_epdc_fb_remove(struct platform_device *pdev)
dma_free_writecombine(&pdev->dev, fb_data->waveform_buffer_size,
fb_data->waveform_buffer_virt,
fb_data->waveform_buffer_phys);
- list_for_each_entry_safe(plist, temp_list, &fb_data->upd_buf_free_list->list, list) {
+ list_for_each_entry_safe(plist, temp_list, &fb_data->upd_buf_free_list,
+ list) {
list_del(&plist->list);
- dma_free_writecombine(&pdev->dev, plist->size, plist->virt_addr,
+ dma_free_writecombine(&pdev->dev, plist->size,
+ plist->virt_addr,
plist->phys_addr);
dma_free_writecombine(&pdev->dev, plist->size*2,
plist->virt_addr_copybuf,