Loading drivers/platform/msm/ipa/ipa.c +31 −31 Original line number Diff line number Diff line Loading @@ -1586,6 +1586,7 @@ void ipa_disable_clks(void) if (msm_bus_scale_client_update_request(ipa_ctx->ipa_bus_hdl, 0)) WARN_ON(1); } /** * ipa_start_tag_process() - Send TAG packet and wait for it to come back * Loading @@ -1602,10 +1603,7 @@ static void ipa_start_tag_process(struct work_struct *work) int res; IPADBG("starting TAG process\n"); mutex_lock(&ipa_ctx->ipa_active_clients_lock); ipa_ctx->start_tag_process_again = false; mutex_unlock(&ipa_ctx->ipa_active_clients_lock); /* close aggregation frames on all pipes */ res = ipa_tag_aggr_force_close(-1); if (res) { Loading @@ -1613,20 +1611,20 @@ static void ipa_start_tag_process(struct work_struct *work) return; } mutex_lock(&ipa_ctx->ipa_active_clients_lock); ipa_ctx->ipa_active_clients--; if (ipa_ctx->ipa_active_clients == 0) { ipa_active_clients_lock(); ipa_ctx->ipa_active_clients.cnt--; if (ipa_ctx->ipa_active_clients.cnt == 0) { /* check if during tag process a client used IPA */ if (ipa_ctx->start_tag_process_again) { IPADBG("Starting TAG process again\n"); ipa_ctx->ipa_active_clients = 1; mutex_unlock(&ipa_ctx->ipa_active_clients_lock); ipa_ctx->ipa_active_clients.cnt = 1; ipa_active_clients_unlock(); queue_work(ipa_ctx->power_mgmt_wq, &ipa_tag_work); return; } ipa_disable_clks(); } mutex_unlock(&ipa_ctx->ipa_active_clients_lock); ipa_active_clients_unlock(); IPADBG("TAG process done\n"); return; Loading @@ -1641,12 +1639,12 @@ static void ipa_start_tag_process(struct work_struct *work) */ void ipa_inc_client_enable_clks(void) { mutex_lock(&ipa_ctx->ipa_active_clients_lock); ipa_ctx->ipa_active_clients++; IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients); if (ipa_ctx->ipa_active_clients == 1) ipa_active_clients_lock(); ipa_ctx->ipa_active_clients.cnt++; if (ipa_ctx->ipa_active_clients.cnt == 1) ipa_enable_clks(); mutex_unlock(&ipa_ctx->ipa_active_clients_lock); IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients.cnt); ipa_active_clients_unlock(); } /** Loading @@ -1661,17 +1659,18 @@ int ipa_inc_client_enable_clks_no_block(void) { int res = 0; if (mutex_trylock(&ipa_ctx->ipa_active_clients_lock) == 0) if (ipa_active_clients_trylock() == 0) return -EPERM; if (ipa_ctx->ipa_active_clients == 0) { if (ipa_ctx->ipa_active_clients.cnt == 0) { res = -EPERM; goto bail; } ipa_ctx->ipa_active_clients++; IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients); ipa_ctx->ipa_active_clients.cnt++; IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients.cnt); bail: mutex_unlock(&ipa_ctx->ipa_active_clients_lock); ipa_active_clients_unlock(); return res; } Loading @@ -1689,18 +1688,18 @@ bail: */ void ipa_dec_client_disable_clks(void) { mutex_lock(&ipa_ctx->ipa_active_clients_lock); ipa_active_clients_lock(); ipa_ctx->start_tag_process_again = true; ipa_ctx->ipa_active_clients--; IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients); if (ipa_ctx->ipa_active_clients == 0) { ipa_ctx->ipa_active_clients.cnt--; IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients.cnt); if (ipa_ctx->ipa_active_clients.cnt == 0) { /* when TAG process ends, active clients will be decreased */ ipa_ctx->ipa_active_clients = 1; mutex_unlock(&ipa_ctx->ipa_active_clients_lock); ipa_ctx->ipa_active_clients.cnt = 1; ipa_active_clients_unlock(); queue_work(ipa_ctx->power_mgmt_wq, &ipa_tag_work); return; } mutex_unlock(&ipa_ctx->ipa_active_clients_lock); ipa_active_clients_unlock(); } static int ipa_setup_bam_cfg(const struct ipa_plat_drv_res *res) Loading Loading @@ -1779,14 +1778,14 @@ int ipa_set_required_perf_profile(enum ipa_voltage_level floor_voltage, return 0; } mutex_lock(&ipa_ctx->ipa_active_clients_lock); ipa_active_clients_lock(); ipa_ctx->curr_ipa_clk_rate = clk_rate; IPADBG("setting clock rate to %u\n", ipa_ctx->curr_ipa_clk_rate); if (ipa_ctx->ipa_active_clients > 0) if (ipa_ctx->ipa_active_clients.cnt > 0) clk_set_rate(ipa_clk, ipa_ctx->curr_ipa_clk_rate); else IPADBG("clocks are gated, not setting rate\n"); mutex_unlock(&ipa_ctx->ipa_active_clients_lock); ipa_active_clients_unlock(); IPADBG("Done\n"); return 0; } Loading Loading @@ -2194,8 +2193,9 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p, idr_init(&ipa_ctx->ipa_idr); spin_lock_init(&ipa_ctx->idr_lock); mutex_init(&ipa_ctx->ipa_active_clients_lock); ipa_ctx->ipa_active_clients = 1; mutex_init(&ipa_ctx->ipa_active_clients.mutex); spin_lock_init(&ipa_ctx->ipa_active_clients.spinlock); ipa_ctx->ipa_active_clients.cnt = 1; /* wlan related member */ spin_lock_init(&ipa_ctx->wlan_spinlock); Loading drivers/platform/msm/ipa/ipa_debugfs.c +2 −2 Original line number Diff line number Diff line Loading @@ -729,7 +729,7 @@ static ssize_t ipa_read_stats(struct file *file, char __user *ubuf, ipa_ctx->stats.stat_compl, ipa_ctx->stats.aggr_close, ipa_ctx->stats.wan_aggr_close, ipa_ctx->ipa_active_clients, ipa_ctx->ipa_active_clients.cnt, connect); cnt += nbytes; Loading @@ -755,7 +755,7 @@ static ssize_t ipa_read_stats(struct file *file, char __user *ubuf, ipa_ctx->stats.rx_pkts, ipa_ctx->stats.rx_repl_repost, ipa_ctx->stats.rx_q_len, ipa_ctx->ipa_active_clients, ipa_ctx->ipa_active_clients.cnt, connect); cnt += nbytes; Loading drivers/platform/msm/ipa/ipa_i.h +11 −3 Original line number Diff line number Diff line Loading @@ -593,6 +593,12 @@ struct ipa_wlan_stats { u32 tx_pkts_dropped; }; struct ipa_active_clients { struct mutex mutex; spinlock_t spinlock; bool mutex_locked; int cnt; }; struct ipa_controller; Loading Loading @@ -644,6 +650,7 @@ struct ipa_controller; * @start_tag_process_again: indicates whether to start tag process again * @pipe_mem_pool: pipe memory pool * @dma_pool: special purpose DMA pool * @ipa_active_clients: structure for reference counting connected IPA clients * @ipa_hw_type: type of IPA HW type (e.g. IPA 1.0, IPA 1.1 etc') * @ipa_hw_mode: mode of IPA HW mode (e.g. Normal, Virtual or over PCIe) * @use_ipa_teth_bridge: use tethering bridge driver Loading Loading @@ -698,8 +705,7 @@ struct ipa_context { struct ipa_mem_buffer empty_rt_tbl_mem; struct gen_pool *pipe_mem_pool; struct dma_pool *dma_pool; struct mutex ipa_active_clients_lock; int ipa_active_clients; struct ipa_active_clients ipa_active_clients; struct workqueue_struct *power_mgmt_wq; bool start_tag_process_again; u32 clnt_hdl_cmd; Loading Loading @@ -948,6 +954,8 @@ int ipa_resume_resource(enum ipa_rm_resource_name name); bool ipa_should_pipe_be_suspended(enum ipa_client_type client); int ipa_tag_aggr_force_close(int pipe_num); void ipa_active_clients_lock(void); int ipa_active_clients_trylock(void); void ipa_active_clients_unlock(void); #endif /* _IPA_I_H_ */ drivers/platform/msm/ipa/ipa_utils.c +37 −5 Original line number Diff line number Diff line Loading @@ -230,6 +230,37 @@ static struct msm_bus_scale_pdata ipa_bus_client_pdata_v2_0 = { .name = "ipa", }; void ipa_active_clients_lock(void) { mutex_lock(&ipa_ctx->ipa_active_clients.mutex); spin_lock(&ipa_ctx->ipa_active_clients.spinlock); ipa_ctx->ipa_active_clients.mutex_locked = true; spin_unlock(&ipa_ctx->ipa_active_clients.spinlock); } int ipa_active_clients_trylock(void) { spin_lock(&ipa_ctx->ipa_active_clients.spinlock); if (ipa_ctx->ipa_active_clients.mutex_locked) { spin_unlock(&ipa_ctx->ipa_active_clients.spinlock); return 0; } return 1; } void ipa_active_clients_unlock(void) { if (ipa_ctx->ipa_active_clients.mutex_locked) { spin_lock(&ipa_ctx->ipa_active_clients.spinlock); ipa_ctx->ipa_active_clients.mutex_locked = false; spin_unlock(&ipa_ctx->ipa_active_clients.spinlock); mutex_unlock(&ipa_ctx->ipa_active_clients.mutex); return; } spin_unlock(&ipa_ctx->ipa_active_clients.spinlock); } /** * ipa_get_clients_from_rm_resource() - get IPA clients which are related to an * IPA_RM resource Loading Loading @@ -381,9 +412,9 @@ int ipa_suspend_resource_no_block(enum ipa_rm_resource_name resource) struct ipa_ep_cfg_ctrl suspend; int ipa_ep_idx; if (mutex_trylock(&ipa_ctx->ipa_active_clients_lock) == 0) if (ipa_active_clients_trylock() == 0) return -EPERM; if (ipa_ctx->ipa_active_clients == 1) { if (ipa_ctx->ipa_active_clients.cnt == 1) { res = -EPERM; goto bail; } Loading Loading @@ -414,11 +445,12 @@ int ipa_suspend_resource_no_block(enum ipa_rm_resource_name resource) } if (res == 0) { ipa_ctx->ipa_active_clients--; IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients); ipa_ctx->ipa_active_clients.cnt--; IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients.cnt); } bail: mutex_unlock(&ipa_ctx->ipa_active_clients_lock); ipa_active_clients_unlock(); return res; } Loading Loading
drivers/platform/msm/ipa/ipa.c +31 −31 Original line number Diff line number Diff line Loading @@ -1586,6 +1586,7 @@ void ipa_disable_clks(void) if (msm_bus_scale_client_update_request(ipa_ctx->ipa_bus_hdl, 0)) WARN_ON(1); } /** * ipa_start_tag_process() - Send TAG packet and wait for it to come back * Loading @@ -1602,10 +1603,7 @@ static void ipa_start_tag_process(struct work_struct *work) int res; IPADBG("starting TAG process\n"); mutex_lock(&ipa_ctx->ipa_active_clients_lock); ipa_ctx->start_tag_process_again = false; mutex_unlock(&ipa_ctx->ipa_active_clients_lock); /* close aggregation frames on all pipes */ res = ipa_tag_aggr_force_close(-1); if (res) { Loading @@ -1613,20 +1611,20 @@ static void ipa_start_tag_process(struct work_struct *work) return; } mutex_lock(&ipa_ctx->ipa_active_clients_lock); ipa_ctx->ipa_active_clients--; if (ipa_ctx->ipa_active_clients == 0) { ipa_active_clients_lock(); ipa_ctx->ipa_active_clients.cnt--; if (ipa_ctx->ipa_active_clients.cnt == 0) { /* check if during tag process a client used IPA */ if (ipa_ctx->start_tag_process_again) { IPADBG("Starting TAG process again\n"); ipa_ctx->ipa_active_clients = 1; mutex_unlock(&ipa_ctx->ipa_active_clients_lock); ipa_ctx->ipa_active_clients.cnt = 1; ipa_active_clients_unlock(); queue_work(ipa_ctx->power_mgmt_wq, &ipa_tag_work); return; } ipa_disable_clks(); } mutex_unlock(&ipa_ctx->ipa_active_clients_lock); ipa_active_clients_unlock(); IPADBG("TAG process done\n"); return; Loading @@ -1641,12 +1639,12 @@ static void ipa_start_tag_process(struct work_struct *work) */ void ipa_inc_client_enable_clks(void) { mutex_lock(&ipa_ctx->ipa_active_clients_lock); ipa_ctx->ipa_active_clients++; IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients); if (ipa_ctx->ipa_active_clients == 1) ipa_active_clients_lock(); ipa_ctx->ipa_active_clients.cnt++; if (ipa_ctx->ipa_active_clients.cnt == 1) ipa_enable_clks(); mutex_unlock(&ipa_ctx->ipa_active_clients_lock); IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients.cnt); ipa_active_clients_unlock(); } /** Loading @@ -1661,17 +1659,18 @@ int ipa_inc_client_enable_clks_no_block(void) { int res = 0; if (mutex_trylock(&ipa_ctx->ipa_active_clients_lock) == 0) if (ipa_active_clients_trylock() == 0) return -EPERM; if (ipa_ctx->ipa_active_clients == 0) { if (ipa_ctx->ipa_active_clients.cnt == 0) { res = -EPERM; goto bail; } ipa_ctx->ipa_active_clients++; IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients); ipa_ctx->ipa_active_clients.cnt++; IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients.cnt); bail: mutex_unlock(&ipa_ctx->ipa_active_clients_lock); ipa_active_clients_unlock(); return res; } Loading @@ -1689,18 +1688,18 @@ bail: */ void ipa_dec_client_disable_clks(void) { mutex_lock(&ipa_ctx->ipa_active_clients_lock); ipa_active_clients_lock(); ipa_ctx->start_tag_process_again = true; ipa_ctx->ipa_active_clients--; IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients); if (ipa_ctx->ipa_active_clients == 0) { ipa_ctx->ipa_active_clients.cnt--; IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients.cnt); if (ipa_ctx->ipa_active_clients.cnt == 0) { /* when TAG process ends, active clients will be decreased */ ipa_ctx->ipa_active_clients = 1; mutex_unlock(&ipa_ctx->ipa_active_clients_lock); ipa_ctx->ipa_active_clients.cnt = 1; ipa_active_clients_unlock(); queue_work(ipa_ctx->power_mgmt_wq, &ipa_tag_work); return; } mutex_unlock(&ipa_ctx->ipa_active_clients_lock); ipa_active_clients_unlock(); } static int ipa_setup_bam_cfg(const struct ipa_plat_drv_res *res) Loading Loading @@ -1779,14 +1778,14 @@ int ipa_set_required_perf_profile(enum ipa_voltage_level floor_voltage, return 0; } mutex_lock(&ipa_ctx->ipa_active_clients_lock); ipa_active_clients_lock(); ipa_ctx->curr_ipa_clk_rate = clk_rate; IPADBG("setting clock rate to %u\n", ipa_ctx->curr_ipa_clk_rate); if (ipa_ctx->ipa_active_clients > 0) if (ipa_ctx->ipa_active_clients.cnt > 0) clk_set_rate(ipa_clk, ipa_ctx->curr_ipa_clk_rate); else IPADBG("clocks are gated, not setting rate\n"); mutex_unlock(&ipa_ctx->ipa_active_clients_lock); ipa_active_clients_unlock(); IPADBG("Done\n"); return 0; } Loading Loading @@ -2194,8 +2193,9 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p, idr_init(&ipa_ctx->ipa_idr); spin_lock_init(&ipa_ctx->idr_lock); mutex_init(&ipa_ctx->ipa_active_clients_lock); ipa_ctx->ipa_active_clients = 1; mutex_init(&ipa_ctx->ipa_active_clients.mutex); spin_lock_init(&ipa_ctx->ipa_active_clients.spinlock); ipa_ctx->ipa_active_clients.cnt = 1; /* wlan related member */ spin_lock_init(&ipa_ctx->wlan_spinlock); Loading
drivers/platform/msm/ipa/ipa_debugfs.c +2 −2 Original line number Diff line number Diff line Loading @@ -729,7 +729,7 @@ static ssize_t ipa_read_stats(struct file *file, char __user *ubuf, ipa_ctx->stats.stat_compl, ipa_ctx->stats.aggr_close, ipa_ctx->stats.wan_aggr_close, ipa_ctx->ipa_active_clients, ipa_ctx->ipa_active_clients.cnt, connect); cnt += nbytes; Loading @@ -755,7 +755,7 @@ static ssize_t ipa_read_stats(struct file *file, char __user *ubuf, ipa_ctx->stats.rx_pkts, ipa_ctx->stats.rx_repl_repost, ipa_ctx->stats.rx_q_len, ipa_ctx->ipa_active_clients, ipa_ctx->ipa_active_clients.cnt, connect); cnt += nbytes; Loading
drivers/platform/msm/ipa/ipa_i.h +11 −3 Original line number Diff line number Diff line Loading @@ -593,6 +593,12 @@ struct ipa_wlan_stats { u32 tx_pkts_dropped; }; struct ipa_active_clients { struct mutex mutex; spinlock_t spinlock; bool mutex_locked; int cnt; }; struct ipa_controller; Loading Loading @@ -644,6 +650,7 @@ struct ipa_controller; * @start_tag_process_again: indicates whether to start tag process again * @pipe_mem_pool: pipe memory pool * @dma_pool: special purpose DMA pool * @ipa_active_clients: structure for reference counting connected IPA clients * @ipa_hw_type: type of IPA HW type (e.g. IPA 1.0, IPA 1.1 etc') * @ipa_hw_mode: mode of IPA HW mode (e.g. Normal, Virtual or over PCIe) * @use_ipa_teth_bridge: use tethering bridge driver Loading Loading @@ -698,8 +705,7 @@ struct ipa_context { struct ipa_mem_buffer empty_rt_tbl_mem; struct gen_pool *pipe_mem_pool; struct dma_pool *dma_pool; struct mutex ipa_active_clients_lock; int ipa_active_clients; struct ipa_active_clients ipa_active_clients; struct workqueue_struct *power_mgmt_wq; bool start_tag_process_again; u32 clnt_hdl_cmd; Loading Loading @@ -948,6 +954,8 @@ int ipa_resume_resource(enum ipa_rm_resource_name name); bool ipa_should_pipe_be_suspended(enum ipa_client_type client); int ipa_tag_aggr_force_close(int pipe_num); void ipa_active_clients_lock(void); int ipa_active_clients_trylock(void); void ipa_active_clients_unlock(void); #endif /* _IPA_I_H_ */
drivers/platform/msm/ipa/ipa_utils.c +37 −5 Original line number Diff line number Diff line Loading @@ -230,6 +230,37 @@ static struct msm_bus_scale_pdata ipa_bus_client_pdata_v2_0 = { .name = "ipa", }; void ipa_active_clients_lock(void) { mutex_lock(&ipa_ctx->ipa_active_clients.mutex); spin_lock(&ipa_ctx->ipa_active_clients.spinlock); ipa_ctx->ipa_active_clients.mutex_locked = true; spin_unlock(&ipa_ctx->ipa_active_clients.spinlock); } int ipa_active_clients_trylock(void) { spin_lock(&ipa_ctx->ipa_active_clients.spinlock); if (ipa_ctx->ipa_active_clients.mutex_locked) { spin_unlock(&ipa_ctx->ipa_active_clients.spinlock); return 0; } return 1; } void ipa_active_clients_unlock(void) { if (ipa_ctx->ipa_active_clients.mutex_locked) { spin_lock(&ipa_ctx->ipa_active_clients.spinlock); ipa_ctx->ipa_active_clients.mutex_locked = false; spin_unlock(&ipa_ctx->ipa_active_clients.spinlock); mutex_unlock(&ipa_ctx->ipa_active_clients.mutex); return; } spin_unlock(&ipa_ctx->ipa_active_clients.spinlock); } /** * ipa_get_clients_from_rm_resource() - get IPA clients which are related to an * IPA_RM resource Loading Loading @@ -381,9 +412,9 @@ int ipa_suspend_resource_no_block(enum ipa_rm_resource_name resource) struct ipa_ep_cfg_ctrl suspend; int ipa_ep_idx; if (mutex_trylock(&ipa_ctx->ipa_active_clients_lock) == 0) if (ipa_active_clients_trylock() == 0) return -EPERM; if (ipa_ctx->ipa_active_clients == 1) { if (ipa_ctx->ipa_active_clients.cnt == 1) { res = -EPERM; goto bail; } Loading Loading @@ -414,11 +445,12 @@ int ipa_suspend_resource_no_block(enum ipa_rm_resource_name resource) } if (res == 0) { ipa_ctx->ipa_active_clients--; IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients); ipa_ctx->ipa_active_clients.cnt--; IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients.cnt); } bail: mutex_unlock(&ipa_ctx->ipa_active_clients_lock); ipa_active_clients_unlock(); return res; } Loading