summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorSridhar Ancha <sancha@codeaurora.org>2016-04-10 21:51:51 +0530
committerJeevan Shriram <jshriram@codeaurora.org>2016-05-03 15:49:29 -0700
commit7d371f05d03dcc771a1491034d2c8b517caee360 (patch)
tree98d2c9ba678a41a6316ed8414ed3c27bb5fcf338
parent983ca3d58a78a1470c36183bc66ac65fd37b662d (diff)
msm: ipa: Fix to QMI initialization and polling state
Using a workqueue for initializing QMI functionality can result in race conditions with cleanup operation during SSR handling because of scheduling delays. Make a change to not to use workqueue and initialize the QMI functionality as part of probe itself. For polling state, there is a possibility that pipe is disconnected during switch between poll mode interrupt mode. This can result in queueing switch_to_intr_work work multiple times till the pipe is connected and there is some activity. Make a change to check if the ep is valid before queuing the work. Change-Id: Id5a5128edb379308fa91b53062b6773af1b6de18 Acked-by: Chaitanya Pratapa <cpratapa@qti.qualcomm.com> Signed-off-by: Sridhar Ancha <sancha@codeaurora.org>
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_dp.c10
-rw-r--r--drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c7
2 files changed, 11 insertions, 6 deletions
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c
index 35157f961231..6cfa477608b5 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_dp.c
@@ -815,6 +815,11 @@ static void ipa_rx_switch_to_intr_mode(struct ipa_sys_context *sys)
{
int ret;
+ if (!sys->ep || !sys->ep->valid) {
+ IPAERR("EP Not Valid, no need to cleanup.\n");
+ return;
+ }
+
if (!atomic_read(&sys->curr_polling_state)) {
IPAERR("already in intr mode\n");
goto fail;
@@ -1427,8 +1432,11 @@ int ipa2_teardown_sys_pipe(u32 clnt_hdl)
} while (1);
}
- if (IPA_CLIENT_IS_CONS(ep->client))
+ if (IPA_CLIENT_IS_CONS(ep->client)) {
cancel_delayed_work_sync(&ep->sys->replenish_rx_work);
+ cancel_delayed_work_sync(&ep->sys->switch_to_intr_work);
+ }
+
flush_workqueue(ep->sys->wq);
sps_disconnect(ep->ep_hdl);
dma_free_coherent(ipa_ctx->pdev, ep->connect.desc.size,
diff --git a/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c b/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c
index 70e0db98e948..7a8318a6e138 100644
--- a/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c
+++ b/drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c
@@ -46,7 +46,6 @@ static struct workqueue_struct *ipa_clnt_req_workqueue;
static struct workqueue_struct *ipa_clnt_resp_workqueue;
static void *curr_conn;
static bool qmi_modem_init_fin, qmi_indication_fin;
-static struct work_struct ipa_qmi_service_init_work;
static uint32_t ipa_wan_platform;
struct ipa_qmi_context *ipa_qmi_ctx;
static bool first_time_handshake;
@@ -871,7 +870,7 @@ static struct notifier_block ipa_q6_clnt_nb = {
.notifier_call = ipa_q6_clnt_svc_event_notify,
};
-static void ipa_qmi_service_init_worker(struct work_struct *work)
+static void ipa_qmi_service_init_worker(void)
{
int rc;
@@ -968,9 +967,7 @@ int ipa_qmi_service_init(uint32_t wan_platform_type)
atomic_set(&workqueues_stopped, 0);
if (0 == atomic_read(&ipa_qmi_initialized)) {
- INIT_WORK(&ipa_qmi_service_init_work,
- ipa_qmi_service_init_worker);
- schedule_work(&ipa_qmi_service_init_work);
+ ipa_qmi_service_init_worker();
}
return 0;
}