Merge branch 'upstream' of git://git.infradead.org/users/pcmoore/audit
[firefly-linux-kernel-4.4.55.git] / drivers / cpufreq / cpufreq-dt.c
index c3583cdfadbdf2704e0a8a1e83d9e74324940a6e..90d64081ddb34ee8ba7a06372a269defdcf07a97 100644 (file)
@@ -196,6 +196,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
        struct device *cpu_dev;
        struct regulator *cpu_reg;
        struct clk *cpu_clk;
+       struct dev_pm_opp *suspend_opp;
        unsigned long min_uV = ~0, max_uV = 0;
        unsigned int transition_latency;
        bool need_update = false;
@@ -215,7 +216,7 @@ static int cpufreq_init(struct cpufreq_policy *policy)
        }
 
        /* Get OPP-sharing information from "operating-points-v2" bindings */
-       ret = of_get_cpus_sharing_opps(cpu_dev, policy->cpus);
+       ret = dev_pm_opp_of_get_sharing_cpus(cpu_dev, policy->cpus);
        if (ret) {
                /*
                 * operating-points-v2 not supported, fallback to old method of
@@ -237,7 +238,18 @@ static int cpufreq_init(struct cpufreq_policy *policy)
         *
         * OPPs might be populated at runtime, don't check for error here
         */
-       of_cpumask_init_opp_table(policy->cpus);
+       dev_pm_opp_of_cpumask_add_table(policy->cpus);
+
+       /*
+        * But we need OPP table to function so if it is not there let's
+        * give platform code chance to provide it for us.
+        */
+       ret = dev_pm_opp_get_opp_count(cpu_dev);
+       if (ret <= 0) {
+               pr_debug("OPP table is not ready, deferring probe\n");
+               ret = -EPROBE_DEFER;
+               goto out_free_opp;
+       }
 
        if (need_update) {
                struct cpufreq_dt_platform_data *pd = cpufreq_get_driver_data();
@@ -249,24 +261,16 @@ static int cpufreq_init(struct cpufreq_policy *policy)
                 * OPP tables are initialized only for policy->cpu, do it for
                 * others as well.
                 */
-               set_cpus_sharing_opps(cpu_dev, policy->cpus);
+               ret = dev_pm_opp_set_sharing_cpus(cpu_dev, policy->cpus);
+               if (ret)
+                       dev_err(cpu_dev, "%s: failed to mark OPPs as shared: %d\n",
+                               __func__, ret);
 
                of_property_read_u32(np, "clock-latency", &transition_latency);
        } else {
                transition_latency = dev_pm_opp_get_max_clock_latency(cpu_dev);
        }
 
-       /*
-        * But we need OPP table to function so if it is not there let's
-        * give platform code chance to provide it for us.
-        */
-       ret = dev_pm_opp_get_opp_count(cpu_dev);
-       if (ret <= 0) {
-               pr_debug("OPP table is not ready, deferring probe\n");
-               ret = -EPROBE_DEFER;
-               goto out_free_opp;
-       }
-
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv) {
                ret = -ENOMEM;
@@ -300,7 +304,8 @@ static int cpufreq_init(struct cpufreq_policy *policy)
                        rcu_read_unlock();
 
                        tol_uV = opp_uV * priv->voltage_tolerance / 100;
-                       if (regulator_is_supported_voltage(cpu_reg, opp_uV,
+                       if (regulator_is_supported_voltage(cpu_reg,
+                                                          opp_uV - tol_uV,
                                                           opp_uV + tol_uV)) {
                                if (opp_uV < min_uV)
                                        min_uV = opp_uV;
@@ -329,6 +334,13 @@ static int cpufreq_init(struct cpufreq_policy *policy)
        policy->driver_data = priv;
 
        policy->clk = cpu_clk;
+
+       rcu_read_lock();
+       suspend_opp = dev_pm_opp_get_suspend_opp(cpu_dev);
+       if (suspend_opp)
+               policy->suspend_freq = dev_pm_opp_get_freq(suspend_opp) / 1000;
+       rcu_read_unlock();
+
        ret = cpufreq_table_validate_and_show(policy, freq_table);
        if (ret) {
                dev_err(cpu_dev, "%s: invalid frequency table: %d\n", __func__,
@@ -356,7 +368,7 @@ out_free_cpufreq_table:
 out_free_priv:
        kfree(priv);
 out_free_opp:
-       of_cpumask_free_opp_table(policy->cpus);
+       dev_pm_opp_of_cpumask_remove_table(policy->cpus);
 out_node_put:
        of_node_put(np);
 out_put_reg_clk:
@@ -373,7 +385,7 @@ static int cpufreq_exit(struct cpufreq_policy *policy)
 
        cpufreq_cooling_unregister(priv->cdev);
        dev_pm_opp_free_cpufreq_table(priv->cpu_dev, &policy->freq_table);
-       of_cpumask_free_opp_table(policy->related_cpus);
+       dev_pm_opp_of_cpumask_remove_table(policy->related_cpus);
        clk_put(policy->clk);
        if (!IS_ERR(priv->cpu_reg))
                regulator_put(priv->cpu_reg);
@@ -419,6 +431,7 @@ static struct cpufreq_driver dt_cpufreq_driver = {
        .ready = cpufreq_ready,
        .name = "cpufreq-dt",
        .attr = cpufreq_dt_attr,
+       .suspend = cpufreq_generic_suspend,
 };
 
 static int dt_cpufreq_probe(struct platform_device *pdev)