summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorHari Kanigeri <h-kanigeri2@ti.com>2009-12-15 20:29:22 -0600
committerSantosh Shilimkar <santosh.shilimkar@ti.com>2010-01-05 06:26:15 +0530
commit59c9880a675b42d828a8a238012c4ab440e3090f (patch)
tree0686b029d8d5122e51ec64bd80e8c3b1e2588871
parentbb33d83194c286bb8dc6cdcad3d5261042dc6897 (diff)
SYSLINK: Stabilize IPC for multithreaded applicationsti-2.6.31-omap4-L24.3-for-testing
This includes the changes to apply memory barriers in key areas and extend the check in the notify module to wait till the other core processed the event that was sent before returning. Signed-off-by: Hari Kanigeri <h-kanigeri2@ti.com>
-rwxr-xr-xdrivers/dsp/syslink/multicore_ipc/listmp_sharedmemory.c25
-rw-r--r--drivers/dsp/syslink/multicore_ipc/platform.c2
-rw-r--r--drivers/dsp/syslink/notify_ducatidriver/notify_ducati.c29
3 files changed, 42 insertions, 14 deletions
diff --git a/drivers/dsp/syslink/multicore_ipc/listmp_sharedmemory.c b/drivers/dsp/syslink/multicore_ipc/listmp_sharedmemory.c
index 1530a89717a5..5904c6d18000 100755
--- a/drivers/dsp/syslink/multicore_ipc/listmp_sharedmemory.c
+++ b/drivers/dsp/syslink/multicore_ipc/listmp_sharedmemory.c
@@ -809,7 +809,7 @@ bool listmp_sharedmemory_empty(listmp_sharedmemory_handle listmp_handle)
/*! @retval true if list is empty */
sharedHead = (struct listmp_elem *)(sharedregion_get_srptr(
(void *)obj->listmp_elem, obj->index));
-
+ dsb();
if (obj->listmp_elem->next == sharedHead)
is_empty = true;
@@ -856,6 +856,7 @@ void *listmp_sharedmemory_get_head(listmp_sharedmemory_handle listmp_handle)
}
localHeadNext = sharedregion_get_ptr((u32 *)obj->listmp_elem->next);
+ dsb();
/* See if the listmp_sharedmemory_object was empty */
if (localHeadNext == (struct listmp_elem *)obj->listmp_elem) {
/*! @retval NULL if list is empty */
@@ -863,14 +864,14 @@ void *listmp_sharedmemory_get_head(listmp_sharedmemory_handle listmp_handle)
} else {
/* Elem to return */
elem = localHeadNext;
-
+ dsb();
localNext = sharedregion_get_ptr((u32 *)elem->next);
sharedHead = (struct listmp_elem *) sharedregion_get_srptr(
(void *)obj->listmp_elem, obj->index);
/* Fix the head of the list next pointer */
obj->listmp_elem->next = elem->next;
-
+ dsb();
/* Fix the prev pointer of the new first elem on the
list */
localNext->prev = sharedHead;
@@ -979,12 +980,12 @@ int listmp_sharedmemory_put_head(listmp_sharedmemory_handle listmp_handle,
handle = (listmp_sharedmemory_object *)listmp_handle;
obj = (struct listmp_sharedmemory_obj *) handle->obj;
-
+ dsb();
index = sharedregion_get_index(elem);
sharedElem = (struct listmp_elem *) sharedregion_get_srptr(elem, index);
sharedHead = (struct listmp_elem *)sharedregion_get_srptr(
(void *)obj->listmp_elem, obj->index);
-
+ dsb();
if (obj->params.gate != NULL) {
retval = gatepeterson_enter(obj->params.gate);
if (retval < 0) {
@@ -992,10 +993,10 @@ int listmp_sharedmemory_put_head(listmp_sharedmemory_handle listmp_handle,
goto exit;
}
}
-
/* Add the new elem into the list */
elem->next = obj->listmp_elem->next;
elem->prev = sharedHead;
+ dsb();
localNextElem = sharedregion_get_ptr((u32 *)elem->next);
localNextElem->prev = sharedElem;
obj->listmp_elem->next = sharedElem;
@@ -1042,7 +1043,7 @@ int listmp_sharedmemory_put_tail(listmp_sharedmemory_handle listmp_handle,
handle = (listmp_sharedmemory_object *)listmp_handle;
obj = (struct listmp_sharedmemory_obj *) handle->obj;
-
+ dsb();
/* Safe to do outside the gate */
index = sharedregion_get_index(elem);
sharedElem = (struct listmp_elem *)
@@ -1058,11 +1059,12 @@ int listmp_sharedmemory_put_tail(listmp_sharedmemory_handle listmp_handle,
goto exit;
}
}
-
/* Add the new elem into the list */
elem->next = sharedHead;
elem->prev = obj->listmp_elem->prev;
+ dsb();
localPrevElem = sharedregion_get_ptr((u32 *)elem->prev);
+ dsb();
localPrevElem->next = sharedElem;
obj->listmp_elem->prev = sharedElem;
@@ -1126,7 +1128,7 @@ int listmp_sharedmemory_insert(listmp_sharedmemory_handle listmp_handle,
index = sharedregion_get_index(new_elem);
sharedNewElem = (struct listmp_elem *)
sharedregion_get_srptr(new_elem, index);
-
+ dsb();
/* Get SRPtr for cur_elem */
index = sharedregion_get_index(cur_elem);
sharedCurElem = (struct listmp_elem *)
@@ -1134,10 +1136,11 @@ int listmp_sharedmemory_insert(listmp_sharedmemory_handle listmp_handle,
/* Get SRPtr for cur_elem->prev */
localPrevElem = sharedregion_get_ptr((u32 *)cur_elem->prev);
-
+ dsb();
new_elem->next = sharedCurElem;
new_elem->prev = cur_elem->prev;
localPrevElem->next = sharedNewElem;
+ dsb();
cur_elem->prev = sharedNewElem;
if (obj->params.gate != NULL)
@@ -1191,7 +1194,7 @@ int listmp_sharedmemory_remove(listmp_sharedmemory_handle listmp_handle,
localPrevElem = sharedregion_get_ptr((u32 *)elem->prev);
localNextElem = sharedregion_get_ptr((u32 *)elem->next);
-
+ dsb();
localPrevElem->next = elem->next;
localNextElem->prev = elem->prev;
diff --git a/drivers/dsp/syslink/multicore_ipc/platform.c b/drivers/dsp/syslink/multicore_ipc/platform.c
index 957e9a2a84f1..5a08400b0743 100644
--- a/drivers/dsp/syslink/multicore_ipc/platform.c
+++ b/drivers/dsp/syslink/multicore_ipc/platform.c
@@ -94,7 +94,7 @@
/*!
* @brief Wait for this much poll count when sending event
*/
-#define NOTIFY_SENDEVENTPOLLCOUNT ((u32) -1)
+#define NOTIFY_SENDEVENTPOLLCOUNT 0xfffff
/*!
* @brief Align buffer in Heap
diff --git a/drivers/dsp/syslink/notify_ducatidriver/notify_ducati.c b/drivers/dsp/syslink/notify_ducatidriver/notify_ducati.c
index 413cae455eb3..860709f26430 100644
--- a/drivers/dsp/syslink/notify_ducatidriver/notify_ducati.c
+++ b/drivers/dsp/syslink/notify_ducatidriver/notify_ducati.c
@@ -941,7 +941,7 @@ int notify_ducatidrv_sendevent(struct notify_driver_object *handle,
BUG_ON(handle == NULL);
BUG_ON(handle->driver_object == NULL);
-
+ dsb();
driver_object = (struct notify_ducatidrv_object *)
handle->driver_object;
@@ -970,9 +970,12 @@ int notify_ducatidrv_sendevent(struct notify_driver_object *handle,
proc_ctrl[driver_object->other_id].reg_mask.
enable_mask) != 1)) {
status = -ENODEV;
+ printk(KERN_ERR "NOTIFY DRV: OTHER SIDE NOT READY TO"
+ "RECEIVE. %d\n", event_no);
/* This may be used for polling till other-side
is ready, so do not set failure reason.*/
} else {
+ dsb();
/* Enter critical section protection. */
if (mutex_lock_interruptible(notify_ducatidriver_state.
gate_handle) != 0)
@@ -1009,6 +1012,23 @@ int notify_ducatidrv_sendevent(struct notify_driver_object *handle,
information to theremote processor */
status = omap_mbox_msg_send(ducati_mbox,
payload);
+ i = 0;
+ while ((other_event_chart[event_no].flag
+ != DOWN)
+ && status == 0) {
+ /* Leave critical section protection
+ Create a window of opportunity
+ for other interrupts to be handled.
+ */
+ i++;
+ if ((max_poll_count != (int) -1)
+ && (i == max_poll_count)) {
+ status = -EBUSY;
+ printk(KERN_ERR "NOTIFY-remote"
+ "not processed event %d\n",
+ event_no);
+ }
+ }
}
/* Leave critical section protection. */
mutex_unlock(notify_ducatidriver_state.gate_handle);
@@ -1147,12 +1167,14 @@ static void notify_ducatidrv_isr_callback(void *ref_data, void* ntfy_msg)
struct notify_shmdrv_eventreg *reg_chart;
VOLATILE struct notify_shmdrv_proc_ctrl *proc_ctrl_ptr;
int event_no;
+ dsb();
+ /* Enter critical section protection. */
driver_obj = (struct notify_ducatidrv_object *) ref_data;
proc_ctrl_ptr = &(driver_obj->ctrl_ptr->proc_ctrl[driver_obj->self_id]);
reg_chart = driver_obj->reg_chart;
self_event_chart = proc_ctrl_ptr->self_event_chart;
-
+ dsb();
/* Execute the loop till no asserted event
is found for one complete loop
through all registered events
@@ -1169,9 +1191,11 @@ static void notify_ducatidrv_isr_callback(void *ref_data, void* ntfy_msg)
payload = self_event_chart[event_no].
payload;
+ dsb();
/* Acknowledge the event. */
payload = (int)ntfy_msg;
self_event_chart[event_no].flag = DOWN;
+ dsb();
/*Call the callbacks associated with the event*/
temp = driver_obj->
event_list[event_no].
@@ -1212,6 +1236,7 @@ static void notify_ducatidrv_isr_callback(void *ref_data, void* ntfy_msg)
}
} while ((event_no != (int) -1)
&& (i < driver_obj->params.num_events));
+
}
/*