In addition to clocks and regulators, some devices can scale the bandwidth
of their on-chip interconnect - for example between CPU and DDR memory. Add
support for that, so that platforms which support it can make use of it.

Signed-off-by: Georgi Djakov <georgi.dja...@linaro.org>
---
 drivers/cpufreq/cpufreq-dt.c | 27 ++++++++++++++++++++++++++-
 1 file changed, 26 insertions(+), 1 deletion(-)

diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c
index e58bfcb1169e..30fed0fc266d 100644
--- a/drivers/cpufreq/cpufreq-dt.c
+++ b/drivers/cpufreq/cpufreq-dt.c
@@ -17,6 +17,7 @@
 #include <linux/cpufreq.h>
 #include <linux/cpumask.h>
 #include <linux/err.h>
+#include <linux/interconnect.h>
 #include <linux/module.h>
 #include <linux/of.h>
 #include <linux/pm_opp.h>
@@ -100,6 +101,7 @@ static int resources_available(void)
        struct device *cpu_dev;
        struct regulator *cpu_reg;
        struct clk *cpu_clk;
+       struct icc_path *cpu_path;
        int ret = 0;
        const char *name;
 
@@ -126,6 +128,19 @@ static int resources_available(void)
 
        clk_put(cpu_clk);
 
+       cpu_path = of_icc_get(cpu_dev, NULL);
+       ret = PTR_ERR_OR_ZERO(cpu_path);
+       if (ret) {
+               if (ret == -EPROBE_DEFER)
+                       dev_dbg(cpu_dev, "defer icc path: %d\n", ret);
+               else
+                       dev_err(cpu_dev, "failed to get icc path: %d\n", ret);
+
+               return ret;
+       }
+
+       icc_put(cpu_path);
+
        name = find_supply_name(cpu_dev);
        /* Platform doesn't require regulator */
        if (!name)
@@ -205,10 +220,18 @@ static int cpufreq_init(struct cpufreq_policy *policy)
                }
        }
 
+       opp_table = dev_pm_opp_set_path(cpu_dev, NULL);
+       if (IS_ERR(opp_table)) {
+               ret = PTR_ERR(opp_table);
+               dev_err(cpu_dev, "Failed to set interconnect path for cpu%d: 
%d\n",
+                       policy->cpu, ret);
+               goto out_put_regulator;
+       }
+
        priv = kzalloc(sizeof(*priv), GFP_KERNEL);
        if (!priv) {
                ret = -ENOMEM;
-               goto out_put_regulator;
+               goto out_put_path;
        }
 
        priv->reg_name = name;
@@ -288,6 +311,8 @@ static int cpufreq_init(struct cpufreq_policy *policy)
        if (priv->have_static_opps)
                dev_pm_opp_of_cpumask_remove_table(policy->cpus);
        kfree(priv);
+out_put_path:
+       dev_pm_opp_put_path(opp_table);
 out_put_regulator:
        if (name)
                dev_pm_opp_put_regulators(opp_table);

Reply via email to