diff --git a/drivers/platform/msm/gsi/gsi.c b/drivers/platform/msm/gsi/gsi.c index 98edaf21c748..b070a36c0f74 100644 --- a/drivers/platform/msm/gsi/gsi.c +++ b/drivers/platform/msm/gsi/gsi.c @@ -3979,17 +3979,19 @@ int gsi_config_channel_mode(unsigned long chan_hdl, enum gsi_chan_mode mode) return -GSI_STATUS_UNSUPPORTED_OP; } + spin_lock_irqsave(&gsi_ctx->slock, flags); + if (atomic_read(&ctx->poll_mode)) curr = GSI_CHAN_MODE_POLL; else curr = GSI_CHAN_MODE_CALLBACK; if (mode == curr) { - GSIDBG("already in requested mode %u chan_hdl=%lu\n", + GSIERR("already in requested mode %u chan_hdl=%lu\n", curr, chan_hdl); + spin_unlock_irqrestore(&gsi_ctx->slock, flags); return -GSI_STATUS_UNSUPPORTED_OP; } - spin_lock_irqsave(&gsi_ctx->slock, flags); if (curr == GSI_CHAN_MODE_CALLBACK && mode == GSI_CHAN_MODE_POLL) { __gsi_config_ieob_irq(gsi_ctx->per.ee, 1 << ctx->evtr->id, 0); diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c index 8bd99389e5c8..c696707f419c 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_dp.c @@ -1937,6 +1937,7 @@ static void ipa3_wq_handle_rx(struct work_struct *work) if (sys->napi_obj) { ipa_pm_activate_sync(sys->pm_hdl); napi_schedule(sys->napi_obj); + IPA_STATS_INC_CNT(sys->napi_sch_cnt); } else if (IPA_CLIENT_IS_LOW_LAT_CONS(sys->ep->client)) { ipa_pm_activate_sync(sys->pm_hdl); tasklet_schedule(&sys->tasklet); @@ -4590,13 +4591,16 @@ void __ipa_gsi_irq_rx_scedule_poll(struct ipa3_sys_context *sys) * or after NAPI poll */ clk_off = ipa_pm_activate(sys->pm_hdl); - if (!clk_off && sys->napi_obj) + if (!clk_off && sys->napi_obj) { napi_schedule(sys->napi_obj); - else if (!clk_off && + IPA_STATS_INC_CNT(sys->napi_sch_cnt); + } else if (!clk_off && IPA_CLIENT_IS_LOW_LAT_CONS(sys->ep->client)) { tasklet_schedule(&sys->tasklet); - } else + } else { queue_work(sys->wq, &sys->work); + } + } static void ipa_gsi_irq_rx_notify_cb(struct gsi_chan_xfer_notify *notify) @@ -5312,6 +5316,7 @@ start_poll: if (cnt < weight && ep->sys->len > IPA_DEFAULT_SYS_YELLOW_WM && wan_def_sys->len > IPA_DEFAULT_SYS_YELLOW_WM) { napi_complete(ep->sys->napi_obj); + IPA_STATS_INC_CNT(ep->sys->napi_comp_cnt); ret = ipa3_rx_switch_to_intr_mode(ep->sys); if (ret == -GSI_STATUS_PENDING_IRQ && napi_reschedule(ep->sys->napi_obj)) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index e00ee682e10f..435550eb21f6 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -1100,6 +1100,8 @@ struct ipa3_sys_context { struct workqueue_struct *repl_wq; struct ipa3_status_stats *status_stat; u32 pm_hdl; + unsigned int napi_sch_cnt; + unsigned int napi_comp_cnt; /* ordering is important - other immutable fields go below */ }; diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index bff636232011..adf855d0a658 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -8503,6 +8503,16 @@ static int _ipa_suspend_resume_pipe(enum ipa_client_type client, bool suspend) ipa_assert(); } } else { + if (IPA_CLIENT_IS_APPS_PROD(client) || + (client == IPA_CLIENT_APPS_WAN_CONS && + coal_ep_idx != IPA_EP_NOT_ALLOCATED)) + goto chan_statrt; + if (!atomic_read(&ep->sys->curr_polling_state)) { + IPADBG("switch ch %ld to callback\n", ep->gsi_chan_hdl); + gsi_config_channel_mode(ep->gsi_chan_hdl, + GSI_CHAN_MODE_CALLBACK); + } +chan_statrt: res = gsi_start_channel(ep->gsi_chan_hdl); if (res) { IPAERR("failed to start LAN channel\n"); @@ -8529,12 +8539,7 @@ static int _ipa_suspend_resume_pipe(enum ipa_client_type client, bool suspend) gsi_config_channel_mode(ep->gsi_chan_hdl, GSI_CHAN_MODE_POLL); if (!ipa3_gsi_channel_is_quite(ep)) return -EAGAIN; - } else if (!atomic_read(&ep->sys->curr_polling_state)) { - IPADBG("switch ch %ld to callback\n", ep->gsi_chan_hdl); - gsi_config_channel_mode(ep->gsi_chan_hdl, - GSI_CHAN_MODE_CALLBACK); } - return 0; }