Loading drivers/platform/msm/ipa/ipa_v2/ipa.c +41 −1 Original line number Diff line number Diff line Loading @@ -2802,6 +2802,45 @@ void ipa_dec_client_disable_clks(void) ipa_active_clients_unlock(); } /** * ipa_inc_acquire_wakelock() - Increase active clients counter, and * acquire wakelock if necessary * * Return codes: * None */ void ipa_inc_acquire_wakelock(void) { unsigned long flags; spin_lock_irqsave(&ipa_ctx->wakelock_ref_cnt.spinlock, flags); ipa_ctx->wakelock_ref_cnt.cnt++; if (ipa_ctx->wakelock_ref_cnt.cnt == 1) __pm_stay_awake(&ipa_ctx->w_lock); IPADBG("active wakelock ref cnt = %d\n", ipa_ctx->wakelock_ref_cnt.cnt); spin_unlock_irqrestore(&ipa_ctx->wakelock_ref_cnt.spinlock, flags); } /** * ipa_dec_release_wakelock() - Decrease active clients counter * * In case if the ref count is 0, release the wakelock. * * Return codes: * None */ void ipa_dec_release_wakelock(void) { unsigned long flags; spin_lock_irqsave(&ipa_ctx->wakelock_ref_cnt.spinlock, flags); ipa_ctx->wakelock_ref_cnt.cnt--; IPADBG("active wakelock ref cnt = %d\n", ipa_ctx->wakelock_ref_cnt.cnt); if (ipa_ctx->wakelock_ref_cnt.cnt == 0) __pm_relax(&ipa_ctx->w_lock); spin_unlock_irqrestore(&ipa_ctx->wakelock_ref_cnt.spinlock, flags); } static int ipa_setup_bam_cfg(const struct ipa_plat_drv_res *res) { void *ipa_bam_mmio; Loading Loading @@ -3552,7 +3591,8 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p, /* Create a wakeup source. */ ipa_ctx->pdev->power.wakeup = wakeup_source_register("IPA_WS"); wakeup_source_init(&ipa_ctx->w_lock, "IPA_WS"); spin_lock_init(&ipa_ctx->wakelock_ref_cnt.spinlock); /* Initialize IPA RM (resource manager) */ result = ipa_rm_initialize(); Loading drivers/platform/msm/ipa/ipa_v2/ipa_dp.c +4 −4 Original line number Diff line number Diff line Loading @@ -233,6 +233,7 @@ static void ipa_tx_switch_to_intr_mode(struct ipa_sys_context *sys) } atomic_set(&sys->curr_polling_state, 0); ipa_handle_tx_core(sys, true, false); ipa_dec_release_wakelock(); return; fail: Loading @@ -246,7 +247,6 @@ static void ipa_handle_tx(struct ipa_sys_context *sys) int cnt; ipa_inc_client_enable_clks(); pm_stay_awake(ipa_ctx->pdev); do { cnt = ipa_handle_tx_core(sys, true, true); if (cnt == 0) { Loading @@ -259,7 +259,6 @@ static void ipa_handle_tx(struct ipa_sys_context *sys) } while (inactive_cycles <= POLLING_INACTIVITY_TX); ipa_tx_switch_to_intr_mode(sys); pm_relax(ipa_ctx->pdev); ipa_dec_client_disable_clks(); } Loading Loading @@ -670,6 +669,7 @@ static void ipa_sps_irq_tx_notify(struct sps_event_notify *notify) IPAERR("sps_set_config() failed %d\n", ret); break; } ipa_inc_acquire_wakelock(); atomic_set(&sys->curr_polling_state, 1); queue_work(sys->wq, &sys->work); } Loading Loading @@ -785,6 +785,7 @@ static void ipa_rx_switch_to_intr_mode(struct ipa_sys_context *sys) } atomic_set(&sys->curr_polling_state, 0); ipa_handle_rx_core(sys, true, false); ipa_dec_release_wakelock(); return; fail: Loading Loading @@ -902,6 +903,7 @@ static void ipa_sps_irq_rx_notify(struct sps_event_notify *notify) IPAERR("sps_set_config() failed %d\n", ret); break; } ipa_inc_acquire_wakelock(); atomic_set(&sys->curr_polling_state, 1); queue_work(sys->wq, &sys->work); } Loading Loading @@ -935,7 +937,6 @@ static void ipa_handle_rx(struct ipa_sys_context *sys) int cnt; ipa_inc_client_enable_clks(); pm_stay_awake(ipa_ctx->pdev); do { cnt = ipa_handle_rx_core(sys, true, true); if (cnt == 0) { Loading @@ -956,7 +957,6 @@ static void ipa_handle_rx(struct ipa_sys_context *sys) } while (inactive_cycles <= POLLING_INACTIVITY_RX); ipa_rx_switch_to_intr_mode(sys); pm_relax(ipa_ctx->pdev); ipa_dec_client_disable_clks(); } Loading drivers/platform/msm/ipa/ipa_v2/ipa_i.h +12 −0 Original line number Diff line number Diff line Loading @@ -788,6 +788,11 @@ struct ipa_active_clients { int cnt; }; struct ipa_wakelock_ref_cnt { spinlock_t spinlock; int cnt; }; struct ipa_tag_completion { struct completion comp; atomic_t cnt; Loading Loading @@ -1160,6 +1165,8 @@ struct ipacm_client_info { * @ipa_num_pipes: The number of pipes used by IPA HW * @skip_uc_pipe_reset: Indicates whether pipe reset via uC needs to be avoided * @ipa_client_apps_wan_cons_agg_gro: RMNET_IOCTL_INGRESS_FORMAT_AGG_DATA * @w_lock: Indicates the wakeup source. * @wakelock_ref_cnt: Indicates the number of times wakelock is acquired * IPA context - holds all relevant info about IPA driver and its state */ Loading Loading @@ -1261,6 +1268,9 @@ struct ipa_context { u32 peer_bam_map_cnt; u32 wdi_map_cnt; bool use_dma_zone; struct wakeup_source w_lock; struct ipa_wakelock_ref_cnt wakelock_ref_cnt; /* RMNET_IOCTL_INGRESS_FORMAT_AGG_DATA */ bool ipa_client_apps_wan_cons_agg_gro; /* M-release support to know client pipes */ Loading Loading @@ -1988,4 +1998,6 @@ void ipa_flow_control(enum ipa_client_type ipa_client, bool enable, uint32_t qmap_id); int ipa2_restore_suspend_handler(void); void ipa_sps_irq_control_all(bool enable); void ipa_inc_acquire_wakelock(void); void ipa_dec_release_wakelock(void); #endif /* _IPA_I_H_ */ drivers/platform/msm/ipa/ipa_v3/ipa.c +45 −0 Original line number Diff line number Diff line Loading @@ -2881,6 +2881,47 @@ void ipa3_dec_client_disable_clks(void) ipa3_active_clients_unlock(); } /** * ipa3_inc_acquire_wakelock() - Increase active clients counter, and * acquire wakelock if necessary * * Return codes: * None */ void ipa3_inc_acquire_wakelock(void) { unsigned long flags; spin_lock_irqsave(&ipa3_ctx->wakelock_ref_cnt.spinlock, flags); ipa3_ctx->wakelock_ref_cnt.cnt++; if (ipa3_ctx->wakelock_ref_cnt.cnt == 1) __pm_stay_awake(&ipa3_ctx->w_lock); IPADBG("active wakelock ref cnt = %d\n", ipa3_ctx->wakelock_ref_cnt.cnt); spin_unlock_irqrestore(&ipa3_ctx->wakelock_ref_cnt.spinlock, flags); } /** * ipa3_dec_release_wakelock() - Decrease active clients counter * * In case if the ref count is 0, release the wakelock. * * Return codes: * None */ void ipa3_dec_release_wakelock(void) { unsigned long flags; spin_lock_irqsave(&ipa3_ctx->wakelock_ref_cnt.spinlock, flags); ipa3_ctx->wakelock_ref_cnt.cnt--; IPADBG("active wakelock ref cnt = %d\n", ipa3_ctx->wakelock_ref_cnt.cnt); if (ipa3_ctx->wakelock_ref_cnt.cnt == 0) __pm_relax(&ipa3_ctx->w_lock); spin_unlock_irqrestore(&ipa3_ctx->wakelock_ref_cnt.spinlock, flags); } int ipa3_set_required_perf_profile(enum ipa_voltage_level floor_voltage, u32 bandwidth_mbps) { Loading Loading @@ -3625,6 +3666,10 @@ static int ipa3_init(const struct ipa3_plat_drv_res *resource_p, goto fail_nat_dev_add; } /* Create a wakeup source. */ wakeup_source_init(&ipa3_ctx->w_lock, "IPA_WS"); spin_lock_init(&ipa3_ctx->wakelock_ref_cnt.spinlock); /* Initialize IPA RM (resource manager) */ result = ipa3_rm_initialize(); if (result) { Loading drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +8 −2 Original line number Diff line number Diff line Loading @@ -212,6 +212,7 @@ static void ipa3_tx_switch_to_intr_mode(struct ipa3_sys_context *sys) if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) { atomic_set(&sys->curr_polling_state, 0); ipa3_dec_release_wakelock(); ret = gsi_config_channel_mode(sys->ep->gsi_chan_hdl, GSI_CHAN_MODE_CALLBACK); if (ret != GSI_STATUS_SUCCESS) { Loading Loading @@ -239,8 +240,8 @@ static void ipa3_tx_switch_to_intr_mode(struct ipa3_sys_context *sys) } atomic_set(&sys->curr_polling_state, 0); ipa3_handle_tx_core(sys, true, false); ipa3_dec_release_wakelock(); } return; fail: Loading Loading @@ -775,6 +776,7 @@ static void ipa3_sps_irq_tx_notify(struct sps_event_notify *notify) IPAERR("sps_set_config() failed %d\n", ret); break; } ipa3_inc_acquire_wakelock(); atomic_set(&sys->curr_polling_state, 1); queue_work(sys->wq, &sys->work); } Loading Loading @@ -852,6 +854,7 @@ static void ipa3_rx_switch_to_intr_mode(struct ipa3_sys_context *sys) if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) { atomic_set(&sys->curr_polling_state, 0); ipa3_dec_release_wakelock(); ret = gsi_config_channel_mode(sys->ep->gsi_chan_hdl, GSI_CHAN_MODE_CALLBACK); if (ret != GSI_STATUS_SUCCESS) { Loading Loading @@ -879,8 +882,8 @@ static void ipa3_rx_switch_to_intr_mode(struct ipa3_sys_context *sys) } atomic_set(&sys->curr_polling_state, 0); ipa3_handle_rx_core(sys, true, false); ipa3_dec_release_wakelock(); } return; fail: Loading Loading @@ -927,6 +930,7 @@ static void ipa3_sps_irq_rx_notify(struct sps_event_notify *notify) IPAERR("sps_set_config() failed %d\n", ret); break; } ipa3_inc_acquire_wakelock(); atomic_set(&sys->curr_polling_state, 1); queue_work(sys->wq, &sys->work); } Loading Loading @@ -3296,6 +3300,7 @@ static void ipa_gsi_irq_rx_notify_cb(struct gsi_chan_xfer_notify *notify) /* put the gsi channel into polling mode */ gsi_config_channel_mode(sys->ep->gsi_chan_hdl, GSI_CHAN_MODE_POLL); ipa3_inc_acquire_wakelock(); atomic_set(&sys->curr_polling_state, 1); queue_work(sys->wq, &sys->work); } Loading Loading @@ -3341,6 +3346,7 @@ static void ipa_dma_gsi_irq_rx_notify_cb(struct gsi_chan_xfer_notify *notify) /* put the gsi channel into polling mode */ gsi_config_channel_mode(sys->ep->gsi_chan_hdl, GSI_CHAN_MODE_POLL); ipa3_inc_acquire_wakelock(); atomic_set(&sys->curr_polling_state, 1); queue_work(sys->wq, &sys->work); } Loading Loading
drivers/platform/msm/ipa/ipa_v2/ipa.c +41 −1 Original line number Diff line number Diff line Loading @@ -2802,6 +2802,45 @@ void ipa_dec_client_disable_clks(void) ipa_active_clients_unlock(); } /** * ipa_inc_acquire_wakelock() - Increase active clients counter, and * acquire wakelock if necessary * * Return codes: * None */ void ipa_inc_acquire_wakelock(void) { unsigned long flags; spin_lock_irqsave(&ipa_ctx->wakelock_ref_cnt.spinlock, flags); ipa_ctx->wakelock_ref_cnt.cnt++; if (ipa_ctx->wakelock_ref_cnt.cnt == 1) __pm_stay_awake(&ipa_ctx->w_lock); IPADBG("active wakelock ref cnt = %d\n", ipa_ctx->wakelock_ref_cnt.cnt); spin_unlock_irqrestore(&ipa_ctx->wakelock_ref_cnt.spinlock, flags); } /** * ipa_dec_release_wakelock() - Decrease active clients counter * * In case if the ref count is 0, release the wakelock. * * Return codes: * None */ void ipa_dec_release_wakelock(void) { unsigned long flags; spin_lock_irqsave(&ipa_ctx->wakelock_ref_cnt.spinlock, flags); ipa_ctx->wakelock_ref_cnt.cnt--; IPADBG("active wakelock ref cnt = %d\n", ipa_ctx->wakelock_ref_cnt.cnt); if (ipa_ctx->wakelock_ref_cnt.cnt == 0) __pm_relax(&ipa_ctx->w_lock); spin_unlock_irqrestore(&ipa_ctx->wakelock_ref_cnt.spinlock, flags); } static int ipa_setup_bam_cfg(const struct ipa_plat_drv_res *res) { void *ipa_bam_mmio; Loading Loading @@ -3552,7 +3591,8 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p, /* Create a wakeup source. */ ipa_ctx->pdev->power.wakeup = wakeup_source_register("IPA_WS"); wakeup_source_init(&ipa_ctx->w_lock, "IPA_WS"); spin_lock_init(&ipa_ctx->wakelock_ref_cnt.spinlock); /* Initialize IPA RM (resource manager) */ result = ipa_rm_initialize(); Loading
drivers/platform/msm/ipa/ipa_v2/ipa_dp.c +4 −4 Original line number Diff line number Diff line Loading @@ -233,6 +233,7 @@ static void ipa_tx_switch_to_intr_mode(struct ipa_sys_context *sys) } atomic_set(&sys->curr_polling_state, 0); ipa_handle_tx_core(sys, true, false); ipa_dec_release_wakelock(); return; fail: Loading @@ -246,7 +247,6 @@ static void ipa_handle_tx(struct ipa_sys_context *sys) int cnt; ipa_inc_client_enable_clks(); pm_stay_awake(ipa_ctx->pdev); do { cnt = ipa_handle_tx_core(sys, true, true); if (cnt == 0) { Loading @@ -259,7 +259,6 @@ static void ipa_handle_tx(struct ipa_sys_context *sys) } while (inactive_cycles <= POLLING_INACTIVITY_TX); ipa_tx_switch_to_intr_mode(sys); pm_relax(ipa_ctx->pdev); ipa_dec_client_disable_clks(); } Loading Loading @@ -670,6 +669,7 @@ static void ipa_sps_irq_tx_notify(struct sps_event_notify *notify) IPAERR("sps_set_config() failed %d\n", ret); break; } ipa_inc_acquire_wakelock(); atomic_set(&sys->curr_polling_state, 1); queue_work(sys->wq, &sys->work); } Loading Loading @@ -785,6 +785,7 @@ static void ipa_rx_switch_to_intr_mode(struct ipa_sys_context *sys) } atomic_set(&sys->curr_polling_state, 0); ipa_handle_rx_core(sys, true, false); ipa_dec_release_wakelock(); return; fail: Loading Loading @@ -902,6 +903,7 @@ static void ipa_sps_irq_rx_notify(struct sps_event_notify *notify) IPAERR("sps_set_config() failed %d\n", ret); break; } ipa_inc_acquire_wakelock(); atomic_set(&sys->curr_polling_state, 1); queue_work(sys->wq, &sys->work); } Loading Loading @@ -935,7 +937,6 @@ static void ipa_handle_rx(struct ipa_sys_context *sys) int cnt; ipa_inc_client_enable_clks(); pm_stay_awake(ipa_ctx->pdev); do { cnt = ipa_handle_rx_core(sys, true, true); if (cnt == 0) { Loading @@ -956,7 +957,6 @@ static void ipa_handle_rx(struct ipa_sys_context *sys) } while (inactive_cycles <= POLLING_INACTIVITY_RX); ipa_rx_switch_to_intr_mode(sys); pm_relax(ipa_ctx->pdev); ipa_dec_client_disable_clks(); } Loading
drivers/platform/msm/ipa/ipa_v2/ipa_i.h +12 −0 Original line number Diff line number Diff line Loading @@ -788,6 +788,11 @@ struct ipa_active_clients { int cnt; }; struct ipa_wakelock_ref_cnt { spinlock_t spinlock; int cnt; }; struct ipa_tag_completion { struct completion comp; atomic_t cnt; Loading Loading @@ -1160,6 +1165,8 @@ struct ipacm_client_info { * @ipa_num_pipes: The number of pipes used by IPA HW * @skip_uc_pipe_reset: Indicates whether pipe reset via uC needs to be avoided * @ipa_client_apps_wan_cons_agg_gro: RMNET_IOCTL_INGRESS_FORMAT_AGG_DATA * @w_lock: Indicates the wakeup source. * @wakelock_ref_cnt: Indicates the number of times wakelock is acquired * IPA context - holds all relevant info about IPA driver and its state */ Loading Loading @@ -1261,6 +1268,9 @@ struct ipa_context { u32 peer_bam_map_cnt; u32 wdi_map_cnt; bool use_dma_zone; struct wakeup_source w_lock; struct ipa_wakelock_ref_cnt wakelock_ref_cnt; /* RMNET_IOCTL_INGRESS_FORMAT_AGG_DATA */ bool ipa_client_apps_wan_cons_agg_gro; /* M-release support to know client pipes */ Loading Loading @@ -1988,4 +1998,6 @@ void ipa_flow_control(enum ipa_client_type ipa_client, bool enable, uint32_t qmap_id); int ipa2_restore_suspend_handler(void); void ipa_sps_irq_control_all(bool enable); void ipa_inc_acquire_wakelock(void); void ipa_dec_release_wakelock(void); #endif /* _IPA_I_H_ */
drivers/platform/msm/ipa/ipa_v3/ipa.c +45 −0 Original line number Diff line number Diff line Loading @@ -2881,6 +2881,47 @@ void ipa3_dec_client_disable_clks(void) ipa3_active_clients_unlock(); } /** * ipa3_inc_acquire_wakelock() - Increase active clients counter, and * acquire wakelock if necessary * * Return codes: * None */ void ipa3_inc_acquire_wakelock(void) { unsigned long flags; spin_lock_irqsave(&ipa3_ctx->wakelock_ref_cnt.spinlock, flags); ipa3_ctx->wakelock_ref_cnt.cnt++; if (ipa3_ctx->wakelock_ref_cnt.cnt == 1) __pm_stay_awake(&ipa3_ctx->w_lock); IPADBG("active wakelock ref cnt = %d\n", ipa3_ctx->wakelock_ref_cnt.cnt); spin_unlock_irqrestore(&ipa3_ctx->wakelock_ref_cnt.spinlock, flags); } /** * ipa3_dec_release_wakelock() - Decrease active clients counter * * In case if the ref count is 0, release the wakelock. * * Return codes: * None */ void ipa3_dec_release_wakelock(void) { unsigned long flags; spin_lock_irqsave(&ipa3_ctx->wakelock_ref_cnt.spinlock, flags); ipa3_ctx->wakelock_ref_cnt.cnt--; IPADBG("active wakelock ref cnt = %d\n", ipa3_ctx->wakelock_ref_cnt.cnt); if (ipa3_ctx->wakelock_ref_cnt.cnt == 0) __pm_relax(&ipa3_ctx->w_lock); spin_unlock_irqrestore(&ipa3_ctx->wakelock_ref_cnt.spinlock, flags); } int ipa3_set_required_perf_profile(enum ipa_voltage_level floor_voltage, u32 bandwidth_mbps) { Loading Loading @@ -3625,6 +3666,10 @@ static int ipa3_init(const struct ipa3_plat_drv_res *resource_p, goto fail_nat_dev_add; } /* Create a wakeup source. */ wakeup_source_init(&ipa3_ctx->w_lock, "IPA_WS"); spin_lock_init(&ipa3_ctx->wakelock_ref_cnt.spinlock); /* Initialize IPA RM (resource manager) */ result = ipa3_rm_initialize(); if (result) { Loading
drivers/platform/msm/ipa/ipa_v3/ipa_dp.c +8 −2 Original line number Diff line number Diff line Loading @@ -212,6 +212,7 @@ static void ipa3_tx_switch_to_intr_mode(struct ipa3_sys_context *sys) if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) { atomic_set(&sys->curr_polling_state, 0); ipa3_dec_release_wakelock(); ret = gsi_config_channel_mode(sys->ep->gsi_chan_hdl, GSI_CHAN_MODE_CALLBACK); if (ret != GSI_STATUS_SUCCESS) { Loading Loading @@ -239,8 +240,8 @@ static void ipa3_tx_switch_to_intr_mode(struct ipa3_sys_context *sys) } atomic_set(&sys->curr_polling_state, 0); ipa3_handle_tx_core(sys, true, false); ipa3_dec_release_wakelock(); } return; fail: Loading Loading @@ -775,6 +776,7 @@ static void ipa3_sps_irq_tx_notify(struct sps_event_notify *notify) IPAERR("sps_set_config() failed %d\n", ret); break; } ipa3_inc_acquire_wakelock(); atomic_set(&sys->curr_polling_state, 1); queue_work(sys->wq, &sys->work); } Loading Loading @@ -852,6 +854,7 @@ static void ipa3_rx_switch_to_intr_mode(struct ipa3_sys_context *sys) if (ipa3_ctx->transport_prototype == IPA_TRANSPORT_TYPE_GSI) { atomic_set(&sys->curr_polling_state, 0); ipa3_dec_release_wakelock(); ret = gsi_config_channel_mode(sys->ep->gsi_chan_hdl, GSI_CHAN_MODE_CALLBACK); if (ret != GSI_STATUS_SUCCESS) { Loading Loading @@ -879,8 +882,8 @@ static void ipa3_rx_switch_to_intr_mode(struct ipa3_sys_context *sys) } atomic_set(&sys->curr_polling_state, 0); ipa3_handle_rx_core(sys, true, false); ipa3_dec_release_wakelock(); } return; fail: Loading Loading @@ -927,6 +930,7 @@ static void ipa3_sps_irq_rx_notify(struct sps_event_notify *notify) IPAERR("sps_set_config() failed %d\n", ret); break; } ipa3_inc_acquire_wakelock(); atomic_set(&sys->curr_polling_state, 1); queue_work(sys->wq, &sys->work); } Loading Loading @@ -3296,6 +3300,7 @@ static void ipa_gsi_irq_rx_notify_cb(struct gsi_chan_xfer_notify *notify) /* put the gsi channel into polling mode */ gsi_config_channel_mode(sys->ep->gsi_chan_hdl, GSI_CHAN_MODE_POLL); ipa3_inc_acquire_wakelock(); atomic_set(&sys->curr_polling_state, 1); queue_work(sys->wq, &sys->work); } Loading Loading @@ -3341,6 +3346,7 @@ static void ipa_dma_gsi_irq_rx_notify_cb(struct gsi_chan_xfer_notify *notify) /* put the gsi channel into polling mode */ gsi_config_channel_mode(sys->ep->gsi_chan_hdl, GSI_CHAN_MODE_POLL); ipa3_inc_acquire_wakelock(); atomic_set(&sys->curr_polling_state, 1); queue_work(sys->wq, &sys->work); } Loading