Merge tag 'pm-5.17-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm
authorLinus Torvalds <torvalds@linux-foundation.org>
Fri, 25 Feb 2022 20:17:20 +0000 (12:17 -0800)
committerLinus Torvalds <torvalds@linux-foundation.org>
Fri, 25 Feb 2022 20:17:20 +0000 (12:17 -0800)
Pull power management fixes from Rafael Wysocki:
 "Fix the throttle IRQ handling during cpufreq initialization on
  Qualcomm platforms (Bjorn Andersson)"

* tag 'pm-5.17-rc6' of git://git.kernel.org/pub/scm/linux/kernel/git/rafael/linux-pm:
  cpufreq: qcom-hw: Delay enabling throttle_irq
  cpufreq: Reintroduce ready() callback

Documentation/cpu-freq/cpu-drivers.rst
Documentation/translations/zh_CN/cpu-freq/cpu-drivers.rst
drivers/cpufreq/cpufreq.c
drivers/cpufreq/qcom-cpufreq-hw.c
include/linux/cpufreq.h

index 3b32336..d84eded 100644 (file)
@@ -75,6 +75,9 @@ And optionally
  .resume - A pointer to a per-policy resume function which is called
  with interrupts disabled and _before_ the governor is started again.
 
+ .ready - A pointer to a per-policy ready function which is called after
+ the policy is fully initialized.
+
  .attr - A pointer to a NULL-terminated list of "struct freq_attr" which
  allow to export values to sysfs.
 
index 87a3604..2ca9204 100644 (file)
@@ -84,6 +84,8 @@ CPUfreq核心层注册一个cpufreq_driver结构体。
  .resume - 一个指向per-policy恢复函数的指针,该函数在关中断且在调节器再一次启动前被
  调用。
 
+ .ready - 一个指向per-policy准备函数的指针,该函数在策略完全初始化之后被调用。
+
  .attr - 一个指向NULL结尾的"struct freq_attr"列表的指针,该列表允许导出值到
  sysfs。
 
index b8d9553..80f535c 100644 (file)
@@ -1518,6 +1518,10 @@ static int cpufreq_online(unsigned int cpu)
 
        kobject_uevent(&policy->kobj, KOBJ_ADD);
 
+       /* Callback for handling stuff after policy is ready */
+       if (cpufreq_driver->ready)
+               cpufreq_driver->ready(policy);
+
        if (cpufreq_thermal_control_enabled(cpufreq_driver))
                policy->cdev = of_cpufreq_cooling_register(policy);
 
index 05f3d78..effbb68 100644 (file)
@@ -388,7 +388,7 @@ static int qcom_cpufreq_hw_lmh_init(struct cpufreq_policy *policy, int index)
 
        snprintf(data->irq_name, sizeof(data->irq_name), "dcvsh-irq-%u", policy->cpu);
        ret = request_threaded_irq(data->throttle_irq, NULL, qcom_lmh_dcvs_handle_irq,
-                                  IRQF_ONESHOT, data->irq_name, data);
+                                  IRQF_ONESHOT | IRQF_NO_AUTOEN, data->irq_name, data);
        if (ret) {
                dev_err(&pdev->dev, "Error registering %s: %d\n", data->irq_name, ret);
                return 0;
@@ -542,6 +542,14 @@ static int qcom_cpufreq_hw_cpu_exit(struct cpufreq_policy *policy)
        return 0;
 }
 
+static void qcom_cpufreq_ready(struct cpufreq_policy *policy)
+{
+       struct qcom_cpufreq_data *data = policy->driver_data;
+
+       if (data->throttle_irq >= 0)
+               enable_irq(data->throttle_irq);
+}
+
 static struct freq_attr *qcom_cpufreq_hw_attr[] = {
        &cpufreq_freq_attr_scaling_available_freqs,
        &cpufreq_freq_attr_scaling_boost_freqs,
@@ -561,6 +569,7 @@ static struct cpufreq_driver cpufreq_qcom_hw_driver = {
        .fast_switch    = qcom_cpufreq_hw_fast_switch,
        .name           = "qcom-cpufreq-hw",
        .attr           = qcom_cpufreq_hw_attr,
+       .ready          = qcom_cpufreq_ready,
 };
 
 static int qcom_cpufreq_hw_driver_probe(struct platform_device *pdev)
index 1ab29e6..3522a27 100644 (file)
@@ -382,6 +382,9 @@ struct cpufreq_driver {
        int             (*suspend)(struct cpufreq_policy *policy);
        int             (*resume)(struct cpufreq_policy *policy);
 
+       /* Will be called after the driver is fully initialized */
+       void            (*ready)(struct cpufreq_policy *policy);
+
        struct freq_attr **attr;
 
        /* platform specific boost support code */