diff options
-rw-r--r-- | sound/soc/fsl/fsl_dsp.h | 15 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_dsp_proxy.c | 77 | ||||
-rw-r--r-- | sound/soc/fsl/fsl_dsp_proxy.h | 25 |
3 files changed, 107 insertions, 10 deletions
diff --git a/sound/soc/fsl/fsl_dsp.h b/sound/soc/fsl/fsl_dsp.h index f39a11dbbf6b..b4ab6fc1a9d4 100644 --- a/sound/soc/fsl/fsl_dsp.h +++ b/sound/soc/fsl/fsl_dsp.h @@ -22,22 +22,21 @@ struct xf_client { struct xf_proxy *proxy; /* ...allocated proxy client id */ - u32 id; + u32 id; /* ...pending response queue */ - struct xf_msg_queue queue; - + struct xf_msg_queue queue; /* ...response waiting queue */ - wait_queue_head_t wait; + wait_queue_head_t wait; /* ...virtual memory mapping */ - unsigned long vm_start; - + unsigned long vm_start; /* ...counter of memory mappings (no real use of it yet - tbd) */ - atomic_t vm_use; + atomic_t vm_use; /* ...global structure pointer */ - void *global; + void *global; + struct xf_message m; }; union xf_client_link { diff --git a/sound/soc/fsl/fsl_dsp_proxy.c b/sound/soc/fsl/fsl_dsp_proxy.c index e55aea78c4a3..0bf1d233fcf5 100644 --- a/sound/soc/fsl/fsl_dsp_proxy.c +++ b/sound/soc/fsl/fsl_dsp_proxy.c @@ -570,6 +570,27 @@ struct xf_message *xf_cmd_recv(struct xf_proxy *proxy, return m; } +struct xf_message *xf_cmd_recv_timeout(struct xf_proxy *proxy, + wait_queue_head_t *wq, + struct xf_msg_queue *queue, int wait) +{ + struct xf_message *m; + int ret; + + /* ...wait for message reception (take lock on success) */ + ret = wait_event_interruptible_timeout(*wq, + (m = xf_msg_received(proxy, queue)) != NULL || !wait, + msecs_to_jiffies(1000)); + if (ret < 0) + return ERR_PTR(-EINTR); + + if (ret == 0) + return ERR_PTR(-ETIMEDOUT); + + /* ...return message with a lock taken */ + return m; +} + /* ...helper function for synchronous command execution */ struct xf_message *xf_cmd_send_recv(struct xf_proxy *proxy, u32 id, u32 opcode, @@ -587,6 +608,62 @@ struct xf_message *xf_cmd_send_recv(struct xf_proxy *proxy, return xf_cmd_recv(proxy, &proxy->wait, &proxy->response, 1); } +struct xf_message *xf_cmd_send_recv_wq(struct xf_proxy *proxy, u32 id, + u32 opcode, void *buffer, u32 length, + wait_queue_head_t *wq, + struct xf_msg_queue *queue) +{ + int ret; + + /* ...send command to remote proxy */ + ret = xf_cmd_send(proxy, id, opcode, buffer, length); + if (ret) + return ERR_PTR(ret); + + /* ...wait for message delivery */ + return xf_cmd_recv(proxy, wq, queue, 1); +} + +struct xf_message *xf_cmd_send_recv_complete(struct xf_client *client, + struct xf_proxy *proxy, + u32 id, u32 opcode, void *buffer, + u32 length, + struct work_struct *work, + struct completion *completion) +{ + struct xf_message *m; + int ret; + + /* ...retrieve message handle (take the lock on success) */ + m = xf_msg_available(proxy); + if (!m) + return ERR_PTR(-EBUSY); + + /* ...fill-in message parameters (lock is taken) */ + m->id = id; + m->opcode = opcode; + m->length = length; + m->buffer = buffer; + m->ret = 0; + + init_completion(completion); + + /* ...submit command to the proxy */ + xf_proxy_command(proxy, m); + + schedule_work(work); + + /* ...wait for message reception (take lock on success) */ + ret = wait_for_completion_timeout(completion, + msecs_to_jiffies(1000)); + if (!ret) + return ERR_PTR(-ETIMEDOUT); + + m = &client->m; + + /* ...return message with a lock taken */ + return m; +} /* * Proxy allocate and free memory functions */ diff --git a/sound/soc/fsl/fsl_dsp_proxy.h b/sound/soc/fsl/fsl_dsp_proxy.h index 131acf3129a7..dc54dc2d00ef 100644 --- a/sound/soc/fsl/fsl_dsp_proxy.h +++ b/sound/soc/fsl/fsl_dsp_proxy.h @@ -21,6 +21,8 @@ #define XF_CFG_MESSAGE_POOL_SIZE 256 +struct xf_client; + /******************************************************************************* * Local proxy data ******************************************************************************/ @@ -284,8 +286,8 @@ struct xf_proxy { /* ...shared memory status change processing item */ struct work_struct work; - struct completion cmd_complete; - int is_ready; + struct completion cmd_complete; + int is_ready; /* ...internal lock */ spinlock_t lock; @@ -366,6 +368,25 @@ struct xf_message *xf_cmd_recv(struct xf_proxy *proxy, struct xf_msg_queue *queue, int wait); +struct xf_message* +xf_cmd_recv_timeout(struct xf_proxy *proxy, wait_queue_head_t *wq, + struct xf_msg_queue *queue, int wait); + +struct xf_message* +xf_cmd_send_recv(struct xf_proxy *proxy, u32 id, u32 opcode, + void *buffer, u32 length); + +struct xf_message* +xf_cmd_send_recv_wq(struct xf_proxy *proxy, u32 id, u32 opcode, void *buffer, + u32 length, wait_queue_head_t *wq, + struct xf_msg_queue *queue); + +struct xf_message* +xf_cmd_send_recv_complete(struct xf_client *client, struct xf_proxy *proxy, + u32 id, u32 opcode, void *buffer, u32 length, + struct work_struct *work, + struct completion *completion); + /* ...mu interrupt handle */ irqreturn_t fsl_dsp_mu_isr(int irq, void *dev_id); |