diff options
| author | Linux Build Service Account <lnxbuild@localhost> | 2016-12-21 15:48:13 -0800 |
|---|---|---|
| committer | Gerrit - the friendly Code Review server <code-review@localhost> | 2016-12-21 15:48:13 -0800 |
| commit | c91ab72258805a352247bf653148319eeabf8c87 (patch) | |
| tree | 522a877e38fdfe1247df4e0018370cf62c3c3463 /drivers/soc | |
| parent | 9c6f2a9076a166f6b0b3808ed907dd853ef48a6c (diff) | |
| parent | 9d8ae4e6989715c720605c1c7a61831f568feb73 (diff) | |
Merge "soc: qcom: glink_ssr: Add rx done for received packets"
Diffstat (limited to 'drivers/soc')
| -rw-r--r-- | drivers/soc/qcom/glink_ssr.c | 33 |
1 files changed, 33 insertions, 0 deletions
diff --git a/drivers/soc/qcom/glink_ssr.c b/drivers/soc/qcom/glink_ssr.c index a14d912b7536..4d94e6446505 100644 --- a/drivers/soc/qcom/glink_ssr.c +++ b/drivers/soc/qcom/glink_ssr.c @@ -80,6 +80,19 @@ struct configure_and_open_ch_work { }; /** + * struct rx_done_ch_work - Work structure used for sending rx_done on + * glink_ssr channels + * handle: G-Link channel handle to be used for sending rx_done + * ptr: Intent pointer data provided in notify rx function + * work: Work structure + */ +struct rx_done_ch_work { + void *handle; + const void *ptr; + struct work_struct work; +}; + +/** * struct close_ch_work - Work structure for used for closing glink_ssr channels * edge: The G-Link edge name for the channel being closed * handle: G-Link channel handle to be closed @@ -102,6 +115,15 @@ static LIST_HEAD(subsystem_list); static atomic_t responses_remaining = ATOMIC_INIT(0); static wait_queue_head_t waitqueue; +static void rx_done_cb_worker(struct work_struct *work) +{ + struct rx_done_ch_work *rx_done_work = + container_of(work, struct rx_done_ch_work, work); + + glink_rx_done(rx_done_work->handle, rx_done_work->ptr, false); + kfree(rx_done_work); +} + static void link_state_cb_worker(struct work_struct *work) { unsigned long flags; @@ -196,7 +218,14 @@ void glink_ssr_notify_rx(void *handle, const void *priv, const void *pkt_priv, { struct ssr_notify_data *cb_data = (struct ssr_notify_data *)priv; struct cleanup_done_msg *resp = (struct cleanup_done_msg *)ptr; + struct rx_done_ch_work *rx_done_work; + rx_done_work = kmalloc(sizeof(*rx_done_work), GFP_ATOMIC); + if (!rx_done_work) { + GLINK_SSR_ERR("<SSR> %s: Could not allocate rx_done_work\n", + __func__); + return; + } if (unlikely(!cb_data)) goto missing_cb_data; if (unlikely(!cb_data->do_cleanup_data)) @@ -221,6 +250,10 @@ void glink_ssr_notify_rx(void *handle, const void *priv, const void *pkt_priv, kfree(cb_data->do_cleanup_data); cb_data->do_cleanup_data = NULL; + rx_done_work->ptr = ptr; + rx_done_work->handle = handle; + INIT_WORK(&rx_done_work->work, rx_done_cb_worker); + queue_work(glink_ssr_wq, &rx_done_work->work); wake_up(&waitqueue); return; |
