summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--arch/arm/mach-tegra/cpu-tegra.c26
-rw-r--r--arch/arm/mach-tegra/dvfs.h10
-rw-r--r--arch/arm/mach-tegra/tegra3_dvfs.c16
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)