Loading drivers/platform/msm/ipa/ipa_v3/ipa.c +15 −5 Original line number Diff line number Diff line Loading @@ -55,6 +55,8 @@ #include "ipa_trace.h" #include "ipa_odl.h" #define IPA_SUSPEND_BUSY_TIMEOUT (msecs_to_jiffies(10)) /* * The following for adding code (ie. for EMULATION) not found on x86. */ Loading Loading @@ -118,7 +120,7 @@ static void ipa3_load_ipa_fw(struct work_struct *work); static DECLARE_WORK(ipa3_fw_loading_work, ipa3_load_ipa_fw); static void ipa_dec_clients_disable_clks_on_wq(struct work_struct *work); static DECLARE_WORK(ipa_dec_clients_disable_clks_on_wq_work, static DECLARE_DELAYED_WORK(ipa_dec_clients_disable_clks_on_wq_work, ipa_dec_clients_disable_clks_on_wq); static int ipa3_ioctl_add_rt_rule_v2(unsigned long arg); Loading Loading @@ -4811,8 +4813,16 @@ static void __ipa3_dec_client_disable_clks(void) ret = atomic_sub_return(1, &ipa3_ctx->ipa3_active_clients.cnt); if (ret > 0) goto unlock_mutex; ipa3_suspend_apps_pipes(true); ret = ipa3_suspend_apps_pipes(true); if (ret) { /* HW is busy, retry after some time */ atomic_inc(&ipa3_ctx->ipa3_active_clients.cnt); queue_delayed_work(ipa3_ctx->power_mgmt_wq, &ipa_dec_clients_disable_clks_on_wq_work, IPA_SUSPEND_BUSY_TIMEOUT); } else { ipa3_disable_clks(); } unlock_mutex: mutex_unlock(&ipa3_ctx->ipa3_active_clients.mutex); Loading Loading @@ -4865,8 +4875,8 @@ void ipa3_dec_client_disable_clks_no_block( } /* seems like this is the only client holding the clocks */ queue_work(ipa3_ctx->power_mgmt_wq, &ipa_dec_clients_disable_clks_on_wq_work); queue_delayed_work(ipa3_ctx->power_mgmt_wq, &ipa_dec_clients_disable_clks_on_wq_work, 0); } /** Loading drivers/platform/msm/ipa/ipa_v3/ipa_i.h +1 −1 Original line number Diff line number Diff line Loading @@ -2915,7 +2915,7 @@ int ipa3_create_wdi_mapping(u32 num_buffers, struct ipa_wdi_buffer_info *info); int ipa3_set_flt_tuple_mask(int pipe_idx, struct ipahal_reg_hash_tuple *tuple); int ipa3_set_rt_tuple_mask(int tbl_idx, struct ipahal_reg_hash_tuple *tuple); void ipa3_set_resorce_groups_min_max_limits(void); void ipa3_suspend_apps_pipes(bool suspend); int ipa3_suspend_apps_pipes(bool suspend); int ipa3_flt_read_tbl_from_hw(u32 pipe_idx, enum ipa_ip_type ip_type, bool hashable, Loading drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +58 −122 Original line number Diff line number Diff line Loading @@ -7486,12 +7486,10 @@ void ipa3_set_resorce_groups_min_max_limits(void) IPADBG("EXIT\n"); } static void ipa3_gsi_poll_after_suspend(struct ipa3_ep_context *ep) static bool ipa3_gsi_channel_is_quite(struct ipa3_ep_context *ep) { bool empty; IPADBG("switch ch %ld to poll\n", ep->gsi_chan_hdl); gsi_config_channel_mode(ep->gsi_chan_hdl, GSI_CHAN_MODE_POLL); gsi_is_channel_empty(ep->gsi_chan_hdl, &empty); if (!empty) { IPADBG("ch %ld not empty\n", ep->gsi_chan_hdl); Loading @@ -7500,6 +7498,7 @@ static void ipa3_gsi_poll_after_suspend(struct ipa3_ep_context *ep) if (!atomic_read(&ep->sys->curr_polling_state)) __ipa_gsi_irq_rx_scedule_poll(ep->sys); } return empty; } static int __ipa3_stop_gsi_channel(u32 clnt_hdl) Loading Loading @@ -7625,26 +7624,28 @@ int ipa3_stop_gsi_channel(u32 clnt_hdl) return res; } void ipa3_suspend_apps_pipes(bool suspend) static int _ipa_suspend_pipe(enum ipa_client_type client, bool suspend) { struct ipa_ep_cfg_ctrl cfg; int ipa_ep_idx; struct ipa3_ep_context *ep; int res; memset(&cfg, 0, sizeof(cfg)); cfg.ipa_ep_suspend = suspend; if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) { IPAERR("not supported\n"); return -EPERM; } ipa_ep_idx = ipa3_get_ep_mapping(IPA_CLIENT_APPS_LAN_CONS); ipa_ep_idx = ipa3_get_ep_mapping(client); if (ipa_ep_idx < 0) { IPAERR("IPA client mapping failed\n"); ipa_assert(); return; IPADBG("client %d not configued\n", client); return 0; } ep = &ipa3_ctx->ep[ipa_ep_idx]; if (ep->valid) { IPADBG("%s pipe %d\n", suspend ? "suspend" : "unsuspend", ipa_ep_idx); if (!ep->valid) return 0; 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 Loading @@ -7654,7 +7655,6 @@ void ipa3_suspend_apps_pipes(bool suspend) gsi_config_channel_mode(ep->gsi_chan_hdl, GSI_CHAN_MODE_CALLBACK); if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) { if (suspend) { res = __ipa3_stop_gsi_channel(ipa_ep_idx); if (res) { Loading @@ -7668,98 +7668,34 @@ void ipa3_suspend_apps_pipes(bool suspend) ipa_assert(); } } } else { ipa3_cfg_ep_ctrl(ipa_ep_idx, &cfg); } if (suspend) ipa3_gsi_poll_after_suspend(ep); } ipa_ep_idx = ipa_get_ep_mapping(IPA_CLIENT_APPS_WAN_CONS); /* Considering the case for SSR. */ if (ipa_ep_idx == -1) { IPADBG("Invalid mapping for IPA_CLIENT_APPS_WAN_CONS\n"); return; } ep = &ipa3_ctx->ep[ipa_ep_idx]; if (ep->valid) { 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 */ if (!suspend && !atomic_read(&ep->sys->curr_polling_state)) gsi_config_channel_mode(ep->gsi_chan_hdl, GSI_CHAN_MODE_CALLBACK); if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) { if (suspend) { res = __ipa3_stop_gsi_channel(ipa_ep_idx); if (res) { IPAERR("failed to stop WAN channel\n"); ipa_assert(); } } else if (!atomic_read(&ipa3_ctx->is_ssr)) { /* If SSR was alreday started not required to * start WAN channel,Because in SSR will stop * channel and reset the channel. */ res = gsi_start_channel(ep->gsi_chan_hdl); if (res) { IPAERR("failed to start WAN channel\n"); ipa_assert(); } } } else { ipa3_cfg_ep_ctrl(ipa_ep_idx, &cfg); } if (suspend) ipa3_gsi_poll_after_suspend(ep); } ipa_ep_idx = ipa_get_ep_mapping(IPA_CLIENT_ODL_DPL_CONS); /* Considering the case for SSR. */ if (ipa_ep_idx == -1) { IPADBG("Invalid mapping for IPA_CLIENT_ODL_DPL_CONS\n"); return; } ep = &ipa3_ctx->ep[ipa_ep_idx]; if (ep->valid) { 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 */ if (!suspend && !atomic_read(&ep->sys->curr_polling_state)) IPADBG("switch ch %ld to poll\n", ep->gsi_chan_hdl); 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); if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) { if (suspend) { res = __ipa3_stop_gsi_channel(ipa_ep_idx); if (res) { IPAERR("failed to stop ODL channel\n"); ipa_assert(); } } else if (!atomic_read(&ipa3_ctx->is_ssr)) { /* If SSR was alreday started not required to * start WAN channel,Because in SSR will stop * channel and reset the channel. */ res = gsi_start_channel(ep->gsi_chan_hdl); if (res) { IPAERR("failed to start ODL channel\n"); ipa_assert(); } } } else { ipa3_cfg_ep_ctrl(ipa_ep_idx, &cfg); } if (suspend) ipa3_gsi_poll_after_suspend(ep); return 0; } int ipa3_suspend_apps_pipes(bool suspend) { int res; res = _ipa_suspend_pipe(IPA_CLIENT_APPS_LAN_CONS, suspend); if (res) return res; res = _ipa_suspend_pipe(IPA_CLIENT_APPS_WAN_CONS, suspend); if (res) return res; return 0; } int ipa3_allocate_dma_task_for_gsi(void) Loading Loading
drivers/platform/msm/ipa/ipa_v3/ipa.c +15 −5 Original line number Diff line number Diff line Loading @@ -55,6 +55,8 @@ #include "ipa_trace.h" #include "ipa_odl.h" #define IPA_SUSPEND_BUSY_TIMEOUT (msecs_to_jiffies(10)) /* * The following for adding code (ie. for EMULATION) not found on x86. */ Loading Loading @@ -118,7 +120,7 @@ static void ipa3_load_ipa_fw(struct work_struct *work); static DECLARE_WORK(ipa3_fw_loading_work, ipa3_load_ipa_fw); static void ipa_dec_clients_disable_clks_on_wq(struct work_struct *work); static DECLARE_WORK(ipa_dec_clients_disable_clks_on_wq_work, static DECLARE_DELAYED_WORK(ipa_dec_clients_disable_clks_on_wq_work, ipa_dec_clients_disable_clks_on_wq); static int ipa3_ioctl_add_rt_rule_v2(unsigned long arg); Loading Loading @@ -4811,8 +4813,16 @@ static void __ipa3_dec_client_disable_clks(void) ret = atomic_sub_return(1, &ipa3_ctx->ipa3_active_clients.cnt); if (ret > 0) goto unlock_mutex; ipa3_suspend_apps_pipes(true); ret = ipa3_suspend_apps_pipes(true); if (ret) { /* HW is busy, retry after some time */ atomic_inc(&ipa3_ctx->ipa3_active_clients.cnt); queue_delayed_work(ipa3_ctx->power_mgmt_wq, &ipa_dec_clients_disable_clks_on_wq_work, IPA_SUSPEND_BUSY_TIMEOUT); } else { ipa3_disable_clks(); } unlock_mutex: mutex_unlock(&ipa3_ctx->ipa3_active_clients.mutex); Loading Loading @@ -4865,8 +4875,8 @@ void ipa3_dec_client_disable_clks_no_block( } /* seems like this is the only client holding the clocks */ queue_work(ipa3_ctx->power_mgmt_wq, &ipa_dec_clients_disable_clks_on_wq_work); queue_delayed_work(ipa3_ctx->power_mgmt_wq, &ipa_dec_clients_disable_clks_on_wq_work, 0); } /** Loading
drivers/platform/msm/ipa/ipa_v3/ipa_i.h +1 −1 Original line number Diff line number Diff line Loading @@ -2915,7 +2915,7 @@ int ipa3_create_wdi_mapping(u32 num_buffers, struct ipa_wdi_buffer_info *info); int ipa3_set_flt_tuple_mask(int pipe_idx, struct ipahal_reg_hash_tuple *tuple); int ipa3_set_rt_tuple_mask(int tbl_idx, struct ipahal_reg_hash_tuple *tuple); void ipa3_set_resorce_groups_min_max_limits(void); void ipa3_suspend_apps_pipes(bool suspend); int ipa3_suspend_apps_pipes(bool suspend); int ipa3_flt_read_tbl_from_hw(u32 pipe_idx, enum ipa_ip_type ip_type, bool hashable, Loading
drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +58 −122 Original line number Diff line number Diff line Loading @@ -7486,12 +7486,10 @@ void ipa3_set_resorce_groups_min_max_limits(void) IPADBG("EXIT\n"); } static void ipa3_gsi_poll_after_suspend(struct ipa3_ep_context *ep) static bool ipa3_gsi_channel_is_quite(struct ipa3_ep_context *ep) { bool empty; IPADBG("switch ch %ld to poll\n", ep->gsi_chan_hdl); gsi_config_channel_mode(ep->gsi_chan_hdl, GSI_CHAN_MODE_POLL); gsi_is_channel_empty(ep->gsi_chan_hdl, &empty); if (!empty) { IPADBG("ch %ld not empty\n", ep->gsi_chan_hdl); Loading @@ -7500,6 +7498,7 @@ static void ipa3_gsi_poll_after_suspend(struct ipa3_ep_context *ep) if (!atomic_read(&ep->sys->curr_polling_state)) __ipa_gsi_irq_rx_scedule_poll(ep->sys); } return empty; } static int __ipa3_stop_gsi_channel(u32 clnt_hdl) Loading Loading @@ -7625,26 +7624,28 @@ int ipa3_stop_gsi_channel(u32 clnt_hdl) return res; } void ipa3_suspend_apps_pipes(bool suspend) static int _ipa_suspend_pipe(enum ipa_client_type client, bool suspend) { struct ipa_ep_cfg_ctrl cfg; int ipa_ep_idx; struct ipa3_ep_context *ep; int res; memset(&cfg, 0, sizeof(cfg)); cfg.ipa_ep_suspend = suspend; if (ipa3_ctx->ipa_hw_type < IPA_HW_v4_0) { IPAERR("not supported\n"); return -EPERM; } ipa_ep_idx = ipa3_get_ep_mapping(IPA_CLIENT_APPS_LAN_CONS); ipa_ep_idx = ipa3_get_ep_mapping(client); if (ipa_ep_idx < 0) { IPAERR("IPA client mapping failed\n"); ipa_assert(); return; IPADBG("client %d not configued\n", client); return 0; } ep = &ipa3_ctx->ep[ipa_ep_idx]; if (ep->valid) { IPADBG("%s pipe %d\n", suspend ? "suspend" : "unsuspend", ipa_ep_idx); if (!ep->valid) return 0; 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 Loading @@ -7654,7 +7655,6 @@ void ipa3_suspend_apps_pipes(bool suspend) gsi_config_channel_mode(ep->gsi_chan_hdl, GSI_CHAN_MODE_CALLBACK); if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) { if (suspend) { res = __ipa3_stop_gsi_channel(ipa_ep_idx); if (res) { Loading @@ -7668,98 +7668,34 @@ void ipa3_suspend_apps_pipes(bool suspend) ipa_assert(); } } } else { ipa3_cfg_ep_ctrl(ipa_ep_idx, &cfg); } if (suspend) ipa3_gsi_poll_after_suspend(ep); } ipa_ep_idx = ipa_get_ep_mapping(IPA_CLIENT_APPS_WAN_CONS); /* Considering the case for SSR. */ if (ipa_ep_idx == -1) { IPADBG("Invalid mapping for IPA_CLIENT_APPS_WAN_CONS\n"); return; } ep = &ipa3_ctx->ep[ipa_ep_idx]; if (ep->valid) { 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 */ if (!suspend && !atomic_read(&ep->sys->curr_polling_state)) gsi_config_channel_mode(ep->gsi_chan_hdl, GSI_CHAN_MODE_CALLBACK); if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) { if (suspend) { res = __ipa3_stop_gsi_channel(ipa_ep_idx); if (res) { IPAERR("failed to stop WAN channel\n"); ipa_assert(); } } else if (!atomic_read(&ipa3_ctx->is_ssr)) { /* If SSR was alreday started not required to * start WAN channel,Because in SSR will stop * channel and reset the channel. */ res = gsi_start_channel(ep->gsi_chan_hdl); if (res) { IPAERR("failed to start WAN channel\n"); ipa_assert(); } } } else { ipa3_cfg_ep_ctrl(ipa_ep_idx, &cfg); } if (suspend) ipa3_gsi_poll_after_suspend(ep); } ipa_ep_idx = ipa_get_ep_mapping(IPA_CLIENT_ODL_DPL_CONS); /* Considering the case for SSR. */ if (ipa_ep_idx == -1) { IPADBG("Invalid mapping for IPA_CLIENT_ODL_DPL_CONS\n"); return; } ep = &ipa3_ctx->ep[ipa_ep_idx]; if (ep->valid) { 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 */ if (!suspend && !atomic_read(&ep->sys->curr_polling_state)) IPADBG("switch ch %ld to poll\n", ep->gsi_chan_hdl); 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); if (ipa3_ctx->ipa_hw_type >= IPA_HW_v4_0) { if (suspend) { res = __ipa3_stop_gsi_channel(ipa_ep_idx); if (res) { IPAERR("failed to stop ODL channel\n"); ipa_assert(); } } else if (!atomic_read(&ipa3_ctx->is_ssr)) { /* If SSR was alreday started not required to * start WAN channel,Because in SSR will stop * channel and reset the channel. */ res = gsi_start_channel(ep->gsi_chan_hdl); if (res) { IPAERR("failed to start ODL channel\n"); ipa_assert(); } } } else { ipa3_cfg_ep_ctrl(ipa_ep_idx, &cfg); } if (suspend) ipa3_gsi_poll_after_suspend(ep); return 0; } int ipa3_suspend_apps_pipes(bool suspend) { int res; res = _ipa_suspend_pipe(IPA_CLIENT_APPS_LAN_CONS, suspend); if (res) return res; res = _ipa_suspend_pipe(IPA_CLIENT_APPS_WAN_CONS, suspend); if (res) return res; return 0; } int ipa3_allocate_dma_task_for_gsi(void) Loading