diff options
| author | Sridhar Ancha <sancha@codeaurora.org> | 2016-04-10 21:51:51 +0530 |
|---|---|---|
| committer | Jeevan Shriram <jshriram@codeaurora.org> | 2016-05-03 15:49:29 -0700 |
| commit | 7d371f05d03dcc771a1491034d2c8b517caee360 (patch) | |
| tree | 98d2c9ba678a41a6316ed8414ed3c27bb5fcf338 | |
| parent | 983ca3d58a78a1470c36183bc66ac65fd37b662d (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.c | 10 | ||||
| -rw-r--r-- | drivers/platform/msm/ipa/ipa_v2/ipa_qmi_service.c | 7 |
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; } |
