summaryrefslogtreecommitdiff
path: root/drivers/soc
diff options
context:
space:
mode:
authorKarthikeyan Ramasubramanian <kramasub@codeaurora.org>2015-12-03 11:53:08 -0700
committerDavid Keitel <dkeitel@codeaurora.org>2016-03-23 21:13:28 -0700
commit868fda3de392bc05eb0f07ae0a8896c36250a30a (patch)
tree8114ff5427a91a44beb9703d53cca81bea056a18 /drivers/soc
parent7efd0a96446240ac8a7eecbcffb8f2f1a0b64597 (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.c46
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,