diff options
-rw-r--r-- | arch/arm/mach-tegra/cpu-tegra.c | 26 | ||||
-rw-r--r-- | arch/arm/mach-tegra/dvfs.h | 10 | ||||
-rw-r--r-- | arch/arm/mach-tegra/tegra3_dvfs.c | 16 |
3 files changed, 28 insertions, 24 deletions
diff --git a/arch/arm/mach-tegra/cpu-tegra.c b/arch/arm/mach-tegra/cpu-tegra.c index 9bed9270b412..ea5bbcf237c0 100644 --- a/arch/arm/mach-tegra/cpu-tegra.c +++ b/arch/arm/mach-tegra/cpu-tegra.c @@ -7,7 +7,7 @@ * Colin Cross <ccross@google.com> * Based on arch/arm/plat-omap/cpu-omap.c, (C) 2005 Nokia Corporation * - * Copyright (C) 2010-2012 NVIDIA Corporation + * Copyright (C) 2010-2012 NVIDIA CORPORATION. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -242,12 +242,12 @@ int tegra_edp_update_thermal_zone(int temperature) /* Update cpu rate if cpufreq (at least on cpu0) is already started; alter cpu dvfs table for this thermal zone if necessary */ - tegra_cpu_dvfs_alter(edp_thermal_index, &edp_cpumask, true); + tegra_cpu_dvfs_alter(edp_thermal_index, &edp_cpumask, true, 0); if (target_cpu_speed[0]) { edp_update_limit(); tegra_cpu_set_speed_cap(NULL); } - tegra_cpu_dvfs_alter(edp_thermal_index, &edp_cpumask, false); + tegra_cpu_dvfs_alter(edp_thermal_index, &edp_cpumask, false, 0); mutex_unlock(&tegra_cpu_lock); return ret; @@ -321,31 +321,31 @@ static int tegra_cpu_edp_notify( case CPU_UP_PREPARE: mutex_lock(&tegra_cpu_lock); cpu_set(cpu, edp_cpumask); - tegra_cpu_dvfs_alter(edp_thermal_index, &edp_cpumask, true); edp_update_limit(); cpu_speed = tegra_getspeed(0); new_speed = edp_governor_speed(cpu_speed); if (new_speed < cpu_speed) { ret = tegra_cpu_set_speed_cap(NULL); - if (ret) { - cpu_clear(cpu, edp_cpumask); - edp_update_limit(); - } - - printk(KERN_DEBUG "tegra CPU:%sforce EDP limit %u kHz" + printk(KERN_DEBUG "cpu-tegra:%sforce EDP limit %u kHz" "\n", ret ? " failed to " : " ", new_speed); } - tegra_cpu_dvfs_alter(edp_thermal_index, &edp_cpumask, false); + if (!ret) + ret = tegra_cpu_dvfs_alter( + edp_thermal_index, &edp_cpumask, false, event); + if (ret) { + cpu_clear(cpu, edp_cpumask); + edp_update_limit(); + } mutex_unlock(&tegra_cpu_lock); break; case CPU_DEAD: mutex_lock(&tegra_cpu_lock); cpu_clear(cpu, edp_cpumask); - tegra_cpu_dvfs_alter(edp_thermal_index, &edp_cpumask, true); + tegra_cpu_dvfs_alter( + edp_thermal_index, &edp_cpumask, true, event); edp_update_limit(); tegra_cpu_set_speed_cap(NULL); - tegra_cpu_dvfs_alter(edp_thermal_index, &edp_cpumask, false); mutex_unlock(&tegra_cpu_lock); break; } diff --git a/arch/arm/mach-tegra/dvfs.h b/arch/arm/mach-tegra/dvfs.h index 3bdb13690278..d18a0382f4da 100644 --- a/arch/arm/mach-tegra/dvfs.h +++ b/arch/arm/mach-tegra/dvfs.h @@ -5,7 +5,7 @@ * Author: * Colin Cross <ccross@google.com> * - * Copyright (C) 2010-2011 NVIDIA Corporation. + * Copyright (C) 2010-2012 NVIDIA CORPORATION. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -118,8 +118,8 @@ int tegra_dvfs_predict_millivolts(struct clk *c, unsigned long rate); void tegra_dvfs_core_cap_enable(bool enable); void tegra_dvfs_core_cap_level_set(int level); int tegra_dvfs_alt_freqs_set(struct dvfs *d, unsigned long *alt_freqs); -void tegra_cpu_dvfs_alter( - int edp_thermal_index, const cpumask_t *cpus, bool before_clk_update); +int tegra_cpu_dvfs_alter(int edp_thermal_index, const cpumask_t *cpus, + bool before_clk_update, int cpu_event); #else static inline void tegra_soc_init_dvfs(void) {} @@ -157,8 +157,8 @@ static inline void tegra_dvfs_core_cap_level_set(int level) static inline int tegra_dvfs_alt_freqs_set(struct dvfs *d, unsigned long *alt_freqs) { return 0; } -static inline void tegra_cpu_dvfs_alter( - int edp_thermal_index, const cpumask_t *cpus, bool before_clk_update) +static inline int tegra_cpu_dvfs_alter(int edp_thermal_index, + const cpumask_t *cpus, bool before_clk_update, int cpu_event) {} #endif diff --git a/arch/arm/mach-tegra/tegra3_dvfs.c b/arch/arm/mach-tegra/tegra3_dvfs.c index 10ba0715c33e..7d8359290a22 100644 --- a/arch/arm/mach-tegra/tegra3_dvfs.c +++ b/arch/arm/mach-tegra/tegra3_dvfs.c @@ -1,7 +1,7 @@ /* * arch/arm/mach-tegra/tegra3_dvfs.c * - * Copyright (C) 2010-2012, NVIDIA Corporation. + * Copyright (C) 2010-2012 NVIDIA CORPORATION. All rights reserved. * * This software is licensed under the terms of the GNU General Public * License version 2, as published by the Free Software Foundation, and @@ -693,19 +693,23 @@ void __init tegra_soc_init_dvfs(void) tegra_dvfs_core_disabled ? "disabled" : "enabled"); } -void tegra_cpu_dvfs_alter(int edp_thermal_index, const cpumask_t *cpus, - bool before_clk_update) +int tegra_cpu_dvfs_alter(int edp_thermal_index, const cpumask_t *cpus, + bool before_clk_update, int cpu_event) { bool cpu_warm = !!edp_thermal_index; unsigned int n = cpumask_weight(cpus); unsigned long *alt_freqs = cpu_warm ? (n > 1 ? NULL : cpu_0_freqs) : cpu_cold_freqs; - if (cpu_warm == before_clk_update) { + if (cpu_event || (cpu_warm == before_clk_update)) { int ret = tegra_dvfs_alt_freqs_set(cpu_dvfs, alt_freqs); - WARN_ONCE(ret, "tegra dvfs: failed to update CPU alternative" - " frequency limits\n"); + if (ret) { + pr_err("tegra dvfs: failed to set alternative dvfs on " + "%u %s CPUs\n", n, cpu_warm ? "warm" : "cold"); + return ret; + } } + return 0; } int tegra_dvfs_rail_disable_prepare(struct dvfs_rail *rail) |