Loading drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +27 −1 Original line number Diff line number Diff line Loading @@ -770,6 +770,26 @@ static int ipa3_handle_rx_core(struct ipa3_sys_context *sys, bool process_all, return cnt; } /** * __ipa3_update_curr_poll_state -> update current polling for default wan and * coalescing pipe. * In RSC/RSB enabled cases using common event ring, so both the pipe * polling state should be in sync. */ void __ipa3_update_curr_poll_state(enum ipa_client_type client, int state) { int ep_idx = IPA_EP_NOT_ALLOCATED; if (client == IPA_CLIENT_APPS_WAN_COAL_CONS) ep_idx = ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_CONS); if (client == IPA_CLIENT_APPS_WAN_CONS) ep_idx = ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_COAL_CONS); if (ep_idx != IPA_EP_NOT_ALLOCATED && ipa3_ctx->ep[ep_idx].sys) atomic_set(&ipa3_ctx->ep[ep_idx].sys->curr_polling_state, state); } /** * ipa3_rx_switch_to_intr_mode() - Operate the Rx data path in interrupt mode */ Loading @@ -778,6 +798,8 @@ static int ipa3_rx_switch_to_intr_mode(struct ipa3_sys_context *sys) int ret; atomic_set(&sys->curr_polling_state, 0); __ipa3_update_curr_poll_state(sys->ep->client, 0); ipa3_dec_release_wakelock(); ret = gsi_config_channel_mode(sys->ep->gsi_chan_hdl, GSI_CHAN_MODE_CALLBACK); Loading @@ -786,8 +808,10 @@ static int ipa3_rx_switch_to_intr_mode(struct ipa3_sys_context *sys) if (ret == -GSI_STATUS_PENDING_IRQ) { ipa3_inc_acquire_wakelock(); atomic_set(&sys->curr_polling_state, 1); __ipa3_update_curr_poll_state(sys->ep->client, 1); } else { IPAERR("Failed to switch to intr mode.\n"); IPAERR("Failed to switch to intr mode %d ch_id %d\n", sys->curr_polling_state, sys->ep->gsi_chan_hdl); } } Loading Loading @@ -4301,6 +4325,8 @@ void __ipa_gsi_irq_rx_scedule_poll(struct ipa3_sys_context *sys) bool clk_off; atomic_set(&sys->curr_polling_state, 1); __ipa3_update_curr_poll_state(sys->ep->client, 1); ipa3_inc_acquire_wakelock(); /* Loading drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +65 −35 Original line number Diff line number Diff line Loading @@ -7704,7 +7704,7 @@ int ipa3_stop_gsi_channel(u32 clnt_hdl) static int _ipa_suspend_resume_pipe(enum ipa_client_type client, bool suspend) { int ipa_ep_idx; int ipa_ep_idx, coal_ep_idx; struct ipa3_ep_context *ep; int res; Loading @@ -7723,16 +7723,16 @@ static int _ipa_suspend_resume_pipe(enum ipa_client_type client, bool suspend) if (!ep->valid) return 0; coal_ep_idx = ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_COAL_CONS); IPADBG("%s pipe %d\n", suspend ? "suspend" : "unsuspend", ipa_ep_idx); /* * move the channel to callback mode. * This needs to happen before starting the channel to make * sure we don't loose any interrupt * Configure the callback mode only one time after starting the channel * otherwise observing IEOB interrupt received before configure callmode * second time. It was leading race condition in updating current * polling state. */ if (!suspend && !atomic_read(&ep->sys->curr_polling_state) && !IPA_CLIENT_IS_APPS_PROD(client)) gsi_config_channel_mode(ep->gsi_chan_hdl, GSI_CHAN_MODE_CALLBACK); if (suspend) { res = __ipa3_stop_gsi_channel(ipa_ep_idx); Loading @@ -7749,7 +7749,17 @@ static int _ipa_suspend_resume_pipe(enum ipa_client_type client, bool suspend) } /* Apps prod pipes use common event ring so cannot configure mode*/ if (IPA_CLIENT_IS_APPS_PROD(client)) /* * Skipping to configure mode for default wan pipe, * as both pipes using commong event ring. if both pipes * configure same event ring observing race condition in * updating current polling state. */ if (IPA_CLIENT_IS_APPS_PROD(client) || (client == IPA_CLIENT_APPS_WAN_CONS && coal_ep_idx != IPA_EP_NOT_ALLOCATED)) return 0; if (suspend) { Loading Loading @@ -7805,18 +7815,29 @@ void ipa3_force_close_coal(void) int ipa3_suspend_apps_pipes(bool suspend) { int res; enum ipa_client_type client; if (suspend) ipa3_force_close_coal(); for (client = 0; client < IPA_CLIENT_MAX; client++) { if (IPA_CLIENT_IS_APPS_CONS(client)) { res = _ipa_suspend_resume_pipe(client, suspend); if (res) goto undo_cons; } } /* As per HPG first need start/stop coalescing channel * then default one. Coalescing client number was greater then * default one so starting the last client. */ res = _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_WAN_COAL_CONS, suspend); if (res == -EAGAIN) goto undo_coal_cons; res = _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_WAN_CONS, suspend); if (res == -EAGAIN) goto undo_wan_cons; res = _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_LAN_CONS, suspend); if (res == -EAGAIN) goto undo_lan_cons; res = _ipa_suspend_resume_pipe(IPA_CLIENT_ODL_DPL_CONS, suspend); if (res == -EAGAIN) goto undo_odl_cons; if (suspend) { struct ipahal_reg_tx_wrapper tx; Loading @@ -7832,7 +7853,7 @@ int ipa3_suspend_apps_pipes(bool suspend) IPADBG("COAL frame is open 0x%x\n", tx.coal_slave_open_frame); res = -EAGAIN; goto undo_cons; goto undo_odl_cons; } usleep_range(IPA_TAG_SLEEP_MIN_USEC, IPA_TAG_SLEEP_MAX_USEC); Loading @@ -7841,28 +7862,37 @@ int ipa3_suspend_apps_pipes(bool suspend) ipa3_ctx->ee); if (res) { IPADBG("suspend irq is pending 0x%x\n", res); goto undo_cons; goto undo_odl_cons; } } do_prod: for (client = 0; client < IPA_CLIENT_MAX; client++) { if (IPA_CLIENT_IS_APPS_PROD(client)) { res = _ipa_suspend_resume_pipe(client, suspend); if (res) goto undo_prod; } } res = _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_LAN_PROD, suspend); if (res == -EAGAIN) goto undo_lan_prod; res = _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_WAN_PROD, suspend); if (res == -EAGAIN) goto undo_wan_prod; return 0; undo_prod: for (client; client <= IPA_CLIENT_MAX && client >= 0; client--) if (IPA_CLIENT_IS_APPS_PROD(client)) _ipa_suspend_resume_pipe(client, !suspend); client = IPA_CLIENT_MAX; undo_cons: for (client; client <= IPA_CLIENT_MAX && client >= 0; client--) if (IPA_CLIENT_IS_APPS_CONS(client)) _ipa_suspend_resume_pipe(client, !suspend); undo_wan_prod: _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_WAN_PROD, !suspend); undo_lan_prod: _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_LAN_PROD, !suspend); undo_odl_cons: _ipa_suspend_resume_pipe(IPA_CLIENT_ODL_DPL_CONS, !suspend); undo_lan_cons: _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_LAN_CONS, !suspend); undo_wan_cons: _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_WAN_COAL_CONS, !suspend); _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_WAN_CONS, !suspend); return res; undo_coal_cons: _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_WAN_COAL_CONS, !suspend); return res; } Loading Loading
drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +27 −1 Original line number Diff line number Diff line Loading @@ -770,6 +770,26 @@ static int ipa3_handle_rx_core(struct ipa3_sys_context *sys, bool process_all, return cnt; } /** * __ipa3_update_curr_poll_state -> update current polling for default wan and * coalescing pipe. * In RSC/RSB enabled cases using common event ring, so both the pipe * polling state should be in sync. */ void __ipa3_update_curr_poll_state(enum ipa_client_type client, int state) { int ep_idx = IPA_EP_NOT_ALLOCATED; if (client == IPA_CLIENT_APPS_WAN_COAL_CONS) ep_idx = ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_CONS); if (client == IPA_CLIENT_APPS_WAN_CONS) ep_idx = ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_COAL_CONS); if (ep_idx != IPA_EP_NOT_ALLOCATED && ipa3_ctx->ep[ep_idx].sys) atomic_set(&ipa3_ctx->ep[ep_idx].sys->curr_polling_state, state); } /** * ipa3_rx_switch_to_intr_mode() - Operate the Rx data path in interrupt mode */ Loading @@ -778,6 +798,8 @@ static int ipa3_rx_switch_to_intr_mode(struct ipa3_sys_context *sys) int ret; atomic_set(&sys->curr_polling_state, 0); __ipa3_update_curr_poll_state(sys->ep->client, 0); ipa3_dec_release_wakelock(); ret = gsi_config_channel_mode(sys->ep->gsi_chan_hdl, GSI_CHAN_MODE_CALLBACK); Loading @@ -786,8 +808,10 @@ static int ipa3_rx_switch_to_intr_mode(struct ipa3_sys_context *sys) if (ret == -GSI_STATUS_PENDING_IRQ) { ipa3_inc_acquire_wakelock(); atomic_set(&sys->curr_polling_state, 1); __ipa3_update_curr_poll_state(sys->ep->client, 1); } else { IPAERR("Failed to switch to intr mode.\n"); IPAERR("Failed to switch to intr mode %d ch_id %d\n", sys->curr_polling_state, sys->ep->gsi_chan_hdl); } } Loading Loading @@ -4301,6 +4325,8 @@ void __ipa_gsi_irq_rx_scedule_poll(struct ipa3_sys_context *sys) bool clk_off; atomic_set(&sys->curr_polling_state, 1); __ipa3_update_curr_poll_state(sys->ep->client, 1); ipa3_inc_acquire_wakelock(); /* Loading
drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +65 −35 Original line number Diff line number Diff line Loading @@ -7704,7 +7704,7 @@ int ipa3_stop_gsi_channel(u32 clnt_hdl) static int _ipa_suspend_resume_pipe(enum ipa_client_type client, bool suspend) { int ipa_ep_idx; int ipa_ep_idx, coal_ep_idx; struct ipa3_ep_context *ep; int res; Loading @@ -7723,16 +7723,16 @@ static int _ipa_suspend_resume_pipe(enum ipa_client_type client, bool suspend) if (!ep->valid) return 0; coal_ep_idx = ipa3_get_ep_mapping(IPA_CLIENT_APPS_WAN_COAL_CONS); IPADBG("%s pipe %d\n", suspend ? "suspend" : "unsuspend", ipa_ep_idx); /* * move the channel to callback mode. * This needs to happen before starting the channel to make * sure we don't loose any interrupt * Configure the callback mode only one time after starting the channel * otherwise observing IEOB interrupt received before configure callmode * second time. It was leading race condition in updating current * polling state. */ if (!suspend && !atomic_read(&ep->sys->curr_polling_state) && !IPA_CLIENT_IS_APPS_PROD(client)) gsi_config_channel_mode(ep->gsi_chan_hdl, GSI_CHAN_MODE_CALLBACK); if (suspend) { res = __ipa3_stop_gsi_channel(ipa_ep_idx); Loading @@ -7749,7 +7749,17 @@ static int _ipa_suspend_resume_pipe(enum ipa_client_type client, bool suspend) } /* Apps prod pipes use common event ring so cannot configure mode*/ if (IPA_CLIENT_IS_APPS_PROD(client)) /* * Skipping to configure mode for default wan pipe, * as both pipes using commong event ring. if both pipes * configure same event ring observing race condition in * updating current polling state. */ if (IPA_CLIENT_IS_APPS_PROD(client) || (client == IPA_CLIENT_APPS_WAN_CONS && coal_ep_idx != IPA_EP_NOT_ALLOCATED)) return 0; if (suspend) { Loading Loading @@ -7805,18 +7815,29 @@ void ipa3_force_close_coal(void) int ipa3_suspend_apps_pipes(bool suspend) { int res; enum ipa_client_type client; if (suspend) ipa3_force_close_coal(); for (client = 0; client < IPA_CLIENT_MAX; client++) { if (IPA_CLIENT_IS_APPS_CONS(client)) { res = _ipa_suspend_resume_pipe(client, suspend); if (res) goto undo_cons; } } /* As per HPG first need start/stop coalescing channel * then default one. Coalescing client number was greater then * default one so starting the last client. */ res = _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_WAN_COAL_CONS, suspend); if (res == -EAGAIN) goto undo_coal_cons; res = _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_WAN_CONS, suspend); if (res == -EAGAIN) goto undo_wan_cons; res = _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_LAN_CONS, suspend); if (res == -EAGAIN) goto undo_lan_cons; res = _ipa_suspend_resume_pipe(IPA_CLIENT_ODL_DPL_CONS, suspend); if (res == -EAGAIN) goto undo_odl_cons; if (suspend) { struct ipahal_reg_tx_wrapper tx; Loading @@ -7832,7 +7853,7 @@ int ipa3_suspend_apps_pipes(bool suspend) IPADBG("COAL frame is open 0x%x\n", tx.coal_slave_open_frame); res = -EAGAIN; goto undo_cons; goto undo_odl_cons; } usleep_range(IPA_TAG_SLEEP_MIN_USEC, IPA_TAG_SLEEP_MAX_USEC); Loading @@ -7841,28 +7862,37 @@ int ipa3_suspend_apps_pipes(bool suspend) ipa3_ctx->ee); if (res) { IPADBG("suspend irq is pending 0x%x\n", res); goto undo_cons; goto undo_odl_cons; } } do_prod: for (client = 0; client < IPA_CLIENT_MAX; client++) { if (IPA_CLIENT_IS_APPS_PROD(client)) { res = _ipa_suspend_resume_pipe(client, suspend); if (res) goto undo_prod; } } res = _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_LAN_PROD, suspend); if (res == -EAGAIN) goto undo_lan_prod; res = _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_WAN_PROD, suspend); if (res == -EAGAIN) goto undo_wan_prod; return 0; undo_prod: for (client; client <= IPA_CLIENT_MAX && client >= 0; client--) if (IPA_CLIENT_IS_APPS_PROD(client)) _ipa_suspend_resume_pipe(client, !suspend); client = IPA_CLIENT_MAX; undo_cons: for (client; client <= IPA_CLIENT_MAX && client >= 0; client--) if (IPA_CLIENT_IS_APPS_CONS(client)) _ipa_suspend_resume_pipe(client, !suspend); undo_wan_prod: _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_WAN_PROD, !suspend); undo_lan_prod: _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_LAN_PROD, !suspend); undo_odl_cons: _ipa_suspend_resume_pipe(IPA_CLIENT_ODL_DPL_CONS, !suspend); undo_lan_cons: _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_LAN_CONS, !suspend); undo_wan_cons: _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_WAN_COAL_CONS, !suspend); _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_WAN_CONS, !suspend); return res; undo_coal_cons: _ipa_suspend_resume_pipe(IPA_CLIENT_APPS_WAN_COAL_CONS, !suspend); return res; } Loading