diff options
| author | Shahid Akhtar <sakhtar@ti.com> | 2010-11-04 19:18:55 -0400 |
|---|---|---|
| committer | Paolo Pisati <paolo.pisati@canonical.com> | 2012-08-17 04:19:08 -0400 |
| commit | 03cda670ebdd78edc449bd049341822605a0ab0f (patch) | |
| tree | a3be5d5ec18c787df8a08d67fa1c90f3866b9b4f /drivers/dsp | |
| parent | aaca0103c44efa5cbca6720309856ddfacd6ffa6 (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>
Diffstat (limited to 'drivers/dsp')
| -rw-r--r-- | drivers/dsp/syslink/multicore_ipc/messageq.c | 41 | ||||
| -rw-r--r-- | drivers/dsp/syslink/multicore_ipc/messageq_ioctl.c | 16 |
2 files changed, 57 insertions, 0 deletions
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 { | |||
| 179 | /* NameServer key */ | 179 | /* NameServer key */ |
| 180 | struct semaphore *synchronizer; | 180 | struct semaphore *synchronizer; |
| 181 | /* Semaphore used for synchronizing message events */ | 181 | /* Semaphore used for synchronizing message events */ |
| 182 | bool unblocked; | ||
| 183 | /* Whether MessageQ is unblocked */ | ||
| 182 | }; | 184 | }; |
| 183 | 185 | ||
| 184 | 186 | ||
| @@ -573,6 +575,9 @@ void *messageq_create(char *name, const struct messageq_params *params) | |||
| 573 | } | 575 | } |
| 574 | } | 576 | } |
| 575 | 577 | ||
| 578 | /* Whether messageq is blocked */ | ||
| 579 | obj->unblocked = false; | ||
| 580 | |||
| 576 | exit: | 581 | exit: |
| 577 | if (unlikely(status < 0)) { | 582 | if (unlikely(status < 0)) { |
| 578 | messageq_delete((void **)&obj); | 583 | messageq_delete((void **)&obj); |
| @@ -814,6 +819,12 @@ int messageq_get(void *messageq_handle, messageq_msg *msg, | |||
| 814 | *msg = NULL; | 819 | *msg = NULL; |
| 815 | break; | 820 | break; |
| 816 | } | 821 | } |
| 822 | if (obj->unblocked) { | ||
| 823 | *msg = NULL; | ||
| 824 | status = MESSAGEQ_E_UNBLOCKED; | ||
| 825 | obj->unblocked = false; | ||
| 826 | break; | ||
| 827 | } | ||
| 817 | } | 828 | } |
| 818 | status = mutex_lock_interruptible( | 829 | status = mutex_lock_interruptible( |
| 819 | messageq_module->gate_handle); | 830 | messageq_module->gate_handle); |
| @@ -1196,6 +1207,36 @@ exit: | |||
| 1196 | } | 1207 | } |
| 1197 | EXPORT_SYMBOL(messageq_unregister_heap); | 1208 | EXPORT_SYMBOL(messageq_unregister_heap); |
| 1198 | 1209 | ||
| 1210 | /* Unblock messageq to prevent waiting forever */ | ||
| 1211 | int messageq_unblock(void *messageq_handle) | ||
| 1212 | { | ||
| 1213 | int status = 0; | ||
| 1214 | struct messageq_object *obj = (struct messageq_object *)messageq_handle; | ||
| 1215 | |||
| 1216 | if (WARN_ON(unlikely(atomic_cmpmask_and_lt( | ||
| 1217 | &(messageq_module->ref_count), | ||
| 1218 | MESSAGEQ_MAKE_MAGICSTAMP(0), | ||
| 1219 | MESSAGEQ_MAKE_MAGICSTAMP(1)) == true))) { | ||
| 1220 | status = -ENODEV; | ||
| 1221 | goto exit; | ||
| 1222 | } | ||
| 1223 | if (WARN_ON(unlikely(obj == NULL)) || (WARN_ON(unlikely( | ||
| 1224 | obj->synchronizer == NULL)))) { | ||
| 1225 | status = -EINVAL; | ||
| 1226 | goto exit; | ||
| 1227 | } | ||
| 1228 | /* Set instance to 'unblocked' state */ | ||
| 1229 | obj->unblocked = true; | ||
| 1230 | up(obj->synchronizer); | ||
| 1231 | |||
| 1232 | exit: | ||
| 1233 | if (status < 0) { | ||
| 1234 | pr_err("messageq_unblock failed! status = 0x%x\n", | ||
| 1235 | status); | ||
| 1236 | } | ||
| 1237 | return status; | ||
| 1238 | } | ||
| 1239 | |||
| 1199 | /* Register a transport */ | 1240 | /* Register a transport */ |
| 1200 | int messageq_register_transport(void *messageq_transportshm_handle, | 1241 | int messageq_register_transport(void *messageq_transportshm_handle, |
| 1201 | u16 proc_id, u32 priority) | 1242 | 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: | |||
| 394 | } | 394 | } |
| 395 | 395 | ||
| 396 | /* | 396 | /* |
| 397 | * ======== messageq_ioctl_unblock ======== | ||
| 398 | * Purpose: | ||
| 399 | * This ioctl interface to messageq_unblock function | ||
| 400 | */ | ||
| 401 | static inline int messageq_ioctl_unblock(struct messageq_cmd_args *cargs) | ||
| 402 | { | ||
| 403 | cargs->api_status = messageq_unblock(cargs->args.unblock.messageq_handle); | ||
| 404 | |||
| 405 | return 0; | ||
| 406 | } | ||
| 407 | |||
| 408 | /* | ||
| 397 | * ======== messageq_ioctl_setup ======== | 409 | * ======== messageq_ioctl_setup ======== |
| 398 | * Purpose: | 410 | * Purpose: |
| 399 | * This ioctl interface to messageq_setup function | 411 | * This ioctl interface to messageq_setup function |
| @@ -631,6 +643,10 @@ int messageq_ioctl(struct inode *inode, struct file *filp, | |||
| 631 | status = messageq_ioctl_get_config(&cargs); | 643 | status = messageq_ioctl_get_config(&cargs); |
| 632 | break; | 644 | break; |
| 633 | 645 | ||
| 646 | case CMD_MESSAGEQ_UNBLOCK: | ||
| 647 | status = messageq_ioctl_unblock(&cargs); | ||
| 648 | break; | ||
| 649 | |||
| 634 | case CMD_MESSAGEQ_SETUP: | 650 | case CMD_MESSAGEQ_SETUP: |
| 635 | status = messageq_ioctl_setup(&cargs); | 651 | status = messageq_ioctl_setup(&cargs); |
| 636 | if (status >= 0) | 652 | if (status >= 0) |
