diff options
| author | Dhoat Harpal <hdhoat@codeaurora.org> | 2016-02-26 18:34:10 +0530 |
|---|---|---|
| committer | Kyle Yan <kyan@codeaurora.org> | 2016-04-28 16:39:46 -0700 |
| commit | 84e397c0d4bd6a2f4c78592ff032bf1ebb3749ed (patch) | |
| tree | 2951decdf610a25e7b1488efa751f03af4c450ae | |
| parent | 6a1f375e9fb1366ef70c8ea7d24ff56a26bd70fb (diff) | |
soc: qcom: glink_smd_xprt: Serialized open ack notify and signal event
SMD channel can get into OPENED state before even the G-Link channel
gets into OPENED/CONNECTED state. This can cause the SMD channel events
to get dropped.
Synchronize handling the SMD_OPEN_EVENT & subsequent events in an SMD
channel with the G-Link channel open operation.
CRs-Fixed: 997404
Change-Id: I4c44011b7fa3b59cbe70a125735e04a076c4d3ca
Signed-off-by: Dhoat Harpal <hdhoat@codeaurora.org>
| -rw-r--r-- | drivers/soc/qcom/glink_smd_xprt.c | 10 |
1 files changed, 9 insertions, 1 deletions
diff --git a/drivers/soc/qcom/glink_smd_xprt.c b/drivers/soc/qcom/glink_smd_xprt.c index c0ed33ed2845..52eedb507709 100644 --- a/drivers/soc/qcom/glink_smd_xprt.c +++ b/drivers/soc/qcom/glink_smd_xprt.c @@ -22,6 +22,7 @@ #include <linux/srcu.h> #include <linux/termios.h> #include <linux/workqueue.h> +#include <linux/completion.h> #include <soc/qcom/smd.h> #include <soc/qcom/glink.h> #include "glink_core_if.h" @@ -162,6 +163,7 @@ struct channel { bool streaming_ch; bool tx_resume_needed; bool is_tasklet_enabled; + struct completion open_notifier; }; /** @@ -328,6 +330,7 @@ static void process_ctl_event(struct work_struct *work) ch->edge = einfo; mutex_init(&ch->ch_probe_lock); mutex_init(&ch->ch_tasklet_lock); + init_completion(&ch->open_notifier); INIT_LIST_HEAD(&ch->intents); INIT_LIST_HEAD(&ch->used_intents); spin_lock_init(&ch->intents_lock); @@ -420,7 +423,7 @@ static void process_ctl_event(struct work_struct *work) __func__, cmd.id); continue; } - + reinit_completion(&ch->open_notifier); add_platform_driver(ch); mutex_lock(&einfo->rx_cmd_lock); einfo->xprt_if.glink_core_if_ptr->rx_cmd_ch_open_ack( @@ -428,6 +431,7 @@ static void process_ctl_event(struct work_struct *work) cmd.id, cmd.priority); mutex_unlock(&einfo->rx_cmd_lock); + complete_all(&ch->open_notifier); } else if (cmd.cmd == CMD_CLOSE) { SMDXPRT_INFO(einfo, "%s RX REMOTE CLOSE rcid %u\n", __func__, cmd.id); @@ -636,6 +640,7 @@ static void process_open_event(struct work_struct *work) ch->is_tasklet_enabled = true; } mutex_unlock(&ch->ch_tasklet_lock); + wait_for_completion(&ch->open_notifier); kfree(ch_work); } @@ -1235,6 +1240,7 @@ static int tx_cmd_ch_open(struct glink_transport_if *if_ptr, uint32_t lcid, ch->edge = einfo; mutex_init(&ch->ch_probe_lock); mutex_init(&ch->ch_tasklet_lock); + init_completion(&ch->open_notifier); INIT_LIST_HEAD(&ch->intents); INIT_LIST_HEAD(&ch->used_intents); spin_lock_init(&ch->intents_lock); @@ -1305,6 +1311,7 @@ static int tx_cmd_ch_open(struct glink_transport_if *if_ptr, uint32_t lcid, ch->rcid = lcid + LEGACY_RCID_CHANNEL_OFFSET; ch->local_legacy = true; ch->remote_legacy = true; + reinit_completion(&ch->open_notifier); ret = add_platform_driver(ch); if (!ret) { mutex_lock(&einfo->rx_cmd_lock); @@ -1313,6 +1320,7 @@ static int tx_cmd_ch_open(struct glink_transport_if *if_ptr, uint32_t lcid, ch->lcid, SMD_TRANS_XPRT_ID); mutex_unlock(&einfo->rx_cmd_lock); } + complete_all(&ch->open_notifier); } srcu_read_unlock(&einfo->ssr_sync, rcu_id); |
