From 7933104ef2b6a17f8737c835f50804cc66859f35 Mon Sep 17 00:00:00 2001 From: Shahid Akhtar Date: Tue, 25 Oct 2011 10:50:21 +0800 Subject: 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 --- arch/arm/plat-omap/include/syslink/ipc_ioctl.h | 2 +- arch/arm/plat-omap/include/syslink/messageq.h | 7 ++++ .../arm/plat-omap/include/syslink/messageq_ioctl.h | 13 ++++++- drivers/dsp/syslink/multicore_ipc/messageq.c | 41 ++++++++++++++++++++++ drivers/dsp/syslink/multicore_ipc/messageq_ioctl.c | 16 +++++++++ 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 @@ -393,6 +393,18 @@ exit: return retval; } +/* + * ======== 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: @@ -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) -- cgit v1.2.3