summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDhoat Harpal <hdhoat@codeaurora.org>2016-02-26 18:34:10 +0530
committerKyle Yan <kyan@codeaurora.org>2016-04-28 16:39:46 -0700
commit84e397c0d4bd6a2f4c78592ff032bf1ebb3749ed (patch)
tree2951decdf610a25e7b1488efa751f03af4c450ae
parent6a1f375e9fb1366ef70c8ea7d24ff56a26bd70fb (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.c10
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);