Merge commit 'main-jb-2012.08.03-B4' into t114-0806
[linux-2.6.git] / arch / arm / mach-tegra / cpu-tegra3.c
index 830a664..46e73d8 100644 (file)
@@ -3,7 +3,7 @@
  *
  * CPU auto-hotplug for Tegra3 CPUs
  *
- * Copyright (c) 2011-2012, NVIDIA Corporation.
+ * Copyright (c) 2011-2012, NVIDIA Corporation. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License as published by
@@ -41,7 +41,7 @@
 #define INITIAL_STATE          TEGRA_HP_DISABLED
 #define UP2G0_DELAY_MS         70
 #define UP2Gn_DELAY_MS         100
-#define DOWN_DELAY_MS          500
+#define DOWN_DELAY_MS          2000
 
 static struct mutex *tegra3_cpu_lock;
 
@@ -189,10 +189,38 @@ enum {
 };
 
 #define NR_FSHIFT      2
-static unsigned int nr_run_thresholds[] = {
+
+static unsigned int rt_profile_sel;
+
+/* avg run threads * 4 (e.g., 9 = 2.25 threads) */
+
+static unsigned int rt_profile_default[] = {
 /*      1,  2,  3,  4 - on-line cpus target */
-       5,  9, 10, UINT_MAX /* avg run threads * 4 (e.g., 9 = 2.25 threads) */
+       5,  9, 10, UINT_MAX
+};
+
+static unsigned int rt_profile_1[] = {
+/*      1,  2,  3,  4 - on-line cpus target */
+       8,  9, 10, UINT_MAX
+};
+
+static unsigned int rt_profile_2[] = {
+/*      1,  2,  3,  4 - on-line cpus target */
+       5,  13, 14, UINT_MAX
+};
+
+static unsigned int rt_profile_off[] = { /* disables runable thread */
+       0,  0,  0, UINT_MAX
+};
+
+static unsigned int *rt_profiles[] = {
+       rt_profile_default,
+       rt_profile_1,
+       rt_profile_2,
+       rt_profile_off
 };
+
+
 static unsigned int nr_run_hysteresis = 2;     /* 0.5 thread */
 static unsigned int nr_run_last;
 
@@ -216,8 +244,10 @@ static noinline int tegra_cpu_speed_balance(void)
         * TEGRA_CPU_SPEED_BIASED to keep CPU core composition unchanged
         * TEGRA_CPU_SPEED_SKEWED to remove CPU core off-line
         */
-       for (nr_run = 1; nr_run < ARRAY_SIZE(nr_run_thresholds); nr_run++) {
-               unsigned int nr_threshold = nr_run_thresholds[nr_run - 1];
+
+       unsigned int *current_profile = rt_profiles[rt_profile_sel];
+       for (nr_run = 1; nr_run < ARRAY_SIZE(rt_profile_default); nr_run++) {
+               unsigned int nr_threshold = current_profile[nr_run - 1];
                if (nr_run_last <= nr_run)
                        nr_threshold += nr_run_hysteresis;
                if (avg_nr_run <= (nr_threshold << (FSHIFT - NR_FSHIFT)))
@@ -527,6 +557,25 @@ static const struct file_operations hp_stats_fops = {
        .release        = single_release,
 };
 
+static int rt_bias_get(void *data, u64 *val)
+{
+       *val = rt_profile_sel;
+       return 0;
+}
+static int rt_bias_set(void *data, u64 val)
+{
+       if (val < ARRAY_SIZE(rt_profiles))
+               rt_profile_sel = (u32)val;
+
+       pr_debug("rt_profile_sel set to %d\nthresholds are now [%d, %d, %d]\n",
+               rt_profile_sel,
+               rt_profiles[rt_profile_sel][0],
+               rt_profiles[rt_profile_sel][1],
+               rt_profiles[rt_profile_sel][2]);
+       return 0;
+}
+DEFINE_SIMPLE_ATTRIBUTE(rt_bias_fops, rt_bias_get, rt_bias_set, "%llu\n");
+
 static int min_cpus_get(void *data, u64 *val)
 {
        *val = pm_qos_request(PM_QOS_MIN_ONLINE_CPUS);
@@ -577,6 +626,10 @@ static int __init tegra_auto_hotplug_debug_init(void)
                "stats", S_IRUGO, hp_debugfs_root, NULL, &hp_stats_fops))
                goto err_out;
 
+       if (!debugfs_create_file(
+               "core_bias", S_IRUGO, hp_debugfs_root, NULL, &rt_bias_fops))
+               goto err_out;
+
        return 0;
 
 err_out: