diff options
| author | Karthikeyan Ramasubramanian <kramasub@codeaurora.org> | 2015-12-03 11:53:08 -0700 |
|---|---|---|
| committer | David Keitel <dkeitel@codeaurora.org> | 2016-03-23 21:13:28 -0700 |
| commit | 868fda3de392bc05eb0f07ae0a8896c36250a30a (patch) | |
| tree | 8114ff5427a91a44beb9703d53cca81bea056a18 /drivers/soc | |
| parent | 7efd0a96446240ac8a7eecbcffb8f2f1a0b64597 (diff) | |
soc: qcom: glink_smd_xprt: Introduce receive command lock
G-Link uses queue concept per transport to handle the incoming commands.
Introduce the transport receive command lock to pass the commands in a
sequential manner.
CRs-Fixed: 945724
Change-Id: Id6e485bb1d3be360a996fd9ae6745b67bded08d1
Signed-off-by: Karthikeyan Ramasubramanian <kramasub@codeaurora.org>
Diffstat (limited to 'drivers/soc')
| -rw-r--r-- | drivers/soc/qcom/glink_smd_xprt.c | 46 |
1 files changed, 42 insertions, 4 deletions
diff --git a/drivers/soc/qcom/glink_smd_xprt.c b/drivers/soc/qcom/glink_smd_xprt.c index 76b0aca3f4a3..f3d868d8cef3 100644 --- a/drivers/soc/qcom/glink_smd_xprt.c +++ b/drivers/soc/qcom/glink_smd_xprt.c @@ -82,6 +82,8 @@ enum command_types { * @in_ssr_lock: Lock to protect the @in_ssr. * @smd_ctl_ch_open: Indicates that @smd_ch is fully open. * @work: Work item for processing migration data. + * @rx_cmd_lock: The transport interface lock to notify about received + * commands in a sequential manner. * * Each transport registered with the core is represented by a single instance * of this structure which allows for complete management of the transport. @@ -102,6 +104,7 @@ struct edge_info { struct mutex in_ssr_lock; bool smd_ctl_ch_open; struct work_struct work; + struct mutex rx_cmd_lock; }; /** @@ -379,11 +382,13 @@ static void process_ctl_event(struct work_struct *work) } ch->rcid = cmd.id; + mutex_lock(&einfo->rx_cmd_lock); einfo->xprt_if.glink_core_if_ptr->rx_cmd_ch_remote_open( &einfo->xprt_if, cmd.id, name, cmd.priority); + mutex_unlock(&einfo->rx_cmd_lock); } else if (cmd.cmd == CMD_OPEN_ACK) { SMDXPRT_INFO(einfo, "%s RX OPEN ACK lcid %u; xprt_req %u\n", @@ -403,10 +408,12 @@ static void process_ctl_event(struct work_struct *work) } add_platform_driver(ch); + mutex_lock(&einfo->rx_cmd_lock); einfo->xprt_if.glink_core_if_ptr->rx_cmd_ch_open_ack( &einfo->xprt_if, cmd.id, cmd.priority); + mutex_unlock(&einfo->rx_cmd_lock); } else if (cmd.cmd == CMD_CLOSE) { SMDXPRT_INFO(einfo, "%s RX REMOTE CLOSE rcid %u\n", __func__, cmd.id); @@ -423,10 +430,12 @@ static void process_ctl_event(struct work_struct *work) __func__, cmd.id); if (found && !ch->remote_legacy) { + mutex_lock(&einfo->rx_cmd_lock); einfo->xprt_if.glink_core_if_ptr-> rx_cmd_ch_remote_close( &einfo->xprt_if, cmd.id); + mutex_unlock(&einfo->rx_cmd_lock); } else { /* not found or a legacy channel */ SMDXPRT_INFO(einfo, @@ -463,9 +472,11 @@ static void process_ctl_event(struct work_struct *work) rcu_id = srcu_read_lock(&einfo->ssr_sync); smd_data_ch_close(ch); srcu_read_unlock(&einfo->ssr_sync, rcu_id); + mutex_lock(&einfo->rx_cmd_lock); einfo->xprt_if.glink_core_if_ptr->rx_cmd_ch_close_ack( &einfo->xprt_if, cmd.id); + mutex_unlock(&einfo->rx_cmd_lock); } } } @@ -548,10 +559,12 @@ static void process_tx_done(struct work_struct *work) riid = ch_work->iid; einfo = ch->edge; kfree(ch_work); + mutex_lock(&einfo->rx_cmd_lock); einfo->xprt_if.glink_core_if_ptr->rx_cmd_tx_done(&einfo->xprt_if, ch->rcid, riid, false); + mutex_unlock(&einfo->rx_cmd_lock); } /** @@ -579,11 +592,13 @@ static void process_open_event(struct work_struct *work) if (ch->remote_legacy || !ch->rcid) { ch->remote_legacy = true; ch->rcid = ch->lcid + LEGACY_RCID_CHANNEL_OFFSET; + mutex_lock(&einfo->rx_cmd_lock); einfo->xprt_if.glink_core_if_ptr->rx_cmd_ch_remote_open( &einfo->xprt_if, ch->rcid, ch->name, SMD_TRANS_XPRT_ID); + mutex_unlock(&einfo->rx_cmd_lock); } kfree(ch_work); } @@ -602,10 +617,13 @@ static void process_close_event(struct work_struct *work) ch = ch_work->ch; einfo = ch->edge; kfree(ch_work); - if (ch->remote_legacy) + if (ch->remote_legacy) { + mutex_lock(&einfo->rx_cmd_lock); einfo->xprt_if.glink_core_if_ptr->rx_cmd_ch_remote_close( &einfo->xprt_if, ch->rcid); + mutex_unlock(&einfo->rx_cmd_lock); + } ch->rcid = 0; } @@ -639,9 +657,11 @@ static void process_status_event(struct work_struct *work) if (set & TIOCM_RI) sigs |= SMD_RI_SIG; + mutex_lock(&einfo->rx_cmd_lock); einfo->xprt_if.glink_core_if_ptr->rx_cmd_remote_sigs(&einfo->xprt_if, ch->rcid, sigs); + mutex_unlock(&einfo->rx_cmd_lock); } /** @@ -658,14 +678,20 @@ static void process_reopen_event(struct work_struct *work) ch = ch_work->ch; einfo = ch->edge; kfree(ch_work); - if (ch->remote_legacy) + if (ch->remote_legacy) { + mutex_lock(&einfo->rx_cmd_lock); einfo->xprt_if.glink_core_if_ptr->rx_cmd_ch_remote_close( &einfo->xprt_if, ch->rcid); - if (ch->local_legacy) + mutex_unlock(&einfo->rx_cmd_lock); + } + if (ch->local_legacy) { + mutex_lock(&einfo->rx_cmd_lock); einfo->xprt_if.glink_core_if_ptr->rx_cmd_ch_close_ack( &einfo->xprt_if, ch->lcid); + mutex_unlock(&einfo->rx_cmd_lock); + } } /** @@ -721,11 +747,13 @@ static void process_data_event(struct work_struct *work) __func__, ch->name, ch->lcid, ch->rcid); ch->intent_req = true; + mutex_lock(&einfo->rx_cmd_lock); einfo->xprt_if.glink_core_if_ptr-> rx_cmd_remote_rx_intent_req( &einfo->xprt_if, ch->rcid, pkt_remaining); + mutex_unlock(&einfo->rx_cmd_lock); return; } } @@ -862,9 +890,11 @@ static void smd_data_ch_close(struct channel *ch) smd_close(ch->smd_ch); ch->smd_ch = NULL; } else if (ch->local_legacy) { + mutex_lock(&ch->edge->rx_cmd_lock); ch->edge->xprt_if.glink_core_if_ptr->rx_cmd_ch_close_ack( &ch->edge->xprt_if, ch->lcid); + mutex_unlock(&ch->edge->rx_cmd_lock); } ch->local_legacy = false; @@ -1045,12 +1075,14 @@ static void tx_cmd_version(struct glink_transport_if *if_ptr, uint32_t version, struct edge_info *einfo; einfo = container_of(if_ptr, struct edge_info, xprt_if); + mutex_lock(&einfo->rx_cmd_lock); einfo->xprt_if.glink_core_if_ptr->rx_cmd_version_ack(&einfo->xprt_if, version, features); einfo->xprt_if.glink_core_if_ptr->rx_cmd_version(&einfo->xprt_if, version, features); + mutex_unlock(&einfo->rx_cmd_lock); } /** @@ -1208,10 +1240,13 @@ static int tx_cmd_ch_open(struct glink_transport_if *if_ptr, uint32_t lcid, ch->local_legacy = true; ch->remote_legacy = true; ret = add_platform_driver(ch); - if (!ret) + if (!ret) { + mutex_lock(&einfo->rx_cmd_lock); einfo->xprt_if.glink_core_if_ptr->rx_cmd_ch_open_ack( &einfo->xprt_if, ch->lcid, SMD_TRANS_XPRT_ID); + mutex_unlock(&einfo->rx_cmd_lock); + } } srcu_read_unlock(&einfo->ssr_sync, rcu_id); @@ -1723,6 +1758,7 @@ static int tx_cmd_rx_intent_req(struct glink_transport_if *if_ptr, break; } spin_unlock_irqrestore(&einfo->channels_lock, flags); + mutex_lock(&einfo->rx_cmd_lock); einfo->xprt_if.glink_core_if_ptr->rx_cmd_rx_intent_req_ack( &einfo->xprt_if, ch->rcid, @@ -1732,6 +1768,7 @@ static int tx_cmd_rx_intent_req(struct glink_transport_if *if_ptr, ch->rcid, ch->next_intent_id++, size); + mutex_unlock(&einfo->rx_cmd_lock); return 0; } @@ -1939,6 +1976,7 @@ static int __init glink_smd_xprt_init(void) init_srcu_struct(&einfo->ssr_sync); mutex_init(&einfo->smd_lock); mutex_init(&einfo->in_ssr_lock); + mutex_init(&einfo->rx_cmd_lock); INIT_DELAYED_WORK(&einfo->ssr_work, ssr_work_func); INIT_WORK(&einfo->work, process_ctl_event); rc = glink_core_register_transport(&einfo->xprt_if, |
