Merge branch 'pm-cpufreq'
authorRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 11 Sep 2015 13:37:25 +0000 (15:37 +0200)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Fri, 11 Sep 2015 13:37:25 +0000 (15:37 +0200)
* pm-cpufreq:
  intel_pstate: fix PCT_TO_HWP macro
  intel_pstate: Fix user input of min/max to legal policy region
  cpufreq-dt: add suspend frequency support
  cpufreq: allow cpufreq_generic_suspend() to work without suspend frequency
  cpufreq: Use __func__ to print function's name
  cpufreq: staticize cpufreq_cpu_get_raw()
  cpufreq: Add ARM_MT8173_CPUFREQ dependency on THERMAL
  cpufreq: dt: Tolerance applies on both sides of target voltage
  cpufreq: dt: Print error on failing to mark OPPs as shared
  cpufreq: dt: Check OPP count before marking them shared

1  2 
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/cpufreq.c
drivers/cpufreq/intel_pstate.c

index 77aa34eae92cbacf67e4027c6068a5551a0b83eb,360c5df552076a82485f1d50587c93d0aafee662..c4c6200be435674bfcfd86e796af2831874ed97c
@@@ -133,6 -133,7 +133,7 @@@ config ARM_KIRKWOOD_CPUFRE
  config ARM_MT8173_CPUFREQ
        bool "Mediatek MT8173 CPUFreq support"
        depends on ARCH_MEDIATEK && REGULATOR
+       depends on !CPU_THERMAL || THERMAL=y
        select PM_OPP
        help
          This adds the CPUFreq driver support for Mediatek MT8173 SoC.
@@@ -254,19 -255,12 +255,19 @@@ config ARM_SPEAR_CPUFRE
        help
          This adds the CPUFreq driver support for SPEAr SOCs.
  
 -config ARM_TEGRA_CPUFREQ
 -      bool "TEGRA CPUFreq support"
 +config ARM_TEGRA20_CPUFREQ
 +      bool "Tegra20 CPUFreq support"
        depends on ARCH_TEGRA
        default y
        help
 -        This adds the CPUFreq driver support for TEGRA SOCs.
 +        This adds the CPUFreq driver support for Tegra20 SOCs.
 +
 +config ARM_TEGRA124_CPUFREQ
 +      tristate "Tegra124 CPUFreq support"
 +      depends on ARCH_TEGRA && CPUFREQ_DT
 +      default y
 +      help
 +        This adds the CPUFreq driver support for Tegra124 SOCs.
  
  config ARM_PXA2xx_CPUFREQ
        tristate "Intel PXA2xx CPUfreq driver"
index b3d9368339af3530baa756441b347df3412a3b64,ca963336c262feb0a58e20ea0e58dca4bfc87ddc..6633b3fa996e06091089297f05e5bb710b995134
@@@ -239,7 -239,7 +239,7 @@@ int cpufreq_generic_init(struct cpufreq
  EXPORT_SYMBOL_GPL(cpufreq_generic_init);
  
  /* Only for cpufreq core internal use */
- struct cpufreq_policy *cpufreq_cpu_get_raw(unsigned int cpu)
+ static struct cpufreq_policy *cpufreq_cpu_get_raw(unsigned int cpu)
  {
        struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
  
@@@ -1445,13 -1445,13 +1445,13 @@@ static void cpufreq_offline_finish(unsi
   *
   * Removes the cpufreq interface for a CPU device.
   */
 -static int cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
 +static void cpufreq_remove_dev(struct device *dev, struct subsys_interface *sif)
  {
        unsigned int cpu = dev->id;
        struct cpufreq_policy *policy = per_cpu(cpufreq_cpu_data, cpu);
  
        if (!policy)
 -              return 0;
 +              return;
  
        if (cpu_online(cpu)) {
                cpufreq_offline_prepare(cpu);
  
        if (cpumask_empty(policy->real_cpus)) {
                cpufreq_policy_free(policy, true);
 -              return 0;
 +              return;
        }
  
        if (cpu != policy->kobj_cpu) {
                policy->kobj_cpu = new_cpu;
                WARN_ON(kobject_move(&policy->kobj, &new_dev->kobj));
        }
 -
 -      return 0;
  }
  
  static void handle_update(struct work_struct *work)
@@@ -1626,8 -1628,8 +1626,8 @@@ int cpufreq_generic_suspend(struct cpuf
        int ret;
  
        if (!policy->suspend_freq) {
-               pr_err("%s: suspend_freq can't be zero\n", __func__);
-               return -EINVAL;
+               pr_debug("%s: suspend_freq not defined\n", __func__);
+               return 0;
        }
  
        pr_debug("%s: Setting suspend-freq: %u\n", __func__,
@@@ -2031,8 -2033,7 +2031,7 @@@ static int __cpufreq_governor(struct cp
                if (!try_module_get(policy->governor->owner))
                        return -EINVAL;
  
-       pr_debug("__cpufreq_governor for CPU %u, event %u\n",
-                policy->cpu, event);
+       pr_debug("%s: for CPU %u, event %u\n", __func__, policy->cpu, event);
  
        mutex_lock(&cpufreq_governor_lock);
        if ((policy->governor_enabled && event == CPUFREQ_GOV_START)
index cddc61939a86a911f1792ba9eb89a955b55a24ce,27faee5f0e237990de3c532b1227b9b3ad01b603..3af9dd7332e6927d8dd860b5af410fba738bff4a
@@@ -260,24 -260,31 +260,31 @@@ static inline void update_turbo_state(v
                 cpu->pstate.max_pstate == cpu->pstate.turbo_pstate);
  }
  
- #define PCT_TO_HWP(x) (x * 255 / 100)
  static void intel_pstate_hwp_set(void)
  {
-       int min, max, cpu;
-       u64 value, freq;
+       int min, hw_min, max, hw_max, cpu, range, adj_range;
+       u64 value, cap;
+       rdmsrl(MSR_HWP_CAPABILITIES, cap);
+       hw_min = HWP_LOWEST_PERF(cap);
+       hw_max = HWP_HIGHEST_PERF(cap);
+       range = hw_max - hw_min;
  
        get_online_cpus();
  
        for_each_online_cpu(cpu) {
                rdmsrl_on_cpu(cpu, MSR_HWP_REQUEST, &value);
-               min = PCT_TO_HWP(limits.min_perf_pct);
+               adj_range = limits.min_perf_pct * range / 100;
+               min = hw_min + adj_range;
                value &= ~HWP_MIN_PERF(~0L);
                value |= HWP_MIN_PERF(min);
  
-               max = PCT_TO_HWP(limits.max_perf_pct);
+               adj_range = limits.max_perf_pct * range / 100;
+               max = hw_min + adj_range;
                if (limits.no_turbo) {
-                       rdmsrl( MSR_HWP_CAPABILITIES, freq);
-                       max = HWP_GUARANTEED_PERF(freq);
+                       hw_max = HWP_GUARANTEED_PERF(cap);
+                       if (hw_max < max)
+                               max = hw_max;
                }
  
                value &= ~HWP_MAX_PERF(~0L);
@@@ -423,6 -430,8 +430,8 @@@ static ssize_t store_max_perf_pct(struc
  
        limits.max_sysfs_pct = clamp_t(int, input, 0 , 100);
        limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct);
+       limits.max_perf_pct = max(limits.min_policy_pct, limits.max_perf_pct);
+       limits.max_perf_pct = max(limits.min_perf_pct, limits.max_perf_pct);
        limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100));
  
        if (hwp_active)
@@@ -442,6 -451,8 +451,8 @@@ static ssize_t store_min_perf_pct(struc
  
        limits.min_sysfs_pct = clamp_t(int, input, 0 , 100);
        limits.min_perf_pct = max(limits.min_policy_pct, limits.min_sysfs_pct);
+       limits.min_perf_pct = min(limits.max_policy_pct, limits.min_perf_pct);
+       limits.min_perf_pct = min(limits.max_perf_pct, limits.min_perf_pct);
        limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100));
  
        if (hwp_active)
@@@ -765,7 -776,7 +776,7 @@@ static inline void intel_pstate_sample(
        local_irq_save(flags);
        rdmsrl(MSR_IA32_APERF, aperf);
        rdmsrl(MSR_IA32_MPERF, mperf);
 -      tsc = native_read_tsc();
 +      tsc = rdtsc();
        local_irq_restore(flags);
  
        cpu->last_sample_time = cpu->sample.time;
@@@ -989,12 -1000,19 +1000,19 @@@ static int intel_pstate_set_policy(stru
  
        limits.min_policy_pct = (policy->min * 100) / policy->cpuinfo.max_freq;
        limits.min_policy_pct = clamp_t(int, limits.min_policy_pct, 0 , 100);
-       limits.min_perf_pct = max(limits.min_policy_pct, limits.min_sysfs_pct);
-       limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100));
        limits.max_policy_pct = (policy->max * 100) / policy->cpuinfo.max_freq;
        limits.max_policy_pct = clamp_t(int, limits.max_policy_pct, 0 , 100);
+       /* Normalize user input to [min_policy_pct, max_policy_pct] */
+       limits.min_perf_pct = max(limits.min_policy_pct, limits.min_sysfs_pct);
+       limits.min_perf_pct = min(limits.max_policy_pct, limits.min_perf_pct);
        limits.max_perf_pct = min(limits.max_policy_pct, limits.max_sysfs_pct);
+       limits.max_perf_pct = max(limits.min_policy_pct, limits.max_perf_pct);
+       /* Make sure min_perf_pct <= max_perf_pct */
+       limits.min_perf_pct = min(limits.max_perf_pct, limits.min_perf_pct);
+       limits.min_perf = div_fp(int_tofp(limits.min_perf_pct), int_tofp(100));
        limits.max_perf = div_fp(int_tofp(limits.max_perf_pct), int_tofp(100));
  
        if (hwp_active)