cpufreq: qcom-hw: Fix cpufreq_driver->get() for non-LMH systems
authorDouglas Anderson <dianders@chromium.org>
Thu, 2 Feb 2023 22:00:23 +0000 (14:00 -0800)
committerViresh Kumar <viresh.kumar@linaro.org>
Mon, 6 Feb 2023 04:01:38 +0000 (09:31 +0530)
On a sc7180-based Chromebook, when I go to
/sys/devices/system/cpu/cpu0/cpufreq I can see:

  cpuinfo_cur_freq:2995200
  cpuinfo_max_freq:1804800
  scaling_available_frequencies:300000 576000 ... 1708800 1804800
  scaling_cur_freq:1804800
  scaling_max_freq:1804800

As you can see the `cpuinfo_cur_freq` is bogus. It turns out that this
bogus info started showing up as of commit c72cf0cb1d77 ("cpufreq:
qcom-hw: Fix the frequency returned by cpufreq_driver->get()"). That
commit seems to assume that everyone is on the LMH bandwagon, but
sc7180 isn't.

Let's go back to the old code in the case where LMH isn't used.

Fixes: c72cf0cb1d77 ("cpufreq: qcom-hw: Fix the frequency returned by cpufreq_driver->get()")
Signed-off-by: Douglas Anderson <dianders@chromium.org>
Reviewed-by: Konrad Dybcio <konrad.dybcio@linaro.org>
Reviewed-by: Manivannan Sadhasivam <mani@kernel.org>
[ Viresh: Fixed the 'fixes' tag ]
Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
drivers/cpufreq/qcom-cpufreq-hw.c

index 340fed3..39a8702 100644 (file)
@@ -143,40 +143,42 @@ static unsigned long qcom_lmh_get_throttle_freq(struct qcom_cpufreq_data *data)
        return lval * xo_rate;
 }
 
-/* Get the current frequency of the CPU (after throttling) */
-static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
+/* Get the frequency requested by the cpufreq core for the CPU */
+static unsigned int qcom_cpufreq_get_freq(unsigned int cpu)
 {
        struct qcom_cpufreq_data *data;
+       const struct qcom_cpufreq_soc_data *soc_data;
        struct cpufreq_policy *policy;
+       unsigned int index;
 
        policy = cpufreq_cpu_get_raw(cpu);
        if (!policy)
                return 0;
 
        data = policy->driver_data;
+       soc_data = qcom_cpufreq.soc_data;
 
-       return qcom_lmh_get_throttle_freq(data) / HZ_PER_KHZ;
+       index = readl_relaxed(data->base + soc_data->reg_perf_state);
+       index = min(index, LUT_MAX_ENTRIES - 1);
+
+       return policy->freq_table[index].frequency;
 }
 
-/* Get the frequency requested by the cpufreq core for the CPU */
-static unsigned int qcom_cpufreq_get_freq(unsigned int cpu)
+static unsigned int qcom_cpufreq_hw_get(unsigned int cpu)
 {
        struct qcom_cpufreq_data *data;
-       const struct qcom_cpufreq_soc_data *soc_data;
        struct cpufreq_policy *policy;
-       unsigned int index;
 
        policy = cpufreq_cpu_get_raw(cpu);
        if (!policy)
                return 0;
 
        data = policy->driver_data;
-       soc_data = qcom_cpufreq.soc_data;
 
-       index = readl_relaxed(data->base + soc_data->reg_perf_state);
-       index = min(index, LUT_MAX_ENTRIES - 1);
+       if (data->throttle_irq >= 0)
+               return qcom_lmh_get_throttle_freq(data) / HZ_PER_KHZ;
 
-       return policy->freq_table[index].frequency;
+       return qcom_cpufreq_get_freq(cpu);
 }
 
 static unsigned int qcom_cpufreq_hw_fast_switch(struct cpufreq_policy *policy,