From 4d8c37b3d77830ac223dde3d6f644f2415ca70a6 Mon Sep 17 00:00:00 2001 From: Alex Frid Date: Thu, 6 Oct 2011 23:38:21 -0700 Subject: ARM: tegra: power Limit CPU complex speed through sysfs Added sysfs node /sys/module/cpu_tegra/parameters/cpu_user_cap to set maximum CPU rate from user space. Unlike per-cpu frequency governor limit (scaling_max_freq), this cap is applied directly to common CPU complex frequency underneath per-cpu governors. (cherry picked from commit 5fbd5b19ddb43a03391957000f23b729f394b05b) (cherry picked from commit bf81c8efc2c98e5008527ce019669dc57718f44b) Change-Id: Ic2f152e1fd58f2f0062489309c0cffd32a2462ae Reviewed-on: http://git-master/r/61711 Reviewed-by: Varun Colbert Tested-by: Varun Colbert Rebase-Id: R800c2a4d5e097bdd29fa1b0b901264a2723abff0 --- arch/arm/mach-tegra/cpu-tegra.c | 48 +++++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) (limited to 'arch/arm/mach-tegra/cpu-tegra.c') diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c index 90745de96c6b..d6793f87cc5f 100644 --- a/arch/arm/mach-tegra/cpu-tegra.c +++ b/arch/arm/mach-tegra/cpu-tegra.c @@ -84,6 +84,53 @@ static struct kernel_param_ops policy_ops = { module_param_cb(force_policy_max, &policy_ops, &force_policy_max, 0644); +static unsigned int cpu_user_cap; + +static int cpu_user_cap_set(const char *arg, const struct kernel_param *kp) +{ + int ret; + + mutex_lock(&tegra_cpu_lock); + + ret = param_set_uint(arg, kp); + if (ret == 0) { +#ifndef CONFIG_TEGRA_CPU_CAP_EXACT_FREQ + if (cpu_user_cap != 0) { + int i; + for (i = 0; freq_table[i].frequency != + CPUFREQ_TABLE_END; i++) { + if (freq_table[i].frequency > cpu_user_cap) + break; + } + i = (i == 0) ? 0 : i - 1; + cpu_user_cap = freq_table[i].frequency; + } +#endif + tegra_cpu_set_speed_cap(NULL); + } + + mutex_unlock(&tegra_cpu_lock); + return ret; +} + +static int cpu_user_cap_get(char *buffer, const struct kernel_param *kp) +{ + return param_get_uint(buffer, kp); +} + +static struct kernel_param_ops cap_ops = { + .set = cpu_user_cap_set, + .get = cpu_user_cap_get, +}; +module_param_cb(cpu_user_cap, &cap_ops, &cpu_user_cap, 0644); + +static unsigned int user_cap_speed(unsigned int requested_speed) +{ + if ((cpu_user_cap) && (requested_speed > cpu_user_cap)) + return cpu_user_cap; + return requested_speed; +} + #ifdef CONFIG_TEGRA_THERMAL_THROTTLE static ssize_t show_throttle(struct cpufreq_policy *policy, char *buf) @@ -444,6 +491,7 @@ int tegra_cpu_set_speed_cap(unsigned int *speed_cap) new_speed = tegra_throttle_governor_speed(new_speed); new_speed = edp_governor_speed(new_speed); + new_speed = user_cap_speed(new_speed); if (speed_cap) *speed_cap = new_speed; -- cgit v1.2.3