Loading drivers/platform/msm/ipa/ipa_v2/ipa.c +227 −16 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <linux/netdevice.h> #include <linux/delay.h> #include <linux/qcom_iommu.h> #include <linux/time.h> #include "ipa_i.h" #include "ipa_rm_i.h" Loading Loading @@ -194,6 +195,160 @@ static bool smmu_present; static bool arm_smmu; static bool smmu_disable_htw; const char *ipa2_clients_strings[IPA_CLIENT_MAX] = { __stringify(IPA_CLIENT_HSIC1_PROD), __stringify(IPA_CLIENT_WLAN1_PROD), __stringify(IPA_CLIENT_USB2_PROD), __stringify(IPA_CLIENT_HSIC3_PROD), __stringify(IPA_CLIENT_HSIC2_PROD), __stringify(IPA_CLIENT_USB3_PROD), __stringify(IPA_CLIENT_HSIC4_PROD), __stringify(IPA_CLIENT_USB4_PROD), __stringify(IPA_CLIENT_HSIC5_PROD), __stringify(IPA_CLIENT_USB_PROD), __stringify(IPA_CLIENT_A5_WLAN_AMPDU_PROD), __stringify(IPA_CLIENT_A2_EMBEDDED_PROD), __stringify(IPA_CLIENT_A2_TETHERED_PROD), __stringify(IPA_CLIENT_APPS_LAN_WAN_PROD), __stringify(IPA_CLIENT_APPS_CMD_PROD), __stringify(IPA_CLIENT_ODU_PROD), __stringify(IPA_CLIENT_MHI_PROD), __stringify(IPA_CLIENT_Q6_LAN_PROD), __stringify(IPA_CLIENT_Q6_WAN_PROD), __stringify(IPA_CLIENT_Q6_CMD_PROD), __stringify(IPA_CLIENT_MEMCPY_DMA_SYNC_PROD), __stringify(IPA_CLIENT_MEMCPY_DMA_ASYNC_PROD), __stringify(IPA_CLIENT_Q6_DECOMP_PROD), __stringify(IPA_CLIENT_Q6_DECOMP2_PROD), __stringify(IPA_CLIENT_UC_USB_PROD), /* Below PROD client type is only for test purpose */ __stringify(IPA_CLIENT_TEST_PROD), __stringify(IPA_CLIENT_TEST1_PROD), __stringify(IPA_CLIENT_TEST2_PROD), __stringify(IPA_CLIENT_TEST3_PROD), __stringify(IPA_CLIENT_TEST4_PROD), __stringify(IPA_CLIENT_HSIC1_CONS), __stringify(IPA_CLIENT_WLAN1_CONS), __stringify(IPA_CLIENT_HSIC2_CONS), __stringify(IPA_CLIENT_USB2_CONS), __stringify(IPA_CLIENT_WLAN2_CONS), __stringify(IPA_CLIENT_HSIC3_CONS), __stringify(IPA_CLIENT_USB3_CONS), __stringify(IPA_CLIENT_WLAN3_CONS), __stringify(IPA_CLIENT_HSIC4_CONS), __stringify(IPA_CLIENT_USB4_CONS), __stringify(IPA_CLIENT_WLAN4_CONS), __stringify(IPA_CLIENT_HSIC5_CONS), __stringify(IPA_CLIENT_USB_CONS), __stringify(IPA_CLIENT_USB_DPL_CONS), __stringify(IPA_CLIENT_A2_EMBEDDED_CONS), __stringify(IPA_CLIENT_A2_TETHERED_CONS), __stringify(IPA_CLIENT_A5_LAN_WAN_CONS), __stringify(IPA_CLIENT_APPS_LAN_CONS), __stringify(IPA_CLIENT_APPS_WAN_CONS), __stringify(IPA_CLIENT_ODU_EMB_CONS), __stringify(IPA_CLIENT_ODU_TETH_CONS), __stringify(IPA_CLIENT_MHI_CONS), __stringify(IPA_CLIENT_Q6_LAN_CONS), __stringify(IPA_CLIENT_Q6_WAN_CONS), __stringify(IPA_CLIENT_Q6_DUN_CONS), __stringify(IPA_CLIENT_MEMCPY_DMA_SYNC_CONS), __stringify(IPA_CLIENT_MEMCPY_DMA_ASYNC_CONS), __stringify(IPA_CLIENT_Q6_DECOMP_CONS), __stringify(IPA_CLIENT_Q6_DECOMP2_CONS), __stringify(IPA_CLIENT_Q6_LTE_WIFI_AGGR_CONS), /* Below CONS client type is only for test purpose */ __stringify(IPA_CLIENT_TEST_CONS), __stringify(IPA_CLIENT_TEST1_CONS), __stringify(IPA_CLIENT_TEST2_CONS), __stringify(IPA_CLIENT_TEST3_CONS), __stringify(IPA_CLIENT_TEST4_CONS), }; static int ipa2_active_clients_log_insert(const char *string) { if (!ipa_ctx->ipa2_active_clients_logging.log_rdy) return -EPERM; strlcpy(ipa_ctx->ipa2_active_clients_logging.log_buffer [ipa_ctx->ipa2_active_clients_logging.log_head], string, (size_t)IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN); ipa_ctx->ipa2_active_clients_logging.log_head = (ipa_ctx->ipa2_active_clients_logging.log_head + 1) % IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES; if (ipa_ctx->ipa2_active_clients_logging.log_tail == ipa_ctx->ipa2_active_clients_logging.log_head) { ipa_ctx->ipa2_active_clients_logging.log_tail = (ipa_ctx->ipa2_active_clients_logging.log_tail + 1) % IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES; } return 0; } static int ipa2_active_clients_log_init(void) { int i; ipa_ctx->ipa2_active_clients_logging.log_buffer[0] = kzalloc( IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES * sizeof(char[IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN]), GFP_KERNEL); if (ipa_ctx->ipa2_active_clients_logging.log_buffer == NULL) { IPAERR("Active Clients Logging memory allocation failed"); goto bail; } for (i = 0; i < IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES; i++) { ipa_ctx->ipa2_active_clients_logging.log_buffer[i] = ipa_ctx->ipa2_active_clients_logging.log_buffer[0] + (IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN * i); } ipa_ctx->ipa2_active_clients_logging.log_head = 0; ipa_ctx->ipa2_active_clients_logging.log_tail = IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES - 1; ipa_ctx->ipa2_active_clients_logging.log_rdy = 1; return 0; bail: return -ENOMEM; } void ipa2_active_clients_log_clear(void) { ipa_active_clients_lock(); ipa_ctx->ipa2_active_clients_logging.log_head = 0; ipa_ctx->ipa2_active_clients_logging.log_tail = IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES - 1; ipa_active_clients_unlock(); } static void ipa2_active_clients_log_destroy(void) { ipa_ctx->ipa2_active_clients_logging.log_rdy = 0; kfree(ipa_ctx->ipa2_active_clients_logging.log_buffer[0]); ipa_ctx->ipa2_active_clients_logging.log_head = 0; ipa_ctx->ipa2_active_clients_logging.log_tail = IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES - 1; } void ipa2_active_clients_log_print_buffer(void) { int i; ipa_active_clients_lock(); for (i = (ipa_ctx->ipa2_active_clients_logging.log_tail + 1) % IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES; i != ipa_ctx->ipa2_active_clients_logging.log_head; i = (i + 1) % IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES) { pr_err("%s\n", ipa_ctx->ipa2_active_clients_logging .log_buffer[i]); } ipa_active_clients_unlock(); } enum ipa_smmu_cb_type { IPA_SMMU_CB_AP, IPA_SMMU_CB_WLAN, Loading Loading @@ -387,7 +542,7 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (_IOC_NR(cmd) >= IPA_IOCTL_MAX) return -ENOTTY; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); switch (cmd) { case IPA_IOC_ALLOC_NAT_MEM: Loading Loading @@ -1090,12 +1245,12 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; default: /* redundant, as cmd was checked against MAXNR */ ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return -ENOTTY; } kfree(param); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return retval; } Loading Loading @@ -1282,7 +1437,7 @@ int ipa_init_q6_smem(void) { int rc; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); if (ipa_ctx->ipa_hw_type == IPA_HW_v2_0) rc = ipa_init_smem_region(IPA_MEM_PART(modem_size) - Loading @@ -1294,7 +1449,7 @@ int ipa_init_q6_smem(void) if (rc) { IPAERR("failed to initialize Modem RAM memory\n"); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return rc; } Loading @@ -1302,7 +1457,7 @@ int ipa_init_q6_smem(void) IPA_MEM_PART(modem_hdr_ofst)); if (rc) { IPAERR("failed to initialize Modem HDRs RAM memory\n"); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return rc; } Loading @@ -1310,7 +1465,7 @@ int ipa_init_q6_smem(void) IPA_MEM_PART(modem_hdr_proc_ctx_ofst)); if (rc) { IPAERR("failed to initialize Modem proc ctx RAM memory\n"); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return rc; } Loading @@ -1318,11 +1473,11 @@ int ipa_init_q6_smem(void) IPA_MEM_PART(modem_comp_decomp_ofst)); if (rc) { IPAERR("failed to initialize Modem Comp/Decomp RAM memory\n"); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return rc; } ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return rc; } Loading Loading @@ -1714,7 +1869,7 @@ int ipa_q6_pre_shutdown_cleanup(void) if (ipa_ctx->uc_ctx.uc_zip_error) BUG(); ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SPECIAL("Q6"); /* * pipe delay and holb discard for ZIP pipes are handled * in post shutdown callback. Loading Loading @@ -2767,7 +2922,7 @@ static void ipa_start_tag_process(struct work_struct *work) if (res) IPAERR("ipa_tag_aggr_force_close failed %d\n", res); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); IPADBG("TAG process done\n"); } Loading @@ -2776,12 +2931,28 @@ static void ipa_start_tag_process(struct work_struct *work) * ipa_inc_client_enable_clks() - Increase active clients counter, and * enable ipa clocks if necessary * * Please do not use this API, use the wrapper macros instead (ipa_i.h) * IPA2_ACTIVE_CLIENTS_INC_XXXX(); * * Return codes: * None */ void ipa_inc_client_enable_clks(void) void ipa2_inc_client_enable_clks(struct ipa2_active_client_logging_info *id) { char temp_str[IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN]; unsigned long long t; unsigned long nanosec_rem; ipa_active_clients_lock(); if (id->type != SIMPLE) { t = cpu_clock(smp_processor_id()); nanosec_rem = do_div(t, 1000000000) / 1000; snprintf(temp_str, IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN, "[%5lu.%06lu] ^ %s, %s: %d", (unsigned long)t, nanosec_rem, id->id_string, id->file, id->line); ipa2_active_clients_log_insert(temp_str); } ipa_ctx->ipa_active_clients.cnt++; if (ipa_ctx->ipa_active_clients.cnt == 1) ipa_enable_clks(); Loading @@ -2794,13 +2965,20 @@ void ipa_inc_client_enable_clks(void) * clients if no asynchronous actions should be done. Asynchronous actions are * locking a mutex and waking up IPA HW. * * Please do not use this API, use the wrapper macros instead (ipa_i.h) * * * Return codes: 0 for success * -EPERM if an asynchronous action should have been done */ int ipa_inc_client_enable_clks_no_block(void) int ipa2_inc_client_enable_clks_no_block(struct ipa2_active_client_logging_info *id) { int res = 0; unsigned long flags; char temp_str[IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN]; unsigned long long t; unsigned long nanosec_rem; if (ipa_active_clients_trylock(&flags) == 0) return -EPERM; Loading @@ -2810,6 +2988,16 @@ int ipa_inc_client_enable_clks_no_block(void) goto bail; } if (id->type != SIMPLE) { t = cpu_clock(smp_processor_id()); nanosec_rem = do_div(t, 1000000000) / 1000; snprintf(temp_str, IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN, "[%5lu.%06lu] ^ %s, %s: %d", (unsigned long)t, nanosec_rem, id->id_string, id->file, id->line); ipa2_active_clients_log_insert(temp_str); } ipa_ctx->ipa_active_clients.cnt++; IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients.cnt); bail: Loading @@ -2826,12 +3014,28 @@ bail: * start_tag_process_again flag is set during this function to signal TAG * process to start again as there was another client that may send data to ipa * * Please do not use this API, use the wrapper macros instead (ipa_i.h) * IPA2_ACTIVE_CLIENTS_DEC_XXXX(); * * Return codes: * None */ void ipa_dec_client_disable_clks(void) void ipa2_dec_client_disable_clks(struct ipa2_active_client_logging_info *id) { char temp_str[IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN]; unsigned long long t; unsigned long nanosec_rem; ipa_active_clients_lock(); if (id->type != SIMPLE) { t = cpu_clock(smp_processor_id()); nanosec_rem = do_div(t, 1000000000) / 1000; snprintf(temp_str, IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN, "[%5lu.%06lu] v %s, %s: %d", (unsigned long)t, nanosec_rem, id->id_string, id->file, id->line); ipa2_active_clients_log_insert(temp_str); } 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) { Loading Loading @@ -3112,7 +3316,8 @@ void ipa_suspend_handler(enum ipa_irq_type interrupt, if (!atomic_read( &ipa_ctx->sps_pm.dec_clients) ) { ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP( ipa_ctx->ep[i].client); IPADBG("Pipes un-suspended.\n"); IPADBG("Enter poll mode.\n"); atomic_set( Loading Loading @@ -3188,7 +3393,7 @@ static void ipa_sps_release_resource(struct work_struct *work) ipa_sps_process_irq_schedule_rel(); } else { atomic_set(&ipa_ctx->sps_pm.dec_clients, 0); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SPECIAL("SPS_RESOURCE"); } } atomic_set(&ipa_ctx->sps_pm.eot_activity, 0); Loading Loading @@ -3293,6 +3498,7 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p, ipa_ctx->aggregation_type = IPA_MBIM_16; ipa_ctx->aggregation_byte_limit = 1; ipa_ctx->aggregation_time_limit = 0; ipa_ctx->ipa2_active_clients_logging.log_rdy = false; ipa_ctx->ctrl = kzalloc(sizeof(*ipa_ctx->ctrl), GFP_KERNEL); if (!ipa_ctx->ctrl) { Loading Loading @@ -3332,6 +3538,9 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p, IPADBG("Skipping bus scaling registration on Virtual plat\n"); } if (ipa2_active_clients_log_init()) goto fail_init_active_client; /* get IPA clocks */ result = ipa_get_clks(master_dev); if (result) Loading Loading @@ -3762,6 +3971,8 @@ fail_init_hw: fail_remap: ipa_disable_clks(); fail_clk: ipa2_active_clients_log_destroy(); fail_init_active_client: msm_bus_scale_unregister_client(ipa_ctx->ipa_bus_hdl); fail_bus_reg: if (bus_scale_table) { Loading drivers/platform/msm/ipa/ipa_v2/ipa_client.c +11 −10 Original line number Diff line number Diff line Loading @@ -289,7 +289,8 @@ int ipa2_connect(const struct ipa_connect_params *in, } memset(&ipa_ctx->ep[ipa_ep_idx], 0, sizeof(struct ipa_ep_context)); ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP(in->client); ep->skip_ep_cfg = in->skip_ep_cfg; ep->valid = 1; Loading Loading @@ -430,7 +431,7 @@ int ipa2_connect(const struct ipa_connect_params *in, ipa_install_dflt_flt_rules(ipa_ep_idx); if (!ep->keep_ipa_awake) ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(in->client); IPADBG("client %d (ep: %d) connected\n", in->client, ipa_ep_idx); Loading Loading @@ -484,7 +485,7 @@ desc_mem_alloc_fail: sps_free_endpoint(ep->ep_hdl); ipa_cfg_ep_fail: memset(&ipa_ctx->ep[ipa_ep_idx], 0, sizeof(struct ipa_ep_context)); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(in->client); fail: return result; } Loading Loading @@ -553,7 +554,8 @@ int ipa2_disconnect(u32 clnt_hdl) ep = &ipa_ctx->ep[clnt_hdl]; if (!ep->keep_ipa_awake) ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP(ipa2_get_client_mapping(clnt_hdl)); /* Set Disconnect in Progress flag. */ spin_lock(&ipa_ctx->disconnect_lock); Loading Loading @@ -660,7 +662,7 @@ int ipa2_disconnect(u32 clnt_hdl) memset(&ipa_ctx->ep[clnt_hdl], 0, sizeof(struct ipa_ep_context)); spin_unlock(&ipa_ctx->disconnect_lock); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(ipa2_get_client_mapping(clnt_hdl)); IPADBG("client (ep: %d) disconnected\n", clnt_hdl); Loading Loading @@ -691,7 +693,7 @@ int ipa2_reset_endpoint(u32 clnt_hdl) } ep = &ipa_ctx->ep[clnt_hdl]; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP(ipa2_get_client_mapping(clnt_hdl)); res = sps_disconnect(ep->ep_hdl); if (res) { IPAERR("sps_disconnect() failed, res=%d.\n", res); Loading @@ -706,7 +708,7 @@ int ipa2_reset_endpoint(u32 clnt_hdl) } bail: ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(ipa2_get_client_mapping(clnt_hdl)); return res; } Loading Loading @@ -758,8 +760,7 @@ int ipa2_clear_endpoint_delay(u32 clnt_hdl) ep->qmi_request_sent = true; } ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP(ipa2_get_client_mapping(clnt_hdl)); /* Set disconnect in progress flag so further flow control events are * not honored. */ Loading @@ -772,7 +773,7 @@ int ipa2_clear_endpoint_delay(u32 clnt_hdl) ep_ctrl.ipa_ep_suspend = false; ipa2_cfg_ep_ctrl(clnt_hdl, &ep_ctrl); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(ipa2_get_client_mapping(clnt_hdl)); IPADBG("client (ep: %d) removed ep delay\n", clnt_hdl); Loading drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c +53 −11 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ static struct dentry *dfile_msg; static struct dentry *dfile_ip4_nat; static struct dentry *dfile_rm_stats; static struct dentry *dfile_status_stats; static struct dentry *dfile_active_clients; static char dbg_buff[IPA_MAX_MSG_LEN]; static s8 ep_reg_idx; Loading Loading @@ -153,9 +154,9 @@ static ssize_t ipa_read_gen_reg(struct file *file, char __user *ubuf, { int nbytes; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); nbytes = ipa_ctx->ctrl->ipa_read_gen_reg(dbg_buff, IPA_MAX_MSG_LEN); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes); } Loading Loading @@ -323,7 +324,7 @@ static ssize_t ipa_read_ep_reg(struct file *file, char __user *ubuf, end_idx = start_idx + 1; } pos = *ppos; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); for (i = start_idx; i < end_idx; i++) { nbytes = ipa_ctx->ctrl->ipa_read_ep_reg(dbg_buff, Loading @@ -333,7 +334,7 @@ static ssize_t ipa_read_ep_reg(struct file *file, char __user *ubuf, ret = simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes); if (ret < 0) { ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return ret; } Loading @@ -341,7 +342,7 @@ static ssize_t ipa_read_ep_reg(struct file *file, char __user *ubuf, ubuf += nbytes; count -= nbytes; } ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); *ppos = pos + size; return size; Loading @@ -365,9 +366,9 @@ static ssize_t ipa_write_keep_awake(struct file *file, const char __user *buf, return -EFAULT; if (option == 1) ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); else if (option == 0) ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); else return -EFAULT; Loading Loading @@ -1225,9 +1226,9 @@ static ssize_t ipa_write_dbg_cnt(struct file *file, const char __user *buf, if (kstrtou32(dbg_buff, 0, &option)) return -EFAULT; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); ipa_ctx->ctrl->ipa_write_dbg_cnt(option); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return count; } Loading Loading @@ -1259,9 +1260,9 @@ static ssize_t ipa_read_dbg_cnt(struct file *file, char __user *ubuf, { int nbytes; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); nbytes = ipa_ctx->ctrl->ipa_read_dbg_cnt(dbg_buff, IPA_MAX_MSG_LEN); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes); } Loading Loading @@ -1548,6 +1549,35 @@ static ssize_t ipa_status_stats_read(struct file *file, char __user *ubuf, return 0; } static ssize_t ipa2_print_active_clients_log(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { ipa2_active_clients_log_print_buffer(); return 0; } static ssize_t ipa2_clear_active_clients_log(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) { unsigned long missing; s8 option = 0; if (sizeof(dbg_buff) < count + 1) return -EFAULT; missing = copy_from_user(dbg_buff, ubuf, count); if (missing) return -EFAULT; dbg_buff[count] = '\0'; if (kstrtos8(dbg_buff, 0, &option)) return -EFAULT; ipa2_active_clients_log_clear(); return count; } const struct file_operations ipa_gen_reg_ops = { .read = ipa_read_gen_reg, Loading Loading @@ -1618,6 +1648,11 @@ const struct file_operations ipa_status_stats_ops = { .read = ipa_status_stats_read, }; const struct file_operations ipa2_active_clients = { .read = ipa2_print_active_clients_log, .write = ipa2_clear_active_clients_log, }; void ipa_debugfs_init(void) { const mode_t read_only_mode = S_IRUSR | S_IRGRP | S_IROTH; Loading Loading @@ -1647,6 +1682,13 @@ void ipa_debugfs_init(void) goto fail; } dfile_ep_reg = debugfs_create_file("active_clients", read_write_mode, dent, 0, &ipa2_active_clients); if (!dfile_ep_reg || IS_ERR(dfile_active_clients)) { IPAERR("fail to create file for debug_fs ep_reg\n"); goto fail; } dfile_ep_reg = debugfs_create_file("ep_reg", read_write_mode, dent, 0, &ipa_ep_reg_ops); if (!dfile_ep_reg || IS_ERR(dfile_ep_reg)) { Loading drivers/platform/msm/ipa/ipa_v2/ipa_dma.c +2 −2 Original line number Diff line number Diff line Loading @@ -274,7 +274,7 @@ int ipa2_dma_enable(void) mutex_unlock(&ipa_dma_ctx->enable_lock); return -EPERM; } ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SPECIAL("DMA"); ipa_dma_ctx->is_enabled = true; mutex_unlock(&ipa_dma_ctx->enable_lock); Loading Loading @@ -337,7 +337,7 @@ int ipa2_dma_disable(void) } ipa_dma_ctx->is_enabled = false; spin_unlock_irqrestore(&ipa_dma_ctx->pending_lock, flags); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SPECIAL("DMA"); mutex_unlock(&ipa_dma_ctx->enable_lock); IPADMA_FUNC_EXIT(); return 0; Loading drivers/platform/msm/ipa/ipa_v2/ipa_dp.c +20 −20 Original line number Diff line number Diff line Loading @@ -255,7 +255,7 @@ static void ipa_handle_tx(struct ipa_sys_context *sys) int inactive_cycles = 0; int cnt; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); do { cnt = ipa_handle_tx_core(sys, true, true); if (cnt == 0) { Loading @@ -268,7 +268,7 @@ static void ipa_handle_tx(struct ipa_sys_context *sys) } while (inactive_cycles <= POLLING_INACTIVITY_TX); ipa_tx_switch_to_intr_mode(sys); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); } static void ipa_wq_handle_tx(struct work_struct *work) Loading Loading @@ -654,7 +654,7 @@ int ipa_send_cmd(u16 num_desc, struct ipa_desc *descr) } sys = ipa_ctx->ep[ep_idx].sys; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); if (num_desc == 1) { init_completion(&descr->xfer_done); Loading Loading @@ -688,7 +688,7 @@ int ipa_send_cmd(u16 num_desc, struct ipa_desc *descr) } bail: ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return result; } Loading Loading @@ -994,7 +994,7 @@ static void ipa_handle_rx(struct ipa_sys_context *sys) int inactive_cycles = 0; int cnt; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); do { cnt = ipa_handle_rx_core(sys, true, true); if (cnt == 0) { Loading @@ -1018,7 +1018,7 @@ static void ipa_handle_rx(struct ipa_sys_context *sys) trace_poll_to_intr(sys->ep->client); ipa_rx_switch_to_intr_mode(sys); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); } static void switch_to_intr_rx_work_func(struct work_struct *work) Loading Loading @@ -1110,7 +1110,7 @@ int ipa2_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) ep = &ipa_ctx->ep[ipa_ep_idx]; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP(sys_in->client); if (ep->valid == 1) { if (sys_in->client != IPA_CLIENT_APPS_LAN_WAN_PROD) { Loading @@ -1135,7 +1135,7 @@ int ipa2_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) ep->priv = sys_in->priv; *clnt_hdl = ipa_ep_idx; if (!ep->keep_ipa_awake) ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(sys_in->client); return 0; } Loading Loading @@ -1349,7 +1349,7 @@ int ipa2_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) } if (!ep->keep_ipa_awake) ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(sys_in->client); IPADBG("client %d (ep: %d) connected sys=%p\n", sys_in->client, ipa_ep_idx, ep->sys); Loading @@ -1372,7 +1372,7 @@ fail_wq: kfree(ep->sys); memset(&ipa_ctx->ep[ipa_ep_idx], 0, sizeof(struct ipa_ep_context)); fail_and_disable_clocks: ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(sys_in->client); fail_gen: return result; } Loading Loading @@ -1402,7 +1402,7 @@ int ipa2_teardown_sys_pipe(u32 clnt_hdl) ep = &ipa_ctx->ep[clnt_hdl]; if (!ep->keep_ipa_awake) ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP(ipa2_get_client_mapping(clnt_hdl)); ipa_disable_data_path(clnt_hdl); ep->valid = 0; Loading Loading @@ -1446,7 +1446,7 @@ int ipa2_teardown_sys_pipe(u32 clnt_hdl) if (!atomic_read(&ipa_ctx->wc_memb.active_clnt_cnt)) ipa_cleanup_wlan_rx_common_cache(); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(ipa2_get_client_mapping(clnt_hdl)); IPADBG("client (ep: %d) disconnected\n", clnt_hdl); Loading Loading @@ -2055,9 +2055,9 @@ static void replenish_rx_work_func(struct work_struct *work) dwork = container_of(work, struct delayed_work, work); sys = container_of(dwork, struct ipa_sys_context, replenish_rx_work); ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); sys->repl_hdlr(sys); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); } /** Loading Loading @@ -3273,7 +3273,7 @@ int ipa2_sys_setup(struct ipa_sys_connect_params *sys_in, ep = &ipa_ctx->ep[ipa_ep_idx]; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP(sys_in->client); if (ep->valid == 1) { if (sys_in->client != IPA_CLIENT_APPS_LAN_WAN_PROD) { Loading @@ -3300,7 +3300,7 @@ int ipa2_sys_setup(struct ipa_sys_connect_params *sys_in, ep->priv = sys_in->priv; *clnt_hdl = ipa_ep_idx; if (!ep->keep_ipa_awake) ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(sys_in->client); return 0; } Loading Loading @@ -3341,7 +3341,7 @@ int ipa2_sys_setup(struct ipa_sys_connect_params *sys_in, *ipa_bam_hdl = ipa_ctx->bam_handle; if (!ep->keep_ipa_awake) ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(sys_in->client); ipa_ctx->skip_ep_cfg_shadow[ipa_ep_idx] = ep->skip_ep_cfg; IPADBG("client %d (ep: %d) connected sys=%p\n", sys_in->client, Loading @@ -3351,7 +3351,7 @@ int ipa2_sys_setup(struct ipa_sys_connect_params *sys_in, fail_gen2: fail_and_disable_clocks: ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(sys_in->client); fail_gen: return result; } Loading @@ -3369,12 +3369,12 @@ int ipa2_sys_teardown(u32 clnt_hdl) ep = &ipa_ctx->ep[clnt_hdl]; if (!ep->keep_ipa_awake) ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP(ipa2_get_client_mapping(clnt_hdl)); ipa_disable_data_path(clnt_hdl); ep->valid = 0; ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(ipa2_get_client_mapping(clnt_hdl)); IPADBG("client (ep: %d) disconnected\n", clnt_hdl); Loading Loading
drivers/platform/msm/ipa/ipa_v2/ipa.c +227 −16 Original line number Diff line number Diff line Loading @@ -31,6 +31,7 @@ #include <linux/netdevice.h> #include <linux/delay.h> #include <linux/qcom_iommu.h> #include <linux/time.h> #include "ipa_i.h" #include "ipa_rm_i.h" Loading Loading @@ -194,6 +195,160 @@ static bool smmu_present; static bool arm_smmu; static bool smmu_disable_htw; const char *ipa2_clients_strings[IPA_CLIENT_MAX] = { __stringify(IPA_CLIENT_HSIC1_PROD), __stringify(IPA_CLIENT_WLAN1_PROD), __stringify(IPA_CLIENT_USB2_PROD), __stringify(IPA_CLIENT_HSIC3_PROD), __stringify(IPA_CLIENT_HSIC2_PROD), __stringify(IPA_CLIENT_USB3_PROD), __stringify(IPA_CLIENT_HSIC4_PROD), __stringify(IPA_CLIENT_USB4_PROD), __stringify(IPA_CLIENT_HSIC5_PROD), __stringify(IPA_CLIENT_USB_PROD), __stringify(IPA_CLIENT_A5_WLAN_AMPDU_PROD), __stringify(IPA_CLIENT_A2_EMBEDDED_PROD), __stringify(IPA_CLIENT_A2_TETHERED_PROD), __stringify(IPA_CLIENT_APPS_LAN_WAN_PROD), __stringify(IPA_CLIENT_APPS_CMD_PROD), __stringify(IPA_CLIENT_ODU_PROD), __stringify(IPA_CLIENT_MHI_PROD), __stringify(IPA_CLIENT_Q6_LAN_PROD), __stringify(IPA_CLIENT_Q6_WAN_PROD), __stringify(IPA_CLIENT_Q6_CMD_PROD), __stringify(IPA_CLIENT_MEMCPY_DMA_SYNC_PROD), __stringify(IPA_CLIENT_MEMCPY_DMA_ASYNC_PROD), __stringify(IPA_CLIENT_Q6_DECOMP_PROD), __stringify(IPA_CLIENT_Q6_DECOMP2_PROD), __stringify(IPA_CLIENT_UC_USB_PROD), /* Below PROD client type is only for test purpose */ __stringify(IPA_CLIENT_TEST_PROD), __stringify(IPA_CLIENT_TEST1_PROD), __stringify(IPA_CLIENT_TEST2_PROD), __stringify(IPA_CLIENT_TEST3_PROD), __stringify(IPA_CLIENT_TEST4_PROD), __stringify(IPA_CLIENT_HSIC1_CONS), __stringify(IPA_CLIENT_WLAN1_CONS), __stringify(IPA_CLIENT_HSIC2_CONS), __stringify(IPA_CLIENT_USB2_CONS), __stringify(IPA_CLIENT_WLAN2_CONS), __stringify(IPA_CLIENT_HSIC3_CONS), __stringify(IPA_CLIENT_USB3_CONS), __stringify(IPA_CLIENT_WLAN3_CONS), __stringify(IPA_CLIENT_HSIC4_CONS), __stringify(IPA_CLIENT_USB4_CONS), __stringify(IPA_CLIENT_WLAN4_CONS), __stringify(IPA_CLIENT_HSIC5_CONS), __stringify(IPA_CLIENT_USB_CONS), __stringify(IPA_CLIENT_USB_DPL_CONS), __stringify(IPA_CLIENT_A2_EMBEDDED_CONS), __stringify(IPA_CLIENT_A2_TETHERED_CONS), __stringify(IPA_CLIENT_A5_LAN_WAN_CONS), __stringify(IPA_CLIENT_APPS_LAN_CONS), __stringify(IPA_CLIENT_APPS_WAN_CONS), __stringify(IPA_CLIENT_ODU_EMB_CONS), __stringify(IPA_CLIENT_ODU_TETH_CONS), __stringify(IPA_CLIENT_MHI_CONS), __stringify(IPA_CLIENT_Q6_LAN_CONS), __stringify(IPA_CLIENT_Q6_WAN_CONS), __stringify(IPA_CLIENT_Q6_DUN_CONS), __stringify(IPA_CLIENT_MEMCPY_DMA_SYNC_CONS), __stringify(IPA_CLIENT_MEMCPY_DMA_ASYNC_CONS), __stringify(IPA_CLIENT_Q6_DECOMP_CONS), __stringify(IPA_CLIENT_Q6_DECOMP2_CONS), __stringify(IPA_CLIENT_Q6_LTE_WIFI_AGGR_CONS), /* Below CONS client type is only for test purpose */ __stringify(IPA_CLIENT_TEST_CONS), __stringify(IPA_CLIENT_TEST1_CONS), __stringify(IPA_CLIENT_TEST2_CONS), __stringify(IPA_CLIENT_TEST3_CONS), __stringify(IPA_CLIENT_TEST4_CONS), }; static int ipa2_active_clients_log_insert(const char *string) { if (!ipa_ctx->ipa2_active_clients_logging.log_rdy) return -EPERM; strlcpy(ipa_ctx->ipa2_active_clients_logging.log_buffer [ipa_ctx->ipa2_active_clients_logging.log_head], string, (size_t)IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN); ipa_ctx->ipa2_active_clients_logging.log_head = (ipa_ctx->ipa2_active_clients_logging.log_head + 1) % IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES; if (ipa_ctx->ipa2_active_clients_logging.log_tail == ipa_ctx->ipa2_active_clients_logging.log_head) { ipa_ctx->ipa2_active_clients_logging.log_tail = (ipa_ctx->ipa2_active_clients_logging.log_tail + 1) % IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES; } return 0; } static int ipa2_active_clients_log_init(void) { int i; ipa_ctx->ipa2_active_clients_logging.log_buffer[0] = kzalloc( IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES * sizeof(char[IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN]), GFP_KERNEL); if (ipa_ctx->ipa2_active_clients_logging.log_buffer == NULL) { IPAERR("Active Clients Logging memory allocation failed"); goto bail; } for (i = 0; i < IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES; i++) { ipa_ctx->ipa2_active_clients_logging.log_buffer[i] = ipa_ctx->ipa2_active_clients_logging.log_buffer[0] + (IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN * i); } ipa_ctx->ipa2_active_clients_logging.log_head = 0; ipa_ctx->ipa2_active_clients_logging.log_tail = IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES - 1; ipa_ctx->ipa2_active_clients_logging.log_rdy = 1; return 0; bail: return -ENOMEM; } void ipa2_active_clients_log_clear(void) { ipa_active_clients_lock(); ipa_ctx->ipa2_active_clients_logging.log_head = 0; ipa_ctx->ipa2_active_clients_logging.log_tail = IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES - 1; ipa_active_clients_unlock(); } static void ipa2_active_clients_log_destroy(void) { ipa_ctx->ipa2_active_clients_logging.log_rdy = 0; kfree(ipa_ctx->ipa2_active_clients_logging.log_buffer[0]); ipa_ctx->ipa2_active_clients_logging.log_head = 0; ipa_ctx->ipa2_active_clients_logging.log_tail = IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES - 1; } void ipa2_active_clients_log_print_buffer(void) { int i; ipa_active_clients_lock(); for (i = (ipa_ctx->ipa2_active_clients_logging.log_tail + 1) % IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES; i != ipa_ctx->ipa2_active_clients_logging.log_head; i = (i + 1) % IPA2_ACTIVE_CLIENTS_LOG_BUFFER_SIZE_LINES) { pr_err("%s\n", ipa_ctx->ipa2_active_clients_logging .log_buffer[i]); } ipa_active_clients_unlock(); } enum ipa_smmu_cb_type { IPA_SMMU_CB_AP, IPA_SMMU_CB_WLAN, Loading Loading @@ -387,7 +542,7 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) if (_IOC_NR(cmd) >= IPA_IOCTL_MAX) return -ENOTTY; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); switch (cmd) { case IPA_IOC_ALLOC_NAT_MEM: Loading Loading @@ -1090,12 +1245,12 @@ static long ipa_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) break; default: /* redundant, as cmd was checked against MAXNR */ ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return -ENOTTY; } kfree(param); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return retval; } Loading Loading @@ -1282,7 +1437,7 @@ int ipa_init_q6_smem(void) { int rc; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); if (ipa_ctx->ipa_hw_type == IPA_HW_v2_0) rc = ipa_init_smem_region(IPA_MEM_PART(modem_size) - Loading @@ -1294,7 +1449,7 @@ int ipa_init_q6_smem(void) if (rc) { IPAERR("failed to initialize Modem RAM memory\n"); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return rc; } Loading @@ -1302,7 +1457,7 @@ int ipa_init_q6_smem(void) IPA_MEM_PART(modem_hdr_ofst)); if (rc) { IPAERR("failed to initialize Modem HDRs RAM memory\n"); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return rc; } Loading @@ -1310,7 +1465,7 @@ int ipa_init_q6_smem(void) IPA_MEM_PART(modem_hdr_proc_ctx_ofst)); if (rc) { IPAERR("failed to initialize Modem proc ctx RAM memory\n"); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return rc; } Loading @@ -1318,11 +1473,11 @@ int ipa_init_q6_smem(void) IPA_MEM_PART(modem_comp_decomp_ofst)); if (rc) { IPAERR("failed to initialize Modem Comp/Decomp RAM memory\n"); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return rc; } ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return rc; } Loading Loading @@ -1714,7 +1869,7 @@ int ipa_q6_pre_shutdown_cleanup(void) if (ipa_ctx->uc_ctx.uc_zip_error) BUG(); ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SPECIAL("Q6"); /* * pipe delay and holb discard for ZIP pipes are handled * in post shutdown callback. Loading Loading @@ -2767,7 +2922,7 @@ static void ipa_start_tag_process(struct work_struct *work) if (res) IPAERR("ipa_tag_aggr_force_close failed %d\n", res); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); IPADBG("TAG process done\n"); } Loading @@ -2776,12 +2931,28 @@ static void ipa_start_tag_process(struct work_struct *work) * ipa_inc_client_enable_clks() - Increase active clients counter, and * enable ipa clocks if necessary * * Please do not use this API, use the wrapper macros instead (ipa_i.h) * IPA2_ACTIVE_CLIENTS_INC_XXXX(); * * Return codes: * None */ void ipa_inc_client_enable_clks(void) void ipa2_inc_client_enable_clks(struct ipa2_active_client_logging_info *id) { char temp_str[IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN]; unsigned long long t; unsigned long nanosec_rem; ipa_active_clients_lock(); if (id->type != SIMPLE) { t = cpu_clock(smp_processor_id()); nanosec_rem = do_div(t, 1000000000) / 1000; snprintf(temp_str, IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN, "[%5lu.%06lu] ^ %s, %s: %d", (unsigned long)t, nanosec_rem, id->id_string, id->file, id->line); ipa2_active_clients_log_insert(temp_str); } ipa_ctx->ipa_active_clients.cnt++; if (ipa_ctx->ipa_active_clients.cnt == 1) ipa_enable_clks(); Loading @@ -2794,13 +2965,20 @@ void ipa_inc_client_enable_clks(void) * clients if no asynchronous actions should be done. Asynchronous actions are * locking a mutex and waking up IPA HW. * * Please do not use this API, use the wrapper macros instead (ipa_i.h) * * * Return codes: 0 for success * -EPERM if an asynchronous action should have been done */ int ipa_inc_client_enable_clks_no_block(void) int ipa2_inc_client_enable_clks_no_block(struct ipa2_active_client_logging_info *id) { int res = 0; unsigned long flags; char temp_str[IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN]; unsigned long long t; unsigned long nanosec_rem; if (ipa_active_clients_trylock(&flags) == 0) return -EPERM; Loading @@ -2810,6 +2988,16 @@ int ipa_inc_client_enable_clks_no_block(void) goto bail; } if (id->type != SIMPLE) { t = cpu_clock(smp_processor_id()); nanosec_rem = do_div(t, 1000000000) / 1000; snprintf(temp_str, IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN, "[%5lu.%06lu] ^ %s, %s: %d", (unsigned long)t, nanosec_rem, id->id_string, id->file, id->line); ipa2_active_clients_log_insert(temp_str); } ipa_ctx->ipa_active_clients.cnt++; IPADBG("active clients = %d\n", ipa_ctx->ipa_active_clients.cnt); bail: Loading @@ -2826,12 +3014,28 @@ bail: * start_tag_process_again flag is set during this function to signal TAG * process to start again as there was another client that may send data to ipa * * Please do not use this API, use the wrapper macros instead (ipa_i.h) * IPA2_ACTIVE_CLIENTS_DEC_XXXX(); * * Return codes: * None */ void ipa_dec_client_disable_clks(void) void ipa2_dec_client_disable_clks(struct ipa2_active_client_logging_info *id) { char temp_str[IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN]; unsigned long long t; unsigned long nanosec_rem; ipa_active_clients_lock(); if (id->type != SIMPLE) { t = cpu_clock(smp_processor_id()); nanosec_rem = do_div(t, 1000000000) / 1000; snprintf(temp_str, IPA2_ACTIVE_CLIENTS_LOG_LINE_LEN, "[%5lu.%06lu] v %s, %s: %d", (unsigned long)t, nanosec_rem, id->id_string, id->file, id->line); ipa2_active_clients_log_insert(temp_str); } 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) { Loading Loading @@ -3112,7 +3316,8 @@ void ipa_suspend_handler(enum ipa_irq_type interrupt, if (!atomic_read( &ipa_ctx->sps_pm.dec_clients) ) { ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP( ipa_ctx->ep[i].client); IPADBG("Pipes un-suspended.\n"); IPADBG("Enter poll mode.\n"); atomic_set( Loading Loading @@ -3188,7 +3393,7 @@ static void ipa_sps_release_resource(struct work_struct *work) ipa_sps_process_irq_schedule_rel(); } else { atomic_set(&ipa_ctx->sps_pm.dec_clients, 0); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SPECIAL("SPS_RESOURCE"); } } atomic_set(&ipa_ctx->sps_pm.eot_activity, 0); Loading Loading @@ -3293,6 +3498,7 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p, ipa_ctx->aggregation_type = IPA_MBIM_16; ipa_ctx->aggregation_byte_limit = 1; ipa_ctx->aggregation_time_limit = 0; ipa_ctx->ipa2_active_clients_logging.log_rdy = false; ipa_ctx->ctrl = kzalloc(sizeof(*ipa_ctx->ctrl), GFP_KERNEL); if (!ipa_ctx->ctrl) { Loading Loading @@ -3332,6 +3538,9 @@ static int ipa_init(const struct ipa_plat_drv_res *resource_p, IPADBG("Skipping bus scaling registration on Virtual plat\n"); } if (ipa2_active_clients_log_init()) goto fail_init_active_client; /* get IPA clocks */ result = ipa_get_clks(master_dev); if (result) Loading Loading @@ -3762,6 +3971,8 @@ fail_init_hw: fail_remap: ipa_disable_clks(); fail_clk: ipa2_active_clients_log_destroy(); fail_init_active_client: msm_bus_scale_unregister_client(ipa_ctx->ipa_bus_hdl); fail_bus_reg: if (bus_scale_table) { Loading
drivers/platform/msm/ipa/ipa_v2/ipa_client.c +11 −10 Original line number Diff line number Diff line Loading @@ -289,7 +289,8 @@ int ipa2_connect(const struct ipa_connect_params *in, } memset(&ipa_ctx->ep[ipa_ep_idx], 0, sizeof(struct ipa_ep_context)); ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP(in->client); ep->skip_ep_cfg = in->skip_ep_cfg; ep->valid = 1; Loading Loading @@ -430,7 +431,7 @@ int ipa2_connect(const struct ipa_connect_params *in, ipa_install_dflt_flt_rules(ipa_ep_idx); if (!ep->keep_ipa_awake) ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(in->client); IPADBG("client %d (ep: %d) connected\n", in->client, ipa_ep_idx); Loading Loading @@ -484,7 +485,7 @@ desc_mem_alloc_fail: sps_free_endpoint(ep->ep_hdl); ipa_cfg_ep_fail: memset(&ipa_ctx->ep[ipa_ep_idx], 0, sizeof(struct ipa_ep_context)); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(in->client); fail: return result; } Loading Loading @@ -553,7 +554,8 @@ int ipa2_disconnect(u32 clnt_hdl) ep = &ipa_ctx->ep[clnt_hdl]; if (!ep->keep_ipa_awake) ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP(ipa2_get_client_mapping(clnt_hdl)); /* Set Disconnect in Progress flag. */ spin_lock(&ipa_ctx->disconnect_lock); Loading Loading @@ -660,7 +662,7 @@ int ipa2_disconnect(u32 clnt_hdl) memset(&ipa_ctx->ep[clnt_hdl], 0, sizeof(struct ipa_ep_context)); spin_unlock(&ipa_ctx->disconnect_lock); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(ipa2_get_client_mapping(clnt_hdl)); IPADBG("client (ep: %d) disconnected\n", clnt_hdl); Loading Loading @@ -691,7 +693,7 @@ int ipa2_reset_endpoint(u32 clnt_hdl) } ep = &ipa_ctx->ep[clnt_hdl]; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP(ipa2_get_client_mapping(clnt_hdl)); res = sps_disconnect(ep->ep_hdl); if (res) { IPAERR("sps_disconnect() failed, res=%d.\n", res); Loading @@ -706,7 +708,7 @@ int ipa2_reset_endpoint(u32 clnt_hdl) } bail: ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(ipa2_get_client_mapping(clnt_hdl)); return res; } Loading Loading @@ -758,8 +760,7 @@ int ipa2_clear_endpoint_delay(u32 clnt_hdl) ep->qmi_request_sent = true; } ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP(ipa2_get_client_mapping(clnt_hdl)); /* Set disconnect in progress flag so further flow control events are * not honored. */ Loading @@ -772,7 +773,7 @@ int ipa2_clear_endpoint_delay(u32 clnt_hdl) ep_ctrl.ipa_ep_suspend = false; ipa2_cfg_ep_ctrl(clnt_hdl, &ep_ctrl); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(ipa2_get_client_mapping(clnt_hdl)); IPADBG("client (ep: %d) removed ep delay\n", clnt_hdl); Loading
drivers/platform/msm/ipa/ipa_v2/ipa_debugfs.c +53 −11 Original line number Diff line number Diff line Loading @@ -106,6 +106,7 @@ static struct dentry *dfile_msg; static struct dentry *dfile_ip4_nat; static struct dentry *dfile_rm_stats; static struct dentry *dfile_status_stats; static struct dentry *dfile_active_clients; static char dbg_buff[IPA_MAX_MSG_LEN]; static s8 ep_reg_idx; Loading Loading @@ -153,9 +154,9 @@ static ssize_t ipa_read_gen_reg(struct file *file, char __user *ubuf, { int nbytes; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); nbytes = ipa_ctx->ctrl->ipa_read_gen_reg(dbg_buff, IPA_MAX_MSG_LEN); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes); } Loading Loading @@ -323,7 +324,7 @@ static ssize_t ipa_read_ep_reg(struct file *file, char __user *ubuf, end_idx = start_idx + 1; } pos = *ppos; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); for (i = start_idx; i < end_idx; i++) { nbytes = ipa_ctx->ctrl->ipa_read_ep_reg(dbg_buff, Loading @@ -333,7 +334,7 @@ static ssize_t ipa_read_ep_reg(struct file *file, char __user *ubuf, ret = simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes); if (ret < 0) { ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return ret; } Loading @@ -341,7 +342,7 @@ static ssize_t ipa_read_ep_reg(struct file *file, char __user *ubuf, ubuf += nbytes; count -= nbytes; } ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); *ppos = pos + size; return size; Loading @@ -365,9 +366,9 @@ static ssize_t ipa_write_keep_awake(struct file *file, const char __user *buf, return -EFAULT; if (option == 1) ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); else if (option == 0) ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); else return -EFAULT; Loading Loading @@ -1225,9 +1226,9 @@ static ssize_t ipa_write_dbg_cnt(struct file *file, const char __user *buf, if (kstrtou32(dbg_buff, 0, &option)) return -EFAULT; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); ipa_ctx->ctrl->ipa_write_dbg_cnt(option); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return count; } Loading Loading @@ -1259,9 +1260,9 @@ static ssize_t ipa_read_dbg_cnt(struct file *file, char __user *ubuf, { int nbytes; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); nbytes = ipa_ctx->ctrl->ipa_read_dbg_cnt(dbg_buff, IPA_MAX_MSG_LEN); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, nbytes); } Loading Loading @@ -1548,6 +1549,35 @@ static ssize_t ipa_status_stats_read(struct file *file, char __user *ubuf, return 0; } static ssize_t ipa2_print_active_clients_log(struct file *file, char __user *ubuf, size_t count, loff_t *ppos) { ipa2_active_clients_log_print_buffer(); return 0; } static ssize_t ipa2_clear_active_clients_log(struct file *file, const char __user *ubuf, size_t count, loff_t *ppos) { unsigned long missing; s8 option = 0; if (sizeof(dbg_buff) < count + 1) return -EFAULT; missing = copy_from_user(dbg_buff, ubuf, count); if (missing) return -EFAULT; dbg_buff[count] = '\0'; if (kstrtos8(dbg_buff, 0, &option)) return -EFAULT; ipa2_active_clients_log_clear(); return count; } const struct file_operations ipa_gen_reg_ops = { .read = ipa_read_gen_reg, Loading Loading @@ -1618,6 +1648,11 @@ const struct file_operations ipa_status_stats_ops = { .read = ipa_status_stats_read, }; const struct file_operations ipa2_active_clients = { .read = ipa2_print_active_clients_log, .write = ipa2_clear_active_clients_log, }; void ipa_debugfs_init(void) { const mode_t read_only_mode = S_IRUSR | S_IRGRP | S_IROTH; Loading Loading @@ -1647,6 +1682,13 @@ void ipa_debugfs_init(void) goto fail; } dfile_ep_reg = debugfs_create_file("active_clients", read_write_mode, dent, 0, &ipa2_active_clients); if (!dfile_ep_reg || IS_ERR(dfile_active_clients)) { IPAERR("fail to create file for debug_fs ep_reg\n"); goto fail; } dfile_ep_reg = debugfs_create_file("ep_reg", read_write_mode, dent, 0, &ipa_ep_reg_ops); if (!dfile_ep_reg || IS_ERR(dfile_ep_reg)) { Loading
drivers/platform/msm/ipa/ipa_v2/ipa_dma.c +2 −2 Original line number Diff line number Diff line Loading @@ -274,7 +274,7 @@ int ipa2_dma_enable(void) mutex_unlock(&ipa_dma_ctx->enable_lock); return -EPERM; } ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SPECIAL("DMA"); ipa_dma_ctx->is_enabled = true; mutex_unlock(&ipa_dma_ctx->enable_lock); Loading Loading @@ -337,7 +337,7 @@ int ipa2_dma_disable(void) } ipa_dma_ctx->is_enabled = false; spin_unlock_irqrestore(&ipa_dma_ctx->pending_lock, flags); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SPECIAL("DMA"); mutex_unlock(&ipa_dma_ctx->enable_lock); IPADMA_FUNC_EXIT(); return 0; Loading
drivers/platform/msm/ipa/ipa_v2/ipa_dp.c +20 −20 Original line number Diff line number Diff line Loading @@ -255,7 +255,7 @@ static void ipa_handle_tx(struct ipa_sys_context *sys) int inactive_cycles = 0; int cnt; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); do { cnt = ipa_handle_tx_core(sys, true, true); if (cnt == 0) { Loading @@ -268,7 +268,7 @@ static void ipa_handle_tx(struct ipa_sys_context *sys) } while (inactive_cycles <= POLLING_INACTIVITY_TX); ipa_tx_switch_to_intr_mode(sys); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); } static void ipa_wq_handle_tx(struct work_struct *work) Loading Loading @@ -654,7 +654,7 @@ int ipa_send_cmd(u16 num_desc, struct ipa_desc *descr) } sys = ipa_ctx->ep[ep_idx].sys; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); if (num_desc == 1) { init_completion(&descr->xfer_done); Loading Loading @@ -688,7 +688,7 @@ int ipa_send_cmd(u16 num_desc, struct ipa_desc *descr) } bail: ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); return result; } Loading Loading @@ -994,7 +994,7 @@ static void ipa_handle_rx(struct ipa_sys_context *sys) int inactive_cycles = 0; int cnt; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); do { cnt = ipa_handle_rx_core(sys, true, true); if (cnt == 0) { Loading @@ -1018,7 +1018,7 @@ static void ipa_handle_rx(struct ipa_sys_context *sys) trace_poll_to_intr(sys->ep->client); ipa_rx_switch_to_intr_mode(sys); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); } static void switch_to_intr_rx_work_func(struct work_struct *work) Loading Loading @@ -1110,7 +1110,7 @@ int ipa2_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) ep = &ipa_ctx->ep[ipa_ep_idx]; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP(sys_in->client); if (ep->valid == 1) { if (sys_in->client != IPA_CLIENT_APPS_LAN_WAN_PROD) { Loading @@ -1135,7 +1135,7 @@ int ipa2_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) ep->priv = sys_in->priv; *clnt_hdl = ipa_ep_idx; if (!ep->keep_ipa_awake) ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(sys_in->client); return 0; } Loading Loading @@ -1349,7 +1349,7 @@ int ipa2_setup_sys_pipe(struct ipa_sys_connect_params *sys_in, u32 *clnt_hdl) } if (!ep->keep_ipa_awake) ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(sys_in->client); IPADBG("client %d (ep: %d) connected sys=%p\n", sys_in->client, ipa_ep_idx, ep->sys); Loading @@ -1372,7 +1372,7 @@ fail_wq: kfree(ep->sys); memset(&ipa_ctx->ep[ipa_ep_idx], 0, sizeof(struct ipa_ep_context)); fail_and_disable_clocks: ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(sys_in->client); fail_gen: return result; } Loading Loading @@ -1402,7 +1402,7 @@ int ipa2_teardown_sys_pipe(u32 clnt_hdl) ep = &ipa_ctx->ep[clnt_hdl]; if (!ep->keep_ipa_awake) ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP(ipa2_get_client_mapping(clnt_hdl)); ipa_disable_data_path(clnt_hdl); ep->valid = 0; Loading Loading @@ -1446,7 +1446,7 @@ int ipa2_teardown_sys_pipe(u32 clnt_hdl) if (!atomic_read(&ipa_ctx->wc_memb.active_clnt_cnt)) ipa_cleanup_wlan_rx_common_cache(); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(ipa2_get_client_mapping(clnt_hdl)); IPADBG("client (ep: %d) disconnected\n", clnt_hdl); Loading Loading @@ -2055,9 +2055,9 @@ static void replenish_rx_work_func(struct work_struct *work) dwork = container_of(work, struct delayed_work, work); sys = container_of(dwork, struct ipa_sys_context, replenish_rx_work); ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_SIMPLE(); sys->repl_hdlr(sys); ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_SIMPLE(); } /** Loading Loading @@ -3273,7 +3273,7 @@ int ipa2_sys_setup(struct ipa_sys_connect_params *sys_in, ep = &ipa_ctx->ep[ipa_ep_idx]; ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP(sys_in->client); if (ep->valid == 1) { if (sys_in->client != IPA_CLIENT_APPS_LAN_WAN_PROD) { Loading @@ -3300,7 +3300,7 @@ int ipa2_sys_setup(struct ipa_sys_connect_params *sys_in, ep->priv = sys_in->priv; *clnt_hdl = ipa_ep_idx; if (!ep->keep_ipa_awake) ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(sys_in->client); return 0; } Loading Loading @@ -3341,7 +3341,7 @@ int ipa2_sys_setup(struct ipa_sys_connect_params *sys_in, *ipa_bam_hdl = ipa_ctx->bam_handle; if (!ep->keep_ipa_awake) ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(sys_in->client); ipa_ctx->skip_ep_cfg_shadow[ipa_ep_idx] = ep->skip_ep_cfg; IPADBG("client %d (ep: %d) connected sys=%p\n", sys_in->client, Loading @@ -3351,7 +3351,7 @@ int ipa2_sys_setup(struct ipa_sys_connect_params *sys_in, fail_gen2: fail_and_disable_clocks: ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(sys_in->client); fail_gen: return result; } Loading @@ -3369,12 +3369,12 @@ int ipa2_sys_teardown(u32 clnt_hdl) ep = &ipa_ctx->ep[clnt_hdl]; if (!ep->keep_ipa_awake) ipa_inc_client_enable_clks(); IPA2_ACTIVE_CLIENTS_INC_EP(ipa2_get_client_mapping(clnt_hdl)); ipa_disable_data_path(clnt_hdl); ep->valid = 0; ipa_dec_client_disable_clks(); IPA2_ACTIVE_CLIENTS_DEC_EP(ipa2_get_client_mapping(clnt_hdl)); IPADBG("client (ep: %d) disconnected\n", clnt_hdl); Loading