cpufreq: powerpc: macintosh: Switch to QoS requests for freq limits
authorViresh Kumar <viresh.kumar@linaro.org>
Tue, 23 Jul 2019 06:14:03 +0000 (11:44 +0530)
committerRafael J. Wysocki <rafael.j.wysocki@intel.com>
Mon, 26 Aug 2019 08:02:01 +0000 (10:02 +0200)
The cpufreq core now takes the min/max frequency constraints via QoS
requests and the CPUFREQ_ADJUST notifier shall get removed later on.

Switch over to using the QoS request for maximum frequency constraint
for windfarm_cpufreq_clamp driver.

Signed-off-by: Viresh Kumar <viresh.kumar@linaro.org>
[ rjw: Subject ]
Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com>
drivers/macintosh/windfarm_cpufreq_clamp.c

index 52fd5fc..705c620 100644 (file)
@@ -3,9 +3,11 @@
 #include <linux/errno.h>
 #include <linux/kernel.h>
 #include <linux/delay.h>
+#include <linux/pm_qos.h>
 #include <linux/slab.h>
 #include <linux/init.h>
 #include <linux/wait.h>
+#include <linux/cpu.h>
 #include <linux/cpufreq.h>
 
 #include <asm/prom.h>
 
 static int clamped;
 static struct wf_control *clamp_control;
-
-static int clamp_notifier_call(struct notifier_block *self,
-                              unsigned long event, void *data)
-{
-       struct cpufreq_policy *p = data;
-       unsigned long max_freq;
-
-       if (event != CPUFREQ_ADJUST)
-               return 0;
-
-       max_freq = clamped ? (p->cpuinfo.min_freq) : (p->cpuinfo.max_freq);
-       cpufreq_verify_within_limits(p, 0, max_freq);
-
-       return 0;
-}
-
-static struct notifier_block clamp_notifier = {
-       .notifier_call = clamp_notifier_call,
-};
+static struct dev_pm_qos_request qos_req;
+static unsigned int min_freq, max_freq;
 
 static int clamp_set(struct wf_control *ct, s32 value)
 {
-       if (value)
+       unsigned int freq;
+
+       if (value) {
+               freq = min_freq;
                printk(KERN_INFO "windfarm: Clamping CPU frequency to "
                       "minimum !\n");
-       else
+       } else {
+               freq = max_freq;
                printk(KERN_INFO "windfarm: CPU frequency unclamped !\n");
+       }
        clamped = value;
-       cpufreq_update_policy(0);
-       return 0;
+
+       return dev_pm_qos_update_request(&qos_req, freq);
 }
 
 static int clamp_get(struct wf_control *ct, s32 *value)
@@ -74,27 +64,60 @@ static const struct wf_control_ops clamp_ops = {
 
 static int __init wf_cpufreq_clamp_init(void)
 {
+       struct cpufreq_policy *policy;
        struct wf_control *clamp;
+       struct device *dev;
+       int ret;
+
+       policy = cpufreq_cpu_get(0);
+       if (!policy) {
+               pr_warn("%s: cpufreq policy not found cpu0\n", __func__);
+               return -EPROBE_DEFER;
+       }
+
+       min_freq = policy->cpuinfo.min_freq;
+       max_freq = policy->cpuinfo.max_freq;
+       cpufreq_cpu_put(policy);
+
+       dev = get_cpu_device(0);
+       if (unlikely(!dev)) {
+               pr_warn("%s: No cpu device for cpu0\n", __func__);
+               return -ENODEV;
+       }
 
        clamp = kmalloc(sizeof(struct wf_control), GFP_KERNEL);
        if (clamp == NULL)
                return -ENOMEM;
-       cpufreq_register_notifier(&clamp_notifier, CPUFREQ_POLICY_NOTIFIER);
+
+       ret = dev_pm_qos_add_request(dev, &qos_req, DEV_PM_QOS_MAX_FREQUENCY,
+                                    max_freq);
+       if (ret < 0) {
+               pr_err("%s: Failed to add freq constraint (%d)\n", __func__,
+                      ret);
+               goto free;
+       }
+
        clamp->ops = &clamp_ops;
        clamp->name = "cpufreq-clamp";
-       if (wf_register_control(clamp))
+       ret = wf_register_control(clamp);
+       if (ret)
                goto fail;
        clamp_control = clamp;
        return 0;
  fail:
+       dev_pm_qos_remove_request(&qos_req);
+
+ free:
        kfree(clamp);
-       return -ENODEV;
+       return ret;
 }
 
 static void __exit wf_cpufreq_clamp_exit(void)
 {
-       if (clamp_control)
+       if (clamp_control) {
                wf_unregister_control(clamp_control);
+               dev_pm_qos_remove_request(&qos_req);
+       }
 }