From 85fffe91bb385e4d77afbba18f04c8b8770bf8a8 Mon Sep 17 00:00:00 2001 From: Alex Frid Date: Fri, 16 Dec 2011 18:07:33 -0800 Subject: ARM: tegra: power: Limit maximum online cpus number Updated Tegra3 auto-hotplug mechanism to keep maximum number of online cpus within the limit specified by the PM QoS parameter PM_QOS_MAX_ONLINE_CPUS. Added respective debugfs node /kernel/debug/tegra_hotplug/max_cpus. Bug 894200 Change-Id: I278cbfd91a1760b282eab186aa21883918b13800 Signed-off-by: Alex Frid Reviewed-on: http://git-master/r/71035 Reviewed-by: Automatic_Commit_Validation_User Reviewed-by: Antti Miettinen Reviewed-by: Diwakar Tundlam Reviewed-by: Yu-Huan Hsu Reviewed-by: Scott Williams --- arch/arm/mach-tegra/cpu-tegra3.c | 35 ++++++++++++++++++++++++++++++++--- 1 file changed, 32 insertions(+), 3 deletions(-) (limited to 'arch/arm/mach-tegra/cpu-tegra3.c') 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 #include #include +#include #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 } -- cgit v1.2.3