summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlex Frid <afrid@nvidia.com>2011-10-06 23:38:21 -0700
committerDan Willemsen <dwillemsen@nvidia.com>2011-11-30 21:49:41 -0800
commit4d8c37b3d77830ac223dde3d6f644f2415ca70a6 (patch)
tree76dadae79bff064faab821687e709ea34368402e
parent9e76eb8d18295d0c383731c52785017f0ebb498f (diff)
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 <vcolbert@nvidia.com> Tested-by: Varun Colbert <vcolbert@nvidia.com> Rebase-Id: R800c2a4d5e097bdd29fa1b0b901264a2723abff0
-rw-r--r--arch/arm/mach-tegra/cpu-tegra.c48
1 files changed, 48 insertions, 0 deletions
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;