diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa.c b/drivers/platform/msm/ipa/ipa_v3/ipa.c index 66b304309670..dada894b12b9 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -2755,6 +2755,11 @@ static long ipa3_ioctl(struct file *filp, unsigned int cmd, unsigned long arg) retval = proc_sram_info_rqst(arg); break; + case IPA_IOC_APP_CLOCK_VOTE: + retval = ipa3_app_clk_vote( + (enum ipa_app_clock_vote_type) arg); + break; + default: IPA_ACTIVE_CLIENTS_DEC_SIMPLE(); return -ENOTTY; @@ -4672,6 +4677,9 @@ long compat_ipa3_ioctl(struct file *file, unsigned int cmd, unsigned long arg) case IPA_IOC_GET_NAT_IN_SRAM_INFO32: cmd = IPA_IOC_GET_NAT_IN_SRAM_INFO; break; + case IPA_IOC_APP_CLOCK_VOTE32: + cmd = IPA_IOC_APP_CLOCK_VOTE; + break; case IPA_IOC_COMMIT_HDR: case IPA_IOC_RESET_HDR: case IPA_IOC_COMMIT_RT: @@ -7033,6 +7041,8 @@ static int ipa3_pre_init(const struct ipa3_plat_drv_res *resource_p, ipa3_wwan_init(); + mutex_init(&ipa3_ctx->app_clock_vote.mutex); + return 0; fail_cdev_add: diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c index 6fc1eba69641..42a5fad6cff9 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_debugfs.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifdef CONFIG_DEBUG_FS @@ -2693,6 +2693,22 @@ done: return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt); } +static ssize_t ipa3_read_app_clk_vote( + struct file *file, + char __user *ubuf, + size_t count, + loff_t *ppos) +{ + int cnt = + scnprintf( + dbg_buff, + IPA_MAX_MSG_LEN, + "%u\n", + ipa3_ctx->app_clock_vote.cnt); + + return simple_read_from_buffer(ubuf, count, ppos, dbg_buff, cnt); +} + static void ipa_dump_status(struct ipahal_pkt_status *status) { IPA_DUMP_STATUS_FIELD(status_opcode); @@ -2970,7 +2986,11 @@ static const struct ipa3_debugfs_file debugfs_files[] = { "usb_gsi_stats", IPA_READ_ONLY_MODE, NULL, { .read = ipa3_read_usb_gsi_stats, } - } + }, { + "app_clk_vote_cnt", IPA_READ_ONLY_MODE, NULL, { + .read = ipa3_read_app_clk_vote, + } + }, }; void ipa3_debugfs_init(void) diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h index 603e4679cae8..f603c8df73a5 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_i.h +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_i.h @@ -1,6 +1,6 @@ /* SPDX-License-Identifier: GPL-2.0-only */ /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #ifndef _IPA3_I_H_ @@ -243,6 +243,8 @@ enum { # define __cpuc_flush_dcache_area __flush_dcache_area #endif +#define IPA_APP_VOTE_MAX 500 + #define IPA_SMP2P_OUT_CLK_RSP_CMPLT_IDX 0 #define IPA_SMP2P_OUT_CLK_VOTE_IDX 1 #define IPA_SMP2P_SMEM_STATE_MASK 3 @@ -434,6 +436,9 @@ enum { #define IPA_IOC_GET_NAT_IN_SRAM_INFO32 _IOWR(IPA_IOC_MAGIC, \ IPA_IOCTL_GET_NAT_IN_SRAM_INFO, \ compat_uptr_t) +#define IPA_IOC_APP_CLOCK_VOTE32 _IOWR(IPA_IOC_MAGIC, \ + IPA_IOCTL_APP_CLOCK_VOTE, \ + compat_uptr_t) #endif /* #ifdef CONFIG_COMPAT */ #define IPA_TZ_UNLOCK_ATTRIBUTE 0x0C0311 @@ -1785,6 +1790,11 @@ struct ipa_fw_load_data { struct mutex lock; }; +struct ipa3_app_clock_vote { + struct mutex mutex; + u32 cnt; +}; + /** * struct ipa3_context - IPA context * @cdev: cdev context @@ -1874,6 +1884,7 @@ struct ipa_fw_load_data { * @flt_rt_counters: the counters usage info for flt rt stats * @wdi3_ctx: IPA wdi3 context * @gsi_info: channel/protocol info for GSI offloading uC stats + * @app_vote: holds userspace application clock vote count * IPA context - holds all relevant info about IPA driver and its state * @lan_rx_napi_enable: flag if NAPI is enabled on the LAN dp * @lan_ndev: dummy netdev for LAN rx NAPI @@ -2061,6 +2072,7 @@ struct ipa3_context { u32 icc_num_paths; u32 icc_clk[IPA_ICC_LVL_MAX][IPA_ICC_PATH_MAX][IPA_ICC_TYPE_MAX]; struct ipahal_imm_cmd_pyld *coal_cmd_pyld; + struct ipa3_app_clock_vote app_clock_vote; }; struct ipa3_plat_drv_res { @@ -2567,6 +2579,7 @@ int ipa3_del_ipv6ct_table(struct ipa_ioc_nat_ipv6ct_table_del *del); int ipa3_nat_mdfy_pdn(struct ipa_ioc_nat_pdn_entry *mdfy_pdn); int ipa3_nat_get_sram_info(struct ipa_nat_in_sram_info *info_ptr); +int ipa3_app_clk_vote(enum ipa_app_clock_vote_type vote_type); /* * Messaging diff --git a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c index c0dc4cddde75..671c1c985ee2 100644 --- a/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c +++ b/drivers/platform/msm/ipa/ipa_v3/ipa_utils.c @@ -1,6 +1,6 @@ // SPDX-License-Identifier: GPL-2.0-only /* - * Copyright (c) 2012-2019, The Linux Foundation. All rights reserved. + * Copyright (c) 2012-2020, The Linux Foundation. All rights reserved. */ #include @@ -8997,6 +8997,52 @@ u32 ipa3_ctx_get_num_pipes(void) return ipa3_ctx->ipa_num_pipes; } +int ipa3_app_clk_vote( + enum ipa_app_clock_vote_type vote_type) +{ + const char *str_ptr = "APP_VOTE"; + int ret = 0; + + IPADBG("In\n"); + + mutex_lock(&ipa3_ctx->app_clock_vote.mutex); + + switch (vote_type) { + case IPA_APP_CLK_VOTE: + if ((ipa3_ctx->app_clock_vote.cnt + 1) <= IPA_APP_VOTE_MAX) { + ipa3_ctx->app_clock_vote.cnt++; + IPA_ACTIVE_CLIENTS_INC_SPECIAL(str_ptr); + } else { + IPAERR_RL("App vote count max hit\n"); + ret = -EPERM; + break; + } + break; + case IPA_APP_CLK_DEVOTE: + if (ipa3_ctx->app_clock_vote.cnt) { + ipa3_ctx->app_clock_vote.cnt--; + IPA_ACTIVE_CLIENTS_DEC_SPECIAL(str_ptr); + } + break; + case IPA_APP_CLK_RESET_VOTE: + while (ipa3_ctx->app_clock_vote.cnt > 0) { + IPA_ACTIVE_CLIENTS_DEC_SPECIAL(str_ptr); + ipa3_ctx->app_clock_vote.cnt--; + } + break; + default: + IPAERR_RL("Unknown vote_type(%u)\n", vote_type); + ret = -EPERM; + break; + } + + mutex_unlock(&ipa3_ctx->app_clock_vote.mutex); + + IPADBG("Out\n"); + + return ret; +} + /* * ipa3_get_prot_id() - Query gsi protocol id * @client: ipa_client_type @@ -9049,4 +9095,3 @@ int ipa3_get_prot_id(enum ipa_client_type client) return prot_id; } -