msm: ipa: debugfs: Update keep_awake to use PM APIs

Update the keep_awake script to call into IPA PM and
add/remove dummy clients to change the clk vote dynamically
based on the loaded device's power thresholds.

Change-Id: Ifaa4ef1e312428245605008998ac59afddf09d99
Signed-off-by: Michael Adisumarta <madisuma@codeaurora.org>
这个提交包含在:
Michael Adisumarta
2021-08-18 15:34:56 -07:00
提交者 Gerrit - the friendly Code Review server
父节点 bf2a8f464b
当前提交 c6e2859a34
修改 3 个文件,包含 167 行新增31 行删除

查看文件

@@ -503,40 +503,21 @@ static ssize_t ipa3_write_keep_awake(struct file *file, const char __user *buf,
{
s8 option = 0;
int ret;
uint32_t bw_mbps = 0;
ret = kstrtos8_from_user(buf, count, 0, &option);
if (ret)
return ret;
switch (option) {
case 0:
IPA_ACTIVE_CLIENTS_DEC_SIMPLE();
bw_mbps = 0;
break;
case 1:
IPA_ACTIVE_CLIENTS_INC_SIMPLE();
bw_mbps = 0;
break;
case 2:
IPA_ACTIVE_CLIENTS_INC_SIMPLE();
bw_mbps = 700;
break;
case 3:
IPA_ACTIVE_CLIENTS_INC_SIMPLE();
bw_mbps = 3000;
break;
case 4:
IPA_ACTIVE_CLIENTS_INC_SIMPLE();
bw_mbps = 7000;
break;
default:
pr_err("Not support this vote (%d)\n", option);
return -EFAULT;
}
if (ipa3_vote_for_bus_bw(&bw_mbps)) {
IPAERR("Failed to vote for bus BW (%u)\n", bw_mbps);
return -EFAULT;
if (option == 0) {
if (ipa_pm_remove_dummy_clients()) {
pr_err("Failed to remove dummy clients\n");
return -EFAULT;
}
} else {
if (ipa_pm_add_dummy_clients(option - 1)) {
pr_err("Failed to add dummy clients\n");
return -EFAULT;
}
}
return count;

查看文件

@@ -195,6 +195,8 @@ static const char *ipa_pm_group_to_str[IPA_PM_GROUP_MAX] = {
__stringify(IPA_PM_GROUP_MODEM),
};
static int dummy_hdl_1, dummy_hdl_2, tput_modem, tput_apps;
/**
* pop_max_from_array() -pop the max and move the last element to where the
* max was popped
@@ -1511,4 +1513,145 @@ int ipa_pm_get_pm_clnt_throughput(enum ipa_client_type client_type)
mutex_unlock(&ipa_pm_ctx->client_mutex);
return 0;
}
}
}
/**
* ipa_pm_add_dummy_clients() - add 2 dummy clients for modem and apps
* @power_plan: [in] The power plan for the dummy clients
* 0 = SVS (lowest plan), 1 = SVS2, ... etc
*
* Returns: 0 on success, negative on failure
*/
int ipa_pm_add_dummy_clients(s8 power_plan)
{
int rc = 0;
int tput;
int hdl_1, hdl_2;
struct ipa_pm_register_params dummy1_params = {
.name = "DummyModem",
.group = IPA_PM_GROUP_MODEM,
.skip_clk_vote = 0,
.callback = NULL,
.user_data = NULL
};
struct ipa_pm_register_params dummy2_params = {
.name = "DummyApps",
.group = IPA_PM_GROUP_APPS,
.skip_clk_vote = 0,
.callback = NULL,
.user_data = NULL
};
if (power_plan < 0 ||
(power_plan - 1) >= ipa_pm_ctx->clk_scaling.threshold_size) {
pr_err("Invalid power plan(%d)\n", power_plan);
return -EFAULT;
}
/* 0 is SVS case which is not part of the threshold */
if (power_plan == 0)
tput = 0;
else
tput = ipa_pm_ctx->clk_scaling.current_threshold[power_plan-1];
/*
* register with local handles to prevent overwriting global handles
* in the case of a failure
*/
rc = ipa_pm_register(&dummy1_params, &hdl_1);
if (rc) {
pr_err("fail to register client 1 rc = %d\n", rc);
return -EFAULT;
}
rc = ipa_pm_register(&dummy2_params, &hdl_2);
if (rc) {
pr_err("fail to register client 2 rc = %d\n", rc);
return -EFAULT;
}
/* replace global handles */
dummy_hdl_1 = hdl_1;
dummy_hdl_2 = hdl_2;
/* save the old throughputs for removal */
tput_modem = ipa_pm_ctx->group_tput[IPA_PM_GROUP_MODEM];
tput_apps = ipa_pm_ctx->group_tput[IPA_PM_GROUP_APPS];
rc = ipa_pm_set_throughput(dummy_hdl_1, tput);
if (rc) {
IPAERR("fail to set tput for client 1 rc = %d\n", rc);
return -EFAULT;
}
rc = ipa_pm_set_throughput(dummy_hdl_2, tput);
if (rc) {
IPAERR("fail to set tput for client 2 rc = %d\n", rc);
return -EFAULT;
}
rc = ipa_pm_activate_sync(dummy_hdl_1);
if (rc) {
IPAERR("fail to activate sync for client 1 rc = %d\n", rc);
return -EFAULT;
}
rc = ipa_pm_activate_sync(dummy_hdl_2);
if (rc) {
IPAERR("fail to activate sync for client 2 rc = %d\n", rc);
return -EFAULT;
}
return rc;
}
/**
* ipa_pm_remove_dummy_clients() - remove the 2 dummy clients for modem and apps
*
* Returns: 0 on success, negative on failure
*/
int ipa_pm_remove_dummy_clients(void)
{
int rc = 0;
rc = ipa_pm_deactivate_sync(dummy_hdl_1);
if (rc) {
IPAERR("fail to deactivate client 1 rc = %d\n", rc);
return -EFAULT;
}
rc = ipa_pm_deactivate_sync(dummy_hdl_2);
if (rc) {
IPAERR("fail to deactivate client 2 rc = %d\n", rc);
return -EFAULT;
}
/* reset the modem and apps tputs back to old values */
rc = ipa_pm_set_throughput(dummy_hdl_1, tput_modem);
if (rc) {
IPAERR("fail to reset tput for client 1 rc = %d\n", rc);
return -EFAULT;
}
rc = ipa_pm_set_throughput(dummy_hdl_2, tput_apps);
if (rc) {
IPAERR("fail to reset tput for client 2 rc = %d\n", rc);
return -EFAULT;
}
rc = ipa_pm_deregister(dummy_hdl_1);
if (rc) {
IPAERR("fail to deregister client 1 rc = %d\n", rc);
return -EFAULT;
}
rc = ipa_pm_deregister(dummy_hdl_2);
if (rc) {
IPAERR("fail to deregister client 2 rc = %d\n", rc);
return -EFAULT;
}
return rc;
}

查看文件

@@ -1,6 +1,6 @@
/* SPDX-License-Identifier: GPL-2.0-only */
/*
* Copyright (c) 2017-2019, The Linux Foundation. All rights reserved.
* Copyright (c) 2017-2021, The Linux Foundation. All rights reserved.
*/
#ifndef _IPA_PM_H_
@@ -103,6 +103,8 @@ int ipa_pm_deactivate_all_deferred(void);
int ipa_pm_stat(char *buf, int size);
int ipa_pm_exceptions_stat(char *buf, int size);
void ipa_pm_set_clock_index(int index);
int ipa_pm_add_dummy_clients(s8 power_plan);
int ipa_pm_remove_dummy_clients(void);
#else /* IS_ENABLED(CONFIG_IPA3) */
@@ -178,6 +180,16 @@ static inline int ipa_pm_exceptions_stat(char *buf, int size)
{
return -EPERM;
}
static inline int ipa_pm_add_dummy_clients(s8 power_plan);
{
return -EPERM;
}
static inline int ipa_pm_remove_dummy_clients(void);
{
return -EPERM;
}
#endif /* IS_ENABLED(CONFIG_IPA3) */
#endif /* _IPA_PM_H_ */