summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorShahid Akhtar <sakhtar@ti.com>2011-10-25 10:50:21 +0800
committerAndy Green <andy.green@linaro.org>2011-10-25 10:50:21 +0800
commit7933104ef2b6a17f8737c835f50804cc66859f35 (patch)
tree9457268e1d9bfd69daf292051b7d7e00bccf7420
parent02782cf0231a200729aa64336e709111f630d04f (diff)
SYSLINK: IPC - changes for messageQ unblock
Added a new command in messageq to unblock. A new variable is also added to the messageq object to unblock the messageq. The purpose of unblock is to unblock the messageq_get() when it is pending for a new message with MessageQ_FOREVER timeout. The messageq_unblock is intended for use before deletion of messageq and it unblocks messageq_get() with MessageQ_FOREVER timeout value for termination. Signed-off-by: Shahid Akhtar <sakhtar@ti.com>
-rw-r--r--arch/arm/plat-omap/include/syslink/ipc_ioctl.h2
-rw-r--r--arch/arm/plat-omap/include/syslink/messageq.h7
-rw-r--r--arch/arm/plat-omap/include/syslink/messageq_ioctl.h13
-rw-r--r--drivers/dsp/syslink/multicore_ipc/messageq.c41
-rw-r--r--drivers/dsp/syslink/multicore_ipc/messageq_ioctl.c16
5 files changed, 77 insertions, 2 deletions
diff --git a/arch/arm/plat-omap/include/syslink/ipc_ioctl.h b/arch/arm/plat-omap/include/syslink/ipc_ioctl.h
index 07ab472ccf0..7230baf4ef8 100644
--- a/arch/arm/plat-omap/include/syslink/ipc_ioctl.h
+++ b/arch/arm/plat-omap/include/syslink/ipc_ioctl.h
@@ -34,7 +34,7 @@ enum ipc_command_count {
SHAREDREGION_CMD_NOS = 13,
GATEMP_CMD_NOS = 13,
LISTMP_CMD_NOS = 19,
- MESSAGEQ_CMD_NOS = 18,
+ MESSAGEQ_CMD_NOS = 19,
IPC_CMD_NOS = 5,
SYSMEMMGR_CMD_NOS = 6,
HEAPMEMMP_CMD_NOS = 15,
diff --git a/arch/arm/plat-omap/include/syslink/messageq.h b/arch/arm/plat-omap/include/syslink/messageq.h
index d0d59970a49..1bfdecd7444 100644
--- a/arch/arm/plat-omap/include/syslink/messageq.h
+++ b/arch/arm/plat-omap/include/syslink/messageq.h
@@ -166,6 +166,11 @@
* @brief Operation is successful.
*/
#define MESSAGEQ_E_CANNOTFREESTATICMSG -18
+/*!
+ * @def MESSAGEQ_E_UNBLOCKED
+ * @brief The resource is now unblocked
+ */
+#define MESSAGEQ_E_UNBLOCKED -20
/* =============================================================================
@@ -436,5 +441,7 @@ int messageq_register_transport(void *imessageq_transport_handle,
/* Unregister a transport with MessageQ */
void messageq_unregister_transport(u16 proc_id, u32 priority);
+/* Unblock messageq to prevent waiting forever */
+int messageq_unblock(void *messageq_handle);
#endif /* _MESSAGEQ_H_ */
diff --git a/arch/arm/plat-omap/include/syslink/messageq_ioctl.h b/arch/arm/plat-omap/include/syslink/messageq_ioctl.h
index 96d4aa7221e..cbb0087fc0b 100644
--- a/arch/arm/plat-omap/include/syslink/messageq_ioctl.h
+++ b/arch/arm/plat-omap/include/syslink/messageq_ioctl.h
@@ -50,7 +50,8 @@ enum messageq_drv_cmd {
MESSAGEQ_ATTACH,
MESSAGEQ_DETACH,
MESSAGEQ_GET,
- MESSAGEQ_SHAREDMEMREQ
+ MESSAGEQ_SHAREDMEMREQ,
+ MESSAGEQ_UNBLOCK
};
/* ----------------------------------------------------------------------------
@@ -120,6 +121,11 @@ enum messageq_drv_cmd {
_IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_PUT, \
struct messageq_cmd_args)
+/* Command for messageq_unblock */
+#define CMD_MESSAGEQ_UNBLOCK \
+ _IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_UNBLOCK, \
+ struct messageq_cmd_args)
+
/* Command for messageq_register_heap */
#define CMD_MESSAGEQ_REGISTERHEAP \
_IOWR(MESSAGEQ_IOC_MAGIC, MESSAGEQ_REGISTERHEAP, \
@@ -237,6 +243,11 @@ struct messageq_cmd_args {
struct {
u16 remote_proc_id;
} detach;
+
+ struct {
+ void *messageq_handle;
+ } unblock;
+
} args;
int api_status;
diff --git a/drivers/dsp/syslink/multicore_ipc/messageq.c b/drivers/dsp/syslink/multicore_ipc/messageq.c
index 04f14a335b0..332288c8142 100644
--- a/drivers/dsp/syslink/multicore_ipc/messageq.c
+++ b/drivers/dsp/syslink/multicore_ipc/messageq.c
@@ -179,6 +179,8 @@ struct messageq_object {
/* NameServer key */
struct semaphore *synchronizer;
/* Semaphore used for synchronizing message events */
+ bool unblocked;
+ /* Whether MessageQ is unblocked */
};
@@ -573,6 +575,9 @@ void *messageq_create(char *name, const struct messageq_params *params)
}
}
+ /* Whether messageq is blocked */
+ obj->unblocked = false;
+
exit:
if (unlikely(status < 0)) {
messageq_delete((void **)&obj);
@@ -814,6 +819,12 @@ int messageq_get(void *messageq_handle, messageq_msg *msg,
*msg = NULL;
break;
}
+ if (obj->unblocked) {
+ *msg = NULL;
+ status = MESSAGEQ_E_UNBLOCKED;
+ obj->unblocked = false;
+ break;
+ }
}
status = mutex_lock_interruptible(
messageq_module->gate_handle);
@@ -1196,6 +1207,36 @@ exit:
}
EXPORT_SYMBOL(messageq_unregister_heap);
+/* Unblock messageq to prevent waiting forever */
+int messageq_unblock(void *messageq_handle)
+{
+ int status = 0;
+ struct messageq_object *obj = (struct messageq_object *)messageq_handle;
+
+ if (WARN_ON(unlikely(atomic_cmpmask_and_lt(
+ &(messageq_module->ref_count),
+ MESSAGEQ_MAKE_MAGICSTAMP(0),
+ MESSAGEQ_MAKE_MAGICSTAMP(1)) == true))) {
+ status = -ENODEV;
+ goto exit;
+ }
+ if (WARN_ON(unlikely(obj == NULL)) || (WARN_ON(unlikely(
+ obj->synchronizer == NULL)))) {
+ status = -EINVAL;
+ goto exit;
+ }
+ /* Set instance to 'unblocked' state */
+ obj->unblocked = true;
+ up(obj->synchronizer);
+
+exit:
+ if (status < 0) {
+ pr_err("messageq_unblock failed! status = 0x%x\n",
+ status);
+ }
+ return status;
+}
+
/* Register a transport */
int messageq_register_transport(void *messageq_transportshm_handle,
u16 proc_id, u32 priority)
diff --git a/drivers/dsp/syslink/multicore_ipc/messageq_ioctl.c b/drivers/dsp/syslink/multicore_ipc/messageq_ioctl.c
index 0da59a3b9b0..5a16d2c7d1f 100644
--- a/drivers/dsp/syslink/multicore_ipc/messageq_ioctl.c
+++ b/drivers/dsp/syslink/multicore_ipc/messageq_ioctl.c
@@ -394,6 +394,18 @@ exit:
}
/*
+ * ======== messageq_ioctl_unblock ========
+ * Purpose:
+ * This ioctl interface to messageq_unblock function
+ */
+static inline int messageq_ioctl_unblock(struct messageq_cmd_args *cargs)
+{
+ cargs->api_status = messageq_unblock(cargs->args.unblock.messageq_handle);
+
+ return 0;
+}
+
+/*
* ======== messageq_ioctl_setup ========
* Purpose:
* This ioctl interface to messageq_setup function
@@ -631,6 +643,10 @@ int messageq_ioctl(struct inode *inode, struct file *filp,
status = messageq_ioctl_get_config(&cargs);
break;
+ case CMD_MESSAGEQ_UNBLOCK:
+ status = messageq_ioctl_unblock(&cargs);
+ break;
+
case CMD_MESSAGEQ_SETUP:
status = messageq_ioctl_setup(&cargs);
if (status >= 0)