summaryrefslogtreecommitdiff
path: root/arch/arm/mach-tegra/cpu-tegra3.c
diff options
context:
space:
mode:
Diffstat (limited to 'arch/arm/mach-tegra/cpu-tegra3.c')
-rw-r--r--arch/arm/mach-tegra/cpu-tegra3.c35
1 files changed, 32 insertions, 3 deletions
diff --git a/arch/arm/mach-tegra/cpu-tegra3.c b/arch/arm/mach-tegra/cpu-tegra3.c
index 05b2e70816e3..6aaa87e36918 100644
--- a/arch/arm/mach-tegra/cpu-tegra3.c
+++ b/arch/arm/mach-tegra/cpu-tegra3.c
@@ -32,6 +32,7 @@
#include <linux/clk.h>
#include <linux/debugfs.h>
#include <linux/seq_file.h>
+#include <linux/pm_qos_params.h>
#include "pm.h"
#include "cpu-tegra.h"
@@ -194,16 +195,21 @@ static noinline int tegra_cpu_speed_balance(void)
unsigned long balanced_speed = highest_speed * balance_level / 100;
unsigned long skewed_speed = balanced_speed / 2;
unsigned int nr_cpus = num_online_cpus();
+ unsigned int max_cpus = pm_qos_request(PM_QOS_MAX_ONLINE_CPUS) ? : 4;
/* balanced: freq targets for all CPUs are above 50% of highest speed
biased: freq target for at least one CPU is below 50% threshold
skewed: freq targets for at least 2 CPUs are below 25% threshold */
if ((tegra_count_slow_cpus(skewed_speed) >= 2) ||
- tegra_cpu_edp_favor_down(nr_cpus, mp_overhead))
+ tegra_cpu_edp_favor_down(nr_cpus, mp_overhead) ||
+ (nr_cpus > max_cpus))
return TEGRA_CPU_SPEED_SKEWED;
- else if ((tegra_count_slow_cpus(balanced_speed) >= 1) ||
- (!tegra_cpu_edp_favor_up(nr_cpus, mp_overhead)))
+
+ if ((tegra_count_slow_cpus(balanced_speed) >= 1) ||
+ (!tegra_cpu_edp_favor_up(nr_cpus, mp_overhead)) ||
+ (nr_cpus == max_cpus))
return TEGRA_CPU_SPEED_BIASED;
+
return TEGRA_CPU_SPEED_BALANCED;
}
@@ -376,6 +382,8 @@ int tegra_auto_hotplug_init(struct mutex *cpu_lock)
static struct dentry *hp_debugfs_root;
+struct pm_qos_request_list max_cpu_req;
+
static int hp_stats_show(struct seq_file *s, void *data)
{
int i;
@@ -427,6 +435,18 @@ static const struct file_operations hp_stats_fops = {
.release = single_release,
};
+static int max_cpus_get(void *data, u64 *val)
+{
+ *val = pm_qos_request(PM_QOS_MAX_ONLINE_CPUS);
+ return 0;
+}
+static int max_cpus_set(void *data, u64 val)
+{
+ pm_qos_update_request(&max_cpu_req, (s32)val);
+ return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(max_cpus_fops, max_cpus_get, max_cpus_set, "%llu\n");
+
static int __init tegra_auto_hotplug_debug_init(void)
{
if (!tegra3_cpu_lock)
@@ -436,6 +456,13 @@ static int __init tegra_auto_hotplug_debug_init(void)
if (!hp_debugfs_root)
return -ENOMEM;
+ pm_qos_add_request(&max_cpu_req, PM_QOS_MAX_ONLINE_CPUS,
+ PM_QOS_DEFAULT_VALUE);
+
+ if (!debugfs_create_file(
+ "max_cpus", S_IRUGO, hp_debugfs_root, NULL, &max_cpus_fops))
+ goto err_out;
+
if (!debugfs_create_file(
"stats", S_IRUGO, hp_debugfs_root, NULL, &hp_stats_fops))
goto err_out;
@@ -444,6 +471,7 @@ static int __init tegra_auto_hotplug_debug_init(void)
err_out:
debugfs_remove_recursive(hp_debugfs_root);
+ pm_qos_remove_request(&max_cpu_req);
return -ENOMEM;
}
@@ -455,5 +483,6 @@ void tegra_auto_hotplug_exit(void)
destroy_workqueue(hotplug_wq);
#ifdef CONFIG_DEBUG_FS
debugfs_remove_recursive(hp_debugfs_root);
+ pm_qos_remove_request(&max_cpu_req);
#endif
}