If in doubt, say N.
 
-# Note that it is not currently possible to set the other governors (such as ondemand)
-# as the default, since if they fail to initialise, cpufreq will be
-# left in an undefined state.
-
 choice
        prompt "Default CPUFreq governor"
        default CPU_FREQ_DEFAULT_GOV_USERSPACE if CPU_FREQ_SA1100 || CPU_FREQ_SA1110
          program shall be able to set the CPU dynamically without having
          to enable the userspace governor manually.
 
+config CPU_FREQ_DEFAULT_GOV_ONDEMAND
+       bool "ondemand"
+       select CPU_FREQ_GOV_ONDEMAND
+       select CPU_FREQ_GOV_PERFORMANCE
+       help
+         Use the CPUFreq governor 'ondemand' as default. This allows
+         you to get a full dynamic frequency capable system by simply
+         loading your cpufreq low-level hardware driver.
+         Be aware that not all cpufreq drivers support the ondemand
+         governor. If unsure have a look at the help section of the
+         driver. Fallback governor will be the performance governor.
+
+config CPU_FREQ_DEFAULT_GOV_CONSERVATIVE
+       bool "conservative"
+       select CPU_FREQ_GOV_CONSERVATIVE
+       select CPU_FREQ_GOV_PERFORMANCE
+       help
+         Use the CPUFreq governor 'conservative' as default. This allows
+         you to get a full dynamic frequency capable system by simply
+         loading your cpufreq low-level hardware driver.
+         Be aware that not all cpufreq drivers support the conservative
+         governor. If unsure have a look at the help section of the
+         driver. Fallback governor will be the performance governor.
 endchoice
 
 config CPU_FREQ_GOV_PERFORMANCE
 
                                        unsigned int event)
 {
        int ret;
+       struct cpufreq_governor *gov = CPUFREQ_PERFORMANCE_GOVERNOR;
+
+       if (policy->governor->max_transition_latency &&
+           policy->cpuinfo.transition_latency >
+           policy->governor->max_transition_latency) {
+               printk(KERN_WARNING "%s governor failed, too long"
+                      " transition latency of HW, fallback"
+                      " to %s governor\n",
+                      policy->governor->name,
+                      gov->name);
+                      policy->governor = gov;
+       }
 
        if (!try_module_get(policy->governor->owner))
                return -EINVAL;
 
 #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER   (1000)
 #define DEF_SAMPLING_DOWN_FACTOR               (1)
 #define MAX_SAMPLING_DOWN_FACTOR               (10)
-#define TRANSITION_LATENCY_LIMIT               (10 * 1000)
+#define TRANSITION_LATENCY_LIMIT               (10 * 1000 * 1000)
 
 static void do_dbs_timer(struct work_struct *work);
 
                    (!policy->cur))
                        return -EINVAL;
 
-               if (policy->cpuinfo.transition_latency >
-                               (TRANSITION_LATENCY_LIMIT * 1000))
-                       return -EINVAL;
                if (this_dbs_info->enable) /* Already enabled */
                        break;
                 
        return 0;
 }
 
-static struct cpufreq_governor cpufreq_gov_dbs = {
-       .name           = "conservative",
-       .governor       = cpufreq_governor_dbs,
-       .owner          = THIS_MODULE,
+struct cpufreq_governor cpufreq_gov_conservative = {
+       .name                   = "conservative",
+       .governor               = cpufreq_governor_dbs,
+       .max_transition_latency = TRANSITION_LATENCY_LIMIT,
+       .owner                  = THIS_MODULE,
 };
+EXPORT_SYMBOL(cpufreq_gov_conservative);
 
 static int __init cpufreq_gov_dbs_init(void)
 {
-       return cpufreq_register_governor(&cpufreq_gov_dbs);
+       return cpufreq_register_governor(&cpufreq_gov_conservative);
 }
 
 static void __exit cpufreq_gov_dbs_exit(void)
        /* Make sure that the scheduled work is indeed not running */
        flush_scheduled_work();
 
-       cpufreq_unregister_governor(&cpufreq_gov_dbs);
+       cpufreq_unregister_governor(&cpufreq_gov_conservative);
 }
 
 
 
                        (def_sampling_rate / MIN_SAMPLING_RATE_RATIO)
 #define MAX_SAMPLING_RATE                      (500 * def_sampling_rate)
 #define DEF_SAMPLING_RATE_LATENCY_MULTIPLIER   (1000)
-#define TRANSITION_LATENCY_LIMIT               (10 * 1000)
+#define TRANSITION_LATENCY_LIMIT               (10 * 1000 * 1000)
 
 static void do_dbs_timer(struct work_struct *work);
 
                if ((!cpu_online(cpu)) || (!policy->cur))
                        return -EINVAL;
 
-               if (policy->cpuinfo.transition_latency >
-                               (TRANSITION_LATENCY_LIMIT * 1000)) {
-                       printk(KERN_WARNING "ondemand governor failed to load "
-                              "due to too long transition latency\n");
-                       return -EINVAL;
-               }
                if (this_dbs_info->enable) /* Already enabled */
                        break;
 
        return 0;
 }
 
-static struct cpufreq_governor cpufreq_gov_dbs = {
-       .name = "ondemand",
-       .governor = cpufreq_governor_dbs,
-       .owner = THIS_MODULE,
+struct cpufreq_governor cpufreq_gov_ondemand = {
+       .name                   = "ondemand",
+       .governor               = cpufreq_governor_dbs,
+       .max_transition_latency = TRANSITION_LATENCY_LIMIT,
+       .owner                  = THIS_MODULE,
 };
+EXPORT_SYMBOL(cpufreq_gov_ondemand);
 
 static int __init cpufreq_gov_dbs_init(void)
 {
                printk(KERN_ERR "Creation of kondemand failed\n");
                return -EFAULT;
        }
-       return cpufreq_register_governor(&cpufreq_gov_dbs);
+       return cpufreq_register_governor(&cpufreq_gov_ondemand);
 }
 
 static void __exit cpufreq_gov_dbs_exit(void)
 {
-       cpufreq_unregister_governor(&cpufreq_gov_dbs);
+       cpufreq_unregister_governor(&cpufreq_gov_ondemand);
        destroy_workqueue(kondemand_wq);
 }
 
 
        char    name[CPUFREQ_NAME_LEN];
        int     (*governor)     (struct cpufreq_policy *policy,
                                 unsigned int event);
+       unsigned int max_transition_latency; /* HW must be able to switch to
+                       next freq faster than this value in nano secs or we
+                       will fallback to performance governor */
        struct list_head        governor_list;
        struct module           *owner;
 };
  *********************************************************************/
 
 
-#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE
+/*
+  Performance governor is fallback governor if any other gov failed to
+  auto load due latency restrictions
+*/
 extern struct cpufreq_governor cpufreq_gov_performance;
-#define CPUFREQ_DEFAULT_GOVERNOR       &cpufreq_gov_performance
+#define CPUFREQ_PERFORMANCE_GOVERNOR   (&cpufreq_gov_performance)
+#ifdef CONFIG_CPU_FREQ_DEFAULT_GOV_PERFORMANCE
+#define CPUFREQ_DEFAULT_GOVERNOR       (&cpufreq_gov_performance)
 #elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_USERSPACE)
 extern struct cpufreq_governor cpufreq_gov_userspace;
-#define CPUFREQ_DEFAULT_GOVERNOR       &cpufreq_gov_userspace
+#define CPUFREQ_DEFAULT_GOVERNOR       (&cpufreq_gov_userspace)
+#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_ONDEMAND)
+extern struct cpufreq_governor cpufreq_gov_ondemand;
+#define CPUFREQ_DEFAULT_GOVERNOR       (&cpufreq_gov_ondemand)
+#elif defined(CONFIG_CPU_FREQ_DEFAULT_GOV_CONSERVATIVE)
+extern struct cpufreq_governor cpufreq_gov_conservative;
+#define CPUFREQ_DEFAULT_GOVERNOR       (&cpufreq_gov_conservative)
 #endif