cpufreq: arm_big_little: Add dt node parsing for cooling device properties
authorChanwoo Choi <cw00.choi@samsung.com>
Fri, 17 Apr 2015 08:29:01 +0000 (17:29 +0900)
committerSeung-Woo Kim <sw0312.kim@samsung.com>
Wed, 14 Dec 2016 04:43:01 +0000 (13:43 +0900)
This patch adds the devicetree node to create the cpufreq cooling device
which is used as cooling device for thermal frameowrk.

Cc: Viresh Kumar <viresh.kumar@linaro.org>
Cc: Eduardo Valentin <edubezval@gmail.com>
Signed-off-by: Chanwoo Choi <cw00.choi@samsung.com>
drivers/cpufreq/Kconfig.arm
drivers/cpufreq/arm_big_little.c
drivers/cpufreq/arm_big_little.h

index 49f2d6e..4017d0e 100644 (file)
@@ -6,6 +6,8 @@
 config ARM_BIG_LITTLE_CPUFREQ
        tristate "Generic ARM big LITTLE CPUfreq driver"
        depends on ((ARM && ARM_CPU_TOPOLOGY) || (ARM64 && SMP)) && BIG_LITTLE && HAVE_CLK
+       # if CPU_THERMAL is on and THERMAL=m, ARM_BIG_LITTLE_CPUFREQ cannot be =y:
+       depends on !CPU_THERMAL || THERMAL
        select PM_OPP
        help
          This enables the Generic CPUfreq driver for ARM big.LITTLE platforms.
index e1a6ba6..12ef227 100644 (file)
@@ -31,6 +31,7 @@
 #include <linux/slab.h>
 #include <linux/topology.h>
 #include <linux/types.h>
+#include <linux/cpu_cooling.h>
 #include <asm/bL_switcher.h>
 
 #include "arm_big_little.h"
@@ -430,6 +431,7 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy)
 {
        u32 cur_cluster = cpu_to_cluster(policy->cpu);
        struct device *cpu_dev;
+       struct private_data *priv;
        int ret;
 
        cpu_dev = get_cpu_device(policy->cpu);
@@ -439,6 +441,12 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy)
                return -ENODEV;
        }
 
+       priv = devm_kzalloc(cpu_dev, sizeof(*priv), GFP_KERNEL);
+       if (!priv)
+               return -ENOMEM;
+       priv->cpu_dev = cpu_dev;
+       policy->driver_data = priv;
+
        ret = get_cluster_clk_and_freq_table(cpu_dev);
        if (ret)
                return ret;
@@ -493,6 +501,25 @@ static int bL_cpufreq_exit(struct cpufreq_policy *policy)
        return 0;
 }
 
+static void bL_cpufreq_ready(struct cpufreq_policy *policy)
+{
+       struct private_data *priv = policy->driver_data;
+       struct device_node *np = of_node_get(priv->cpu_dev->of_node);
+
+       if (of_find_property(np, "#cooling-cells", NULL)) {
+               priv->cdev = of_cpufreq_cooling_register(np,
+                                                        policy->related_cpus);
+               if (IS_ERR(priv->cdev)) {
+                       dev_err(priv->cpu_dev,
+                               "running cpufreq without cooling device: %ld\n",
+                               PTR_ERR(priv->cdev));
+
+                       priv->cdev = NULL;
+               }
+       }
+       of_node_put(np);
+}
+
 static struct cpufreq_driver bL_cpufreq_driver = {
        .name                   = "arm-big-little",
        .flags                  = CPUFREQ_STICKY |
@@ -503,6 +530,7 @@ static struct cpufreq_driver bL_cpufreq_driver = {
        .get                    = bL_cpufreq_get_rate,
        .init                   = bL_cpufreq_init,
        .exit                   = bL_cpufreq_exit,
+       .ready                  = bL_cpufreq_ready,
        .attr                   = cpufreq_generic_attr,
 };
 
index a211f7d..fa24a75 100644 (file)
 #include <linux/cpufreq.h>
 #include <linux/device.h>
 #include <linux/types.h>
+#include <linux/thermal.h>
+
+struct private_data {
+       struct device *cpu_dev;
+       struct thermal_cooling_device *cdev;
+};
 
 struct cpufreq_arm_bL_ops {
        char name[CPUFREQ_NAME_LEN];