Re: [PATCH v5 3/3] cpufreq: arm_big_little: Add support to register a cpufreq cooling device
Viresh Kumar writes: > On 17-11-15, 12:06, Punit Agrawal wrote: >> Register passive cooling devices when initialising cpufreq on >> big.LITTLE systems. If the device tree provides a dynamic power >> coefficient for the CPUs then the bound cooling device will support >> the extensions that allow it to be used with all the existing thermal >> governors including the power allocator governor. >> >> A cooling device will be created per individual frequency domain and >> can be bound to thermal zones via the thermal DT bindings. >> >> Signed-off-by: Punit Agrawal >> Cc: Viresh Kumar >> Cc: Sudeep Holla >> Cc: Eduardo Valentin >> --- >> drivers/cpufreq/Kconfig.arm | 2 ++ >> drivers/cpufreq/arm_big_little.c | 41 >> >> 2 files changed, 43 insertions(+) >> >> diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm >> index 1582c1c..0e0052e 100644 >> --- a/drivers/cpufreq/Kconfig.arm >> +++ b/drivers/cpufreq/Kconfig.arm >> @@ -6,6 +6,8 @@ >> config ARM_BIG_LITTLE_CPUFREQ >> tristate "Generic ARM big LITTLE CPUfreq driver" >> depends on (ARM_CPU_TOPOLOGY || ARM64) && HAVE_CLK >> +# if CPU_THERMAL is on and THERMAL=m, ARM_BIT_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. >> diff --git a/drivers/cpufreq/arm_big_little.c >> b/drivers/cpufreq/arm_big_little.c >> index c5d256c..c251247 100644 >> --- a/drivers/cpufreq/arm_big_little.c >> +++ b/drivers/cpufreq/arm_big_little.c >> @@ -23,6 +23,7 @@ >> #include >> #include >> #include >> +#include >> #include >> #include >> #include >> @@ -55,6 +56,7 @@ static bool bL_switching_enabled; >> #define ACTUAL_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq << 1 : >> freq) >> #define VIRT_FREQ(cluster, freq)((cluster == A7_CLUSTER) ? freq >> 1 : >> freq) >> >> +static struct thermal_cooling_device *cdev[MAX_CLUSTERS]; >> static struct cpufreq_arm_bL_ops *arm_bL_ops; >> static struct clk *clk[MAX_CLUSTERS]; >> static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS + 1]; >> @@ -493,6 +495,12 @@ static int bL_cpufreq_init(struct cpufreq_policy >> *policy) >> static int bL_cpufreq_exit(struct cpufreq_policy *policy) >> { >> struct device *cpu_dev; >> +int cur_cluster = cpu_to_cluster(policy->cpu); >> + >> +if (cur_cluster < MAX_CLUSTERS) { >> +cpufreq_cooling_unregister(cdev[cur_cluster]); >> +cdev[cur_cluster] = NULL; >> +} >> >> cpu_dev = get_cpu_device(policy->cpu); >> if (!cpu_dev) { >> @@ -507,6 +515,38 @@ static int bL_cpufreq_exit(struct cpufreq_policy >> *policy) >> return 0; >> } >> >> +static void bL_cpufreq_ready(struct cpufreq_policy *policy) >> +{ >> +struct device *cpu_dev = get_cpu_device(policy->cpu); >> +int cur_cluster = cpu_to_cluster(policy->cpu); >> +struct device_node *np; >> + >> +/* Do not register a cpu_cooling device if we are in IKS mode */ >> +if (cur_cluster >= MAX_CLUSTERS) >> +return; >> + >> +np = of_node_get(cpu_dev->of_node); >> +if (WARN_ON(!np)) >> +return; >> + >> +if (of_find_property(np, "#cooling-cells", NULL)) { >> +u32 power_coefficient = 0; >> + >> +of_property_read_u32(np, "dynamic-power-coefficient", >> + &power_coefficient); >> + >> +cdev[cur_cluster] = of_cpufreq_power_cooling_register(np, >> +policy->related_cpus, power_coefficient, NULL); >> +if (IS_ERR(cdev[cur_cluster])) { >> +dev_err(cpu_dev, >> +"running cpufreq without cooling device: %ld\n", >> +PTR_ERR(cdev[cur_cluster])); >> +cdev[cur_cluster] = NULL; >> +} >> +} >> +of_node_put(np); >> +} >> + >> static struct cpufreq_driver bL_cpufreq_driver = { >> .name = "arm-big-little", >> .flags = CPUFREQ_STICKY | >> @@ -517,6 +557,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, >> }; > > Acked-by: Viresh Kumar Thanks for the Ack. Will you or Rafael be picking up the series or do they need to go via arm-soc? -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 1/3] devicetree: bindings: Add optional dynamic-power-coefficient property
The dynamic power consumption of a device is proportional to the square of voltage (V) and the clock frequency (f). It can be expressed as Pdyn = dynamic-power-coefficient * V^2 * f. The coefficient represents the running time dynamic power consumption in units of mw/MHz/uVolt^2 and can be used in the above formula to calculate the dynamic power in mW. Signed-off-by: Punit Agrawal Acked-by: Rob Herring Reviewed-by: Viresh Kumar Cc: Mark Rutland --- Documentation/devicetree/bindings/arm/cpus.txt | 17 + 1 file changed, 17 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index 3a07a87..6aca64f 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt @@ -242,6 +242,23 @@ nodes to be present and contain the properties described below. Definition: Specifies the syscon node controlling the cpu core power domains. + - dynamic-power-coefficient + Usage: optional + Value type: + Definition: A u32 value that represents the running time dynamic + power coefficient in units of mW/MHz/uVolt^2. The + coefficient can either be calculated from power + measurements or derived by analysis. + + The dynamic power consumption of the CPU is + proportional to the square of the Voltage (V) and + the clock frequency (f). The coefficient is used to + calculate the dynamic power as below - + + Pdyn = dynamic-power-coefficient * V^2 * f + + where voltage is in uV, frequency is in MHz. + Example 1 (dual-cluster big.LITTLE system 32-bit): cpus { -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 2/3] cpufreq-dt: Supply power coefficient when registering cooling devices
Support registering cooling devices with dynamic power coefficient where provided by the device tree. This allows OF registered cooling devices driver to be used with the power_allocator thermal governor. Signed-off-by: Punit Agrawal Acked-by: Viresh Kumar Reviewed-by: Javi Merino Cc: Eduardo Valentin --- drivers/cpufreq/cpufreq-dt.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 90d6408..1ceece9 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -407,8 +407,13 @@ static void cpufreq_ready(struct cpufreq_policy *policy) * thermal DT code takes care of matching them. */ if (of_find_property(np, "#cooling-cells", NULL)) { - priv->cdev = of_cpufreq_cooling_register(np, -policy->related_cpus); + u32 power_coefficient = 0; + + of_property_read_u32(np, "dynamic-power-coefficient", +&power_coefficient); + + priv->cdev = of_cpufreq_power_cooling_register(np, + policy->related_cpus, power_coefficient, NULL); if (IS_ERR(priv->cdev)) { dev_err(priv->cpu_dev, "running cpufreq without cooling device: %ld\n", -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 3/3] cpufreq: arm_big_little: Add support to register a cpufreq cooling device
Register passive cooling devices when initialising cpufreq on big.LITTLE systems. If the device tree provides a dynamic power coefficient for the CPUs then the bound cooling device will support the extensions that allow it to be used with all the existing thermal governors including the power allocator governor. A cooling device will be created per individual frequency domain and can be bound to thermal zones via the thermal DT bindings. Signed-off-by: Punit Agrawal Cc: Viresh Kumar Cc: Sudeep Holla Cc: Eduardo Valentin --- drivers/cpufreq/Kconfig.arm | 2 ++ drivers/cpufreq/arm_big_little.c | 41 2 files changed, 43 insertions(+) diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index 1582c1c..0e0052e 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -6,6 +6,8 @@ config ARM_BIG_LITTLE_CPUFREQ tristate "Generic ARM big LITTLE CPUfreq driver" depends on (ARM_CPU_TOPOLOGY || ARM64) && HAVE_CLK + # if CPU_THERMAL is on and THERMAL=m, ARM_BIT_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. diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index c5d256c..c251247 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,7 @@ static bool bL_switching_enabled; #define ACTUAL_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq << 1 : freq) #define VIRT_FREQ(cluster, freq)((cluster == A7_CLUSTER) ? freq >> 1 : freq) +static struct thermal_cooling_device *cdev[MAX_CLUSTERS]; static struct cpufreq_arm_bL_ops *arm_bL_ops; static struct clk *clk[MAX_CLUSTERS]; static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS + 1]; @@ -493,6 +495,12 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy) static int bL_cpufreq_exit(struct cpufreq_policy *policy) { struct device *cpu_dev; + int cur_cluster = cpu_to_cluster(policy->cpu); + + if (cur_cluster < MAX_CLUSTERS) { + cpufreq_cooling_unregister(cdev[cur_cluster]); + cdev[cur_cluster] = NULL; + } cpu_dev = get_cpu_device(policy->cpu); if (!cpu_dev) { @@ -507,6 +515,38 @@ static int bL_cpufreq_exit(struct cpufreq_policy *policy) return 0; } +static void bL_cpufreq_ready(struct cpufreq_policy *policy) +{ + struct device *cpu_dev = get_cpu_device(policy->cpu); + int cur_cluster = cpu_to_cluster(policy->cpu); + struct device_node *np; + + /* Do not register a cpu_cooling device if we are in IKS mode */ + if (cur_cluster >= MAX_CLUSTERS) + return; + + np = of_node_get(cpu_dev->of_node); + if (WARN_ON(!np)) + return; + + if (of_find_property(np, "#cooling-cells", NULL)) { + u32 power_coefficient = 0; + + of_property_read_u32(np, "dynamic-power-coefficient", +&power_coefficient); + + cdev[cur_cluster] = of_cpufreq_power_cooling_register(np, + policy->related_cpus, power_coefficient, NULL); + if (IS_ERR(cdev[cur_cluster])) { + dev_err(cpu_dev, + "running cpufreq without cooling device: %ld\n", + PTR_ERR(cdev[cur_cluster])); + cdev[cur_cluster] = NULL; + } + } + of_node_put(np); +} + static struct cpufreq_driver bL_cpufreq_driver = { .name = "arm-big-little", .flags = CPUFREQ_STICKY | @@ -517,6 +557,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, }; -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v5 0/3] Dynamic power model from device tree
Hi, This patchset adds support to build a single-coefficient dynamic power model for a CPU. The model is used by the CPU cooling device to provide an estimate of power consumption and also translate allocated power to performance cap. Changes from previous posting - v4 -> v5 Updated tags across the patches arm_big_little: Do not register cooling devices when in IKS v3 -> v4: arm_big_little: Migrated to using static arrays arm_big_little: Updated Kconfig to support building thermal as module Patch 1 extends the CPU nodes binding to provide an optional dynamic power coefficient which can be used to create a dynamic power model for the CPUs. This model is used to constrain device power consumption (using power_allocator governor) when the system is thermally constrained. Patches 2-3 extends the cpufreq-dt and arm_big_little driver to register cpu cooling devices with the dynamic coefficient when provided. The patches were previously posted at [0][1][2][3]. Mediatek platform 8173 builds on these bindings to build a power model. Thanks, Punit [0] http://thread.gmane.org/gmane.linux.kernel/2002152 [1] http://thread.gmane.org/gmane.linux.kernel/2011466 [2] http://marc.info/?l=linux-kernel&m=144709020014884&w=2 [3] http://marc.info/?l=linux-pm&m=144770224915315&w=2 Punit Agrawal (3): devicetree: bindings: Add optional dynamic-power-coefficient property cpufreq-dt: Supply power coefficient when registering cooling devices cpufreq: arm_big_little: Add support to register a cpufreq cooling device Documentation/devicetree/bindings/arm/cpus.txt | 17 +++ drivers/cpufreq/Kconfig.arm| 2 ++ drivers/cpufreq/arm_big_little.c | 41 ++ drivers/cpufreq/cpufreq-dt.c | 9 -- 4 files changed, 67 insertions(+), 2 deletions(-) -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 3/3] cpufreq: arm_big_little: Add support to register a cpufreq cooling device
Viresh Kumar writes: > On Tue, Nov 17, 2015 at 1:00 AM, Punit Agrawal wrote: >> Register passive cooling devices when initialising cpufreq on >> big.LITTLE systems. If the device tree provides a dynamic power >> coefficient for the CPUs then the bound cooling device will support >> the extensions that allow it to be used with all the existing thermal >> governors including the power allocator governor. >> >> A cooling device will be created per individual frequency domain and >> can be bound to thermal zones via the thermal DT bindings. >> >> Signed-off-by: Punit Agrawal >> Acked-by: Viresh Kumar > > Remind me when did I Ack this version of your patch .. You didn't - I missed removing the tag before sending the patch out. Dropped locally now. > >> Cc: Sudeep Holla >> Cc: Eduardo Valentin >> --- >> drivers/cpufreq/Kconfig.arm | 2 ++ >> drivers/cpufreq/arm_big_little.c | 35 +++ >> 2 files changed, 37 insertions(+) >> >> diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm >> index 1582c1c..0e0052e 100644 >> --- a/drivers/cpufreq/Kconfig.arm >> +++ b/drivers/cpufreq/Kconfig.arm >> @@ -6,6 +6,8 @@ >> config ARM_BIG_LITTLE_CPUFREQ >> tristate "Generic ARM big LITTLE CPUfreq driver" >> depends on (ARM_CPU_TOPOLOGY || ARM64) && HAVE_CLK >> + # if CPU_THERMAL is on and THERMAL=m, ARM_BIT_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. >> diff --git a/drivers/cpufreq/arm_big_little.c >> b/drivers/cpufreq/arm_big_little.c >> index c5d256c..60d09c0 100644 >> --- a/drivers/cpufreq/arm_big_little.c >> +++ b/drivers/cpufreq/arm_big_little.c >> @@ -23,6 +23,7 @@ >> #include >> #include >> #include >> +#include >> #include >> #include >> #include >> @@ -55,6 +56,7 @@ static bool bL_switching_enabled; >> #define ACTUAL_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq << 1 : >> freq) >> #define VIRT_FREQ(cluster, freq)((cluster == A7_CLUSTER) ? freq >> 1 : >> freq) >> >> +static struct thermal_cooling_device *cdev[MAX_CLUSTERS]; >> static struct cpufreq_arm_bL_ops *arm_bL_ops; >> static struct clk *clk[MAX_CLUSTERS]; >> static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS + 1]; >> @@ -493,6 +495,7 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy) >> static int bL_cpufreq_exit(struct cpufreq_policy *policy) >> { >> struct device *cpu_dev; >> + int domain; >> >> cpu_dev = get_cpu_device(policy->cpu); >> if (!cpu_dev) { >> @@ -501,12 +504,43 @@ static int bL_cpufreq_exit(struct cpufreq_policy >> *policy) >> return -ENODEV; >> } >> >> + domain = topology_physical_package_id(cpu_dev->id); > > And this is broken. > > Have you tested this for IKS ? That's what the primary use-case of > this driver is. Juno dvfs uses this driver - which is where I've been testing the changes. Unfortunately, there is no IKS there. > And yeah, I would like to migrate the bL usecase to cpufreq-dt, now that it > can > support multiple clusters. It would be great to have a unified cpufreq driver servicing multiple dvfs domains. If I understand correctly, we can drop $SUBJECT when that happens. In the meanwhile... > > This is broken, because exit() might get called for a CPU from big > cluster, while > read() was called for a CPU on little cluster. Good catch. The patch will definitely not do the right thing when IKS is enabled. Looking at the code, it looks like you can switch in and out of IKS at run time. The cpu_cooling device doesn't cope with different types of cores, so I'll just have to skip registering (and un-registering) the cooling device when IKS is enabled. I'll send out a new version addressing the issues you've pointed out. Thanks for your comments. Punit > > -- > viresh > -- > To unsubscribe from this list: send the line "unsubscribe devicetree" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 0/3] Dynamic power model from device tree
Viresh Kumar writes: > On Tue, Nov 17, 2015 at 1:00 AM, Punit Agrawal wrote: >> Hi, >> >> This patchset adds support to build a single-coefficient dynamic power >> model for a CPU. The model is used by the CPU cooling device to >> provide an estimate of power consumption and also translate allocated >> power to performance cap. >> >> Changes from previous posting - >> >> v3 -> v4: >> arm_big_little: Migrated to using static arrays >> arm_big_little: Updated Kconfig to support building thermal as module >> >> Patch 1 extends the CPU nodes binding to provide an optional dynamic >> power coefficient which can be used to create a dynamic power model >> for the CPUs. This model is used to constrain device power consumption >> (using power_allocator governor) when the system is thermally >> constrained. >> >> Patches 2-3 extends the cpufreq-dt and arm_big_little driver to >> register cpu cooling devices with the dynamic coefficient when >> provided. >> >> The patches were previously posted at [0][1][2]. Mediatek platform >> 8173 builds on these bindings to build the power model. >> >> If there are no objections, I'd appreciate Acks from device tree >> bindings maintainers. > > You forgot to cc cpufreq maintainers for this and there are good chances > that I may completely miss the series some times.. Yikes! I'll make sure to include both Rafael and you for future postings. > -- > To unsubscribe from this list: send the line "unsubscribe devicetree" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 3/3] cpufreq: arm_big_little: Add support to register a cpufreq cooling device
Register passive cooling devices when initialising cpufreq on big.LITTLE systems. If the device tree provides a dynamic power coefficient for the CPUs then the bound cooling device will support the extensions that allow it to be used with all the existing thermal governors including the power allocator governor. A cooling device will be created per individual frequency domain and can be bound to thermal zones via the thermal DT bindings. Signed-off-by: Punit Agrawal Acked-by: Viresh Kumar Cc: Sudeep Holla Cc: Eduardo Valentin --- drivers/cpufreq/Kconfig.arm | 2 ++ drivers/cpufreq/arm_big_little.c | 35 +++ 2 files changed, 37 insertions(+) diff --git a/drivers/cpufreq/Kconfig.arm b/drivers/cpufreq/Kconfig.arm index 1582c1c..0e0052e 100644 --- a/drivers/cpufreq/Kconfig.arm +++ b/drivers/cpufreq/Kconfig.arm @@ -6,6 +6,8 @@ config ARM_BIG_LITTLE_CPUFREQ tristate "Generic ARM big LITTLE CPUfreq driver" depends on (ARM_CPU_TOPOLOGY || ARM64) && HAVE_CLK + # if CPU_THERMAL is on and THERMAL=m, ARM_BIT_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. diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index c5d256c..60d09c0 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,7 @@ static bool bL_switching_enabled; #define ACTUAL_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq << 1 : freq) #define VIRT_FREQ(cluster, freq)((cluster == A7_CLUSTER) ? freq >> 1 : freq) +static struct thermal_cooling_device *cdev[MAX_CLUSTERS]; static struct cpufreq_arm_bL_ops *arm_bL_ops; static struct clk *clk[MAX_CLUSTERS]; static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS + 1]; @@ -493,6 +495,7 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy) static int bL_cpufreq_exit(struct cpufreq_policy *policy) { struct device *cpu_dev; + int domain; cpu_dev = get_cpu_device(policy->cpu); if (!cpu_dev) { @@ -501,12 +504,43 @@ static int bL_cpufreq_exit(struct cpufreq_policy *policy) return -ENODEV; } + domain = topology_physical_package_id(cpu_dev->id); + cpufreq_cooling_unregister(cdev[domain]); + cdev[domain] = NULL; + put_cluster_clk_and_freq_table(cpu_dev); dev_dbg(cpu_dev, "%s: Exited, cpu: %d\n", __func__, policy->cpu); return 0; } +static void bL_cpufreq_ready(struct cpufreq_policy *policy) +{ + struct device *cpu_dev = get_cpu_device(policy->cpu); + struct device_node *np = of_node_get(cpu_dev->of_node); + int domain = topology_physical_package_id(cpu_dev->id); + + if (WARN_ON(!np)) + return; + + if (of_find_property(np, "#cooling-cells", NULL)) { + u32 power_coefficient = 0; + + of_property_read_u32(np, "dynamic-power-coefficient", +&power_coefficient); + + cdev[domain] = of_cpufreq_power_cooling_register(np, + policy->related_cpus, power_coefficient, NULL); + if (IS_ERR(cdev[domain])) { + dev_err(cpu_dev, + "running cpufreq without cooling device: %ld\n", + PTR_ERR(cdev[domain])); + cdev[domain] = NULL; + } + } + of_node_put(np); +} + static struct cpufreq_driver bL_cpufreq_driver = { .name = "arm-big-little", .flags = CPUFREQ_STICKY | @@ -517,6 +551,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, }; -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 2/3] cpufreq-dt: Supply power coefficient when registering cooling devices
Support registering cooling devices with dynamic power coefficient where provided by the device tree. This allows OF registered cooling devices driver to be used with the power_allocator thermal governor. Signed-off-by: Punit Agrawal Acked-by: Viresh Kumar Reviewed-by: Javi Merino Cc: Eduardo Valentin --- drivers/cpufreq/cpufreq-dt.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 90d6408..1ceece9 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -407,8 +407,13 @@ static void cpufreq_ready(struct cpufreq_policy *policy) * thermal DT code takes care of matching them. */ if (of_find_property(np, "#cooling-cells", NULL)) { - priv->cdev = of_cpufreq_cooling_register(np, -policy->related_cpus); + u32 power_coefficient = 0; + + of_property_read_u32(np, "dynamic-power-coefficient", +&power_coefficient); + + priv->cdev = of_cpufreq_power_cooling_register(np, + policy->related_cpus, power_coefficient, NULL); if (IS_ERR(priv->cdev)) { dev_err(priv->cpu_dev, "running cpufreq without cooling device: %ld\n", -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 1/3] devicetree: bindings: Add optional dynamic-power-coefficient property
The dynamic power consumption of a device is proportional to the square of voltage (V) and the clock frequency (f). It can be expressed as Pdyn = dynamic-power-coefficient * V^2 * f. The coefficient represents the running time dynamic power consumption in units of mw/MHz/uVolt^2 and can be used in the above formula to calculate the dynamic power in mW. Signed-off-by: Punit Agrawal Cc: Rob Herring Cc: Mark Rutland --- Documentation/devicetree/bindings/arm/cpus.txt | 17 + 1 file changed, 17 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index 3a07a87..6aca64f 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt @@ -242,6 +242,23 @@ nodes to be present and contain the properties described below. Definition: Specifies the syscon node controlling the cpu core power domains. + - dynamic-power-coefficient + Usage: optional + Value type: + Definition: A u32 value that represents the running time dynamic + power coefficient in units of mW/MHz/uVolt^2. The + coefficient can either be calculated from power + measurements or derived by analysis. + + The dynamic power consumption of the CPU is + proportional to the square of the Voltage (V) and + the clock frequency (f). The coefficient is used to + calculate the dynamic power as below - + + Pdyn = dynamic-power-coefficient * V^2 * f + + where voltage is in uV, frequency is in MHz. + Example 1 (dual-cluster big.LITTLE system 32-bit): cpus { -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 0/3] Dynamic power model from device tree
Hi, This patchset adds support to build a single-coefficient dynamic power model for a CPU. The model is used by the CPU cooling device to provide an estimate of power consumption and also translate allocated power to performance cap. Changes from previous posting - v3 -> v4: arm_big_little: Migrated to using static arrays arm_big_little: Updated Kconfig to support building thermal as module Patch 1 extends the CPU nodes binding to provide an optional dynamic power coefficient which can be used to create a dynamic power model for the CPUs. This model is used to constrain device power consumption (using power_allocator governor) when the system is thermally constrained. Patches 2-3 extends the cpufreq-dt and arm_big_little driver to register cpu cooling devices with the dynamic coefficient when provided. The patches were previously posted at [0][1][2]. Mediatek platform 8173 builds on these bindings to build the power model. If there are no objections, I'd appreciate Acks from device tree bindings maintainers. Thanks, Punit [0] http://thread.gmane.org/gmane.linux.kernel/2002152 [1] http://thread.gmane.org/gmane.linux.kernel/2011466 [2] http://marc.info/?l=linux-kernel&m=144709020014884&w=2 Punit Agrawal (3): devicetree: bindings: Add optional dynamic-power-coefficient property cpufreq-dt: Supply power coefficient when registering cooling devices cpufreq: arm_big_little: Add support to register a cpufreq cooling device Documentation/devicetree/bindings/arm/cpus.txt | 17 + drivers/cpufreq/Kconfig.arm| 2 ++ drivers/cpufreq/arm_big_little.c | 35 ++ drivers/cpufreq/cpufreq-dt.c | 9 +-- 4 files changed, 61 insertions(+), 2 deletions(-) -- 2.6.2 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 3/3] cpufreq: arm_big_little: Add support to register a cpufreq cooling device
Viresh Kumar writes: > On 09-11-15, 17:29, Punit Agrawal wrote: >> Register passive cooling devices when initialising cpufreq on >> big.LITTLE systems. If the device tree provides a dynamic power >> coefficient for the CPUs then the bound cooling device will support >> the extensions that allow it to be used with all the existing thermal >> governors including the power allocator governor. >> >> A cooling device will be created per individual frequency domain and >> can be bound to thermal zones via the thermal DT bindings. >> >> Signed-off-by: Punit Agrawal >> Acked-by: Viresh Kumar >> Cc: Sudeep Holla >> Cc: Eduardo Valentin >> --- >> drivers/cpufreq/arm_big_little.c | 52 >> ++-- >> 1 file changed, 50 insertions(+), 2 deletions(-) >> >> diff --git a/drivers/cpufreq/arm_big_little.c >> b/drivers/cpufreq/arm_big_little.c >> index f1e42f8..72a2777 100644 >> --- a/drivers/cpufreq/arm_big_little.c >> +++ b/drivers/cpufreq/arm_big_little.c >> @@ -23,6 +23,7 @@ >> #include >> #include >> #include >> +#include >> #include >> #include >> #include >> @@ -55,6 +56,10 @@ static bool bL_switching_enabled; >> #define ACTUAL_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq << 1 : >> freq) >> #define VIRT_FREQ(cluster, freq)((cluster == A7_CLUSTER) ? freq >> 1 : >> freq) >> >> +struct private_data { >> +struct thermal_cooling_device *cdev; >> +}; > > I think we need to be consistent within the driver, and so this must > be stored in a similar way to what we do for other structures. We have > static arrays for them, please do it that way only OR first change all > of them to be part of a bigger private_data structure. Sure, I'll switch to using static arrays. There seem to be a lot of assumptions that might be easily broken in moving all the data into a single structure. I'll leave that as a later change. -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 1/3] devicetree: bindings: Add optional dynamic-power-coefficient property
Rob Herring writes: > On Mon, Nov 09, 2015 at 05:29:21PM +0000, Punit Agrawal wrote: >> The dynamic power consumption of a device is proportional to the >> square of voltage (V) and the clock frequency (f). It can be expressed as >> >> Pdyn = dynamic-power-coefficient * V^2 * f. >> >> The coefficient represents the running time dynamic power consumption in >> units of mw/MHz/uVolt^2 and can be used in the above formula to >> calculate the dynamic power in mW. > > I have no issue with the binding, but I wonder if a single value is > really sufficient to model this. Don't you also need a static > component? In general, power consumption does consist of the static and dynamic power. Here we are only modelling the dynamic component. For CPUs, we found that a single-coefficient model using frequency and voltages gives a reasonable estimation of dynamic power consumption. For thermal management, because of using closed loop control providing the dynamic consumption is good enough as long as static power for your platform is not significant. On the other hand, there isn't a generally applicable model for static power - it has complex relationships with temperature, voltages, etc which make it hard to express as a simple formula. For platforms where static power is significant, providing it via platform code is the only option for now. This patchset enables platforms where dynamic power works well to setup their power model for thermal management via device tree. > > Rob > >> >> Signed-off-by: Punit Agrawal >> Cc: Rob Herring >> Cc: Mark Rutland >> --- >> Documentation/devicetree/bindings/arm/cpus.txt | 17 + >> 1 file changed, 17 insertions(+) >> >> diff --git a/Documentation/devicetree/bindings/arm/cpus.txt >> b/Documentation/devicetree/bindings/arm/cpus.txt >> index 91e6e5c..c33362d 100644 >> --- a/Documentation/devicetree/bindings/arm/cpus.txt >> +++ b/Documentation/devicetree/bindings/arm/cpus.txt >> @@ -240,6 +240,23 @@ nodes to be present and contain the properties >> described below. >> Definition: Specifies the syscon node controlling the cpu core >> power domains. >> >> +- dynamic-power-coefficient >> +Usage: optional >> +Value type: >> +Definition: A u32 value that represents the running time dynamic >> +power coefficient in units of mW/MHz/uVolt^2. The >> +coefficient can either be calculated from power >> +measurements or derived by analysis. >> + >> +The dynamic power consumption of the CPU is >> +proportional to the square of the Voltage (V) and >> +the clock frequency (f). The coefficient is used to >> +calculate the dynamic power as below - >> + >> +Pdyn = dynamic-power-coefficient * V^2 * f >> + >> +where voltage is in uV, frequency is in MHz. >> + >> Example 1 (dual-cluster big.LITTLE system 32-bit): >> >> cpus { >> -- >> 2.5.3 >> > -- > To unsubscribe from this list: send the line "unsubscribe devicetree" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 2/3] cpufreq-dt: Supply power coefficient when registering cooling devices
Support registering cooling devices with dynamic power coefficient where provided by the device tree. This allows OF registered cooling devices driver to be used with the power_allocator thermal governor. Signed-off-by: Punit Agrawal Acked-by: Viresh Kumar Cc: Eduardo Valentin --- drivers/cpufreq/cpufreq-dt.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 7c0d70e..4434e45 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -407,8 +407,13 @@ static void cpufreq_ready(struct cpufreq_policy *policy) * thermal DT code takes care of matching them. */ if (of_find_property(np, "#cooling-cells", NULL)) { - priv->cdev = of_cpufreq_cooling_register(np, -policy->related_cpus); + u32 power_coefficient = 0; + + of_property_read_u32(np, "dynamic-power-coefficient", +&power_coefficient); + + priv->cdev = of_cpufreq_power_cooling_register(np, + policy->related_cpus, power_coefficient, NULL); if (IS_ERR(priv->cdev)) { dev_err(priv->cpu_dev, "running cpufreq without cooling device: %ld\n", -- 2.5.3 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/3] devicetree: bindings: Add optional dynamic-power-coefficient property
The dynamic power consumption of a device is proportional to the square of voltage (V) and the clock frequency (f). It can be expressed as Pdyn = dynamic-power-coefficient * V^2 * f. The coefficient represents the running time dynamic power consumption in units of mw/MHz/uVolt^2 and can be used in the above formula to calculate the dynamic power in mW. Signed-off-by: Punit Agrawal Cc: Rob Herring Cc: Mark Rutland --- Documentation/devicetree/bindings/arm/cpus.txt | 17 + 1 file changed, 17 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index 91e6e5c..c33362d 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt @@ -240,6 +240,23 @@ nodes to be present and contain the properties described below. Definition: Specifies the syscon node controlling the cpu core power domains. + - dynamic-power-coefficient + Usage: optional + Value type: + Definition: A u32 value that represents the running time dynamic + power coefficient in units of mW/MHz/uVolt^2. The + coefficient can either be calculated from power + measurements or derived by analysis. + + The dynamic power consumption of the CPU is + proportional to the square of the Voltage (V) and + the clock frequency (f). The coefficient is used to + calculate the dynamic power as below - + + Pdyn = dynamic-power-coefficient * V^2 * f + + where voltage is in uV, frequency is in MHz. + Example 1 (dual-cluster big.LITTLE system 32-bit): cpus { -- 2.5.3 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 3/3] cpufreq: arm_big_little: Add support to register a cpufreq cooling device
Register passive cooling devices when initialising cpufreq on big.LITTLE systems. If the device tree provides a dynamic power coefficient for the CPUs then the bound cooling device will support the extensions that allow it to be used with all the existing thermal governors including the power allocator governor. A cooling device will be created per individual frequency domain and can be bound to thermal zones via the thermal DT bindings. Signed-off-by: Punit Agrawal Acked-by: Viresh Kumar Cc: Sudeep Holla Cc: Eduardo Valentin --- drivers/cpufreq/arm_big_little.c | 52 ++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index f1e42f8..72a2777 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,10 @@ static bool bL_switching_enabled; #define ACTUAL_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq << 1 : freq) #define VIRT_FREQ(cluster, freq)((cluster == A7_CLUSTER) ? freq >> 1 : freq) +struct private_data { + struct thermal_cooling_device *cdev; +}; + static struct cpufreq_arm_bL_ops *arm_bL_ops; static struct clk *clk[MAX_CLUSTERS]; static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS + 1]; @@ -440,6 +445,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); @@ -457,9 +463,15 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy) if (ret) { dev_err(cpu_dev, "CPU %d, cluster: %d invalid freq table\n", policy->cpu, cur_cluster); - put_cluster_clk_and_freq_table(cpu_dev); - return ret; + goto out_free_cpufreq_table; + } + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + ret = -ENOMEM; + goto out_free_cpufreq_table; } + policy->driver_data = priv; if (cur_cluster < MAX_CLUSTERS) { int cpu; @@ -484,12 +496,19 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy) dev_info(cpu_dev, "%s: CPU %d initialized\n", __func__, policy->cpu); return 0; + +out_free_cpufreq_table: + put_cluster_clk_and_freq_table(cpu_dev); + + return ret; } static int bL_cpufreq_exit(struct cpufreq_policy *policy) { struct device *cpu_dev; + struct private_data *priv = policy->driver_data; + cpufreq_cooling_unregister(priv->cdev); cpu_dev = get_cpu_device(policy->cpu); if (!cpu_dev) { pr_err("%s: failed to get cpu%d device\n", __func__, @@ -498,11 +517,39 @@ static int bL_cpufreq_exit(struct cpufreq_policy *policy) } put_cluster_clk_and_freq_table(cpu_dev); + kfree(priv); dev_dbg(cpu_dev, "%s: Exited, cpu: %d\n", __func__, policy->cpu); return 0; } +static void bL_cpufreq_ready(struct cpufreq_policy *policy) +{ + struct device *cpu_dev = get_cpu_device(policy->cpu); + struct device_node *np = of_node_get(cpu_dev->of_node); + struct private_data *priv = policy->driver_data; + + if (WARN_ON(!np)) + return; + + if (of_find_property(np, "#cooling-cells", NULL)) { + u32 power_coefficient = 0; + + of_property_read_u32(np, "dynamic-power-coefficient", +&power_coefficient); + + priv->cdev = of_cpufreq_power_cooling_register(np, + policy->related_cpus, power_coefficient, NULL); + if (IS_ERR(priv->cdev)) { + dev_err(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 | @@ -513,6 +560,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, }; -- 2.5.3 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 0/3] Dynamic power model from device tree
Hi, This patchset adds support to build a single-coefficient dynamic power model for a CPU. The model is used by the CPU cooling device to provide an estimate of power consumption and also translate allocated power to performance cap. Patch 1 extends the CPU nodes binding to provide an optional dynamic power coefficient which can be used to create a dynamic power model for the CPUs. This model is used to constrain device power consumption (using power_allocator governor) when the system is thermally constrained. Patches 2-3 extends the cpufreq-dt and arm_big_little driver to register cpu cooling devices with the dynamic coefficient when provided. The patches were previously posted as part of [0][1]. Since the last posting Mediatek platform 8173 is also building on these bindings to build the power model. Feedback on the bindings would be particularly appreciated. Thanks, Punit [0] http://thread.gmane.org/gmane.linux.kernel/2002152 [1] http://thread.gmane.org/gmane.linux.kernel/2011466 Punit Agrawal (3): devicetree: bindings: Add optional dynamic-power-coefficient property cpufreq-dt: Supply power coefficient when registering cooling devices cpufreq: arm_big_little: Add support to register a cpufreq cooling device Documentation/devicetree/bindings/arm/cpus.txt | 17 + drivers/cpufreq/arm_big_little.c | 52 +- drivers/cpufreq/cpufreq-dt.c | 9 - 3 files changed, 74 insertions(+), 4 deletions(-) -- 2.5.3 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 0/2] thermal: mediatek: Add cpu power cooling model
Viresh Kumar writes: > On 22-10-15, 20:02, Dawei Chien wrote: >> Use Intelligent Power Allocation (IPA) technical to add static/dynamic power >> model for binding CPU thermal zone. >> The power allocator governor allocates power budget to control CPU >> temperature. >> >> Power Allocator governor is able to keep SOC temperature within a >> defined temperature range to avoid SOC overheat and keep it's >> performance. mt8173-cpufreq.c need to register its' own power model >> with power allocator thermal governor, so that power allocator >> governor can allocates suitable power budget to control CPU >> temperature. >> >> PATCH1 is base on >> https://patchwork.kernel.org/patch/7034601/ >> >> PATCH2 is base on Sascha's thermal driver V9 >> https://patchwork.kernel.org/patch/7249821/ >> https://patchwork.kernel.org/patch/7249861/ >> https://patchwork.kernel.org/patch/7249891/ >> >> Change since V1: >> include mt8171.h and sort header file for mt8173.dtsi >> >> Change since V2: >> Move dynamic/static power model in device tree >> >> Dawei.Chien (2): >> thermal: mediatek: Add cpu power cooling model. >> arm64: dts: mt8173: Add thermal zone node for mt8173. > > Sorry for being extremely late in reviewing this stuff. You are > already on v3 and I haven't reviewed it once. Mostly due to bad timing > of my holidays and other work pressure. > > Now, there are few things that I feel are not properly addressed here, > and I may be wrong: > - Where are the bindings for static-power-points and > dynamic-power-coefficient. Sorry I failed to see them in this or > other series you mentioned. For dynamic power, I had posted some patches[0][1][2] introducing the binding as well as updating cooling device registration via cpufreq driver. Now that the SCPI hwmon driver is merged, I should re-send the remaining patches. [0] http://lkml.iu.edu/hypermail/linux/kernel/1508.0/01020.html [1] http://lkml.iu.edu/hypermail/linux/kernel/1508.0/01022.html [3] http://lkml.iu.edu/hypermail/linux/kernel/1508.0/01031.html > - Even then, why should we be adding another table into DT for > voltage/power ? And not reuse and extend the opp-v2 stuff which is > already mainlined now. > - There are few issues with the code as well, but I want to see where > the bindings should go first. And then only discuss the code > further. -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 1/2] thermal: mediatek: Add cpu power cooling model.
Mark Rutland writes: > On Wed, Oct 07, 2015 at 08:22:40PM +0800, Dawei Chien wrote: >> From: "Dawei.Chien" >> >> This power model is base on Intelligent Power Allocation (IPA) technical, >> requires that the operating-points of the CPUs are registered using the >> kernel's opp library and the `cpufreq_frequency_table` is assigned to the >> `struct device` of the cpu MT8173. >> >> Signed-off-by: Dawei.Chien >> --- >> This patch is base on >> https://patchwork.kernel.org/patch/7034601/ >> --- >> drivers/cpufreq/mt8173-cpufreq.c | 97 >> +- >> 1 file changed, 86 insertions(+), 11 deletions(-) >> >> diff --git a/drivers/cpufreq/mt8173-cpufreq.c >> b/drivers/cpufreq/mt8173-cpufreq.c >> index 49caed2..9233ec5 100644 >> --- a/drivers/cpufreq/mt8173-cpufreq.c >> +++ b/drivers/cpufreq/mt8173-cpufreq.c >> @@ -28,7 +28,8 @@ >> #define MAX_VOLT_SHIFT (20) >> #define MAX_VOLT_LIMIT (115) >> #define VOLT_TOL(1) >> - >> +#define CAPACITANCE_CA53(263) >> +#define CAPACITANCE_CA57(530) >> /* >> * The struct mtk_cpu_dvfs_info holds necessary information for doing CPU >> DVFS >> * on each CPU power/clock domain of Mediatek SoCs. Each CPU cluster in >> @@ -51,6 +52,72 @@ struct mtk_cpu_dvfs_info { >> bool need_voltage_tracking; >> }; >> >> +struct mtk_cpu_static_power { >> +unsigned long voltage; >> +unsigned int power; >> +}; >> + >> +/* measured by WA program. */ >> +static const struct mtk_cpu_static_power mtk_ca53_static_power[] = { >> +{859000, 43}, >> +{908000, 52}, >> +{983000, 86}, >> +{1009000, 123}, >> +{1028000, 138}, >> +{1083000, 172}, >> +{1109000, 180}, >> +{1125000, 192}, >> +}; >> + >> +/* measured by WA program. */ >> +static const struct mtk_cpu_static_power mtk_ca57_static_power[] = { >> +{828000, 72}, >> +{867000, 90}, >> +{927000, 156}, >> +{968000, 181}, >> +{1007000, 298}, >> +{1049000, 435}, >> +{1089000, 533}, >> +{1125000, 533}, >> +}; > > This should be described in the DT, rather than necessitating tonnes of > these tables in the kernel. The above table is a simplification that is tying the static power of a device to a voltage (indirectly via frequency for ease of indexing perhaps). We should definitely look at describing the static power model in the device tree - but it is not entirely clear what is the best model to use as basis for the device tree bindings. Static power consumption depends on a few different parameters (silicon process, voltage, temperature, etc.). The relationship between them maybe non-linear and not all of these maybe significant for a given platform. e.g., for Juno, we are using a regression based on voltage and temperature which was deemed close enough (very subjective tbh). On the other hand, dynamic power consumption is somewhat simpler and I have patches[0][1][2] enabling it's description in device tree. Your comments there would be very much appreciated. As for this patch, I hope it can be moved to using the device tree when the bindings for static power are agreed upon. Although sub-optimal, I can't see any other way forward for now. [0] http://thread.gmane.org/gmane.linux.kernel/2011466/focus=130373 [1] http://thread.gmane.org/gmane.linux.kernel/2011466/focus=2011465 [2] http://article.gmane.org/gmane.linux.drivers.sensors/37859 > > Mark. > -- > To unsubscribe from this list: send the line "unsubscribe linux-pm" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 2/5] firmware: arm_scpi: Extend to support sensors
Sudeep Holla writes: > On 15/09/15 17:50, Punit Agrawal wrote: >> ARM System Control Processor (SCP) provides an API to query and use >> the sensors available in the system. Extend the SCPI driver to support >> sensor messages. >> >> Signed-off-by: Punit Agrawal >> Cc: Sudeep Holla > > Acked-by: Sudeep Holla Thanks, Sudeep! > -- > To unsubscribe from this list: send the line "unsubscribe devicetree" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/3] thermal: Add Mediatek thermal controller support
Sascha Hauer writes: > Hi Punit, > > On Wed, Sep 30, 2015 at 10:36:14AM +0100, Punit Agrawal wrote: >> Hi Sascha, >> >> Re-posting a comment from v7. Perhaps you missed it... > > Uh, sorry. In fact I didn't miss it and I thought I have answered it. > Appearantly I haven't. > >> > + struct mtk_thermal *mt = bank->mt; >> > + int temp, i, max; >> > + u32 raw; >> > + >> > + temp = max = INT_MIN; >> > + >> > + for (i = 0; i < bank_data[bank->id].num_sensors; i++) { >> > + raw = readl(mt->thermal_base + sensing_points[i].msr); >> > + >> > + temp = raw_to_mcelsius(mt, raw); >> > + >> > + /* >> > + * The first read of a sensor often contains very high bogus >> > + * temperature value. Filter these out so that the system does >> > + * not immediately shut down. >> > + */ >> > + if (temp > 20) >> > + temp = 0; >> > + >> >> If the bogus value is only the first time the sensor is read, instead of >> filtering here, you could call mtk_thermal_bank_temperature at probe >> time when you are initialising the banks and ignore the returned value. > > It seems that after initialization the hardware needs some time to > settle before correct values can be read. Doing what you suggest would > mean we have to delay the boot by several 100ms. I'd rather not do that. Fair enough. Thanks for clarifying. > > Sascha -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 2/3] thermal: Add Mediatek thermal controller support
Hi Sascha, Re-posting a comment from v7. Perhaps you missed it... Sascha Hauer writes: > This adds support for the Mediatek thermal controller found on MT8173 > and likely other SoCs. > The controller is a bit special. It does not have its own ADC, instead > it controls the on-SoC AUXADC via AHB bus accesses. For this reason > we need the physical address of the AUXADC. Also it controls a mux > using AHB bus accesses, so we need the APMIXEDSYS physical address aswell. > > Signed-off-by: Sascha Hauer > Reviewed-by: Daniel Kurtz > --- > drivers/thermal/Kconfig | 8 + > drivers/thermal/Makefile | 1 + > drivers/thermal/mtk_thermal.c | 537 > ++ > 3 files changed, 546 insertions(+) > create mode 100644 drivers/thermal/mtk_thermal.c > > diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig > index 0390044..dadd1eb 100644 > --- a/drivers/thermal/Kconfig > +++ b/drivers/thermal/Kconfig > @@ -348,6 +348,14 @@ config INTEL_PCH_THERMAL > Thermal reporting device will provide temperature reading, > programmable trip points and other information. > > +config MTK_THERMAL > + tristate "Temperature sensor driver for mediatek SoCs" > + depends on ARCH_MEDIATEK || COMPILE_TEST > + default y > + help > + Enable this option if you want to have support for thermal management > + controller present in Mediatek SoCs > + > menu "Texas Instruments thermal drivers" > source "drivers/thermal/ti-soc-thermal/Kconfig" > endmenu > diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile > index 26f1608..5f979e7 100644 > --- a/drivers/thermal/Makefile > +++ b/drivers/thermal/Makefile > @@ -45,3 +45,4 @@ obj-$(CONFIG_INTEL_PCH_THERMAL) += intel_pch_thermal.o > obj-$(CONFIG_ST_THERMAL) += st/ > obj-$(CONFIG_TEGRA_SOCTHERM) += tegra_soctherm.o > obj-$(CONFIG_HISI_THERMAL) += hisi_thermal.o > +obj-$(CONFIG_MTK_THERMAL)+= mtk_thermal.o > diff --git a/drivers/thermal/mtk_thermal.c b/drivers/thermal/mtk_thermal.c > new file mode 100644 > index 000..6be1a6c > --- /dev/null > +++ b/drivers/thermal/mtk_thermal.c > @@ -0,0 +1,537 @@ > +/* > + * Copyright (c) 2015 MediaTek Inc. > + * Author: Hanyi Wu > + * > + * This program is free software; you can redistribute it and/or modify > + * it under the terms of the GNU General Public License version 2 as > + * published by the Free Software Foundation. > + * > + * This program is distributed in the hope that it will be useful, > + * but WITHOUT ANY WARRANTY; without even the implied warranty of > + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the > + * GNU General Public License for more details. > + */ > + > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > +#include > + > +/* AUXADC Registers */ > +#define AUXADC_CON0_V0x000 > +#define AUXADC_CON1_V0x004 > +#define AUXADC_CON1_SET_V0x008 > +#define AUXADC_CON1_CLR_V0x00c > +#define AUXADC_CON2_V0x010 > +#define AUXADC_DATA(channel) (0x14 + (channel) * 4) > +#define AUXADC_MISC_V0x094 > + > +#define AUXADC_CON1_CHANNEL(x) BIT(x) > + > +#define APMIXED_SYS_TS_CON1 0x604 > + > +/* Thermal Controller Registers */ > +#define TEMP_MONCTL0 0x000 > +#define TEMP_MONCTL1 0x004 > +#define TEMP_MONCTL2 0x008 > +#define TEMP_MONIDET00x014 > +#define TEMP_MONIDET10x018 > +#define TEMP_MSRCTL0 0x038 > +#define TEMP_AHBPOLL 0x040 > +#define TEMP_AHBTO 0x044 > +#define TEMP_ADCPNP0 0x048 > +#define TEMP_ADCPNP1 0x04c > +#define TEMP_ADCPNP2 0x050 > +#define TEMP_ADCPNP3 0x0b4 > + > +#define TEMP_ADCMUX 0x054 > +#define TEMP_ADCEN 0x060 > +#define TEMP_PNPMUXADDR 0x064 > +#define TEMP_ADCMUXADDR 0x068 > +#define TEMP_ADCENADDR 0x074 > +#define TEMP_ADCVALIDADDR0x078 > +#define TEMP_ADCVOLTADDR 0x07c > +#define TEMP_RDCTRL 0x080 > +#define TEMP_ADCVALIDMASK0x084 > +#define TEMP_ADCVOLTAGESHIFT 0x088 > +#define TEMP_ADCWRITECTRL0x08c > +#define TEMP_MSR00x090 > +#define TEMP_MSR10x094 > +#define TEMP_MSR20x098 > +#define TEMP_MSR30x0B8 > + > +#define TEMP_SPARE0 0x0f0 > + > +#define PTPCORESEL 0x400 > + > +#define TEMP_MONCTL1_PERIOD_UNIT(x) ((x) & 0x3ff) > + > +#define TEMP_MONCTL2_FILTER_INTERVAL(x) (((x) & 0x3ff)) << 16 > +#define TEMP_MONCTL2_SENSOR_INTERVAL(x) ((x) & 0x3ff) > + > +#define TEMP_AHBPOLL_ADC_POLL_INTERVAL(x)(x) > + > +#define TEMP_ADCWRITECTRL_ADC_PNP_WRITE BIT(0) > +#define TEMP_ADCWRITECTRL_ADC_MUX_WRITE BIT(1) > + > +#define TEMP_ADCVALIDMASK_VALID_HIGH BIT(5) > +#d
Re: [PATCH v4 1/5] Documentation: add DT bindings for ARM SCPI sensors
Rob Herring writes: > On Tue, Sep 15, 2015 at 11:50 AM, Punit Agrawal wrote: >> The System Control Processor (SCP) provides access to SoC sensors via >> the System Control and Power Interface (SCPI) Message Protocol. Add >> bindings to allow probing of these sensors. Also support referencing >> of the sensors for setting up thermal zones via the thermal DT >> bindings. >> >> Signed-off-by: Punit Agrawal >> Cc: Rob Herring > > Acked-by: Rob Herring Thanks, Rob! Sudeep, now that we have acks for all the patches, are you OK to take this patchset along with your series adding support for SCPI? Punit > >> Cc: Mark Rutland >> Cc: Sudeep Holla >> --- >> Documentation/devicetree/bindings/arm/arm,scpi.txt | 38 >> ++ >> 1 file changed, 38 insertions(+) >> >> diff --git a/Documentation/devicetree/bindings/arm/arm,scpi.txt >> b/Documentation/devicetree/bindings/arm/arm,scpi.txt >> index f002460..86302de 100644 >> --- a/Documentation/devicetree/bindings/arm/arm,scpi.txt >> +++ b/Documentation/devicetree/bindings/arm/arm,scpi.txt >> @@ -72,8 +72,25 @@ Required sub-node properties: >> - compatible : should be "arm,juno-scp-shmem" for Non-secure SRAM based >>shared memory on Juno platforms >> >> +Sensor bindings for the sensors based on SCPI Message Protocol >> +-- >> +SCPI provides an API to access the various sensors on the SoC. >> + >> +Required properties: >> +- compatible : should be "arm,scpi-sensors". >> +- #thermal-sensor-cells: should be set to 1. This property follows the >> +thermal device tree bindings[2]. >> + >> +Valid cell values are raw identifiers (Sensor >> +ID) as used by the firmware. Refer to >> +platform documentation for your >> +implementation for the IDs to use. For Juno >> +R0 and Juno R1 refer to [3]. >> + >> [0] http://infocenter.arm.com/help/topic/com.arm.doc.dui0922b/index.html >> [1] Documentation/devicetree/bindings/clock/clock-bindings.txt >> +[2] Documentation/devicetree/bindings/thermal/thermal.txt >> +[3] >> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/apas03s22.html >> >> Example: >> >> @@ -122,6 +139,11 @@ scpi_protocol: scpi@2e00 { >> clock-output-names = "pxlclk0", "pxlclk1"; >> }; >> }; >> + >> + scpi_sensors0: sensors { >> + compatible = "arm,scpi-sensors"; >> + #thermal-sensor-cells = <1>; >> + }; >> }; >> >> cpu@0 { >> @@ -136,6 +158,17 @@ hdlcd@7ff6 { >> clocks = <&scpi_clk 4>; >> }; >> >> +thermal-zones { >> + soc_thermal { >> + polling-delay-passive = <100>; >> + polling-delay = <1000>; >> + >> + /* sensor ID */ >> + thermal-sensors = <&scpi_sensors0 3>; >> + ... >> + }; >> +}; >> + >> In the above example, the #clock-cells is set to 1 as required. >> scpi_dvfs has 3 output clocks namely: atlclk, aplclk, and gpuclk with 0, >> 1 and 2 as clock-indices. scpi_clk has 2 output clocks namely: pxlclk0 >> @@ -148,3 +181,8 @@ scpi_dvfs i.e. "atlclk". >> Similarly the second example is hdlcd@7ff6 and it has pxlclk1 as input >> clock. '4' in the clock specifier here points to the second entry >> in the output clocks of scpi_clocks i.e. "pxlclk1" >> + >> +The thermal-sensors property in the soc_thermal node uses the >> +temperature sensor provided by SCP firmware to setup a thermal >> +zone. The ID "3" is the sensor identifier for the temperature sensor >> +as used by the firmware. >> -- >> 2.5.1 >> > -- > To unsubscribe from this list: send the line "unsubscribe devicetree" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 1/5] Documentation: add DT bindings for ARM SCPI sensors
Punit Agrawal writes: > Punit Agrawal writes: > >> The System Control Processor (SCP) provides access to SoC sensors via >> the System Control and Power Interface (SCPI) Message Protocol. Add >> bindings to allow probing of these sensors. Also support referencing >> of the sensors for setting up thermal zones via the thermal DT >> bindings. >> >> Signed-off-by: Punit Agrawal >> Cc: Rob Herring >> Cc: Mark Rutland >> Cc: Sudeep Holla > > Gentle reminder for review of the below bindings. They've been updated > based on feedback on the earlier version [a]. > > If there are no further comments, I'd like to request an ack from the DT > reviewers. Ping! > > [a] > http://thread.gmane.org/gmane.linux.power-management.general/65475/focus=134976 > >> --- >> Documentation/devicetree/bindings/arm/arm,scpi.txt | 38 >> ++ >> 1 file changed, 38 insertions(+) >> >> diff --git a/Documentation/devicetree/bindings/arm/arm,scpi.txt >> b/Documentation/devicetree/bindings/arm/arm,scpi.txt >> index f002460..86302de 100644 >> --- a/Documentation/devicetree/bindings/arm/arm,scpi.txt >> +++ b/Documentation/devicetree/bindings/arm/arm,scpi.txt >> @@ -72,8 +72,25 @@ Required sub-node properties: >> - compatible : should be "arm,juno-scp-shmem" for Non-secure SRAM based >> shared memory on Juno platforms >> >> +Sensor bindings for the sensors based on SCPI Message Protocol >> +-- >> +SCPI provides an API to access the various sensors on the SoC. >> + >> +Required properties: >> +- compatible : should be "arm,scpi-sensors". >> +- #thermal-sensor-cells: should be set to 1. This property follows the >> + thermal device tree bindings[2]. >> + >> + Valid cell values are raw identifiers (Sensor >> + ID) as used by the firmware. Refer to >> + platform documentation for your >> + implementation for the IDs to use. For Juno >> + R0 and Juno R1 refer to [3]. >> + >> [0] http://infocenter.arm.com/help/topic/com.arm.doc.dui0922b/index.html >> [1] Documentation/devicetree/bindings/clock/clock-bindings.txt >> +[2] Documentation/devicetree/bindings/thermal/thermal.txt >> +[3] >> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/apas03s22.html >> >> Example: >> >> @@ -122,6 +139,11 @@ scpi_protocol: scpi@2e00 { >> clock-output-names = "pxlclk0", "pxlclk1"; >> }; >> }; >> + >> +scpi_sensors0: sensors { >> +compatible = "arm,scpi-sensors"; >> +#thermal-sensor-cells = <1>; >> +}; >> }; >> >> cpu@0 { >> @@ -136,6 +158,17 @@ hdlcd@7ff6 { >> clocks = <&scpi_clk 4>; >> }; >> >> +thermal-zones { >> +soc_thermal { >> +polling-delay-passive = <100>; >> +polling-delay = <1000>; >> + >> +/* sensor ID */ >> +thermal-sensors = <&scpi_sensors0 3>; >> +... >> +}; >> +}; >> + >> In the above example, the #clock-cells is set to 1 as required. >> scpi_dvfs has 3 output clocks namely: atlclk, aplclk, and gpuclk with 0, >> 1 and 2 as clock-indices. scpi_clk has 2 output clocks namely: pxlclk0 >> @@ -148,3 +181,8 @@ scpi_dvfs i.e. "atlclk". >> Similarly the second example is hdlcd@7ff6 and it has pxlclk1 as input >> clock. '4' in the clock specifier here points to the second entry >> in the output clocks of scpi_clocks i.e. "pxlclk1" >> + >> +The thermal-sensors property in the soc_thermal node uses the >> +temperature sensor provided by SCP firmware to setup a thermal >> +zone. The ID "3" is the sensor identifier for the temperature sensor >> +as used by the firmware. > -- > To unsubscribe from this list: send the line "unsubscribe devicetree" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/2] of: thermal: Fix inconsitency between cooling-*-state and cooling-*-level
Hi Rob, Rob Herring writes: > On Tue, Sep 8, 2015 at 6:20 AM, Punit Agrawal wrote: >> The device trees in the kernel as well as the binding description in >> Documentation/devicetree/bindings/cpufreq/cpufreq-dt.txt use the >> cooling-{min,max}-level property. >> >> Fix the inconsistency with the binding description in >> Documentation/devicetree/bindings/thermal/thermal.txt by changing >> cooling-*-state properties to cooling-*-level. >> >> Signed-off-by: Punit Agrawal >> Cc: Eduardo Valentin >> Cc: Rob Herring >> Cc: Mark Rutland >> Cc: Ian Campbell >> Cc: Kumar Gala > > Both patches applied. Thanks. I see the patches in v4.3-rc3 now. Thanks for picking up these fixes. Cheers, Punit > > Rob > >> --- >> Documentation/devicetree/bindings/thermal/thermal.txt | 14 +++--- >> 1 file changed, 7 insertions(+), 7 deletions(-) >> >> diff --git a/Documentation/devicetree/bindings/thermal/thermal.txt >> b/Documentation/devicetree/bindings/thermal/thermal.txt >> index 8a49362..8320186 100644 >> --- a/Documentation/devicetree/bindings/thermal/thermal.txt >> +++ b/Documentation/devicetree/bindings/thermal/thermal.txt >> @@ -55,16 +55,16 @@ of heat dissipation). For example a fan's cooling states >> correspond to >> the different fan speeds possible. Cooling states are referred to by >> single unsigned integers, where larger numbers mean greater heat >> dissipation. The precise set of cooling states associated with a device >> -(as referred to be the cooling-min-state and cooling-max-state >> +(as referred to by the cooling-min-level and cooling-max-level >> properties) should be defined in a particular device's binding. >> For more examples of cooling devices, refer to the example sections below. >> >> Required properties: >> -- cooling-min-state: An integer indicating the smallest >> +- cooling-min-level: An integer indicating the smallest >>Type: unsigned cooling state accepted. Typically 0. >>Size: one cell >> >> -- cooling-max-state: An integer indicating the largest >> +- cooling-max-level: An integer indicating the largest >>Type: unsigned cooling state accepted. >>Size: one cell >> >> @@ -225,8 +225,8 @@ cpus { >> 396000 95 >> 198000 85 >> >; >> - cooling-min-state = <0>; >> - cooling-max-state = <3>; >> + cooling-min-level = <0>; >> + cooling-max-level = <3>; >> #cooling-cells = <2>; /* min followed by max */ >> }; >> ... >> @@ -240,8 +240,8 @@ cpus { >> */ >> fan0: fan@0x48 { >> ... >> - cooling-min-state = <0>; >> - cooling-max-state = <9>; >> + cooling-min-level = <0>; >> + cooling-max-level = <9>; >> #cooling-cells = <2>; /* min followed by max */ >> }; >> }; >> -- >> 2.5.0 >> > -- > To unsubscribe from this list: send the line "unsubscribe devicetree" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 5/5] arm64: dts: Add sensor node to Juno dt
Liviu Dudau writes: > On Tue, Sep 15, 2015 at 05:51:01PM +0100, Punit Agrawal wrote: >> The SCP firmware on Juno provides access to SoC sensors via the >> SCPI. Add the sensor nodes to the device tree to enable this support. >> >> Signed-off-by: Punit Agrawal >> Cc: Rob Herring >> Cc: Mark Rutland >> Cc: Liviu Dudau > > Acked-by: Liviu Dudau Thanks Liviu! > >> Cc: Sudeep Holla >> --- >> arch/arm64/boot/dts/arm/juno-base.dtsi | 5 + >> 1 file changed, 5 insertions(+) >> >> diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi >> b/arch/arm64/boot/dts/arm/juno-base.dtsi >> index c624208..dd5158e 100644 >> --- a/arch/arm64/boot/dts/arm/juno-base.dtsi >> +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi >> @@ -96,6 +96,11 @@ >> clock-output-names = "pxlclk0", "pxlclk1"; >> }; >> }; >> + >> +scpi_sensors0: sensors { >> +compatible = "arm,scpi-sensors"; >> +#thermal-sensor-cells = <1>; >> +}; >> }; >> >> /include/ "juno-clocks.dtsi" >> -- >> 2.5.1 >> -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v4 1/5] Documentation: add DT bindings for ARM SCPI sensors
Punit Agrawal writes: > The System Control Processor (SCP) provides access to SoC sensors via > the System Control and Power Interface (SCPI) Message Protocol. Add > bindings to allow probing of these sensors. Also support referencing > of the sensors for setting up thermal zones via the thermal DT > bindings. > > Signed-off-by: Punit Agrawal > Cc: Rob Herring > Cc: Mark Rutland > Cc: Sudeep Holla Gentle reminder for review of the below bindings. They've been updated based on feedback on the earlier version [a]. If there are no further comments, I'd like to request an ack from the DT reviewers. [a] http://thread.gmane.org/gmane.linux.power-management.general/65475/focus=134976 > --- > Documentation/devicetree/bindings/arm/arm,scpi.txt | 38 > ++ > 1 file changed, 38 insertions(+) > > diff --git a/Documentation/devicetree/bindings/arm/arm,scpi.txt > b/Documentation/devicetree/bindings/arm/arm,scpi.txt > index f002460..86302de 100644 > --- a/Documentation/devicetree/bindings/arm/arm,scpi.txt > +++ b/Documentation/devicetree/bindings/arm/arm,scpi.txt > @@ -72,8 +72,25 @@ Required sub-node properties: > - compatible : should be "arm,juno-scp-shmem" for Non-secure SRAM based > shared memory on Juno platforms > > +Sensor bindings for the sensors based on SCPI Message Protocol > +-- > +SCPI provides an API to access the various sensors on the SoC. > + > +Required properties: > +- compatible : should be "arm,scpi-sensors". > +- #thermal-sensor-cells: should be set to 1. This property follows the > + thermal device tree bindings[2]. > + > + Valid cell values are raw identifiers (Sensor > + ID) as used by the firmware. Refer to > + platform documentation for your > + implementation for the IDs to use. For Juno > + R0 and Juno R1 refer to [3]. > + > [0] http://infocenter.arm.com/help/topic/com.arm.doc.dui0922b/index.html > [1] Documentation/devicetree/bindings/clock/clock-bindings.txt > +[2] Documentation/devicetree/bindings/thermal/thermal.txt > +[3] > http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/apas03s22.html > > Example: > > @@ -122,6 +139,11 @@ scpi_protocol: scpi@2e00 { > clock-output-names = "pxlclk0", "pxlclk1"; > }; > }; > + > + scpi_sensors0: sensors { > + compatible = "arm,scpi-sensors"; > + #thermal-sensor-cells = <1>; > + }; > }; > > cpu@0 { > @@ -136,6 +158,17 @@ hdlcd@7ff6 { > clocks = <&scpi_clk 4>; > }; > > +thermal-zones { > + soc_thermal { > + polling-delay-passive = <100>; > + polling-delay = <1000>; > + > + /* sensor ID */ > + thermal-sensors = <&scpi_sensors0 3>; > + ... > + }; > +}; > + > In the above example, the #clock-cells is set to 1 as required. > scpi_dvfs has 3 output clocks namely: atlclk, aplclk, and gpuclk with 0, > 1 and 2 as clock-indices. scpi_clk has 2 output clocks namely: pxlclk0 > @@ -148,3 +181,8 @@ scpi_dvfs i.e. "atlclk". > Similarly the second example is hdlcd@7ff6 and it has pxlclk1 as input > clock. '4' in the clock specifier here points to the second entry > in the output clocks of scpi_clocks i.e. "pxlclk1" > + > +The thermal-sensors property in the soc_thermal node uses the > +temperature sensor provided by SCP firmware to setup a thermal > +zone. The ID "3" is the sensor identifier for the temperature sensor > +as used by the firmware. -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 0/2] Update OF thermal properties for cooling-{min,max}-level
Punit Agrawal writes: > Hi, > > The device tree properties regarding the specification and usage of > states for cooling devices suffer from inconsistency in the bindings > as well as the usage. > > The two patches here update the bindings to be consistent without > breaking existing support for the device trees already in upstream. > Gentle reminder to request review of the below two patches! > Thanks, > Punit > > Punit Agrawal (2): > of: thermal: Fix inconsitency between cooling-*-state and > cooling-*-level > of: thermal: Mark cooling-*-level properties optional > > .../devicetree/bindings/thermal/thermal.txt| 27 > +++--- > 1 file changed, 14 insertions(+), 13 deletions(-) -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 4/5] hwmon: Support thermal zones registration for SCP temperature sensors
Add support to create thermal zones based on the temperature sensors provided by the SCP. The thermal zones can be defined using the thermal DT bindings and should refer to the SCP sensor id to select the sensor. Signed-off-by: Punit Agrawal Acked-by: Guenter Roeck Cc: Eduardo Valentin --- drivers/hwmon/scpi-hwmon.c | 104 - 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c index c7d1d14..2c1241b 100644 --- a/drivers/hwmon/scpi-hwmon.c +++ b/drivers/hwmon/scpi-hwmon.c @@ -20,6 +20,7 @@ #include #include #include +#include struct sensor_data { struct scpi_sensor_info info; @@ -29,14 +30,39 @@ struct sensor_data { char label[20]; }; +struct scpi_thermal_zone { + struct list_head list; + int sensor_id; + struct scpi_sensors *scpi_sensors; + struct thermal_zone_device *tzd; +}; + struct scpi_sensors { struct scpi_ops *scpi_ops; struct sensor_data *data; + struct list_head thermal_zones; struct attribute **attrs; struct attribute_group group; const struct attribute_group *groups[2]; }; +static int scpi_read_temp(void *dev, int *temp) +{ + struct scpi_thermal_zone *zone = dev; + struct scpi_sensors *scpi_sensors = zone->scpi_sensors; + struct scpi_ops *scpi_ops = scpi_sensors->scpi_ops; + struct sensor_data *sensor = &scpi_sensors->data[zone->sensor_id]; + u32 value; + int ret; + + ret = scpi_ops->sensor_get_value(sensor->info.sensor_id, &value); + if (ret) + return ret; + + *temp = value; + return 0; +} + /* hwmon callback functions */ static ssize_t scpi_show_sensor(struct device *dev, struct device_attribute *attr, char *buf) @@ -66,6 +92,24 @@ scpi_show_label(struct device *dev, struct device_attribute *attr, char *buf) return sprintf(buf, "%s\n", sensor->info.name); } +static void +unregister_thermal_zones(struct platform_device *pdev, +struct scpi_sensors *scpi_sensors) +{ + struct list_head *pos; + + list_for_each(pos, &scpi_sensors->thermal_zones) { + struct scpi_thermal_zone *zone; + + zone = list_entry(pos, struct scpi_thermal_zone, list); + thermal_zone_of_sensor_unregister(&pdev->dev, zone->tzd); + } +} + +static struct thermal_zone_of_device_ops scpi_sensor_ops = { + .get_temp = scpi_read_temp, +}; + static int scpi_hwmon_probe(struct platform_device *pdev) { u16 nr_sensors, i; @@ -160,10 +204,67 @@ static int scpi_hwmon_probe(struct platform_device *pdev) scpi_sensors->group.attrs = scpi_sensors->attrs; scpi_sensors->groups[0] = &scpi_sensors->group; + platform_set_drvdata(pdev, scpi_sensors); + hwdev = devm_hwmon_device_register_with_groups(dev, "scpi_sensors", scpi_sensors, scpi_sensors->groups); - return PTR_ERR_OR_ZERO(hwdev); + if (IS_ERR(hwdev)) + return PTR_ERR(hwdev); + + /* +* Register the temperature sensors with the thermal framework +* to allow their usage in setting up the thermal zones from +* device tree. +* +* NOTE: Not all temperature sensors maybe used for thermal +* control +*/ + INIT_LIST_HEAD(&scpi_sensors->thermal_zones); + for (i = 0; i < nr_sensors; i++) { + struct sensor_data *sensor = &scpi_sensors->data[i]; + struct scpi_thermal_zone *zone; + + if (sensor->info.class != TEMPERATURE) + continue; + + zone = devm_kzalloc(dev, sizeof(*zone), GFP_KERNEL); + if (!zone) { + ret = -ENOMEM; + goto unregister_tzd; + } + + zone->sensor_id = i; + zone->scpi_sensors = scpi_sensors; + zone->tzd = thermal_zone_of_sensor_register(dev, i, zone, + &scpi_sensor_ops); + /* +* The call to thermal_zone_of_sensor_register returns +* an error for sensors that are not associated with +* any thermal zones or if the thermal subsystem is +* not configured. +*/ + if (IS_ERR(zone->tzd)) { + devm_kfree(dev, zone); + continue; + } + list_add(&zone->list, &scpi_sensors->thermal_zones); + } + + return 0; + +unregister_tzd: + unregister_thermal_zones(pdev, scpi_sensors); + return ret; +} + +static int scpi_hwmon_remove(struct platform_device *pdev) +{ + str
[PATCH v4 3/5] hwmon: Support sensors exported via ARM SCP interface
Create a driver to add support for SoC sensors exported by the System Control Processor (SCP) via the System Control and Power Interface (SCPI). The supported sensor types is one of voltage, temperature, current, and power. The sensor labels and values provided by the SCP are exported via the hwmon sysfs interface. Signed-off-by: Punit Agrawal Acked-by: Guenter Roeck Cc: Sudeep Holla --- Documentation/hwmon/scpi-hwmon | 33 drivers/hwmon/Kconfig | 8 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/scpi-hwmon.c | 186 + 4 files changed, 228 insertions(+) create mode 100644 Documentation/hwmon/scpi-hwmon create mode 100644 drivers/hwmon/scpi-hwmon.c diff --git a/Documentation/hwmon/scpi-hwmon b/Documentation/hwmon/scpi-hwmon new file mode 100644 index 000..4cfcdf2d --- /dev/null +++ b/Documentation/hwmon/scpi-hwmon @@ -0,0 +1,33 @@ +Kernel driver scpi-hwmon + + +Supported chips: + * Chips based on ARM System Control Processor Interface + Addresses scanned: - + Datasheet: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/index.html + +Author: Punit Agrawal + +Description +--- + +This driver supports hardware monitoring for SoC's based on the ARM +System Control Processor (SCP) implementing the System Control +Processor Interface (SCPI). The following sensor types are supported +by the SCP - + + * temperature + * voltage + * current + * power + +The SCP interface provides an API to query the available sensors and +their values which are then exported to userspace by this driver. + +Usage Notes +--- + +The driver relies on device tree node to indicate the presence of SCPI +support in the kernel. See +Documentation/devicetree/bindings/arm/arm,scpi.txt for details of the +devicetree node. \ No newline at end of file diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index c7a4f09..4b94327 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1551,6 +1551,14 @@ config SENSORS_VEXPRESS the ARM Ltd's Versatile Express platform. It can provide wide range of information like temperature, power, energy. +config SENSORS_ARM_SCPI + tristate "ARM SCPI Sensors" + depends on ARM_SCPI_PROTOCOL + help + This driver provides support for temperature, voltage, current + and power sensors available on ARM Ltd's SCP based platforms. The + actual number and type of sensors exported depend the platform. + config SENSORS_VIA_CPUTEMP tristate "VIA CPU temperature sensor" depends on X86 diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 8aba87f..4961710 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -150,6 +150,7 @@ obj-$(CONFIG_SENSORS_TMP421)+= tmp421.o obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o obj-$(CONFIG_SENSORS_V2M_JUNO) += v2m-juno.o obj-$(CONFIG_SENSORS_VEXPRESS) += vexpress.o +obj-$(CONFIG_SENSORS_ARM_SCPI) += scpi-hwmon.o obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o obj-$(CONFIG_SENSORS_VIA686A) += via686a.o obj-$(CONFIG_SENSORS_VT1211) += vt1211.o diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c new file mode 100644 index 000..c7d1d14 --- /dev/null +++ b/drivers/hwmon/scpi-hwmon.c @@ -0,0 +1,186 @@ +/* + * System Control and Power Interface(SCPI) based hwmon sensor driver + * + * Copyright (C) 2015 ARM Ltd. + * Punit Agrawal + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include + +struct sensor_data { + struct scpi_sensor_info info; + struct device_attribute dev_attr_input; + struct device_attribute dev_attr_label; + char input[20]; + char label[20]; +}; + +struct scpi_sensors { + struct scpi_ops *scpi_ops; + struct sensor_data *data; + struct attribute **attrs; + struct attribute_group group; + const struct attribute_group *groups[2]; +}; + +/* hwmon callback functions */ +static ssize_t +scpi_show_sensor(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct scpi_sensors *scpi_sensors = dev_get_drvdata(dev); + struct scpi_ops *scpi_ops = scpi_sensors->scpi_ops; + struct sensor_data *sensor; + u32 value; + int ret; + + sensor = container_of(attr, struct sensor_data, dev_attr_input); + + ret = scpi_ops->sensor_get_val
[PATCH v4 5/5] arm64: dts: Add sensor node to Juno dt
The SCP firmware on Juno provides access to SoC sensors via the SCPI. Add the sensor nodes to the device tree to enable this support. Signed-off-by: Punit Agrawal Cc: Rob Herring Cc: Mark Rutland Cc: Liviu Dudau Cc: Sudeep Holla --- arch/arm64/boot/dts/arm/juno-base.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi index c624208..dd5158e 100644 --- a/arch/arm64/boot/dts/arm/juno-base.dtsi +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -96,6 +96,11 @@ clock-output-names = "pxlclk0", "pxlclk1"; }; }; + + scpi_sensors0: sensors { + compatible = "arm,scpi-sensors"; + #thermal-sensor-cells = <1>; + }; }; /include/ "juno-clocks.dtsi" -- 2.5.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 1/5] Documentation: add DT bindings for ARM SCPI sensors
The System Control Processor (SCP) provides access to SoC sensors via the System Control and Power Interface (SCPI) Message Protocol. Add bindings to allow probing of these sensors. Also support referencing of the sensors for setting up thermal zones via the thermal DT bindings. Signed-off-by: Punit Agrawal Cc: Rob Herring Cc: Mark Rutland Cc: Sudeep Holla --- Documentation/devicetree/bindings/arm/arm,scpi.txt | 38 ++ 1 file changed, 38 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/arm,scpi.txt b/Documentation/devicetree/bindings/arm/arm,scpi.txt index f002460..86302de 100644 --- a/Documentation/devicetree/bindings/arm/arm,scpi.txt +++ b/Documentation/devicetree/bindings/arm/arm,scpi.txt @@ -72,8 +72,25 @@ Required sub-node properties: - compatible : should be "arm,juno-scp-shmem" for Non-secure SRAM based shared memory on Juno platforms +Sensor bindings for the sensors based on SCPI Message Protocol +-- +SCPI provides an API to access the various sensors on the SoC. + +Required properties: +- compatible : should be "arm,scpi-sensors". +- #thermal-sensor-cells: should be set to 1. This property follows the +thermal device tree bindings[2]. + +Valid cell values are raw identifiers (Sensor +ID) as used by the firmware. Refer to +platform documentation for your +implementation for the IDs to use. For Juno +R0 and Juno R1 refer to [3]. + [0] http://infocenter.arm.com/help/topic/com.arm.doc.dui0922b/index.html [1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/thermal/thermal.txt +[3] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/apas03s22.html Example: @@ -122,6 +139,11 @@ scpi_protocol: scpi@2e00 { clock-output-names = "pxlclk0", "pxlclk1"; }; }; + + scpi_sensors0: sensors { + compatible = "arm,scpi-sensors"; + #thermal-sensor-cells = <1>; + }; }; cpu@0 { @@ -136,6 +158,17 @@ hdlcd@7ff6 { clocks = <&scpi_clk 4>; }; +thermal-zones { + soc_thermal { + polling-delay-passive = <100>; + polling-delay = <1000>; + + /* sensor ID */ + thermal-sensors = <&scpi_sensors0 3>; + ... + }; +}; + In the above example, the #clock-cells is set to 1 as required. scpi_dvfs has 3 output clocks namely: atlclk, aplclk, and gpuclk with 0, 1 and 2 as clock-indices. scpi_clk has 2 output clocks namely: pxlclk0 @@ -148,3 +181,8 @@ scpi_dvfs i.e. "atlclk". Similarly the second example is hdlcd@7ff6 and it has pxlclk1 as input clock. '4' in the clock specifier here points to the second entry in the output clocks of scpi_clocks i.e. "pxlclk1" + +The thermal-sensors property in the soc_thermal node uses the +temperature sensor provided by SCP firmware to setup a thermal +zone. The ID "3" is the sensor identifier for the temperature sensor +as used by the firmware. -- 2.5.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 2/5] firmware: arm_scpi: Extend to support sensors
ARM System Control Processor (SCP) provides an API to query and use the sensors available in the system. Extend the SCPI driver to support sensor messages. Signed-off-by: Punit Agrawal Cc: Sudeep Holla --- drivers/firmware/arm_scpi.c | 60 +++ include/linux/scpi_protocol.h | 17 2 files changed, 77 insertions(+) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index cb75c75..321680e 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -219,6 +219,21 @@ struct dvfs_set { u8 index; } __packed; +struct sensor_capabilities { + __le16 sensors; +} __packed; + +struct _scpi_sensor_info { + __le16 sensor_id; + u8 class; + u8 trigger_type; + char name[20]; +}; + +struct sensor_value { + __le32 val; +} __packed; + static struct scpi_drvinfo *scpi_info; static int scpi_linux_errmap[SCPI_ERR_MAX] = { @@ -481,6 +496,48 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain) return info; } +static int scpi_sensor_get_capability(u16 *sensors) +{ + struct sensor_capabilities cap_buf; + int ret; + + ret = scpi_send_message(SCPI_CMD_SENSOR_CAPABILITIES, NULL, 0, &cap_buf, + sizeof(cap_buf)); + if (!ret) + *sensors = le16_to_cpu(cap_buf.sensors); + + return ret; +} + +static int scpi_sensor_get_info(u16 sensor_id, struct scpi_sensor_info *info) +{ + __le16 id = cpu_to_le16(sensor_id); + struct _scpi_sensor_info _info; + int ret; + + ret = scpi_send_message(SCPI_CMD_SENSOR_INFO, &id, +sizeof(id), &_info, sizeof(_info)); + if (!ret) { + memcpy(info, &_info, sizeof(*info)); + info->sensor_id = le16_to_cpu(_info.sensor_id); + } + + return ret; +} + +int scpi_sensor_get_value(u16 sensor, u32 *val) +{ + struct sensor_value buf; + int ret; + + ret = scpi_send_message(SCPI_CMD_SENSOR_VALUE, &sensor, sizeof(sensor), + &buf, sizeof(buf)); + if (!ret) + *val = le32_to_cpu(buf.val); + + return ret; +} + static struct scpi_ops scpi_ops = { .get_version = scpi_get_version, .clk_get_range = scpi_clk_get_range, @@ -489,6 +546,9 @@ static struct scpi_ops scpi_ops = { .dvfs_get_idx = scpi_dvfs_get_idx, .dvfs_set_idx = scpi_dvfs_set_idx, .dvfs_get_info = scpi_dvfs_get_info, + .sensor_get_capability = scpi_sensor_get_capability, + .sensor_get_info = scpi_sensor_get_info, + .sensor_get_value = scpi_sensor_get_value, }; struct scpi_ops *get_scpi_ops(void) diff --git a/include/linux/scpi_protocol.h b/include/linux/scpi_protocol.h index e7169cd..80af3cd 100644 --- a/include/linux/scpi_protocol.h +++ b/include/linux/scpi_protocol.h @@ -28,6 +28,20 @@ struct scpi_dvfs_info { struct scpi_opp *opps; }; +enum scpi_sensor_class { + TEMPERATURE, + VOLTAGE, + CURRENT, + POWER, +}; + +struct scpi_sensor_info { + u16 sensor_id; + u8 class; + u8 trigger_type; + char name[20]; +} __packed; + /** * struct scpi_ops - represents the various operations provided * by SCP through SCPI message protocol @@ -52,6 +66,9 @@ struct scpi_ops { int (*dvfs_get_idx)(u8); int (*dvfs_set_idx)(u8, u8); struct scpi_dvfs_info *(*dvfs_get_info)(u8); + int (*sensor_get_capability)(u16 *sensors); + int (*sensor_get_info)(u16 sensor_id, struct scpi_sensor_info *); + int (*sensor_get_value)(u16, u32 *); }; #if IS_ENABLED(CONFIG_ARM_SCPI_PROTOCOL) -- 2.5.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v4 0/5] SCPI sensors support
Hi, This series adds support for SCPI based sensors for ARM development platform. In addition to supporting sensors, when a temperature sensor is discovered the driver registers the sensor with the thermal framework. The sensor patches here have been split out from a longer series adding support for registering power model based cooling devices for the CPU via device tree. Earliers postings can be seen at [0], [1], [2]. Patches 1-3 create a hwmon sensor driver for sensors provided by SCPI firmware. Patch 4 adds support for the temperature sensors to register with the thermal framework. This allows setting up platform thermals using OF thermal bindings. The last patch adds support for the sensors in the Juno r0 device tree. The patches depend on SCPI and mailbox patches[3] from Sudeep. The SCPI protocol document with details of the sensor interface can be found at [4]. I'd like to aim for merging the patches with the SCPI changes if possible. The hwmon patches have been acked by Guenter. If there aren't any objections, I would like to request acks for the binding updates in Patch 1. Thanks, Punit Changes v3 -> v4 - clarified binding regarding use of sensor identifier Changes v2 -> v3 - split out the sensor patches (posted here) - rebase onto v4.3-rc1 Changes v1 -> v2 - added documentation for the scpi-hwmon driver - replaced static allocation of platform structure in scpi-hwmon.c with dynamic allocation - re-structured registering of thermal zones to better handle error conditions - reduced chattiness in scpi-hwmon.c - corrected sensor numbering to align with hwmon documentation - dynamic allocation of attributes and attribute groups [0] http://thread.gmane.org/gmane.linux.kernel/2002152 [1] http://thread.gmane.org/gmane.linux.kernel/2011466 [2] http://thread.gmane.org/gmane.linux.power-management.general/65475 [3] http://thread.gmane.org/gmane.linux.kernel/2009735 [4] http://infocenter.arm.com/help/topic/com.arm.doc.dui0922b/index.html Punit Agrawal (5): Documentation: add DT bindings for ARM SCPI sensors firmware: arm_scpi: Extend to support sensors hwmon: Support sensors exported via ARM SCP interface hwmon: Support thermal zones registration for SCP temperature sensors arm64: dts: Add sensor node to Juno dt Documentation/devicetree/bindings/arm/arm,scpi.txt | 38 +++ Documentation/hwmon/scpi-hwmon | 33 +++ arch/arm64/boot/dts/arm/juno-base.dtsi | 5 + drivers/firmware/arm_scpi.c| 60 + drivers/hwmon/Kconfig | 8 + drivers/hwmon/Makefile | 1 + drivers/hwmon/scpi-hwmon.c | 288 + include/linux/scpi_protocol.h | 17 ++ 8 files changed, 450 insertions(+) create mode 100644 Documentation/hwmon/scpi-hwmon create mode 100644 drivers/hwmon/scpi-hwmon.c -- 2.5.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 1/5] Documentation: add DT bindings for ARM SCPI sensors
"Jon Medhurst (Tixy)" writes: > On Tue, 2015-09-15 at 10:37 +0100, Punit Agrawal wrote: >> "Jon Medhurst (Tixy)" writes: >> >> > On Mon, 2015-09-14 at 15:38 +0100, Punit Agrawal wrote: >> >> Mark Rutland writes: >> >> > [...] >> >> The way the SCP interface is defined, the sensor identifiers are >> >> contiguous, >> > >> > Is there any documentation other than DUI0922A? [1] From what I can seen >> > that just says it's a 16-bit value and doesn't put any particular >> > constraints on its value. >> >> Although not explicitly stated, if you look at the Get Sensor Capability >> [2] and Get Sensor Info [3] commands you can indirectly infer that the >> Sensor IDs are contiguous. > > I personally wouldn't even indirectly infer they are contiguous from > what the document says. If I were implementing the firmware I would feel > quite in my rights to, for example, use the top 8 bits of the ID for a > sensor type and the bottom 8 for an index, if that made dispatching of > requests more efficient. Or if some optional hardware was detected as > missing, leaving some holes in ID space. True. And without a command to convey the list of valid IDs, the consumer of the API would have to iterate over the entire 16bit space to locate valid IDs. > > As a specification of a 'standard' the document seems to be rather > lacking. So, Sensor ID should be documented as being "an unsigned > integer less than then number of sensors returned by the Get Sensor > Capability command", or something like that. I guess clocks and other > devices suffer from similar lack of specificity. I was thinking of suggesting something similar as an update. > >> Not the strongest guarantee I know. >> >> All platforms currently using SCP (Juno R0 and R1) do indeed expose >> contiguous identifiers. > > IMO, Linux drivers should be coded to the standard or written > specification (where they are available) not the particular > implementations available. > >> > >> > [1] >> > http://community.arm.com/servlet/JiveServlet/download/8401-40-18262/DUI0922A_scp_message_interface.pdf >> [2] >> http://arminfo.emea.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/ch03s02s21.html >> [3] >> http://arminfo.emea.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/BABCCCJJ.html > > I think those links are on ARM's intranet, they return NXDOMAIN for me. Apologies, the below should work. [2] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/ch03s02s21.html [3] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/BABCCCJJ.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 1/5] Documentation: add DT bindings for ARM SCPI sensors
"Jon Medhurst (Tixy)" writes: > On Mon, 2015-09-14 at 15:38 +0100, Punit Agrawal wrote: >> Mark Rutland writes: >> >> >> >> +Sensor bindings for the sensors based on SCPI Message Protocol >> >> >> +-- >> >> >> +SCPI provides an API to access the various sensors on the SoC. >> >> >> + >> >> >> +Required properties: >> >> >> +- compatible : should be "arm,scpi-sensors". >> >> >> +- #thermal-sensor-cells: should be set to 1. This property follows the >> >> >> + thermal device tree bindings[2]. >> >> > >> >> > You need to specify what the valid values for this cell are. >> >> >> >> The enumeration depends on the number of sensors exported by SCP >> >> firmware - which is platform dependent. I could add add something like >> >> if you think that is helpful - >> >> >> >> "Valid cell value is a number between 0..n-1, where n is the number >> >> of sensors exported by SCP firmware." >> > >> > Can the FW identifer space have holes? Or are they always contiguous? >> >> The way the SCP interface is defined, the sensor identifiers are >> contiguous, > > Is there any documentation other than DUI0922A? [1] From what I can seen > that just says it's a 16-bit value and doesn't put any particular > constraints on its value. Although not explicitly stated, if you look at the Get Sensor Capability [2] and Get Sensor Info [3] commands you can indirectly infer that the Sensor IDs are contiguous. Not the strongest guarantee I know. All platforms currently using SCP (Juno R0 and R1) do indeed expose contiguous identifiers. Maybe we can convince the authors to make it explicit. > > [1] > http://community.arm.com/servlet/JiveServlet/download/8401-40-18262/DUI0922A_scp_message_interface.pdf [2] http://arminfo.emea.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/ch03s02s21.html [3] http://arminfo.emea.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/BABCCCJJ.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 1/5] Documentation: add DT bindings for ARM SCPI sensors
Mark Rutland writes: > On Mon, Sep 14, 2015 at 04:01:09PM +0100, Punit Agrawal wrote: >> Mark Rutland writes: >> [...] >> >> After seeing the mapping already published, I am wondering if there is >> any value in duplicating the information. If there are no objections, >> I'll update this patch to add pointers instead. > > That's fine by me. The important part is that the value is a raw Sensor > ID as the FW uses. So long as we state that, the IDs themselves can come > from whatever documentation is valid for a particular instance. > > Thanks for the info! Sure. I've updated the patch to explain what the valid cell values are along with a pointer to platform documentation for Juno R0 and R1. I've also added an example to show usage of the sensors to create a thermal zone. I'll post a new version shortly. Thanks for your having a look. > > Thanks, > Mark. > -- > To unsubscribe from this list: send the line "unsubscribe linux-pm" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 1/5] Documentation: add DT bindings for ARM SCPI sensors
Mark Rutland writes: > On Mon, Sep 14, 2015 at 03:38:36PM +0100, Punit Agrawal wrote: >> Mark Rutland writes: >> >> >> >> +Sensor bindings for the sensors based on SCPI Message Protocol >> >> >> +-- >> >> >> +SCPI provides an API to access the various sensors on the SoC. >> >> >> + >> >> >> +Required properties: >> >> >> +- compatible : should be "arm,scpi-sensors". >> >> >> +- #thermal-sensor-cells: should be set to 1. This property follows the >> >> >> + thermal device tree bindings[2]. >> >> > >> >> > You need to specify what the valid values for this cell are. >> >> >> >> The enumeration depends on the number of sensors exported by SCP >> >> firmware - which is platform dependent. I could add add something like >> >> if you think that is helpful - >> >> >> >> "Valid cell value is a number between 0..n-1, where n is the number >> >> of sensors exported by SCP firmware." >> > >> > Can the FW identifer space have holes? Or are they always contiguous? >> >> The way the SCP interface is defined, the sensor identifiers are >> contiguous, but not all are temperature sensors. > > Ok. So how exactly are they enumerated for this binding? The sensor enumeration for r0 (which I've verified) and r1 can be found at [0]. The valid cell values are identifiers for the temperature sensors. > >> > If this is the same as the raw FW identifer value, specify that. >> > Otherwise, you need to specify the mapping. >> >> I'll update the patch to add mappings for Juno r0 (and r1 if I can get >> my hands on one). > > If there's identical logic mapping the two, we might just be able to > describe that rather than having to add tables all the time. > After seeing the mapping already published, I am wondering if there is any value in duplicating the information. If there are no objections, I'll update this patch to add pointers instead. >> > There needs to be enough information for a dts author to figure out >> > which values to place in the DT. >> >> I understand. Except sometimes it is hard to get the firmware to commit to >> not >> modify the ordering - discoverability and all that. :) > > If they do that, then things are broken regardless, no? I guess that'll > be clear if/when I see how the mapping works. [0] http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/apas03s22.html > > Thanks, > Mark. > -- > To unsubscribe from this list: send the line "unsubscribe devicetree" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 1/5] Documentation: add DT bindings for ARM SCPI sensors
Mark Rutland writes: >> >> +Sensor bindings for the sensors based on SCPI Message Protocol >> >> +-- >> >> +SCPI provides an API to access the various sensors on the SoC. >> >> + >> >> +Required properties: >> >> +- compatible : should be "arm,scpi-sensors". >> >> +- #thermal-sensor-cells: should be set to 1. This property follows the >> >> + thermal device tree bindings[2]. >> > >> > You need to specify what the valid values for this cell are. >> >> The enumeration depends on the number of sensors exported by SCP >> firmware - which is platform dependent. I could add add something like >> if you think that is helpful - >> >> "Valid cell value is a number between 0..n-1, where n is the number >> of sensors exported by SCP firmware." > > Can the FW identifer space have holes? Or are they always contiguous? The way the SCP interface is defined, the sensor identifiers are contiguous, but not all are temperature sensors. > > If this is the same as the raw FW identifer value, specify that. > Otherwise, you need to specify the mapping. I'll update the patch to add mappings for Juno r0 (and r1 if I can get my hands on one). > > There needs to be enough information for a dts author to figure out > which values to place in the DT. I understand. Except sometimes it is hard to get the firmware to commit to not modify the ordering - discoverability and all that. :) > > Thanks, > Mark. > -- > To unsubscribe from this list: send the line "unsubscribe devicetree" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v3 1/5] Documentation: add DT bindings for ARM SCPI sensors
Hi Mark, Thanks for taking a look. Mark Rutland writes: > On Mon, Sep 14, 2015 at 02:00:14PM +0100, Punit Agrawal wrote: >> The System Control Processor (SCP) provides access to SoC sensors via >> the System Control and Power Interface (SCPI) Message Protocol. Add >> bindings to allow probing of these sensors. Also support referencing >> of the sensors for setting up thermal zones via the thermal DT >> bindings. >> >> Signed-off-by: Punit Agrawal >> Cc: Rob Herring >> Cc: Mark Rutland >> Cc: Sudeep Holla >> --- >> Documentation/devicetree/bindings/arm/arm,scpi.txt | 15 +++ >> 1 file changed, 15 insertions(+) >> >> diff --git a/Documentation/devicetree/bindings/arm/arm,scpi.txt >> b/Documentation/devicetree/bindings/arm/arm,scpi.txt >> index f002460..af66f7f 100644 >> --- a/Documentation/devicetree/bindings/arm/arm,scpi.txt >> +++ b/Documentation/devicetree/bindings/arm/arm,scpi.txt >> @@ -72,8 +72,18 @@ Required sub-node properties: >> - compatible : should be "arm,juno-scp-shmem" for Non-secure SRAM based >> shared memory on Juno platforms >> >> +Sensor bindings for the sensors based on SCPI Message Protocol >> +-- >> +SCPI provides an API to access the various sensors on the SoC. >> + >> +Required properties: >> +- compatible : should be "arm,scpi-sensors". >> +- #thermal-sensor-cells: should be set to 1. This property follows the >> + thermal device tree bindings[2]. > > You need to specify what the valid values for this cell are. The enumeration depends on the number of sensors exported by SCP firmware - which is platform dependent. I could add add something like if you think that is helpful - "Valid cell value is a number between 0..n-1, where n is the number of sensors exported by SCP firmware." Thanks, Punit > > Mark. > >> + >> [0] http://infocenter.arm.com/help/topic/com.arm.doc.dui0922b/index.html >> [1] Documentation/devicetree/bindings/clock/clock-bindings.txt >> +[2] Documentation/devicetree/bindings/thermal/thermal.txt >> >> Example: >> >> @@ -122,6 +132,11 @@ scpi_protocol: scpi@2e00 { >> clock-output-names = "pxlclk0", "pxlclk1"; >> }; >> }; >> + >> +scpi_sensors0: sensors { >> +compatible = "arm,scpi-sensors"; >> +#thermal-sensor-cells = <1>; >> +}; >> }; >> >> cpu@0 { >> -- >> 2.5.0 >> > -- > To unsubscribe from this list: send the line "unsubscribe devicetree" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [Patch v3 4/5] hwmon: Support registration of thermal zones for SCP temperature sensors
Please ignore this particular patch. I had an earlier one lying around when I used git send-email *. Punit Agrawal writes: > Add support to create thermal zones based on the temperature sensors > provided by the SCP. The thermal zones can be defined using the > thermal DT bindings and should refer to the SCP sensor id to select > the sensor. > > Signed-off-by: Punit Agrawal > Acked-by: Guenter Roeck > Cc: Eduardo Valentin > --- > drivers/hwmon/scpi-hwmon.c | 104 > - > 1 file changed, 103 insertions(+), 1 deletion(-) > > diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c > index c7d1d14..2c1241b 100644 > --- a/drivers/hwmon/scpi-hwmon.c > +++ b/drivers/hwmon/scpi-hwmon.c > @@ -20,6 +20,7 @@ > #include > #include > #include > +#include > > struct sensor_data { > struct scpi_sensor_info info; > @@ -29,14 +30,39 @@ struct sensor_data { > char label[20]; > }; > > +struct scpi_thermal_zone { > + struct list_head list; > + int sensor_id; > + struct scpi_sensors *scpi_sensors; > + struct thermal_zone_device *tzd; > +}; > + > struct scpi_sensors { > struct scpi_ops *scpi_ops; > struct sensor_data *data; > + struct list_head thermal_zones; > struct attribute **attrs; > struct attribute_group group; > const struct attribute_group *groups[2]; > }; > > +static int scpi_read_temp(void *dev, int *temp) > +{ > + struct scpi_thermal_zone *zone = dev; > + struct scpi_sensors *scpi_sensors = zone->scpi_sensors; > + struct scpi_ops *scpi_ops = scpi_sensors->scpi_ops; > + struct sensor_data *sensor = &scpi_sensors->data[zone->sensor_id]; > + u32 value; > + int ret; > + > + ret = scpi_ops->sensor_get_value(sensor->info.sensor_id, &value); > + if (ret) > + return ret; > + > + *temp = value; > + return 0; > +} > + > /* hwmon callback functions */ > static ssize_t > scpi_show_sensor(struct device *dev, struct device_attribute *attr, char > *buf) > @@ -66,6 +92,24 @@ scpi_show_label(struct device *dev, struct > device_attribute *attr, char *buf) > return sprintf(buf, "%s\n", sensor->info.name); > } > > +static void > +unregister_thermal_zones(struct platform_device *pdev, > + struct scpi_sensors *scpi_sensors) > +{ > + struct list_head *pos; > + > + list_for_each(pos, &scpi_sensors->thermal_zones) { > + struct scpi_thermal_zone *zone; > + > + zone = list_entry(pos, struct scpi_thermal_zone, list); > + thermal_zone_of_sensor_unregister(&pdev->dev, zone->tzd); > + } > +} > + > +static struct thermal_zone_of_device_ops scpi_sensor_ops = { > + .get_temp = scpi_read_temp, > +}; > + > static int scpi_hwmon_probe(struct platform_device *pdev) > { > u16 nr_sensors, i; > @@ -160,10 +204,67 @@ static int scpi_hwmon_probe(struct platform_device > *pdev) > scpi_sensors->group.attrs = scpi_sensors->attrs; > scpi_sensors->groups[0] = &scpi_sensors->group; > > + platform_set_drvdata(pdev, scpi_sensors); > + > hwdev = devm_hwmon_device_register_with_groups(dev, > "scpi_sensors", scpi_sensors, scpi_sensors->groups); > > - return PTR_ERR_OR_ZERO(hwdev); > + if (IS_ERR(hwdev)) > + return PTR_ERR(hwdev); > + > + /* > + * Register the temperature sensors with the thermal framework > + * to allow their usage in setting up the thermal zones from > + * device tree. > + * > + * NOTE: Not all temperature sensors maybe used for thermal > + * control > + */ > + INIT_LIST_HEAD(&scpi_sensors->thermal_zones); > + for (i = 0; i < nr_sensors; i++) { > + struct sensor_data *sensor = &scpi_sensors->data[i]; > + struct scpi_thermal_zone *zone; > + > + if (sensor->info.class != TEMPERATURE) > + continue; > + > + zone = devm_kzalloc(dev, sizeof(*zone), GFP_KERNEL); > + if (!zone) { > + ret = -ENOMEM; > + goto unregister_tzd; > + } > + > + zone->sensor_id = i; > + zone->scpi_sensors = scpi_sensors; > + zone->tzd = thermal_zone_of_sensor_register(dev, i, zone, > + &scpi_sensor_ops); > + /* > +
[PATCH v3 5/5] arm64: dts: Add sensor node to Juno dt
The SCP firmware on Juno provides access to SoC sensors via the SCPI. Add the sensor nodes to the device tree to enable this support. Signed-off-by: Punit Agrawal Cc: Rob Herring Cc: Mark Rutland Cc: Liviu Dudau Cc: Sudeep Holla --- arch/arm64/boot/dts/arm/juno-base.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi index c624208..dd5158e 100644 --- a/arch/arm64/boot/dts/arm/juno-base.dtsi +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -96,6 +96,11 @@ clock-output-names = "pxlclk0", "pxlclk1"; }; }; + + scpi_sensors0: sensors { + compatible = "arm,scpi-sensors"; + #thermal-sensor-cells = <1>; + }; }; /include/ "juno-clocks.dtsi" -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 4/5] hwmon: Support thermal zones registration for SCP temperature sensors
Add support to create thermal zones based on the temperature sensors provided by the SCP. The thermal zones can be defined using the thermal DT bindings and should refer to the SCP sensor id to select the sensor. Signed-off-by: Punit Agrawal Acked-by: Guenter Roeck Cc: Eduardo Valentin --- drivers/hwmon/scpi-hwmon.c | 104 - 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c index c7d1d14..2c1241b 100644 --- a/drivers/hwmon/scpi-hwmon.c +++ b/drivers/hwmon/scpi-hwmon.c @@ -20,6 +20,7 @@ #include #include #include +#include struct sensor_data { struct scpi_sensor_info info; @@ -29,14 +30,39 @@ struct sensor_data { char label[20]; }; +struct scpi_thermal_zone { + struct list_head list; + int sensor_id; + struct scpi_sensors *scpi_sensors; + struct thermal_zone_device *tzd; +}; + struct scpi_sensors { struct scpi_ops *scpi_ops; struct sensor_data *data; + struct list_head thermal_zones; struct attribute **attrs; struct attribute_group group; const struct attribute_group *groups[2]; }; +static int scpi_read_temp(void *dev, int *temp) +{ + struct scpi_thermal_zone *zone = dev; + struct scpi_sensors *scpi_sensors = zone->scpi_sensors; + struct scpi_ops *scpi_ops = scpi_sensors->scpi_ops; + struct sensor_data *sensor = &scpi_sensors->data[zone->sensor_id]; + u32 value; + int ret; + + ret = scpi_ops->sensor_get_value(sensor->info.sensor_id, &value); + if (ret) + return ret; + + *temp = value; + return 0; +} + /* hwmon callback functions */ static ssize_t scpi_show_sensor(struct device *dev, struct device_attribute *attr, char *buf) @@ -66,6 +92,24 @@ scpi_show_label(struct device *dev, struct device_attribute *attr, char *buf) return sprintf(buf, "%s\n", sensor->info.name); } +static void +unregister_thermal_zones(struct platform_device *pdev, +struct scpi_sensors *scpi_sensors) +{ + struct list_head *pos; + + list_for_each(pos, &scpi_sensors->thermal_zones) { + struct scpi_thermal_zone *zone; + + zone = list_entry(pos, struct scpi_thermal_zone, list); + thermal_zone_of_sensor_unregister(&pdev->dev, zone->tzd); + } +} + +static struct thermal_zone_of_device_ops scpi_sensor_ops = { + .get_temp = scpi_read_temp, +}; + static int scpi_hwmon_probe(struct platform_device *pdev) { u16 nr_sensors, i; @@ -160,10 +204,67 @@ static int scpi_hwmon_probe(struct platform_device *pdev) scpi_sensors->group.attrs = scpi_sensors->attrs; scpi_sensors->groups[0] = &scpi_sensors->group; + platform_set_drvdata(pdev, scpi_sensors); + hwdev = devm_hwmon_device_register_with_groups(dev, "scpi_sensors", scpi_sensors, scpi_sensors->groups); - return PTR_ERR_OR_ZERO(hwdev); + if (IS_ERR(hwdev)) + return PTR_ERR(hwdev); + + /* +* Register the temperature sensors with the thermal framework +* to allow their usage in setting up the thermal zones from +* device tree. +* +* NOTE: Not all temperature sensors maybe used for thermal +* control +*/ + INIT_LIST_HEAD(&scpi_sensors->thermal_zones); + for (i = 0; i < nr_sensors; i++) { + struct sensor_data *sensor = &scpi_sensors->data[i]; + struct scpi_thermal_zone *zone; + + if (sensor->info.class != TEMPERATURE) + continue; + + zone = devm_kzalloc(dev, sizeof(*zone), GFP_KERNEL); + if (!zone) { + ret = -ENOMEM; + goto unregister_tzd; + } + + zone->sensor_id = i; + zone->scpi_sensors = scpi_sensors; + zone->tzd = thermal_zone_of_sensor_register(dev, i, zone, + &scpi_sensor_ops); + /* +* The call to thermal_zone_of_sensor_register returns +* an error for sensors that are not associated with +* any thermal zones or if the thermal subsystem is +* not configured. +*/ + if (IS_ERR(zone->tzd)) { + devm_kfree(dev, zone); + continue; + } + list_add(&zone->list, &scpi_sensors->thermal_zones); + } + + return 0; + +unregister_tzd: + unregister_thermal_zones(pdev, scpi_sensors); + return ret; +} + +static int scpi_hwmon_remove(struct platform_device *pdev) +{ + str
[Patch v3 4/5] hwmon: Support registration of thermal zones for SCP temperature sensors
Add support to create thermal zones based on the temperature sensors provided by the SCP. The thermal zones can be defined using the thermal DT bindings and should refer to the SCP sensor id to select the sensor. Signed-off-by: Punit Agrawal Acked-by: Guenter Roeck Cc: Eduardo Valentin --- drivers/hwmon/scpi-hwmon.c | 104 - 1 file changed, 103 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c index c7d1d14..2c1241b 100644 --- a/drivers/hwmon/scpi-hwmon.c +++ b/drivers/hwmon/scpi-hwmon.c @@ -20,6 +20,7 @@ #include #include #include +#include struct sensor_data { struct scpi_sensor_info info; @@ -29,14 +30,39 @@ struct sensor_data { char label[20]; }; +struct scpi_thermal_zone { + struct list_head list; + int sensor_id; + struct scpi_sensors *scpi_sensors; + struct thermal_zone_device *tzd; +}; + struct scpi_sensors { struct scpi_ops *scpi_ops; struct sensor_data *data; + struct list_head thermal_zones; struct attribute **attrs; struct attribute_group group; const struct attribute_group *groups[2]; }; +static int scpi_read_temp(void *dev, int *temp) +{ + struct scpi_thermal_zone *zone = dev; + struct scpi_sensors *scpi_sensors = zone->scpi_sensors; + struct scpi_ops *scpi_ops = scpi_sensors->scpi_ops; + struct sensor_data *sensor = &scpi_sensors->data[zone->sensor_id]; + u32 value; + int ret; + + ret = scpi_ops->sensor_get_value(sensor->info.sensor_id, &value); + if (ret) + return ret; + + *temp = value; + return 0; +} + /* hwmon callback functions */ static ssize_t scpi_show_sensor(struct device *dev, struct device_attribute *attr, char *buf) @@ -66,6 +92,24 @@ scpi_show_label(struct device *dev, struct device_attribute *attr, char *buf) return sprintf(buf, "%s\n", sensor->info.name); } +static void +unregister_thermal_zones(struct platform_device *pdev, +struct scpi_sensors *scpi_sensors) +{ + struct list_head *pos; + + list_for_each(pos, &scpi_sensors->thermal_zones) { + struct scpi_thermal_zone *zone; + + zone = list_entry(pos, struct scpi_thermal_zone, list); + thermal_zone_of_sensor_unregister(&pdev->dev, zone->tzd); + } +} + +static struct thermal_zone_of_device_ops scpi_sensor_ops = { + .get_temp = scpi_read_temp, +}; + static int scpi_hwmon_probe(struct platform_device *pdev) { u16 nr_sensors, i; @@ -160,10 +204,67 @@ static int scpi_hwmon_probe(struct platform_device *pdev) scpi_sensors->group.attrs = scpi_sensors->attrs; scpi_sensors->groups[0] = &scpi_sensors->group; + platform_set_drvdata(pdev, scpi_sensors); + hwdev = devm_hwmon_device_register_with_groups(dev, "scpi_sensors", scpi_sensors, scpi_sensors->groups); - return PTR_ERR_OR_ZERO(hwdev); + if (IS_ERR(hwdev)) + return PTR_ERR(hwdev); + + /* +* Register the temperature sensors with the thermal framework +* to allow their usage in setting up the thermal zones from +* device tree. +* +* NOTE: Not all temperature sensors maybe used for thermal +* control +*/ + INIT_LIST_HEAD(&scpi_sensors->thermal_zones); + for (i = 0; i < nr_sensors; i++) { + struct sensor_data *sensor = &scpi_sensors->data[i]; + struct scpi_thermal_zone *zone; + + if (sensor->info.class != TEMPERATURE) + continue; + + zone = devm_kzalloc(dev, sizeof(*zone), GFP_KERNEL); + if (!zone) { + ret = -ENOMEM; + goto unregister_tzd; + } + + zone->sensor_id = i; + zone->scpi_sensors = scpi_sensors; + zone->tzd = thermal_zone_of_sensor_register(dev, i, zone, + &scpi_sensor_ops); + /* +* The call to thermal_zone_of_sensor_register returns +* an error for sensors that are not associated with +* any thermal zones or if the thermal subsystem is +* not configured. +*/ + if (IS_ERR(zone->tzd)) { + devm_kfree(dev, zone); + continue; + } + list_add(&zone->list, &scpi_sensors->thermal_zones); + } + + return 0; + +unregister_tzd: + unregister_thermal_zones(pdev, scpi_sensors); + return ret; +} + +static int scpi_hwmon_remove(struct platform_device *pdev) +{ + str
[PATCH v3 3/5] hwmon: Support sensors exported via ARM SCP interface
Create a driver to add support for SoC sensors exported by the System Control Processor (SCP) via the System Control and Power Interface (SCPI). The supported sensor types is one of voltage, temperature, current, and power. The sensor labels and values provided by the SCP are exported via the hwmon sysfs interface. Signed-off-by: Punit Agrawal Acked-by: Guenter Roeck Cc: Sudeep Holla --- Documentation/hwmon/scpi-hwmon | 33 drivers/hwmon/Kconfig | 8 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/scpi-hwmon.c | 186 + 4 files changed, 228 insertions(+) create mode 100644 Documentation/hwmon/scpi-hwmon create mode 100644 drivers/hwmon/scpi-hwmon.c diff --git a/Documentation/hwmon/scpi-hwmon b/Documentation/hwmon/scpi-hwmon new file mode 100644 index 000..4cfcdf2d --- /dev/null +++ b/Documentation/hwmon/scpi-hwmon @@ -0,0 +1,33 @@ +Kernel driver scpi-hwmon + + +Supported chips: + * Chips based on ARM System Control Processor Interface + Addresses scanned: - + Datasheet: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/index.html + +Author: Punit Agrawal + +Description +--- + +This driver supports hardware monitoring for SoC's based on the ARM +System Control Processor (SCP) implementing the System Control +Processor Interface (SCPI). The following sensor types are supported +by the SCP - + + * temperature + * voltage + * current + * power + +The SCP interface provides an API to query the available sensors and +their values which are then exported to userspace by this driver. + +Usage Notes +--- + +The driver relies on device tree node to indicate the presence of SCPI +support in the kernel. See +Documentation/devicetree/bindings/arm/arm,scpi.txt for details of the +devicetree node. \ No newline at end of file diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index c7a4f09..4b94327 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1551,6 +1551,14 @@ config SENSORS_VEXPRESS the ARM Ltd's Versatile Express platform. It can provide wide range of information like temperature, power, energy. +config SENSORS_ARM_SCPI + tristate "ARM SCPI Sensors" + depends on ARM_SCPI_PROTOCOL + help + This driver provides support for temperature, voltage, current + and power sensors available on ARM Ltd's SCP based platforms. The + actual number and type of sensors exported depend the platform. + config SENSORS_VIA_CPUTEMP tristate "VIA CPU temperature sensor" depends on X86 diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 8aba87f..4961710 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -150,6 +150,7 @@ obj-$(CONFIG_SENSORS_TMP421)+= tmp421.o obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o obj-$(CONFIG_SENSORS_V2M_JUNO) += v2m-juno.o obj-$(CONFIG_SENSORS_VEXPRESS) += vexpress.o +obj-$(CONFIG_SENSORS_ARM_SCPI) += scpi-hwmon.o obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o obj-$(CONFIG_SENSORS_VIA686A) += via686a.o obj-$(CONFIG_SENSORS_VT1211) += vt1211.o diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c new file mode 100644 index 000..c7d1d14 --- /dev/null +++ b/drivers/hwmon/scpi-hwmon.c @@ -0,0 +1,186 @@ +/* + * System Control and Power Interface(SCPI) based hwmon sensor driver + * + * Copyright (C) 2015 ARM Ltd. + * Punit Agrawal + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include + +struct sensor_data { + struct scpi_sensor_info info; + struct device_attribute dev_attr_input; + struct device_attribute dev_attr_label; + char input[20]; + char label[20]; +}; + +struct scpi_sensors { + struct scpi_ops *scpi_ops; + struct sensor_data *data; + struct attribute **attrs; + struct attribute_group group; + const struct attribute_group *groups[2]; +}; + +/* hwmon callback functions */ +static ssize_t +scpi_show_sensor(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct scpi_sensors *scpi_sensors = dev_get_drvdata(dev); + struct scpi_ops *scpi_ops = scpi_sensors->scpi_ops; + struct sensor_data *sensor; + u32 value; + int ret; + + sensor = container_of(attr, struct sensor_data, dev_attr_input); + + ret = scpi_ops->sensor_get_val
[PATCH v3 2/5] firmware: arm_scpi: Extend to support sensors
ARM System Control Processor (SCP) provides an API to query and use the sensors available in the system. Extend the SCPI driver to support sensor messages. Signed-off-by: Punit Agrawal Cc: Sudeep Holla --- drivers/firmware/arm_scpi.c | 60 +++ include/linux/scpi_protocol.h | 17 2 files changed, 77 insertions(+) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index cb75c75..321680e 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -219,6 +219,21 @@ struct dvfs_set { u8 index; } __packed; +struct sensor_capabilities { + __le16 sensors; +} __packed; + +struct _scpi_sensor_info { + __le16 sensor_id; + u8 class; + u8 trigger_type; + char name[20]; +}; + +struct sensor_value { + __le32 val; +} __packed; + static struct scpi_drvinfo *scpi_info; static int scpi_linux_errmap[SCPI_ERR_MAX] = { @@ -481,6 +496,48 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain) return info; } +static int scpi_sensor_get_capability(u16 *sensors) +{ + struct sensor_capabilities cap_buf; + int ret; + + ret = scpi_send_message(SCPI_CMD_SENSOR_CAPABILITIES, NULL, 0, &cap_buf, + sizeof(cap_buf)); + if (!ret) + *sensors = le16_to_cpu(cap_buf.sensors); + + return ret; +} + +static int scpi_sensor_get_info(u16 sensor_id, struct scpi_sensor_info *info) +{ + __le16 id = cpu_to_le16(sensor_id); + struct _scpi_sensor_info _info; + int ret; + + ret = scpi_send_message(SCPI_CMD_SENSOR_INFO, &id, +sizeof(id), &_info, sizeof(_info)); + if (!ret) { + memcpy(info, &_info, sizeof(*info)); + info->sensor_id = le16_to_cpu(_info.sensor_id); + } + + return ret; +} + +int scpi_sensor_get_value(u16 sensor, u32 *val) +{ + struct sensor_value buf; + int ret; + + ret = scpi_send_message(SCPI_CMD_SENSOR_VALUE, &sensor, sizeof(sensor), + &buf, sizeof(buf)); + if (!ret) + *val = le32_to_cpu(buf.val); + + return ret; +} + static struct scpi_ops scpi_ops = { .get_version = scpi_get_version, .clk_get_range = scpi_clk_get_range, @@ -489,6 +546,9 @@ static struct scpi_ops scpi_ops = { .dvfs_get_idx = scpi_dvfs_get_idx, .dvfs_set_idx = scpi_dvfs_set_idx, .dvfs_get_info = scpi_dvfs_get_info, + .sensor_get_capability = scpi_sensor_get_capability, + .sensor_get_info = scpi_sensor_get_info, + .sensor_get_value = scpi_sensor_get_value, }; struct scpi_ops *get_scpi_ops(void) diff --git a/include/linux/scpi_protocol.h b/include/linux/scpi_protocol.h index e7169cd..80af3cd 100644 --- a/include/linux/scpi_protocol.h +++ b/include/linux/scpi_protocol.h @@ -28,6 +28,20 @@ struct scpi_dvfs_info { struct scpi_opp *opps; }; +enum scpi_sensor_class { + TEMPERATURE, + VOLTAGE, + CURRENT, + POWER, +}; + +struct scpi_sensor_info { + u16 sensor_id; + u8 class; + u8 trigger_type; + char name[20]; +} __packed; + /** * struct scpi_ops - represents the various operations provided * by SCP through SCPI message protocol @@ -52,6 +66,9 @@ struct scpi_ops { int (*dvfs_get_idx)(u8); int (*dvfs_set_idx)(u8, u8); struct scpi_dvfs_info *(*dvfs_get_info)(u8); + int (*sensor_get_capability)(u16 *sensors); + int (*sensor_get_info)(u16 sensor_id, struct scpi_sensor_info *); + int (*sensor_get_value)(u16, u32 *); }; #if IS_ENABLED(CONFIG_ARM_SCPI_PROTOCOL) -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 1/5] Documentation: add DT bindings for ARM SCPI sensors
The System Control Processor (SCP) provides access to SoC sensors via the System Control and Power Interface (SCPI) Message Protocol. Add bindings to allow probing of these sensors. Also support referencing of the sensors for setting up thermal zones via the thermal DT bindings. Signed-off-by: Punit Agrawal Cc: Rob Herring Cc: Mark Rutland Cc: Sudeep Holla --- Documentation/devicetree/bindings/arm/arm,scpi.txt | 15 +++ 1 file changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/arm,scpi.txt b/Documentation/devicetree/bindings/arm/arm,scpi.txt index f002460..af66f7f 100644 --- a/Documentation/devicetree/bindings/arm/arm,scpi.txt +++ b/Documentation/devicetree/bindings/arm/arm,scpi.txt @@ -72,8 +72,18 @@ Required sub-node properties: - compatible : should be "arm,juno-scp-shmem" for Non-secure SRAM based shared memory on Juno platforms +Sensor bindings for the sensors based on SCPI Message Protocol +-- +SCPI provides an API to access the various sensors on the SoC. + +Required properties: +- compatible : should be "arm,scpi-sensors". +- #thermal-sensor-cells: should be set to 1. This property follows the +thermal device tree bindings[2]. + [0] http://infocenter.arm.com/help/topic/com.arm.doc.dui0922b/index.html [1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/thermal/thermal.txt Example: @@ -122,6 +132,11 @@ scpi_protocol: scpi@2e00 { clock-output-names = "pxlclk0", "pxlclk1"; }; }; + + scpi_sensors0: sensors { + compatible = "arm,scpi-sensors"; + #thermal-sensor-cells = <1>; + }; }; cpu@0 { -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v3 0/5] SCPI Sensor support
Hi The series adds support for SCPI based sensors for ARM development platform. In addition to supporting sensors, when a temperature sensor is discovered the driver registers the sensor with the thermal framework. The sensor patches here have been split out from a longer series adding support for registering power model based cooling devices for the CPU via device tree. Earliers postings can be seen at [0], [1]. Patches 1-3 create a hwmon sensor driver for sensors provided by SCPI firmware. Patch 4 adds support for the temperature sensors to register with the thermal framework. This allows setting up platform thermals using OF thermal bindings. The last patch adds support for the sensors in the Juno device tree. The patches depend on SCPI and mailbox patches[2] from Sudeep. The SCPI protocol document with details of the sensor interface can be found at [3]. I'd like to aim for merging the patches with the SCPI changes if possible. The hwmon patches have been acked by Guenter. If there aren't any objections, I would like to request acks for the binding updates in Patch 1. Thanks, Punit Changes v2->v3 - split out the sensor patches (posted here) - rebase onto v4.3-rc1 Changes v1->v2 - added documentation for the scpi-hwmon driver - replaced static allocation of platform structure in scpi-hwmon.c with dynamic allocation - re-structured registering of thermal zones to better handle error conditions - reduced chattiness in scpi-hwmon.c - corrected sensor numbering to align with hwmon documentation - dynamic allocation of attributes and attribute groups [0] http://thread.gmane.org/gmane.linux.kernel/2002152 [1] http://thread.gmane.org/gmane.linux.kernel/2011466 [2] http://thread.gmane.org/gmane.linux.kernel/2009735 [3] http://infocenter.arm.com/help/topic/com.arm.doc.dui0922b/index.html Punit Agrawal (5): Documentation: add DT bindings for ARM SCPI sensors firmware: arm_scpi: Extend to support sensors hwmon: Support sensors exported via ARM SCP interface hwmon: Support registration of thermal zones for SCP temperature sensors arm64: dts: Add sensor node to Juno dt Documentation/devicetree/bindings/arm/arm,scpi.txt | 15 ++ Documentation/hwmon/scpi-hwmon | 33 +++ arch/arm64/boot/dts/arm/juno-base.dtsi | 5 + drivers/firmware/arm_scpi.c| 60 + drivers/hwmon/Kconfig | 8 + drivers/hwmon/Makefile | 1 + drivers/hwmon/scpi-hwmon.c | 288 + include/linux/scpi_protocol.h | 17 ++ 8 files changed, 427 insertions(+) create mode 100644 Documentation/hwmon/scpi-hwmon create mode 100644 drivers/hwmon/scpi-hwmon.c -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/2] of: thermal: Mark cooling-*-level properties optional
The cooling-{min,max}-level properties are marked as optional in Documentation/devicetree/bindings/cpufreq/cpufreq-dt.txt and the usage in various device tree matches this, i.e., some cooling device in the device trees provide these properties while others do not. Make the bindings in Documentation/devicetree/bindings/thermal/thermal.txt consistent with the cpufreq-dt bindings by marking the cooling-*-level properties as optional. Signed-off-by: Punit Agrawal Cc: Eduardo Valentin Cc: Rob Herring Cc: Mark Rutland Cc: Ian Campbell Cc: Kumar Gala --- Documentation/devicetree/bindings/thermal/thermal.txt | 17 + 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/thermal.txt b/Documentation/devicetree/bindings/thermal/thermal.txt index 8320186..41b817f 100644 --- a/Documentation/devicetree/bindings/thermal/thermal.txt +++ b/Documentation/devicetree/bindings/thermal/thermal.txt @@ -60,14 +60,6 @@ properties) should be defined in a particular device's binding. For more examples of cooling devices, refer to the example sections below. Required properties: -- cooling-min-level: An integer indicating the smallest - Type: unsigned cooling state accepted. Typically 0. - Size: one cell - -- cooling-max-level: An integer indicating the largest - Type: unsigned cooling state accepted. - Size: one cell - - #cooling-cells: Used to provide cooling device specific information Type: unsigned while referring to it. Must be at least 2, in order Size: one cell to specify minimum and maximum cooling state used @@ -77,6 +69,15 @@ Required properties: See Cooling device maps section below for more details on how consumers refer to cooling devices. +Optional properties: +- cooling-min-level: An integer indicating the smallest + Type: unsigned cooling state accepted. Typically 0. + Size: one cell + +- cooling-max-level: An integer indicating the largest + Type: unsigned cooling state accepted. + Size: one cell + * Trip points The trip node is a node to describe a point in the temperature domain -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/2] of: thermal: Fix inconsitency between cooling-*-state and cooling-*-level
The device trees in the kernel as well as the binding description in Documentation/devicetree/bindings/cpufreq/cpufreq-dt.txt use the cooling-{min,max}-level property. Fix the inconsistency with the binding description in Documentation/devicetree/bindings/thermal/thermal.txt by changing cooling-*-state properties to cooling-*-level. Signed-off-by: Punit Agrawal Cc: Eduardo Valentin Cc: Rob Herring Cc: Mark Rutland Cc: Ian Campbell Cc: Kumar Gala --- Documentation/devicetree/bindings/thermal/thermal.txt | 14 +++--- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/Documentation/devicetree/bindings/thermal/thermal.txt b/Documentation/devicetree/bindings/thermal/thermal.txt index 8a49362..8320186 100644 --- a/Documentation/devicetree/bindings/thermal/thermal.txt +++ b/Documentation/devicetree/bindings/thermal/thermal.txt @@ -55,16 +55,16 @@ of heat dissipation). For example a fan's cooling states correspond to the different fan speeds possible. Cooling states are referred to by single unsigned integers, where larger numbers mean greater heat dissipation. The precise set of cooling states associated with a device -(as referred to be the cooling-min-state and cooling-max-state +(as referred to by the cooling-min-level and cooling-max-level properties) should be defined in a particular device's binding. For more examples of cooling devices, refer to the example sections below. Required properties: -- cooling-min-state: An integer indicating the smallest +- cooling-min-level: An integer indicating the smallest Type: unsigned cooling state accepted. Typically 0. Size: one cell -- cooling-max-state: An integer indicating the largest +- cooling-max-level: An integer indicating the largest Type: unsigned cooling state accepted. Size: one cell @@ -225,8 +225,8 @@ cpus { 396000 95 198000 85 >; - cooling-min-state = <0>; - cooling-max-state = <3>; + cooling-min-level = <0>; + cooling-max-level = <3>; #cooling-cells = <2>; /* min followed by max */ }; ... @@ -240,8 +240,8 @@ cpus { */ fan0: fan@0x48 { ... - cooling-min-state = <0>; - cooling-max-state = <9>; + cooling-min-level = <0>; + cooling-max-level = <9>; #cooling-cells = <2>; /* min followed by max */ }; }; -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/2] Update OF thermal properties for cooling-{min,max}-level
Hi, The device tree properties regarding the specification and usage of states for cooling devices suffer from inconsistency in the bindings as well as the usage. The two patches here update the bindings to be consistent without breaking existing support for the device trees already in upstream. Thanks, Punit Punit Agrawal (2): of: thermal: Fix inconsitency between cooling-*-state and cooling-*-level of: thermal: Mark cooling-*-level properties optional .../devicetree/bindings/thermal/thermal.txt| 27 +++--- 1 file changed, 14 insertions(+), 13 deletions(-) -- 2.5.0 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 05/10] Documentation: add DT bindings for ARM SCPI sensors
Punit Agrawal writes: > The System Control Processor (SCP) provides access to SoC sensors via > the System Control and Power Interface (SCPI) Message Protocol. Add > bindings to allow probing of these sensors. Also support referencing > of the sensors for setting up thermal zones via the thermal DT > bindings. > > Signed-off-by: Punit Agrawal > Cc: Rob Herring > Cc: Mark Rutland > Cc: Sudeep Holla Gentle ping for the bindings review. > --- > Documentation/devicetree/bindings/arm/arm,scpi.txt | 15 +++ > 1 file changed, 15 insertions(+) > > diff --git a/Documentation/devicetree/bindings/arm/arm,scpi.txt > b/Documentation/devicetree/bindings/arm/arm,scpi.txt > index e309249..8ead68a 100644 > --- a/Documentation/devicetree/bindings/arm/arm,scpi.txt > +++ b/Documentation/devicetree/bindings/arm/arm,scpi.txt > @@ -72,8 +72,18 @@ Required sub-node properties: > - compatible : should be "arm,juno-scp-shmem" for Non-secure SRAM based > shared memory on Juno platforms > > +Sensor bindings for the sensors based on SCPI Message Protocol > +-- > +SCPI provides an API to access the various sensors on the SoC. > + > +Required properties: > +- compatible : should be "arm,scpi-sensors". > +- #thermal-sensor-cells: should be set to 1. This property follows the > + thermal device tree bindings[2]. > + > [0] > http://community.arm.com/servlet/JiveServlet/download/8401-45-18326/DUI0922B_scp_message_interface.pdf > [1] Documentation/devicetree/bindings/clock/clock-bindings.txt > +[2] Documentation/devicetree/bindings/thermal/thermal.txt > > Example: > > @@ -122,6 +132,11 @@ scpi_protocol: scpi@2e00 { > clock-output-names = "pxlclk0", "pxlclk1"; > }; > }; > + > + scpi_sensors0: sensors { > + compatible = "arm,scpi-sensors"; > + #thermal-sensor-cells = <1>; > + }; > }; > > cpu@0 { -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 1/3] dt-bindings: thermal: Add binding document for Mediatek thermal controller
[ + device tree folks ] Hi Sascha, When introducing a new binding, it is a good idea to get reviews from the device tree maintainers. I've added a few folks here. Please keep them in the loop for future postings. Sascha Hauer writes: > Signed-off-by: Sascha Hauer > Reviewed-by: Daniel Kurtz Please add a commit log. > --- > .../bindings/thermal/mediatek-thermal.txt | 38 > ++ > include/dt-bindings/thermal/mt8173.h | 13 > 2 files changed, 51 insertions(+) > create mode 100644 > Documentation/devicetree/bindings/thermal/mediatek-thermal.txt > create mode 100644 include/dt-bindings/thermal/mt8173.h > > diff --git a/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt > b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt > new file mode 100644 > index 000..1697375 > --- /dev/null > +++ b/Documentation/devicetree/bindings/thermal/mediatek-thermal.txt > @@ -0,0 +1,38 @@ > +* Mediatek Thermal > + > +This describes the device tree binding for the Mediatek thermal controller > +which measures the on-SoC temperatures. This device does not have its own > ADC, > +instead it directly controls the AUXADC via AHB bus accesses. For this reason > +this device needs phandles to the AUXADC. Also it controls a mux in the > +apmixedsys register space via AHB bus accesses, so a phandle to the > APMIXEDSYS > +is also needed. > + > +Required properties: > +- compatible: "mediatek,mt8173-thermal" > +- reg: Address range of the thermal controller > +- interrupts: IRQ for the thermal controller > +- clocks, clock-names: Clocks needed for the thermal controller. required > + clocks are: > +"therm": Main clock needed for register access > +"auxadc": The AUXADC clock > +- resets: Reference to the reset controller controlling the thermal > controller. > +- mediatek,auxadc: A phandle to the AUXADC which the thermal controller uses > +- mediatek,apmixedsys: A phandle to the APMIXEDSYS controller. > +- #thermal-sensor-cells : Should be 1. See ./thermal.txt for a description. > See > + include/dt-bindings/thermal/mt8173.h for valid sensor > + numbers. > + > +Example: > + > + thermal: thermal@1100b000 { > + #thermal-sensor-cells = <1>; > + compatible = "mediatek,mt8173-thermal"; > + reg = <0 0x1100b000 0 0x1000>; > + interrupts = <0 70 IRQ_TYPE_LEVEL_LOW>; > + clocks = <&pericfg CLK_PERI_THERM>, <&pericfg CLK_PERI_AUXADC>; > + clock-names = "therm", "auxadc"; > + resets = <&pericfg MT8173_PERI_THERM_SW_RST>; > + reset-names = "therm"; > + mediatek,auxadc = <&auxadc>; > + mediatek,apmixedsys = <&apmixedsys>; > + }; > diff --git a/include/dt-bindings/thermal/mt8173.h > b/include/dt-bindings/thermal/mt8173.h > new file mode 100644 > index 000..692e74c > --- /dev/null > +++ b/include/dt-bindings/thermal/mt8173.h > @@ -0,0 +1,13 @@ > +/* > + * This header provides constants for mediatek,mt8173-thermal > + */ > + > +#ifndef _DT_BINDINGS_THERMAL_MEDIATEK_MT8173_H > +#define _DT_BINDINGS_THERMAL_MEDIATEK_MT8173_H > + > +#define MT8173_THERMAL_ZONE_CA53 0 > +#define MT8173_THERMAL_ZONE_CA57 1 > +#define MT8173_THERMAL_ZONE_GPU 2 > +#define MT8173_THERMAL_ZONE_CORE 3 > + > +#endif /* _DT_BINDINGS_THERMAL_MEDIATEK_MT8173_H */ The constants in this include are not used in the patchset. Please drop this hunk and introduce it when you use it. Thanks, Punit -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 10/10] arm64: dts: Create SoC thermal zone for Juno
Apologies for the duplicate, I accidentally Hit send before I finished the reply. Punit Agrawal writes: > [ adding Eduardo, Rui for their take on OF-thermal bindings ] > > Punit Agrawal writes: > >> Hi Liviu, >> >> Thanks for having a look. >> >> Liviu Dudau writes: >> >>> On Mon, Aug 03, 2015 at 04:22:58PM +0100, Punit Agrawal wrote: >>>> Setup a thermal zone driven by the SoC temperature sensor on Juno >>>> r0. Create passive trip points and bind them to cpufreq cooling >>>> devices that support the power extensions. >>> >>> Hi Punit, >>> >>>> >>>> Signed-off-by: Punit Agrawal >>>> Cc: Rob Herring >>>> Cc: Mark Rutland >>>> Cc: Liviu Dudau >>>> Cc: Sudeep Holla >>>> --- >>>> arch/arm64/boot/dts/arm/juno.dts | 50 >>>> >>>> 1 file changed, 50 insertions(+) >>>> >>>> diff --git a/arch/arm64/boot/dts/arm/juno.dts >>>> b/arch/arm64/boot/dts/arm/juno.dts >>>> index d2e67f3..664961c 100644 >>>> --- a/arch/arm64/boot/dts/arm/juno.dts >>>> +++ b/arch/arm64/boot/dts/arm/juno.dts >>>> @@ -9,6 +9,7 @@ >>>> /dts-v1/; >>>> >>>> #include >>>> +#include >>>> >>>> / { >>>>model = "ARM Juno development board (r0)"; >>>> @@ -90,6 +91,8 @@ >>>>next-level-cache = <&A57_L2>; >>>>clocks = <&scpi_dvfs 0>; >>>>cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; >>>> + #cooling-cells = <2>; >>>> + dynamic-power-coefficient = <530>; >>> >>> The Documentation/devicetree/bindings/thermal/thermal.txt document >>> describes two additional >>> required properties, cooling-min-state and cooling-max-state which are >>> missing here. >>> >> >> The bindings do suggest that the cooling-*-state are required but I >> couldn't find any code making use of this property. >> >> I'll send a patch with the next version making those properties >> optional. >> > > On second thoughts... > > The question about cooling-*-state has come up in another thread as > well [0]. I'll re-iterate the question for the thermal maintainers to > clarify. > > The cooling-{max,min}-state properties are marked mandatory in the > bindings but aren't used in the code anywhere. Can we drop those > properties from the binding documentation? Or at the least, make them > optional? > Let me know your preferred approach. I can include a fix in the next version. [0] http://thread.gmane.org/gmane.linux.ports.ppc.embedded/84512/focus=63339 > [...] > > >> -- >> To unsubscribe from this list: send the line "unsubscribe linux-pm" in >> the body of a message to majord...@vger.kernel.org >> More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 10/10] arm64: dts: Create SoC thermal zone for Juno
[ adding Eduardo, Rui for their take on OF-thermal bindings ] Punit Agrawal writes: > Hi Liviu, > > Thanks for having a look. > > Liviu Dudau writes: > >> On Mon, Aug 03, 2015 at 04:22:58PM +0100, Punit Agrawal wrote: >>> Setup a thermal zone driven by the SoC temperature sensor on Juno >>> r0. Create passive trip points and bind them to cpufreq cooling >>> devices that support the power extensions. >> >> Hi Punit, >> >>> >>> Signed-off-by: Punit Agrawal >>> Cc: Rob Herring >>> Cc: Mark Rutland >>> Cc: Liviu Dudau >>> Cc: Sudeep Holla >>> --- >>> arch/arm64/boot/dts/arm/juno.dts | 50 >>> >>> 1 file changed, 50 insertions(+) >>> >>> diff --git a/arch/arm64/boot/dts/arm/juno.dts >>> b/arch/arm64/boot/dts/arm/juno.dts >>> index d2e67f3..664961c 100644 >>> --- a/arch/arm64/boot/dts/arm/juno.dts >>> +++ b/arch/arm64/boot/dts/arm/juno.dts >>> @@ -9,6 +9,7 @@ >>> /dts-v1/; >>> >>> #include >>> +#include >>> >>> / { >>> model = "ARM Juno development board (r0)"; >>> @@ -90,6 +91,8 @@ >>> next-level-cache = <&A57_L2>; >>> clocks = <&scpi_dvfs 0>; >>> cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; >>> + #cooling-cells = <2>; >>> + dynamic-power-coefficient = <530>; >> >> The Documentation/devicetree/bindings/thermal/thermal.txt document describes >> two additional >> required properties, cooling-min-state and cooling-max-state which are >> missing here. >> > > The bindings do suggest that the cooling-*-state are required but I > couldn't find any code making use of this property. > > I'll send a patch with the next version making those properties > optional. > On second thoughts... The question about cooling-*-state has come up in another thread as well [0]. I'll re-iterate the question for the thermal maintainers to clarify. The cooling-{max,min}-state properties are marked mandatory in the bindings but aren't used in the code anywhere. Can we drop those properties from the binding documentation? Or at the least, make them optional? [...] > -- > To unsubscribe from this list: send the line "unsubscribe linux-pm" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 10/10] arm64: dts: Create SoC thermal zone for Juno
Hi Liviu, Thanks for having a look. Liviu Dudau writes: > On Mon, Aug 03, 2015 at 04:22:58PM +0100, Punit Agrawal wrote: >> Setup a thermal zone driven by the SoC temperature sensor on Juno >> r0. Create passive trip points and bind them to cpufreq cooling >> devices that support the power extensions. > > Hi Punit, > >> >> Signed-off-by: Punit Agrawal >> Cc: Rob Herring >> Cc: Mark Rutland >> Cc: Liviu Dudau >> Cc: Sudeep Holla >> --- >> arch/arm64/boot/dts/arm/juno.dts | 50 >> >> 1 file changed, 50 insertions(+) >> >> diff --git a/arch/arm64/boot/dts/arm/juno.dts >> b/arch/arm64/boot/dts/arm/juno.dts >> index d2e67f3..664961c 100644 >> --- a/arch/arm64/boot/dts/arm/juno.dts >> +++ b/arch/arm64/boot/dts/arm/juno.dts >> @@ -9,6 +9,7 @@ >> /dts-v1/; >> >> #include >> +#include >> >> / { >> model = "ARM Juno development board (r0)"; >> @@ -90,6 +91,8 @@ >> next-level-cache = <&A57_L2>; >> clocks = <&scpi_dvfs 0>; >> cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; >> +#cooling-cells = <2>; >> +dynamic-power-coefficient = <530>; > > The Documentation/devicetree/bindings/thermal/thermal.txt document describes > two additional > required properties, cooling-min-state and cooling-max-state which are > missing here. > The bindings do suggest that the cooling-*-state are required but I couldn't find any code making use of this property. I'll send a patch with the next version making those properties optional. >> }; >> >> A57_1: cpu@1 { >> @@ -100,6 +103,8 @@ >> next-level-cache = <&A57_L2>; >> clocks = <&scpi_dvfs 0>; >> cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; >> +#cooling-cells = <2>; >> +dynamic-power-coefficient = <530>; >> }; >> >> A53_0: cpu@100 { >> @@ -110,6 +115,8 @@ >> next-level-cache = <&A53_L2>; >> clocks = <&scpi_dvfs 1>; >> cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; >> +#cooling-cells = <2>; >> +dynamic-power-coefficient = <140>; >> }; >> >> A53_1: cpu@101 { >> @@ -120,6 +127,8 @@ >> next-level-cache = <&A53_L2>; >> clocks = <&scpi_dvfs 1>; >> cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; >> +#cooling-cells = <2>; >> +dynamic-power-coefficient = <140>; >> }; >> >> A53_2: cpu@102 { >> @@ -130,6 +139,8 @@ >> next-level-cache = <&A53_L2>; >> clocks = <&scpi_dvfs 1>; >> cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; >> +#cooling-cells = <2>; >> +dynamic-power-coefficient = <140>; >> }; >> >> A53_3: cpu@103 { >> @@ -140,6 +151,8 @@ >> next-level-cache = <&A53_L2>; >> clocks = <&scpi_dvfs 1>; >> cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; >> +#cooling-cells = <2>; >> +dynamic-power-coefficient = <140>; >> }; >> >> A57_L2: l2-cache0 { >> @@ -167,5 +180,42 @@ >> <&A53_3>; >> }; >> >> +thermal-zones { >> +soc_thermal { >> +polling-delay = <1000>; >> +polling-delay-passive = <100>; >> +sustainable-power = <2500>; >> + >> +thermal-sensors = <&scpi_sensors0 3>; >> + >> +trips { >> +threshold: trip-point@0 { > > You also need a reg= property if you have the @index thing. > Having looked at the examples, I don
Re: [PATCH v2 07/10] hwmon: Support sensors exported via ARM SCP interface
Guenter Roeck writes: > On 08/03/2015 08:22 AM, Punit Agrawal wrote: >> Create a driver to add support for SoC sensors exported by the System >> Control Processor (SCP) via the System Control and Power Interface >> (SCPI). The supported sensor types is one of voltage, temperature, >> current, and power. >> >> The sensor labels and values provided by the SCP are exported via the >> hwmon sysfs interface. >> >> Signed-off-by: Punit Agrawal >> Cc: Jean Delvare >> Cc: Guenter Roeck >> Cc: Sudeep Holla > > Looks good for the most part. Single comment below. > Assuming you fix it up, feel free to add > > Acked-by: Guenter Roeck > > for v3. > > Thanks, > Guenter > >> --- >> Documentation/hwmon/scpi-hwmon | 33 >> drivers/hwmon/Kconfig | 8 ++ >> drivers/hwmon/Makefile | 1 + >> drivers/hwmon/scpi-hwmon.c | 183 >> + >> 4 files changed, 225 insertions(+) >> create mode 100644 Documentation/hwmon/scpi-hwmon >> create mode 100644 drivers/hwmon/scpi-hwmon.c >> >> diff --git a/Documentation/hwmon/scpi-hwmon b/Documentation/hwmon/scpi-hwmon >> new file mode 100644 >> index 000..4cfcdf2d >> --- /dev/null >> +++ b/Documentation/hwmon/scpi-hwmon >> @@ -0,0 +1,33 @@ >> +Kernel driver scpi-hwmon >> + >> + >> +Supported chips: >> + * Chips based on ARM System Control Processor Interface >> + Addresses scanned: - >> + Datasheet: >> http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/index.html >> + >> +Author: Punit Agrawal >> + >> +Description >> +--- >> + >> +This driver supports hardware monitoring for SoC's based on the ARM >> +System Control Processor (SCP) implementing the System Control >> +Processor Interface (SCPI). The following sensor types are supported >> +by the SCP - >> + >> + * temperature >> + * voltage >> + * current >> + * power >> + >> +The SCP interface provides an API to query the available sensors and >> +their values which are then exported to userspace by this driver. >> + >> +Usage Notes >> +--- >> + >> +The driver relies on device tree node to indicate the presence of SCPI >> +support in the kernel. See >> +Documentation/devicetree/bindings/arm/arm,scpi.txt for details of the >> +devicetree node. >> \ No newline at end of file >> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig >> index 4943c3c..c9714b0 100644 >> --- a/drivers/hwmon/Kconfig >> +++ b/drivers/hwmon/Kconfig >> @@ -1551,6 +1551,14 @@ config SENSORS_VEXPRESS >>the ARM Ltd's Versatile Express platform. It can provide wide >>range of information like temperature, power, energy. >> >> +config SENSORS_ARM_SCPI >> +tristate "ARM SCPI Sensors" >> +depends on ARM_SCPI_PROTOCOL >> +help >> + This driver provides support for temperature, voltage, current >> + and power sensors available on ARM Ltd's SCP based platforms. The >> + actual number and type of sensors exported depend the platform. >> + >> config SENSORS_VIA_CPUTEMP >> tristate "VIA CPU temperature sensor" >> depends on X86 >> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile >> index 8aba87f..4961710 100644 >> --- a/drivers/hwmon/Makefile >> +++ b/drivers/hwmon/Makefile >> @@ -150,6 +150,7 @@ obj-$(CONFIG_SENSORS_TMP421) += tmp421.o >> obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o >> obj-$(CONFIG_SENSORS_V2M_JUNO) += v2m-juno.o >> obj-$(CONFIG_SENSORS_VEXPRESS) += vexpress.o >> +obj-$(CONFIG_SENSORS_ARM_SCPI) += scpi-hwmon.o >> obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o >> obj-$(CONFIG_SENSORS_VIA686A) += via686a.o >> obj-$(CONFIG_SENSORS_VT1211) += vt1211.o >> diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c >> new file mode 100644 >> index 000..7e7e06b >> --- /dev/null >> +++ b/drivers/hwmon/scpi-hwmon.c >> @@ -0,0 +1,183 @@ >> +/* >> + * System Control and Power Interface(SCPI) based hwmon sensor driver >> + * >> + * Copyright (C) 2015 ARM Ltd. >> + * Punit Agrawal >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License version 2 as >> + * published by the Free So
Re: [PATCH v2 08/10] hwmon: Support registration of thermal zones for SCP temperature sensors
Guenter Roeck writes: > On 08/03/2015 08:22 AM, Punit Agrawal wrote: >> Add support to create thermal zones based on the temperature sensors >> provided by the SCP. The thermal zones can be defined using the >> thermal DT bindings and should refer to the SCP sensor id to select >> the sensor. >> >> Signed-off-by: Punit Agrawal >> Cc: Jean Delvare >> Cc: Guenter Roeck >> Cc: Eduardo Valentin > > Hi, > > assuming you fix up the nitpicks below, > > Acked-by: Guenter Roeck > >> --- >> drivers/hwmon/scpi-hwmon.c | 103 >> - >> 1 file changed, 102 insertions(+), 1 deletion(-) >> >> diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c >> index 7e7e06b..d96a3e5 100644 >> --- a/drivers/hwmon/scpi-hwmon.c >> +++ b/drivers/hwmon/scpi-hwmon.c >> @@ -20,6 +20,7 @@ >> #include >> #include >> #include >> +#include >> >> struct sensor_data { >> struct scpi_sensor_info info; >> @@ -29,14 +30,39 @@ struct sensor_data { >> char label[20]; >> }; >> >> +struct scpi_thermal_zone { >> +struct list_head list; >> +int sensor_id; >> +struct scpi_sensors *scpi_sensors; >> +struct thermal_zone_device *tzd; >> +}; >> + >> struct scpi_sensors { >> struct scpi_ops *scpi_ops; >> struct sensor_data *data; >> +struct list_head thermal_zones; >> struct attribute **attrs; >> struct attribute_group group; >> const struct attribute_group *groups[2]; >> }; >> >> +static int scpi_read_temp(void *dev, long *temp) >> +{ >> +struct scpi_thermal_zone *zone = dev; >> +struct scpi_sensors *scpi_sensors = zone->scpi_sensors; >> +struct scpi_ops *scpi_ops = scpi_sensors->scpi_ops; >> +struct sensor_data *sensor = &scpi_sensors->data[zone->sensor_id]; >> +u32 value; >> +int ret; >> + >> +ret = scpi_ops->sensor_get_value(sensor->info.sensor_id, &value); >> +if (ret) >> +return ret; >> + >> +*temp = value; >> +return 0; >> +} >> + >> /* hwmon callback functions */ >> static ssize_t >> scpi_show_sensor(struct device *dev, struct device_attribute *attr, char >> *buf) >> @@ -66,6 +92,24 @@ scpi_show_label(struct device *dev, struct >> device_attribute *attr, char *buf) >> return sprintf(buf, "%s\n", sensor->info.name); >> } >> >> +static void >> +unregister_thermal_zones(struct platform_device *pdev, >> + struct scpi_sensors *scpi_sensors) >> +{ >> +struct list_head *pos; >> + >> +list_for_each(pos, &scpi_sensors->thermal_zones) { >> +struct scpi_thermal_zone *zone; >> + >> +zone = list_entry(pos, struct scpi_thermal_zone, list); >> +thermal_zone_of_sensor_unregister(&pdev->dev, zone->tzd); >> +} >> +} >> + >> +static struct thermal_zone_of_device_ops scpi_sensor_ops = { >> +.get_temp = scpi_read_temp, >> +}; >> + >> static int scpi_hwmon_probe(struct platform_device *pdev) >> { >> u16 nr_sensors, i; >> @@ -157,10 +201,66 @@ static int scpi_hwmon_probe(struct platform_device >> *pdev) >> scpi_sensors->group.attrs = scpi_sensors->attrs; >> scpi_sensors->groups[0] = &scpi_sensors->group; >> >> +platform_set_drvdata(pdev, scpi_sensors); >> + >> hwdev = devm_hwmon_device_register_with_groups(dev, >> "scpi_sensors", scpi_sensors, scpi_sensors->groups); >> >> -return PTR_ERR_OR_ZERO(hwdev); >> +if (IS_ERR(hwdev)) >> +return PTR_ERR(hwdev); >> + >> +/* >> + * Register the temperature sensors with the thermal framework >> + * to allow their usage in setting up the thermal zones from >> + * device tree. >> + * >> + * NOTE: Not all temperature sensors maybe used for thermal >> + * control >> + */ >> +INIT_LIST_HEAD(&scpi_sensors->thermal_zones); >> +for (i = 0; i < nr_sensors; i++) { >> +struct sensor_data *sensor = &scpi_sensors->data[i]; >> +struct scpi_thermal_zone *zone; >> + >> +if (sensor->info.class != TEMPERATURE) >> +continue; >> + >> +zone = devm_kza
[PATCH v3] thermal: Fix thermal_zone_of_sensor_register to match documentation
thermal_zone_of_sensor_register is documented as returning a pointer to either a valid thermal_zone_device on success, or a corresponding ERR_PTR() value. In contrast, the function returns NULL when THERMAL_OF is configured off. Fix this. Signed-off-by: Punit Agrawal Cc: Guenter Roeck Cc: Eduardo Valentin Cc: Zhang Rui --- Hi Guenter, It was pointed out that ENOSYS is frowned upon for anything other than indicating lack of support for a syscall. The rest of the functions in the file use ENODEV. Updating thermal_zone_of_sensor_register to do the same. Could you please re-ack if you're ok with this change? Thanks, Punit include/linux/thermal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 037e9df..f344e51 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -364,7 +364,7 @@ static inline struct thermal_zone_device * thermal_zone_of_sensor_register(struct device *dev, int id, void *data, const struct thermal_zone_of_device_ops *ops) { - return NULL; + return ERR_PTR(-ENODEV); } static inline -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH v2 04/10] thermal: Fix thermal_zone_of_sensor_register to match documentation
Guenter Roeck writes: > On 08/03/2015 08:22 AM, Punit Agrawal wrote: >> thermal_zone_of_sensor_register is documented as returning a pointer >> to either a valid thermal_zone_device on success, or a corresponding >> ERR_PTR() value. >> >> In contrast, the function returns NULL when THERMAL_OF is configured >> off. Fix this. >> >> Signed-off-by: Punit Agrawal >> Cc: Guenter Roeck >> Cc: Eduardo Valentin >> Cc: Zhang Rui > > Acked-by: Guenter Roeck > Thanks, Guenter. >> --- >> include/linux/thermal.h | 2 +- >> 1 file changed, 1 insertion(+), 1 deletion(-) >> >> diff --git a/include/linux/thermal.h b/include/linux/thermal.h >> index 037e9df..a47b34a 100644 >> --- a/include/linux/thermal.h >> +++ b/include/linux/thermal.h >> @@ -364,7 +364,7 @@ static inline struct thermal_zone_device * >> thermal_zone_of_sensor_register(struct device *dev, int id, void *data, >> const struct thermal_zone_of_device_ops *ops) >> { >> -return NULL; >> +return ERR_PTR(-ENOSYS); >> } >> >> static inline >> > > -- > To unsubscribe from this list: send the line "unsubscribe linux-pm" in > the body of a message to majord...@vger.kernel.org > More majordomo info at http://vger.kernel.org/majordomo-info.html -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 00/10] Platform support for thermal management on Juno
Hi, The series adds support for thermal management on ARM Juno development platform. As part of this development, common infrastructure is added to support registering cpu cooling devices that work with the power allocator thermal governor. Patch 1 extends the CPU nodes binding to provide an optional dynamic power coefficient which can be used to create a dynamic power model for the CPUs. This model is used to constrain device power consumption (using power_allocator governor) when the system is thermally constrained. Patches 2-3 extends the cpufreq-dt and arm_big_little driver to register cpu cooling devices with the dynamic coefficient when provided. Patch 4 is a fix that aligns the behaviour of thermal_zone_of_sensor_register with it's documented return value when THERMAL_OF is configured off. Patches 5-8 create a hwmon sensor driver for sensors provided by SCPI firmware. Patch 7 adds support for the temperature sensors to register with the thermal framework. This allows setting up platform thermals using OF thermal bindings. The last two patches add support for the sensors and the thermal zones in the Juno device tree. The Juno specific patches depend on SCPI and cpufreq patches[0] from Sudeep. The SCPI protocol document with details of the sensor interface can be found at [1], [2]. Thanks, Punit Changes v1->v2 - added documentation for the scpi-hwmon driver - replaced static allocation of platform structure in scpi-hwmon.c with dynamic allocation - re-structured registering of thermal zones to better handle error conditions - reduced chattiness in scpi-hwmon.c - corrected sensor numbering to align with hwmon documentation - dynamic allocation of attributes and attribute groups [0] http://thread.gmane.org/gmane.linux.kernel/2009735 [1] http://community.arm.com/servlet/JiveServlet/download/8401-45-18326/DUI0922B_scp_message_interface.pdf [2] https://wiki.linaro.org/ARM/Juno?action=AttachFile&do=get&target=DUI0922B_scp_message_interface.pdf v1: http://thread.gmane.org/gmane.linux.kernel/2002152 Punit Agrawal (10): devicetree: bindings: Add optional dynamic-power-coefficient property cpufreq-dt: Supply power coefficient when registering cooling devices cpufreq: arm_big_little: Add support to register a cpufreq cooling device thermal: Fix thermal_zone_of_sensor_register to match documentation Documentation: add DT bindings for ARM SCPI sensors firmware: arm_scpi: Extend to support sensors hwmon: Support sensors exported via ARM SCP interface hwmon: Support registration of thermal zones for SCP temperature sensors arm64: dts: Add sensor node to Juno dt arm64: dts: Create SoC thermal zone for Juno Documentation/devicetree/bindings/arm/arm,scpi.txt | 15 ++ Documentation/devicetree/bindings/arm/cpus.txt | 15 ++ Documentation/hwmon/scpi-hwmon | 33 +++ arch/arm64/boot/dts/arm/juno-base.dtsi | 5 + arch/arm64/boot/dts/arm/juno.dts | 50 drivers/cpufreq/arm_big_little.c | 52 +++- drivers/cpufreq/cpufreq-dt.c | 9 +- drivers/firmware/arm_scpi.c| 60 + drivers/hwmon/Kconfig | 8 + drivers/hwmon/Makefile | 1 + drivers/hwmon/scpi-hwmon.c | 284 + include/linux/scpi_protocol.h | 17 ++ include/linux/thermal.h| 2 +- 13 files changed, 546 insertions(+), 5 deletions(-) create mode 100644 Documentation/hwmon/scpi-hwmon create mode 100644 drivers/hwmon/scpi-hwmon.c -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 05/10] Documentation: add DT bindings for ARM SCPI sensors
The System Control Processor (SCP) provides access to SoC sensors via the System Control and Power Interface (SCPI) Message Protocol. Add bindings to allow probing of these sensors. Also support referencing of the sensors for setting up thermal zones via the thermal DT bindings. Signed-off-by: Punit Agrawal Cc: Rob Herring Cc: Mark Rutland Cc: Sudeep Holla --- Documentation/devicetree/bindings/arm/arm,scpi.txt | 15 +++ 1 file changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/arm,scpi.txt b/Documentation/devicetree/bindings/arm/arm,scpi.txt index e309249..8ead68a 100644 --- a/Documentation/devicetree/bindings/arm/arm,scpi.txt +++ b/Documentation/devicetree/bindings/arm/arm,scpi.txt @@ -72,8 +72,18 @@ Required sub-node properties: - compatible : should be "arm,juno-scp-shmem" for Non-secure SRAM based shared memory on Juno platforms +Sensor bindings for the sensors based on SCPI Message Protocol +-- +SCPI provides an API to access the various sensors on the SoC. + +Required properties: +- compatible : should be "arm,scpi-sensors". +- #thermal-sensor-cells: should be set to 1. This property follows the +thermal device tree bindings[2]. + [0] http://community.arm.com/servlet/JiveServlet/download/8401-45-18326/DUI0922B_scp_message_interface.pdf [1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/thermal/thermal.txt Example: @@ -122,6 +132,11 @@ scpi_protocol: scpi@2e00 { clock-output-names = "pxlclk0", "pxlclk1"; }; }; + + scpi_sensors0: sensors { + compatible = "arm,scpi-sensors"; + #thermal-sensor-cells = <1>; + }; }; cpu@0 { -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 02/10] cpufreq-dt: Supply power coefficient when registering cooling devices
Support registering cooling devices with dynamic power coefficient where provided by the device tree. This allows OF registered cooling devices driver to be used with the power_allocator thermal governor. Signed-off-by: Punit Agrawal Acked-by: Viresh Kumar Cc: Eduardo Valentin --- drivers/cpufreq/cpufreq-dt.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 528a82bf..1d1f61a 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -344,8 +344,13 @@ static void cpufreq_ready(struct cpufreq_policy *policy) * thermal DT code takes care of matching them. */ if (of_find_property(np, "#cooling-cells", NULL)) { - priv->cdev = of_cpufreq_cooling_register(np, -policy->related_cpus); + u32 power_coefficient = 0; + + of_property_read_u32(np, "dynamic-power-coefficient", +&power_coefficient); + + priv->cdev = of_cpufreq_power_cooling_register(np, + policy->related_cpus, power_coefficient, NULL); if (IS_ERR(priv->cdev)) { dev_err(priv->cpu_dev, "running cpufreq without cooling device: %ld\n", -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 06/10] firmware: arm_scpi: Extend to support sensors
ARM System Control Processor (SCP) provides an API to query and use the sensors available in the system. Extend the SCPI driver to support sensor messages. Signed-off-by: Punit Agrawal Cc: Sudeep Holla --- drivers/firmware/arm_scpi.c | 60 +++ include/linux/scpi_protocol.h | 17 2 files changed, 77 insertions(+) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index cb75c75..321680e 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -219,6 +219,21 @@ struct dvfs_set { u8 index; } __packed; +struct sensor_capabilities { + __le16 sensors; +} __packed; + +struct _scpi_sensor_info { + __le16 sensor_id; + u8 class; + u8 trigger_type; + char name[20]; +}; + +struct sensor_value { + __le32 val; +} __packed; + static struct scpi_drvinfo *scpi_info; static int scpi_linux_errmap[SCPI_ERR_MAX] = { @@ -481,6 +496,48 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain) return info; } +static int scpi_sensor_get_capability(u16 *sensors) +{ + struct sensor_capabilities cap_buf; + int ret; + + ret = scpi_send_message(SCPI_CMD_SENSOR_CAPABILITIES, NULL, 0, &cap_buf, + sizeof(cap_buf)); + if (!ret) + *sensors = le16_to_cpu(cap_buf.sensors); + + return ret; +} + +static int scpi_sensor_get_info(u16 sensor_id, struct scpi_sensor_info *info) +{ + __le16 id = cpu_to_le16(sensor_id); + struct _scpi_sensor_info _info; + int ret; + + ret = scpi_send_message(SCPI_CMD_SENSOR_INFO, &id, +sizeof(id), &_info, sizeof(_info)); + if (!ret) { + memcpy(info, &_info, sizeof(*info)); + info->sensor_id = le16_to_cpu(_info.sensor_id); + } + + return ret; +} + +int scpi_sensor_get_value(u16 sensor, u32 *val) +{ + struct sensor_value buf; + int ret; + + ret = scpi_send_message(SCPI_CMD_SENSOR_VALUE, &sensor, sizeof(sensor), + &buf, sizeof(buf)); + if (!ret) + *val = le32_to_cpu(buf.val); + + return ret; +} + static struct scpi_ops scpi_ops = { .get_version = scpi_get_version, .clk_get_range = scpi_clk_get_range, @@ -489,6 +546,9 @@ static struct scpi_ops scpi_ops = { .dvfs_get_idx = scpi_dvfs_get_idx, .dvfs_set_idx = scpi_dvfs_set_idx, .dvfs_get_info = scpi_dvfs_get_info, + .sensor_get_capability = scpi_sensor_get_capability, + .sensor_get_info = scpi_sensor_get_info, + .sensor_get_value = scpi_sensor_get_value, }; struct scpi_ops *get_scpi_ops(void) diff --git a/include/linux/scpi_protocol.h b/include/linux/scpi_protocol.h index e7169cd..80af3cd 100644 --- a/include/linux/scpi_protocol.h +++ b/include/linux/scpi_protocol.h @@ -28,6 +28,20 @@ struct scpi_dvfs_info { struct scpi_opp *opps; }; +enum scpi_sensor_class { + TEMPERATURE, + VOLTAGE, + CURRENT, + POWER, +}; + +struct scpi_sensor_info { + u16 sensor_id; + u8 class; + u8 trigger_type; + char name[20]; +} __packed; + /** * struct scpi_ops - represents the various operations provided * by SCP through SCPI message protocol @@ -52,6 +66,9 @@ struct scpi_ops { int (*dvfs_get_idx)(u8); int (*dvfs_set_idx)(u8, u8); struct scpi_dvfs_info *(*dvfs_get_info)(u8); + int (*sensor_get_capability)(u16 *sensors); + int (*sensor_get_info)(u16 sensor_id, struct scpi_sensor_info *); + int (*sensor_get_value)(u16, u32 *); }; #if IS_ENABLED(CONFIG_ARM_SCPI_PROTOCOL) -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 04/10] thermal: Fix thermal_zone_of_sensor_register to match documentation
thermal_zone_of_sensor_register is documented as returning a pointer to either a valid thermal_zone_device on success, or a corresponding ERR_PTR() value. In contrast, the function returns NULL when THERMAL_OF is configured off. Fix this. Signed-off-by: Punit Agrawal Cc: Guenter Roeck Cc: Eduardo Valentin Cc: Zhang Rui --- include/linux/thermal.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/include/linux/thermal.h b/include/linux/thermal.h index 037e9df..a47b34a 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -364,7 +364,7 @@ static inline struct thermal_zone_device * thermal_zone_of_sensor_register(struct device *dev, int id, void *data, const struct thermal_zone_of_device_ops *ops) { - return NULL; + return ERR_PTR(-ENOSYS); } static inline -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 03/10] cpufreq: arm_big_little: Add support to register a cpufreq cooling device
Register passive cooling devices when initialising cpufreq on big.LITTLE systems. If the device tree provides a dynamic power coefficient for the CPUs then the bound cooling device will support the extensions that allow it to be used with all the existing thermal governors including the power allocator governor. A cooling device will be created per individual frequency domain and can be bound to thermal zones via the thermal DT bindings. Signed-off-by: Punit Agrawal Acked-by: Viresh Kumar Cc: Sudeep Holla Cc: Eduardo Valentin --- drivers/cpufreq/arm_big_little.c | 52 ++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index f1e42f8..72a2777 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,10 @@ static bool bL_switching_enabled; #define ACTUAL_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq << 1 : freq) #define VIRT_FREQ(cluster, freq)((cluster == A7_CLUSTER) ? freq >> 1 : freq) +struct private_data { + struct thermal_cooling_device *cdev; +}; + static struct cpufreq_arm_bL_ops *arm_bL_ops; static struct clk *clk[MAX_CLUSTERS]; static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS + 1]; @@ -440,6 +445,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); @@ -457,9 +463,15 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy) if (ret) { dev_err(cpu_dev, "CPU %d, cluster: %d invalid freq table\n", policy->cpu, cur_cluster); - put_cluster_clk_and_freq_table(cpu_dev); - return ret; + goto out_free_cpufreq_table; + } + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + ret = -ENOMEM; + goto out_free_cpufreq_table; } + policy->driver_data = priv; if (cur_cluster < MAX_CLUSTERS) { int cpu; @@ -484,12 +496,19 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy) dev_info(cpu_dev, "%s: CPU %d initialized\n", __func__, policy->cpu); return 0; + +out_free_cpufreq_table: + put_cluster_clk_and_freq_table(cpu_dev); + + return ret; } static int bL_cpufreq_exit(struct cpufreq_policy *policy) { struct device *cpu_dev; + struct private_data *priv = policy->driver_data; + cpufreq_cooling_unregister(priv->cdev); cpu_dev = get_cpu_device(policy->cpu); if (!cpu_dev) { pr_err("%s: failed to get cpu%d device\n", __func__, @@ -498,11 +517,39 @@ static int bL_cpufreq_exit(struct cpufreq_policy *policy) } put_cluster_clk_and_freq_table(cpu_dev); + kfree(priv); dev_dbg(cpu_dev, "%s: Exited, cpu: %d\n", __func__, policy->cpu); return 0; } +static void bL_cpufreq_ready(struct cpufreq_policy *policy) +{ + struct device *cpu_dev = get_cpu_device(policy->cpu); + struct device_node *np = of_node_get(cpu_dev->of_node); + struct private_data *priv = policy->driver_data; + + if (WARN_ON(!np)) + return; + + if (of_find_property(np, "#cooling-cells", NULL)) { + u32 power_coefficient = 0; + + of_property_read_u32(np, "dynamic-power-coefficient", +&power_coefficient); + + priv->cdev = of_cpufreq_power_cooling_register(np, + policy->related_cpus, power_coefficient, NULL); + if (IS_ERR(priv->cdev)) { + dev_err(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 | @@ -513,6 +560,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, }; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 09/10] arm64: dts: Add sensor node to Juno dt
The SCP firmware on Juno provides access to SoC sensors via the SCPI. Add the sensor nodes to the device tree to enable this support. Signed-off-by: Punit Agrawal Cc: Rob Herring Cc: Mark Rutland Cc: Liviu Dudau Cc: Sudeep Holla --- arch/arm64/boot/dts/arm/juno-base.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi index c624208..dd5158e 100644 --- a/arch/arm64/boot/dts/arm/juno-base.dtsi +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -96,6 +96,11 @@ clock-output-names = "pxlclk0", "pxlclk1"; }; }; + + scpi_sensors0: sensors { + compatible = "arm,scpi-sensors"; + #thermal-sensor-cells = <1>; + }; }; /include/ "juno-clocks.dtsi" -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 07/10] hwmon: Support sensors exported via ARM SCP interface
Create a driver to add support for SoC sensors exported by the System Control Processor (SCP) via the System Control and Power Interface (SCPI). The supported sensor types is one of voltage, temperature, current, and power. The sensor labels and values provided by the SCP are exported via the hwmon sysfs interface. Signed-off-by: Punit Agrawal Cc: Jean Delvare Cc: Guenter Roeck Cc: Sudeep Holla --- Documentation/hwmon/scpi-hwmon | 33 drivers/hwmon/Kconfig | 8 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/scpi-hwmon.c | 183 + 4 files changed, 225 insertions(+) create mode 100644 Documentation/hwmon/scpi-hwmon create mode 100644 drivers/hwmon/scpi-hwmon.c diff --git a/Documentation/hwmon/scpi-hwmon b/Documentation/hwmon/scpi-hwmon new file mode 100644 index 000..4cfcdf2d --- /dev/null +++ b/Documentation/hwmon/scpi-hwmon @@ -0,0 +1,33 @@ +Kernel driver scpi-hwmon + + +Supported chips: + * Chips based on ARM System Control Processor Interface + Addresses scanned: - + Datasheet: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.dui0922b/index.html + +Author: Punit Agrawal + +Description +--- + +This driver supports hardware monitoring for SoC's based on the ARM +System Control Processor (SCP) implementing the System Control +Processor Interface (SCPI). The following sensor types are supported +by the SCP - + + * temperature + * voltage + * current + * power + +The SCP interface provides an API to query the available sensors and +their values which are then exported to userspace by this driver. + +Usage Notes +--- + +The driver relies on device tree node to indicate the presence of SCPI +support in the kernel. See +Documentation/devicetree/bindings/arm/arm,scpi.txt for details of the +devicetree node. \ No newline at end of file diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 4943c3c..c9714b0 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1551,6 +1551,14 @@ config SENSORS_VEXPRESS the ARM Ltd's Versatile Express platform. It can provide wide range of information like temperature, power, energy. +config SENSORS_ARM_SCPI + tristate "ARM SCPI Sensors" + depends on ARM_SCPI_PROTOCOL + help + This driver provides support for temperature, voltage, current + and power sensors available on ARM Ltd's SCP based platforms. The + actual number and type of sensors exported depend the platform. + config SENSORS_VIA_CPUTEMP tristate "VIA CPU temperature sensor" depends on X86 diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 8aba87f..4961710 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -150,6 +150,7 @@ obj-$(CONFIG_SENSORS_TMP421)+= tmp421.o obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o obj-$(CONFIG_SENSORS_V2M_JUNO) += v2m-juno.o obj-$(CONFIG_SENSORS_VEXPRESS) += vexpress.o +obj-$(CONFIG_SENSORS_ARM_SCPI) += scpi-hwmon.o obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o obj-$(CONFIG_SENSORS_VIA686A) += via686a.o obj-$(CONFIG_SENSORS_VT1211) += vt1211.o diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c new file mode 100644 index 000..7e7e06b --- /dev/null +++ b/drivers/hwmon/scpi-hwmon.c @@ -0,0 +1,183 @@ +/* + * System Control and Power Interface(SCPI) based hwmon sensor driver + * + * Copyright (C) 2015 ARM Ltd. + * Punit Agrawal + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#include +#include +#include +#include +#include +#include + +struct sensor_data { + struct scpi_sensor_info info; + struct device_attribute dev_attr_input; + struct device_attribute dev_attr_label; + char input[20]; + char label[20]; +}; + +struct scpi_sensors { + struct scpi_ops *scpi_ops; + struct sensor_data *data; + struct attribute **attrs; + struct attribute_group group; + const struct attribute_group *groups[2]; +}; + +/* hwmon callback functions */ +static ssize_t +scpi_show_sensor(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct scpi_sensors *scpi_sensors = dev_get_drvdata(dev); + struct scpi_ops *scpi_ops = scpi_sensors->scpi_ops; + struct sensor_data *sensor; + u32 value; + int ret; + + sensor = container_of(attr, struct sensor_data, dev_attr_input); + + ret = scpi_ops->sensor_get_val
[PATCH v2 10/10] arm64: dts: Create SoC thermal zone for Juno
Setup a thermal zone driven by the SoC temperature sensor on Juno r0. Create passive trip points and bind them to cpufreq cooling devices that support the power extensions. Signed-off-by: Punit Agrawal Cc: Rob Herring Cc: Mark Rutland Cc: Liviu Dudau Cc: Sudeep Holla --- arch/arm64/boot/dts/arm/juno.dts | 50 1 file changed, 50 insertions(+) diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts index d2e67f3..664961c 100644 --- a/arch/arm64/boot/dts/arm/juno.dts +++ b/arch/arm64/boot/dts/arm/juno.dts @@ -9,6 +9,7 @@ /dts-v1/; #include +#include / { model = "ARM Juno development board (r0)"; @@ -90,6 +91,8 @@ next-level-cache = <&A57_L2>; clocks = <&scpi_dvfs 0>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + #cooling-cells = <2>; + dynamic-power-coefficient = <530>; }; A57_1: cpu@1 { @@ -100,6 +103,8 @@ next-level-cache = <&A57_L2>; clocks = <&scpi_dvfs 0>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + #cooling-cells = <2>; + dynamic-power-coefficient = <530>; }; A53_0: cpu@100 { @@ -110,6 +115,8 @@ next-level-cache = <&A53_L2>; clocks = <&scpi_dvfs 1>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + #cooling-cells = <2>; + dynamic-power-coefficient = <140>; }; A53_1: cpu@101 { @@ -120,6 +127,8 @@ next-level-cache = <&A53_L2>; clocks = <&scpi_dvfs 1>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + #cooling-cells = <2>; + dynamic-power-coefficient = <140>; }; A53_2: cpu@102 { @@ -130,6 +139,8 @@ next-level-cache = <&A53_L2>; clocks = <&scpi_dvfs 1>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + #cooling-cells = <2>; + dynamic-power-coefficient = <140>; }; A53_3: cpu@103 { @@ -140,6 +151,8 @@ next-level-cache = <&A53_L2>; clocks = <&scpi_dvfs 1>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + #cooling-cells = <2>; + dynamic-power-coefficient = <140>; }; A57_L2: l2-cache0 { @@ -167,5 +180,42 @@ <&A53_3>; }; + thermal-zones { + soc_thermal { + polling-delay = <1000>; + polling-delay-passive = <100>; + sustainable-power = <2500>; + + thermal-sensors = <&scpi_sensors0 3>; + + trips { + threshold: trip-point@0 { + temperature = <55000>; + hysteresis = <1000>; + type = "passive"; + }; + target: trip-point@1 { + temperature = <65000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&target>; + cooling-device = <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + contribution = <2048>; + }; + map1 { + trip = <&target>; + cooling-device = <&A57_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + contribution = <1024>; + }; + + }; + }; + }; + #include "juno-base.dtsi" }; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 01/10] devicetree: bindings: Add optional dynamic-power-coefficient property
The dynamic power consumption of a device is proportional to the square of voltage (V) and the clock frequency (f). It can be expressed as Pdyn = dynamic-power-coefficient * V^2 * f. The dynamic-power-coefficient property represents an indicative running time dynamic power coefficient in fundamental units of mw/MHz/uVolt^2 and can be used in the above formula to calculate the dynamic power in mW. Signed-off-by: Punit Agrawal Cc: Rob Herring Cc: Mark Rutland --- Documentation/devicetree/bindings/arm/cpus.txt | 15 +++ 1 file changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index d6b794c..c32bfac 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt @@ -239,6 +239,21 @@ nodes to be present and contain the properties described below. Definition: Specifies the syscon node controlling the cpu core power domains. + - dynamic-power-coefficient + Usage: optional + Value type: + Definition: A u32 value that represents an indicative + running time dynamic power coefficient in + fundamental units of mW/MHz/uVolt^2. + + The dynamic energy consumption of the CPU + is proportional to the square of the + Voltage (V) and the clock frequency (f). + + Pdyn = dynamic-power-coefficient * V^2 * f + + where voltage is in uV, frequency is in MHz. + Example 1 (dual-cluster big.LITTLE system 32-bit): cpus { -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH v2 08/10] hwmon: Support registration of thermal zones for SCP temperature sensors
Add support to create thermal zones based on the temperature sensors provided by the SCP. The thermal zones can be defined using the thermal DT bindings and should refer to the SCP sensor id to select the sensor. Signed-off-by: Punit Agrawal Cc: Jean Delvare Cc: Guenter Roeck Cc: Eduardo Valentin --- drivers/hwmon/scpi-hwmon.c | 103 - 1 file changed, 102 insertions(+), 1 deletion(-) diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c index 7e7e06b..d96a3e5 100644 --- a/drivers/hwmon/scpi-hwmon.c +++ b/drivers/hwmon/scpi-hwmon.c @@ -20,6 +20,7 @@ #include #include #include +#include struct sensor_data { struct scpi_sensor_info info; @@ -29,14 +30,39 @@ struct sensor_data { char label[20]; }; +struct scpi_thermal_zone { + struct list_head list; + int sensor_id; + struct scpi_sensors *scpi_sensors; + struct thermal_zone_device *tzd; +}; + struct scpi_sensors { struct scpi_ops *scpi_ops; struct sensor_data *data; + struct list_head thermal_zones; struct attribute **attrs; struct attribute_group group; const struct attribute_group *groups[2]; }; +static int scpi_read_temp(void *dev, long *temp) +{ + struct scpi_thermal_zone *zone = dev; + struct scpi_sensors *scpi_sensors = zone->scpi_sensors; + struct scpi_ops *scpi_ops = scpi_sensors->scpi_ops; + struct sensor_data *sensor = &scpi_sensors->data[zone->sensor_id]; + u32 value; + int ret; + + ret = scpi_ops->sensor_get_value(sensor->info.sensor_id, &value); + if (ret) + return ret; + + *temp = value; + return 0; +} + /* hwmon callback functions */ static ssize_t scpi_show_sensor(struct device *dev, struct device_attribute *attr, char *buf) @@ -66,6 +92,24 @@ scpi_show_label(struct device *dev, struct device_attribute *attr, char *buf) return sprintf(buf, "%s\n", sensor->info.name); } +static void +unregister_thermal_zones(struct platform_device *pdev, +struct scpi_sensors *scpi_sensors) +{ + struct list_head *pos; + + list_for_each(pos, &scpi_sensors->thermal_zones) { + struct scpi_thermal_zone *zone; + + zone = list_entry(pos, struct scpi_thermal_zone, list); + thermal_zone_of_sensor_unregister(&pdev->dev, zone->tzd); + } +} + +static struct thermal_zone_of_device_ops scpi_sensor_ops = { + .get_temp = scpi_read_temp, +}; + static int scpi_hwmon_probe(struct platform_device *pdev) { u16 nr_sensors, i; @@ -157,10 +201,66 @@ static int scpi_hwmon_probe(struct platform_device *pdev) scpi_sensors->group.attrs = scpi_sensors->attrs; scpi_sensors->groups[0] = &scpi_sensors->group; + platform_set_drvdata(pdev, scpi_sensors); + hwdev = devm_hwmon_device_register_with_groups(dev, "scpi_sensors", scpi_sensors, scpi_sensors->groups); - return PTR_ERR_OR_ZERO(hwdev); + if (IS_ERR(hwdev)) + return PTR_ERR(hwdev); + + /* +* Register the temperature sensors with the thermal framework +* to allow their usage in setting up the thermal zones from +* device tree. +* +* NOTE: Not all temperature sensors maybe used for thermal +* control +*/ + INIT_LIST_HEAD(&scpi_sensors->thermal_zones); + for (i = 0; i < nr_sensors; i++) { + struct sensor_data *sensor = &scpi_sensors->data[i]; + struct scpi_thermal_zone *zone; + + if (sensor->info.class != TEMPERATURE) + continue; + + zone = devm_kzalloc(&pdev->dev, sizeof(*zone), GFP_KERNEL); + if (!zone) { + ret = -ENOMEM; + goto unregister_tzd; + } + + zone->sensor_id = i; + zone->scpi_sensors = scpi_sensors; + zone->tzd = thermal_zone_of_sensor_register(dev, i, zone, + &scpi_sensor_ops); + /* +* The call to thermal_zone_of_sensor_register returns +* an error for sensors that are not associated with +* any thermal zones. +*/ + if (IS_ERR(zone->tzd)) { + devm_kfree(dev, zone); + continue; + } + list_add(&zone->list, &scpi_sensors->thermal_zones); + } + + return 0; + +unregister_tzd: + unregister_thermal_zones(pdev, scpi_sensors); + return ret; +} + +static int scpi_hwmon_remove(struct platform_device *pdev) +{ + struct scpi_sensors *scpi_sensors =
Re: [PATCH 0/9] Platform support for thermal management on Junoe
Hi Viresh, Viresh Kumar writes: > On 22-07-15, 15:02, Punit Agrawal wrote: >> cpufreq-dt: Supply power coefficient when registering cooling devices >> cpufreq: arm_big_little: Add support to register a cpufreq cooling >> device > > Acked-by: Viresh Kumar Thanks for the acks. Once the device tree property is agreed upon, will you be picking up these patches? Punit -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [PATCH 7/9] hwmon: Support registration of thermal zones for SCP temperature sensors
Hi Guenter, Guenter Roeck writes: > On 07/22/2015 07:02 AM, Punit Agrawal wrote: >> Add support to create thermal zones based on the temperature sensors >> provided by the SCP. The thermal zones can be defined using the >> thermal DT bindings and should refer to the SCP sensor id to select >> the sensor. >> >> Signed-off-by: Punit Agrawal >> Cc: Jean Delvare >> Cc: Guenter Roeck >> Cc: Eduardo Valentin >> --- >> drivers/hwmon/scpi-hwmon.c | 53 >> ++ >> 1 file changed, 53 insertions(+) >> >> diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c >> index dd0a6f1..1e52ced 100644 >> --- a/drivers/hwmon/scpi-hwmon.c >> +++ b/drivers/hwmon/scpi-hwmon.c [...] >> @@ -54,6 +61,20 @@ static int scpi_read_sensor(struct sensor_dev *sensor, >> u32 *value) >> return 0; >> } >> >> +static int scpi_read_temp(void *dev, long *temp) >> +{ >> +struct sensor_dev *sensor = dev; >> +u32 value; >> +int ret; >> + >> +ret = scpi_read_sensor(sensor, &value); >> +if (ret) >> +return ret; >> + >> +*temp = value; >> +return 0; >> +} >> + >> /* hwmon callback functions */ >> static ssize_t >> scpi_hwmon_show_sensor(struct device *dev, >> @@ -90,6 +111,10 @@ struct attribute *scpi_attrs[24] = { 0 }; >> struct attribute_group scpi_group; >> const struct attribute_group *scpi_groups[2] = { 0 }; >> >> +struct thermal_zone_of_device_ops scpi_sensor_ops = { > > static struct ... > Updated. >> +.get_temp = scpi_read_temp, >> +}; >> + >> static int scpi_hwmon_probe(struct platform_device *pdev) >> { >> u16 sensors, i; >> @@ -108,9 +133,12 @@ static int scpi_hwmon_probe(struct platform_device >> *pdev) >> if (!scpi_sensors.device) >> return -ENOMEM; >> >> +INIT_LIST_HEAD(&scpi_sensors.thermal_zones); >> + >> dev_info(&pdev->dev, "Found %d sensors\n", sensors); >> for (i = 0; i < sensors; i++) { >> struct sensor_dev *dev = &scpi_sensors.device[i]; >> +struct scpi_thermal_zone *zone; >> >> ret = scpi_ops->sensor_get_info(i, &dev->info); >> if (ret) { >> @@ -130,6 +158,20 @@ static int scpi_hwmon_probe(struct platform_device >> *pdev) >> snprintf(dev->label, 20, >> "temp%d_label", scpi_sensors.num_temp); >> scpi_sensors.num_temp++; >> + >> +zone = devm_kmalloc(&pdev->dev, sizeof(*zone), >> +GFP_KERNEL); > > Please consider using devm_kzalloc(). > Done >> +if (!zone) >> +return -ENOMEM; >> + >> +zone->tzd = thermal_zone_of_sensor_register(&pdev->dev, >> +i, dev, &scpi_sensor_ops); >> +if (!IS_ERR(zone->tzd)) >> +list_add(&zone->list, >> + &scpi_sensors.thermal_zones); >> +else >> +devm_kfree(&pdev->dev, zone); >> + > > I would prefer > > if (IS_ERR_OR_NULL(zone->tzd)) { > devm_kfree(&pdev->dev, zone); > break; > } > list_add(&zone->list, &scpi_sensors.thermal_zones); > > The code has a problem, though: You don't clean up thermal zones if > there is an error later on in the probe function. Either you need to > implement a cleanup function to be called from an error handler (and > from the remove function), or you need to wait with registering > thermal zones to the very end of the probe function. > I've re-factored to register the sensors at the end of the probe. > Note that thermal_zone_of_sensor_register can return NULL if thermal > zones are not configured, so you have to use IS_ERR_OR_NULL > when checking for errors. > You're right. I missed the NULL return when THERMAL_OF is configured off. This doesn't match the documentation at the top of the function in drivers/thermal/of-thermal.c * Return: On success returns a valid struct thermal_zone_device, * otherwise, it returns a corresponding ERR_PTR(). Caller m
Re: [PATCH 6/9] hwmon: Support sensors exported via ARM SCP interface
Hi Guenter, Guenter Roeck writes: > On 07/22/2015 07:02 AM, Punit Agrawal wrote: >> Create a driver to add support for SoC sensors exported by the System >> Control Processor (SCP) via the System Control and Power Interface >> (SCPI). The supported sensor types is one of voltage, temperature, >> current, and power. >> >> The sensor labels and values provided by the SCP are exported via the >> hwmon sysfs interface. >> >> Signed-off-by: Punit Agrawal >> Cc: Jean Delvare >> Cc: Guenter Roeck >> Cc: Sudeep Holla >> --- >> drivers/hwmon/Kconfig | 8 ++ >> drivers/hwmon/Makefile | 1 + >> drivers/hwmon/scpi-hwmon.c | 212 >> + > > Please also provide Documentation/hwmon/scpi-hwmon. > Added documentation in the above location. >> 3 files changed, 221 insertions(+) >> create mode 100644 drivers/hwmon/scpi-hwmon.c >> >> diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig >> index 4943c3c..f5e0862 100644 >> --- a/drivers/hwmon/Kconfig >> +++ b/drivers/hwmon/Kconfig >> @@ -1551,6 +1551,14 @@ config SENSORS_VEXPRESS >>the ARM Ltd's Versatile Express platform. It can provide wide >>range of information like temperature, power, energy. >> >> +config SENSORS_ARM_SCPI >> +tristate "ARM SCPI Sensors" >> +depends on ARM_SCPI_PROTOCOL >> +help >> + This driver provides support for hardware sensors available on >> + the ARM Ltd's SCP based platforms. It can provide temperature > > can provide or provides ? The actual sensors exported are dependent on the platform and the firmware. But the above wording can be improved. I've updated it to This driver provides support for temperature, voltage, current and power sensors available on ARM Ltd's SCP based platforms. The actual number and type of sensors exported depend the platform. >> + and voltage for range of devices on the SoC. > > current, power ? > >> + >> config SENSORS_VIA_CPUTEMP >> tristate "VIA CPU temperature sensor" >> depends on X86 >> diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile >> index 8aba87f..4961710 100644 >> --- a/drivers/hwmon/Makefile >> +++ b/drivers/hwmon/Makefile >> @@ -150,6 +150,7 @@ obj-$(CONFIG_SENSORS_TMP421) += tmp421.o >> obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o >> obj-$(CONFIG_SENSORS_V2M_JUNO) += v2m-juno.o >> obj-$(CONFIG_SENSORS_VEXPRESS) += vexpress.o >> +obj-$(CONFIG_SENSORS_ARM_SCPI) += scpi-hwmon.o >> obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o >> obj-$(CONFIG_SENSORS_VIA686A) += via686a.o >> obj-$(CONFIG_SENSORS_VT1211) += vt1211.o >> diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c >> new file mode 100644 >> index 000..dd0a6f1 >> --- /dev/null >> +++ b/drivers/hwmon/scpi-hwmon.c >> @@ -0,0 +1,212 @@ >> +/* >> + * System Control and Power Interface(SCPI) based hwmon sensor driver >> + * >> + * Copyright (C) 2015 ARM Ltd. >> + * Punit Agrawal >> + * >> + * This program is free software; you can redistribute it and/or modify >> + * it under the terms of the GNU General Public License version 2 as >> + * published by the Free Software Foundation. >> + * >> + * This program is distributed "as is" WITHOUT ANY WARRANTY of any >> + * kind, whether express or implied; without even the implied warranty >> + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the >> + * GNU General Public License for more details. >> + */ >> + >> +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt > > Not needed since there are no pr_xxx() messages in this driver. > Dropped it. >> + >> +#include >> +#include >> +#include >> +#include >> +#include >> +#include >> + >> +static struct scpi_ops *scpi_ops; >> + > This variable should be kept in a local data structure (scpi_sensors). > Moved now. >> +struct sensor_dev { >> +struct scpi_sensor_info info; >> +struct device_attribute dev_attr_input; >> +struct device_attribute dev_attr_label; >> +char input[20]; >> +char label[20]; >> +}; >> + >> +struct scpi_sensors { >> +int num_volt; >> +int num_temp; >> +int num_current; >> +int num_power; > > num_volt, num_temp, num_current, and num_power are not used > outside the probe function and are thus
[PATCH 4/9] Documentation: add DT bindings for ARM SCPI sensors
The System Control Processor (SCP) provides access to SoC sensors via the System Control and Power Interface (SCPI) Message Protocol. Add bindings to allow probing of these sensors. Also support referencing of the sensors for setting up thermal zones via the thermal DT bindings. Signed-off-by: Punit Agrawal Cc: Rob Herring Cc: Mark Rutland Cc: Sudeep Holla --- Documentation/devicetree/bindings/arm/arm,scpi.txt | 15 +++ 1 file changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/arm,scpi.txt b/Documentation/devicetree/bindings/arm/arm,scpi.txt index e3757bc..5cb2b18 100644 --- a/Documentation/devicetree/bindings/arm/arm,scpi.txt +++ b/Documentation/devicetree/bindings/arm/arm,scpi.txt @@ -74,8 +74,18 @@ Required sub-node properties: - compatible : should be "arm,juno-scp-shmem" for Non-secure SRAM based shared memory on Juno platforms +Sensor bindings for the sensors based on SCPI Message Protocol +-- +SCPI provides an API to access the various sensors on the SoC. + +Required properties: +- compatible : should be "arm,scpi-sensors". +- #thermal-sensor-cells: should be set to 1. This property follows the +thermal device tree bindings[2]. + [0] http://community.arm.com/servlet/JiveServlet/download/8401-45-18326/DUI0922B_scp_message_interface.pdf [1] Documentation/devicetree/bindings/clock/clock-bindings.txt +[2] Documentation/devicetree/bindings/thermal/thermal.txt Example: @@ -124,6 +134,11 @@ scpi_protocol: scpi@2e00 { clock-output-names = "pxlclk0", "pxlclk1"; }; }; + + scpi_sensors0: sensors { + compatible = "arm,scpi-sensors"; + #thermal-sensor-cells = <1>; + }; }; cpu@0 { -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 3/9] cpufreq: arm_big_little: Add support to register a cpufreq cooling device
Register passive cooling devices when initialising cpufreq on big.LITTLE systems. If the device tree provides a dynamic power coefficient for the CPUs then the bound cooling device will support the extensions that allow it to be used with all the existing thermal governors including the power allocator governor. A cooling device will be created per individual frequency domain and can be bound to thermal zones via the thermal DT bindings. Signed-off-by: Punit Agrawal Cc: Viresh Kumar Cc: Sudeep Holla Cc: Eduardo Valentin --- drivers/cpufreq/arm_big_little.c | 52 ++-- 1 file changed, 50 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index f1e42f8..72a2777 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -23,6 +23,7 @@ #include #include #include +#include #include #include #include @@ -55,6 +56,10 @@ static bool bL_switching_enabled; #define ACTUAL_FREQ(cluster, freq) ((cluster == A7_CLUSTER) ? freq << 1 : freq) #define VIRT_FREQ(cluster, freq)((cluster == A7_CLUSTER) ? freq >> 1 : freq) +struct private_data { + struct thermal_cooling_device *cdev; +}; + static struct cpufreq_arm_bL_ops *arm_bL_ops; static struct clk *clk[MAX_CLUSTERS]; static struct cpufreq_frequency_table *freq_table[MAX_CLUSTERS + 1]; @@ -440,6 +445,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); @@ -457,9 +463,15 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy) if (ret) { dev_err(cpu_dev, "CPU %d, cluster: %d invalid freq table\n", policy->cpu, cur_cluster); - put_cluster_clk_and_freq_table(cpu_dev); - return ret; + goto out_free_cpufreq_table; + } + + priv = kzalloc(sizeof(*priv), GFP_KERNEL); + if (!priv) { + ret = -ENOMEM; + goto out_free_cpufreq_table; } + policy->driver_data = priv; if (cur_cluster < MAX_CLUSTERS) { int cpu; @@ -484,12 +496,19 @@ static int bL_cpufreq_init(struct cpufreq_policy *policy) dev_info(cpu_dev, "%s: CPU %d initialized\n", __func__, policy->cpu); return 0; + +out_free_cpufreq_table: + put_cluster_clk_and_freq_table(cpu_dev); + + return ret; } static int bL_cpufreq_exit(struct cpufreq_policy *policy) { struct device *cpu_dev; + struct private_data *priv = policy->driver_data; + cpufreq_cooling_unregister(priv->cdev); cpu_dev = get_cpu_device(policy->cpu); if (!cpu_dev) { pr_err("%s: failed to get cpu%d device\n", __func__, @@ -498,11 +517,39 @@ static int bL_cpufreq_exit(struct cpufreq_policy *policy) } put_cluster_clk_and_freq_table(cpu_dev); + kfree(priv); dev_dbg(cpu_dev, "%s: Exited, cpu: %d\n", __func__, policy->cpu); return 0; } +static void bL_cpufreq_ready(struct cpufreq_policy *policy) +{ + struct device *cpu_dev = get_cpu_device(policy->cpu); + struct device_node *np = of_node_get(cpu_dev->of_node); + struct private_data *priv = policy->driver_data; + + if (WARN_ON(!np)) + return; + + if (of_find_property(np, "#cooling-cells", NULL)) { + u32 power_coefficient = 0; + + of_property_read_u32(np, "dynamic-power-coefficient", +&power_coefficient); + + priv->cdev = of_cpufreq_power_cooling_register(np, + policy->related_cpus, power_coefficient, NULL); + if (IS_ERR(priv->cdev)) { + dev_err(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 | @@ -513,6 +560,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, }; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 0/9] Platform support for thermal management on Junoe
Hi, The series adds support for thermal management on ARM Juno development platform. As part of this development, common infrastructure is added to support registering cpu cooling devices that work with the power allocator thermal governor. Patch 1 extends the CPU nodes binding to provide an optional dynamic power coefficient which can be used to create a dynamic power model for the CPUs. This model is used to constrain device power consumption (using power_allocator governor) when the system is thermally constrained. Patches 2-3 extends the cpufreq-dt and arm_big_little driver to register cpu cooling devices with the dynamic coefficient when provided. Patches 4-7 create a hwmon sensor driver for sensors provided by SCPI firmware. Patch 7 adds support for the temperature sensors to register with the thermal framework. This allows setting up platform thermals using OF thermal bindings. The last two patches add support for the sensors and the thermal zones in the Juno device tree. The Juno specific patches depend on SCPI and cpufreq patches[0] from Sudeep. Thanks, Punit [0] http://thread.gmane.org/gmane.linux.power-management.general/61073 Punit Agrawal (9): devicetree: bindings: Add optional dynamic-power-coefficient property cpufreq-dt: Supply power coefficient when registering cooling devices cpufreq: arm_big_little: Add support to register a cpufreq cooling device Documentation: add DT bindings for ARM SCPI sensors firmware: arm_scpi: Extend to support sensors hwmon: Support sensors exported via ARM SCP interface hwmon: Support registration of thermal zones for SCP temperature sensors arm64: dts: Add sensor node to Juno dt arm64: dts: Create SoC thermal zone for Juno Documentation/devicetree/bindings/arm/arm,scpi.txt | 15 ++ Documentation/devicetree/bindings/arm/cpus.txt | 15 ++ arch/arm64/boot/dts/arm/juno-base.dtsi | 5 + arch/arm64/boot/dts/arm/juno.dts | 50 drivers/cpufreq/arm_big_little.c | 52 +++- drivers/cpufreq/cpufreq-dt.c | 9 +- drivers/firmware/arm_scpi.c| 60 + drivers/hwmon/Kconfig | 8 + drivers/hwmon/Makefile | 1 + drivers/hwmon/scpi-hwmon.c | 265 + include/linux/scpi_protocol.h | 17 ++ 11 files changed, 493 insertions(+), 4 deletions(-) create mode 100644 drivers/hwmon/scpi-hwmon.c -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 2/9] cpufreq-dt: Supply power coefficient when registering cooling devices
Support registering cooling devices with dynamic power coefficient where provided by the device tree. This allows OF registered cooling devices driver to be used with the power_allocator thermal governor. Signed-off-by: Punit Agrawal Cc: Viresh Kumar Cc: Eduardo Valentin --- drivers/cpufreq/cpufreq-dt.c | 9 +++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 528a82bf..1d1f61a 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -344,8 +344,13 @@ static void cpufreq_ready(struct cpufreq_policy *policy) * thermal DT code takes care of matching them. */ if (of_find_property(np, "#cooling-cells", NULL)) { - priv->cdev = of_cpufreq_cooling_register(np, -policy->related_cpus); + u32 power_coefficient = 0; + + of_property_read_u32(np, "dynamic-power-coefficient", +&power_coefficient); + + priv->cdev = of_cpufreq_power_cooling_register(np, + policy->related_cpus, power_coefficient, NULL); if (IS_ERR(priv->cdev)) { dev_err(priv->cpu_dev, "running cpufreq without cooling device: %ld\n", -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 7/9] hwmon: Support registration of thermal zones for SCP temperature sensors
Add support to create thermal zones based on the temperature sensors provided by the SCP. The thermal zones can be defined using the thermal DT bindings and should refer to the SCP sensor id to select the sensor. Signed-off-by: Punit Agrawal Cc: Jean Delvare Cc: Guenter Roeck Cc: Eduardo Valentin --- drivers/hwmon/scpi-hwmon.c | 53 ++ 1 file changed, 53 insertions(+) diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c index dd0a6f1..1e52ced 100644 --- a/drivers/hwmon/scpi-hwmon.c +++ b/drivers/hwmon/scpi-hwmon.c @@ -22,6 +22,7 @@ #include #include #include +#include static struct scpi_ops *scpi_ops; @@ -33,12 +34,18 @@ struct sensor_dev { char label[20]; }; +struct scpi_thermal_zone { + struct list_head list; + struct thermal_zone_device *tzd; +}; + struct scpi_sensors { int num_volt; int num_temp; int num_current; int num_power; struct sensor_dev *device; + struct list_head thermal_zones; struct device *hwdev; }; struct scpi_sensors scpi_sensors; @@ -54,6 +61,20 @@ static int scpi_read_sensor(struct sensor_dev *sensor, u32 *value) return 0; } +static int scpi_read_temp(void *dev, long *temp) +{ + struct sensor_dev *sensor = dev; + u32 value; + int ret; + + ret = scpi_read_sensor(sensor, &value); + if (ret) + return ret; + + *temp = value; + return 0; +} + /* hwmon callback functions */ static ssize_t scpi_hwmon_show_sensor(struct device *dev, @@ -90,6 +111,10 @@ struct attribute *scpi_attrs[24] = { 0 }; struct attribute_group scpi_group; const struct attribute_group *scpi_groups[2] = { 0 }; +struct thermal_zone_of_device_ops scpi_sensor_ops = { + .get_temp = scpi_read_temp, +}; + static int scpi_hwmon_probe(struct platform_device *pdev) { u16 sensors, i; @@ -108,9 +133,12 @@ static int scpi_hwmon_probe(struct platform_device *pdev) if (!scpi_sensors.device) return -ENOMEM; + INIT_LIST_HEAD(&scpi_sensors.thermal_zones); + dev_info(&pdev->dev, "Found %d sensors\n", sensors); for (i = 0; i < sensors; i++) { struct sensor_dev *dev = &scpi_sensors.device[i]; + struct scpi_thermal_zone *zone; ret = scpi_ops->sensor_get_info(i, &dev->info); if (ret) { @@ -130,6 +158,20 @@ static int scpi_hwmon_probe(struct platform_device *pdev) snprintf(dev->label, 20, "temp%d_label", scpi_sensors.num_temp); scpi_sensors.num_temp++; + + zone = devm_kmalloc(&pdev->dev, sizeof(*zone), + GFP_KERNEL); + if (!zone) + return -ENOMEM; + + zone->tzd = thermal_zone_of_sensor_register(&pdev->dev, + i, dev, &scpi_sensor_ops); + if (!IS_ERR(zone->tzd)) + list_add(&zone->list, +&scpi_sensors.thermal_zones); + else + devm_kfree(&pdev->dev, zone); + break; case VOLTAGE: snprintf(dev->input, 20, @@ -187,7 +229,18 @@ static int scpi_hwmon_probe(struct platform_device *pdev) static int scpi_hwmon_remove(struct platform_device *pdev) { + struct list_head *pos; + scpi_ops = NULL; + + list_for_each(pos, &scpi_sensors.thermal_zones) { + struct scpi_thermal_zone *zone; + + zone = list_entry(pos, struct scpi_thermal_zone, list); + thermal_zone_of_sensor_unregister(scpi_sensors.hwdev, + zone->tzd); + } + return 0; } -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 8/9] arm64: dts: Add sensor node to Juno dt
The SCP firmware on Juno provides access to SoC sensors via the SCPI. Add the sensor nodes to the device tree to enable this support. Signed-off-by: Punit Agrawal Cc: Rob Herring Cc: Mark Rutland Cc: Liviu Dudau Cc: Sudeep Holla --- arch/arm64/boot/dts/arm/juno-base.dtsi | 5 + 1 file changed, 5 insertions(+) diff --git a/arch/arm64/boot/dts/arm/juno-base.dtsi b/arch/arm64/boot/dts/arm/juno-base.dtsi index c624208..dd5158e 100644 --- a/arch/arm64/boot/dts/arm/juno-base.dtsi +++ b/arch/arm64/boot/dts/arm/juno-base.dtsi @@ -96,6 +96,11 @@ clock-output-names = "pxlclk0", "pxlclk1"; }; }; + + scpi_sensors0: sensors { + compatible = "arm,scpi-sensors"; + #thermal-sensor-cells = <1>; + }; }; /include/ "juno-clocks.dtsi" -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 6/9] hwmon: Support sensors exported via ARM SCP interface
Create a driver to add support for SoC sensors exported by the System Control Processor (SCP) via the System Control and Power Interface (SCPI). The supported sensor types is one of voltage, temperature, current, and power. The sensor labels and values provided by the SCP are exported via the hwmon sysfs interface. Signed-off-by: Punit Agrawal Cc: Jean Delvare Cc: Guenter Roeck Cc: Sudeep Holla --- drivers/hwmon/Kconfig | 8 ++ drivers/hwmon/Makefile | 1 + drivers/hwmon/scpi-hwmon.c | 212 + 3 files changed, 221 insertions(+) create mode 100644 drivers/hwmon/scpi-hwmon.c diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig index 4943c3c..f5e0862 100644 --- a/drivers/hwmon/Kconfig +++ b/drivers/hwmon/Kconfig @@ -1551,6 +1551,14 @@ config SENSORS_VEXPRESS the ARM Ltd's Versatile Express platform. It can provide wide range of information like temperature, power, energy. +config SENSORS_ARM_SCPI + tristate "ARM SCPI Sensors" + depends on ARM_SCPI_PROTOCOL + help + This driver provides support for hardware sensors available on + the ARM Ltd's SCP based platforms. It can provide temperature + and voltage for range of devices on the SoC. + config SENSORS_VIA_CPUTEMP tristate "VIA CPU temperature sensor" depends on X86 diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile index 8aba87f..4961710 100644 --- a/drivers/hwmon/Makefile +++ b/drivers/hwmon/Makefile @@ -150,6 +150,7 @@ obj-$(CONFIG_SENSORS_TMP421)+= tmp421.o obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o obj-$(CONFIG_SENSORS_V2M_JUNO) += v2m-juno.o obj-$(CONFIG_SENSORS_VEXPRESS) += vexpress.o +obj-$(CONFIG_SENSORS_ARM_SCPI) += scpi-hwmon.o obj-$(CONFIG_SENSORS_VIA_CPUTEMP)+= via-cputemp.o obj-$(CONFIG_SENSORS_VIA686A) += via686a.o obj-$(CONFIG_SENSORS_VT1211) += vt1211.o diff --git a/drivers/hwmon/scpi-hwmon.c b/drivers/hwmon/scpi-hwmon.c new file mode 100644 index 000..dd0a6f1 --- /dev/null +++ b/drivers/hwmon/scpi-hwmon.c @@ -0,0 +1,212 @@ +/* + * System Control and Power Interface(SCPI) based hwmon sensor driver + * + * Copyright (C) 2015 ARM Ltd. + * Punit Agrawal + * + * This program is free software; you can redistribute it and/or modify + * it under the terms of the GNU General Public License version 2 as + * published by the Free Software Foundation. + * + * This program is distributed "as is" WITHOUT ANY WARRANTY of any + * kind, whether express or implied; without even the implied warranty + * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + * GNU General Public License for more details. + */ + +#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt + +#include +#include +#include +#include +#include +#include + +static struct scpi_ops *scpi_ops; + +struct sensor_dev { + struct scpi_sensor_info info; + struct device_attribute dev_attr_input; + struct device_attribute dev_attr_label; + char input[20]; + char label[20]; +}; + +struct scpi_sensors { + int num_volt; + int num_temp; + int num_current; + int num_power; + struct sensor_dev *device; + struct device *hwdev; +}; +struct scpi_sensors scpi_sensors; + +static int scpi_read_sensor(struct sensor_dev *sensor, u32 *value) +{ + int ret; + + ret = scpi_ops->sensor_get_value(sensor->info.sensor_id, value); + if (ret) + return ret; + + return 0; +} + +/* hwmon callback functions */ +static ssize_t +scpi_hwmon_show_sensor(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensor_dev *sensor; + u32 value; + int ret; + + sensor = container_of(attr, struct sensor_dev, dev_attr_input); + + ret = scpi_read_sensor(sensor, &value); + if (ret) { + dev_warn(dev, "error (ret=%d) reading sensor (id=%u) value\n", +ret, sensor->info.sensor_id); + return 0; + } + + return sprintf(buf, "%u\n", value); +} + +static ssize_t +scpi_hwmon_show_label(struct device *dev, + struct device_attribute *attr, char *buf) +{ + struct sensor_dev *sensor; + + sensor = container_of(attr, struct sensor_dev, dev_attr_label); + + return sprintf(buf, "%s\n", sensor->info.name); +} + +struct attribute *scpi_attrs[24] = { 0 }; +struct attribute_group scpi_group; +const struct attribute_group *scpi_groups[2] = { 0 }; + +static int scpi_hwmon_probe(struct platform_device *pdev) +{ + u16 sensors, i; + int ret; + + scpi_ops = get_scpi_ops(); + if (!scpi_ops) + return -EPROBE_DEFER; + + ret = scpi_ops->sensor_get_capability(&sensors); + if (ret) + return ret; + + scpi_sensors.de
[PATCH 9/9] arm64: dts: Create SoC thermal zone for Juno
Setup a thermal zone driven by the SoC temperature sensor on Juno r0. Create passive trip points and bind them to cpufreq cooling devices that support the power extensions. Signed-off-by: Punit Agrawal Cc: Rob Herring Cc: Mark Rutland Cc: Liviu Dudau Cc: Sudeep Holla --- arch/arm64/boot/dts/arm/juno.dts | 50 1 file changed, 50 insertions(+) diff --git a/arch/arm64/boot/dts/arm/juno.dts b/arch/arm64/boot/dts/arm/juno.dts index d2e67f3..664961c 100644 --- a/arch/arm64/boot/dts/arm/juno.dts +++ b/arch/arm64/boot/dts/arm/juno.dts @@ -9,6 +9,7 @@ /dts-v1/; #include +#include / { model = "ARM Juno development board (r0)"; @@ -90,6 +91,8 @@ next-level-cache = <&A57_L2>; clocks = <&scpi_dvfs 0>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + #cooling-cells = <2>; + dynamic-power-coefficient = <530>; }; A57_1: cpu@1 { @@ -100,6 +103,8 @@ next-level-cache = <&A57_L2>; clocks = <&scpi_dvfs 0>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + #cooling-cells = <2>; + dynamic-power-coefficient = <530>; }; A53_0: cpu@100 { @@ -110,6 +115,8 @@ next-level-cache = <&A53_L2>; clocks = <&scpi_dvfs 1>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + #cooling-cells = <2>; + dynamic-power-coefficient = <140>; }; A53_1: cpu@101 { @@ -120,6 +127,8 @@ next-level-cache = <&A53_L2>; clocks = <&scpi_dvfs 1>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + #cooling-cells = <2>; + dynamic-power-coefficient = <140>; }; A53_2: cpu@102 { @@ -130,6 +139,8 @@ next-level-cache = <&A53_L2>; clocks = <&scpi_dvfs 1>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + #cooling-cells = <2>; + dynamic-power-coefficient = <140>; }; A53_3: cpu@103 { @@ -140,6 +151,8 @@ next-level-cache = <&A53_L2>; clocks = <&scpi_dvfs 1>; cpu-idle-states = <&CPU_SLEEP_0 &CLUSTER_SLEEP_0>; + #cooling-cells = <2>; + dynamic-power-coefficient = <140>; }; A57_L2: l2-cache0 { @@ -167,5 +180,42 @@ <&A53_3>; }; + thermal-zones { + soc_thermal { + polling-delay = <1000>; + polling-delay-passive = <100>; + sustainable-power = <2500>; + + thermal-sensors = <&scpi_sensors0 3>; + + trips { + threshold: trip-point@0 { + temperature = <55000>; + hysteresis = <1000>; + type = "passive"; + }; + target: trip-point@1 { + temperature = <65000>; + hysteresis = <1000>; + type = "passive"; + }; + }; + + cooling-maps { + map0 { + trip = <&target>; + cooling-device = <&A53_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + contribution = <2048>; + }; + map1 { + trip = <&target>; + cooling-device = <&A57_0 THERMAL_NO_LIMIT THERMAL_NO_LIMIT>; + contribution = <1024>; + }; + + }; + }; + }; + #include "juno-base.dtsi" }; -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 5/9] firmware: arm_scpi: Extend to support sensors
ARM System Control Processor (SCP) provides an API to query and use the sensors available in the system. Extend the SCPI driver to support sensor messages. Signed-off-by: Punit Agrawal Cc: Sudeep Holla --- drivers/firmware/arm_scpi.c | 60 +++ include/linux/scpi_protocol.h | 17 2 files changed, 77 insertions(+) diff --git a/drivers/firmware/arm_scpi.c b/drivers/firmware/arm_scpi.c index a70b7ba..478c5c5 100644 --- a/drivers/firmware/arm_scpi.c +++ b/drivers/firmware/arm_scpi.c @@ -219,6 +219,21 @@ struct dvfs_set { u8 index; } __packed; +struct sensor_capabilities { + __le16 sensors; +} __packed; + +struct _scpi_sensor_info { + __le16 sensor_id; + u8 class; + u8 trigger_type; + char name[20]; +}; + +struct sensor_value { + __le32 val; +} __packed; + static struct scpi_drvinfo *scpi_info; static int scpi_linux_errmap[SCPI_ERR_MAX] = { @@ -481,6 +496,48 @@ static struct scpi_dvfs_info *scpi_dvfs_get_info(u8 domain) return info; } +static int scpi_sensor_get_capability(u16 *sensors) +{ + struct sensor_capabilities cap_buf; + int ret; + + ret = scpi_send_message(SCPI_CMD_SENSOR_CAPABILITIES, NULL, 0, &cap_buf, + sizeof(cap_buf)); + if (!ret) + *sensors = le16_to_cpu(cap_buf.sensors); + + return ret; +} + +static int scpi_sensor_get_info(u16 sensor_id, struct scpi_sensor_info *info) +{ + __le16 id = cpu_to_le16(sensor_id); + struct _scpi_sensor_info _info; + int ret; + + ret = scpi_send_message(SCPI_CMD_SENSOR_INFO, &id, +sizeof(id), &_info, sizeof(_info)); + if (!ret) { + memcpy(info, &_info, sizeof(*info)); + info->sensor_id = le16_to_cpu(_info.sensor_id); + } + + return ret; +} + +int scpi_sensor_get_value(u16 sensor, u32 *val) +{ + struct sensor_value buf; + int ret; + + ret = scpi_send_message(SCPI_CMD_SENSOR_VALUE, &sensor, sizeof(sensor), + &buf, sizeof(buf)); + if (!ret) + *val = le32_to_cpu(buf.val); + + return ret; +} + static struct scpi_ops scpi_ops = { .get_version = scpi_get_version, .clk_get_range = scpi_clk_get_range, @@ -489,6 +546,9 @@ static struct scpi_ops scpi_ops = { .dvfs_get_idx = scpi_dvfs_get_idx, .dvfs_set_idx = scpi_dvfs_set_idx, .dvfs_get_info = scpi_dvfs_get_info, + .sensor_get_capability = scpi_sensor_get_capability, + .sensor_get_info = scpi_sensor_get_info, + .sensor_get_value = scpi_sensor_get_value, }; struct scpi_ops *get_scpi_ops(void) diff --git a/include/linux/scpi_protocol.h b/include/linux/scpi_protocol.h index e7169cd..80af3cd 100644 --- a/include/linux/scpi_protocol.h +++ b/include/linux/scpi_protocol.h @@ -28,6 +28,20 @@ struct scpi_dvfs_info { struct scpi_opp *opps; }; +enum scpi_sensor_class { + TEMPERATURE, + VOLTAGE, + CURRENT, + POWER, +}; + +struct scpi_sensor_info { + u16 sensor_id; + u8 class; + u8 trigger_type; + char name[20]; +} __packed; + /** * struct scpi_ops - represents the various operations provided * by SCP through SCPI message protocol @@ -52,6 +66,9 @@ struct scpi_ops { int (*dvfs_get_idx)(u8); int (*dvfs_set_idx)(u8, u8); struct scpi_dvfs_info *(*dvfs_get_info)(u8); + int (*sensor_get_capability)(u16 *sensors); + int (*sensor_get_info)(u16 sensor_id, struct scpi_sensor_info *); + int (*sensor_get_value)(u16, u32 *); }; #if IS_ENABLED(CONFIG_ARM_SCPI_PROTOCOL) -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH 1/9] devicetree: bindings: Add optional dynamic-power-coefficient property
The dynamic power consumption of a device is proportional to the square of voltage (V) and the clock frequency (f). It can be expressed as Pdyn = dynamic-power-coefficient * V^2 * f. The dynamic-power-coefficient property represents an indicative running time dynamic power coefficient in fundamental units of mw/MHz/uVolt^2 and can be used in the above formula to calculate the dynamic power in mW. Signed-off-by: Punit Agrawal Cc: Rob Herring Cc: Mark Rutland --- Documentation/devicetree/bindings/arm/cpus.txt | 15 +++ 1 file changed, 15 insertions(+) diff --git a/Documentation/devicetree/bindings/arm/cpus.txt b/Documentation/devicetree/bindings/arm/cpus.txt index d6b794c..c32bfac 100644 --- a/Documentation/devicetree/bindings/arm/cpus.txt +++ b/Documentation/devicetree/bindings/arm/cpus.txt @@ -239,6 +239,21 @@ nodes to be present and contain the properties described below. Definition: Specifies the syscon node controlling the cpu core power domains. + - dynamic-power-coefficient + Usage: optional + Value type: + Definition: A u32 value that represents an indicative + running time dynamic power coefficient in + fundamental units of mW/MHz/uVolt^2. + + The dynamic energy consumption of the CPU + is proportional to the square of the + Voltage (V) and the clock frequency (f). + + Pdyn = dynamic-power-coefficient * V^2 * f + + where voltage is in uV, frequency is in MHz. + Example 1 (dual-cluster big.LITTLE system 32-bit): cpus { -- 2.1.4 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
Re: [RFC PATCH 0/2] thermal: Add generic devfreq cooling device
Hi Chanwoo, Chanwoo Choi writes: > Hi Punit, > > On 07/17/2015 07:53 PM, Punit Agrawal wrote: >> Hi Chanwoo, >> >> Chanwoo Choi writes: >> >>> This patchset introduce the generic devfreq cooling device for generic >>> thermal >>> framework. The devfreq devices are used ad cooling device to reduce the >>> overheating temperature. This patch is based on >>> drivers/thermal/cpu_cooling.c. >>> The devfreq cooling device can change the ragne of the frequency table of >>> devfreq device according to cooling level in device tree file. >>> >> >> Have you had a look at the devfreq cooling patches from Javi[0][1]? How >> is the current patchset different? > > I didn't see Javi's patchset before. Thanks for your information. > > I reviewed ths Javi's patchset. Both Javi's patchset and my patchset > has same concept except for applying the power allocator thermal governor > as you below comment. > > But, there are some difference. > > First, > I don't add new devfreq API (devfreq_set_max() / devfreq_set_min()). > The my patchset used existing update_devfreq() to update the > maximum frequency of devfreq device. > Ok. > Second, > In my patchset, the devfreq cooling device will be operated > as existing cpu cooling device. If sensor measure the overheating > temperature, devfreq cooling device will limit the maximum frequency > of devfreq device. Javi's patchset behaves exactly as you describe here. > As below example, the devicetree file includes > the overheating temperature information of each trip-point. > - Javi's patchset used the static power value calculated by > devfreq_cooling_gen_power_table() instead of temperature. > You've got this wrong. The power table is used to model device power consumption which allows the device to be used with the power_allocator governor. Refer to the power_allocator documentation[2] to understand how it is used. This doesn't change the behaviour when used with other governors. [2] https://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/Documentation/thermal/power_allocator.txt?id=refs/tags/v4.2-rc3 > Third, > Javi's patchset used the same string of type when calling > the thermal_of_cooling_device_register() > - Javi's patchset used always the same "devfreq" string. > - My patchset used the different "thermal-devfreq-%d" string > according to each devfreq cooling device. > Except for this difference (which needs to be fixed), the current patchset is a subset of the functionality proposed in [1]. With the merging of the power_allocator governor in v4.2, it makes sense for the devfreq cooling device to also include support for it - especially when the functionality is already under discussion on the list. As such, it would be great if you could provide feedback on that thread. Thanks, Punit > In my patchset, devfreq cooling device uses the same method > to determine the throttling situation as existing cpu cooling > device. It is just my opinion. > >> >> At first glance, it seems that you are not implementing the extensions >> that allow devfreq cooling devices to be used with power_allocator >> thermal governor that got merged in v4.2-rc1. >> >> Thanks, >> Punit >> >> [0] http://article.gmane.org/gmane.linux.power-management.general/61936 >> [1] http://article.gmane.org/gmane.linux.power-management.general/62417 > > Thanks, > Chanwoo Choi > >> >> >>> To verify the devfreq cooling device driver, I testd it with following >>> platform: >>> >>> For example, >>> - The Mali GPU of Exynos5433 SoC uses the devfreq framework to support the >>> DVFS >>> feature and Exynos5433 contains the G3D (GPU) thermal sensor. Following >>> example >>> explain the correlation between mali dt node and thermal sensor/zone. >>> : thermal sensor : G3D sensor of Samsung Exynos5433 [1][2] >>> : devfreq cooling device : Mali GPU [3] >>> >>> According to the temperature of g3d thermal sensor inclued in Exynos5433, >>> devfreq cooling device can change the maximum frequency of Mali GPU. >>> >>> 1. In Exynos5433-based board dts file, Mali GPU dt node uses the devfreq >>> framework to suppot the DVFS feature. Following dt node includes the >>> both 'cooling-cells' and 'operating-points' which means the supported >>> frequency entries: >>> >>> mali: mali@14AC { >>> compatible = "arm,mali-midgard"; >>> reg = &l
Re: [RFC PATCH 0/2] thermal: Add generic devfreq cooling device
Hi Chanwoo, Chanwoo Choi writes: > This patchset introduce the generic devfreq cooling device for generic thermal > framework. The devfreq devices are used ad cooling device to reduce the > overheating temperature. This patch is based on drivers/thermal/cpu_cooling.c. > The devfreq cooling device can change the ragne of the frequency table of > devfreq device according to cooling level in device tree file. > Have you had a look at the devfreq cooling patches from Javi[0][1]? How is the current patchset different? At first glance, it seems that you are not implementing the extensions that allow devfreq cooling devices to be used with power_allocator thermal governor that got merged in v4.2-rc1. Thanks, Punit [0] http://article.gmane.org/gmane.linux.power-management.general/61936 [1] http://article.gmane.org/gmane.linux.power-management.general/62417 > To verify the devfreq cooling device driver, I testd it with following > platform: > > For example, > - The Mali GPU of Exynos5433 SoC uses the devfreq framework to support the > DVFS > feature and Exynos5433 contains the G3D (GPU) thermal sensor. Following > example > explain the correlation between mali dt node and thermal sensor/zone. > : thermal sensor : G3D sensor of Samsung Exynos5433 [1][2] > : devfreq cooling device : Mali GPU [3] > > According to the temperature of g3d thermal sensor inclued in Exynos5433, > devfreq cooling device can change the maximum frequency of Mali GPU. > > 1. In Exynos5433-based board dts file, Mali GPU dt node uses the devfreq > framework to suppot the DVFS feature. Following dt node includes the > both 'cooling-cells' and 'operating-points' which means the supported > frequency entries: > > mali: mali@14AC { > compatible = "arm,mali-midgard"; > reg = <0x14AC 0x5000>; > interrupts = <0 282 0>, <0 283 0>, <0 281 0>; > interrupt-names = "JOB", "MMU", "GPU"; > clocks = <&cmu_g3d CLK_ACLK_G3D>; > clock-names = "clk_mali"; > power-domains = <&pd_g3d>; > status = "disabled"; > > #cooling-cells = <2>; > > operating-points = < > 70 115 > 60 115 > 55 1125000 > 50 1075000 > 42 1025000 > 35 1025000 > 266000 100 > 16 100 > >; > }; > > 2. In exynos5433.dtsi, G3D thermal sensor measure the temperature of Mali GPU: > > tmu_g3d: tmu@1007 { > compatible = "samsung,exynos5433-tmu"; > reg = <0x1007 0x200>; > interrupts = <0 99 0>; > clocks = <&cmu_peris CLK_PCLK_TMU1_APBIF>, ><&cmu_peris CLK_SCLK_TMU1>; > clock-names = "tmu_apbif", "tmu_sclk"; > #include "exynos5433-tmu-sensor-conf.dtsi" > status = "disabled"; > }; > > 3. In exynos5433-tmu.dtsi, thermal-zones includes both trip points and > cooling-maps of g3d thermal sensor. Following cooling-maps show the match > between each trip point and each cooling device (devfreq device of mali): > > thermal-zones { > /* .. */ > g3d_thermal: g3d-thermal { > thermal-sensors = <&tmu_g3d>; > polling-delay-passive = <0>; > polling-delay = <0>; > trips { > g3d_alert_0: g3d-alert-0 { > temperature = <3>; /* millicelsius > */ > hysteresis = <1>; /* millicelsius > */ > type = "active"; > }; > g3d_alert_1: g3d-alert-1 { > temperature = <4>; /* millicelsius > */ > hysteresis = <1>; /* millicelsius > */ > type = "active"; > }; > > /* .. */ > }; > > cooling-maps { > map0 { > /* Set maximum frequency as 550MHz */ > trip = <&g3d_alert_0>; > cooling-device = <&mali 2 2>; > }; > map1 { > /* Set maximum frequency as 420MHz */ > trip = <&g3d_alert_1>; > cooling-device = <&mali 4 4>; > }; > > /* .. */ > }; >
Re: [PATCHv3 0/5] arm-cci400: PMU monitoring support on ARM64
"Suzuki K. Poulose" writes: > From: "Suzuki K. Poulose" > > This series enables the PMU monitoring support for CCI400 on ARM64. > The existing CCI400 driver code is a mix of PMU driver and the MCPM > driver code. The MCPM driver is only used on ARM(32) and contains > arm32 assembly and hence can't be built on ARM64. This patch splits > the code to > > - ARM_CCI400_PORT_CTRL driver - depends on ARM && V7 > - ARM_CCI400_PMU driver > > Accessing the Peripheral ID2 register(PID2) on CCI-400, to detect > the revision of the chipset, is a secure operation. Hence, it prevents > us from running this on non-secure platforms. The issue is overcome by > explicitly mentioning the revision number of the CCI PMU in the device tree > binding. The device-tree binding has been updated with the new bindings. > > i.e, arm-cci-400-pmu,r0 => revision 0 > arm-cci-400-pmu,r1 => revision 1 > arm-cci-400-pmu => (old) DEPRECATED > > The old binding has been DEPRECATED and must be used only on ARM32 > system with secure access. We don't have a reliable dynamic way to detect > if the system is running secure. This series tries to use the best safe > method by relying on the availability of MCPM(as it was prior to the series). > It is upto the MCPM platform driver to decide, if the system is secure before > it goes ahead and registers its drivers and pokes the CCI. This series doesn't > address/solve the problem of MCPM. I will be happy to use a better approach, > if there is any. > > Tested on (non-secure)TC2 and A53x2. > For the series, Acked-by: Punit Agrawal Cheers, Punit [...] -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html
[PATCH] thermal: Fix cdev registration with THERMAL_NO_LIMIT on 64bit
The size of unsigned long varies between 32 and 64 bit systems while the size of phandle arguments is always 32 bits per parameter. On 64-bit systems, cooling devices registered via of-thermal apis fail to bind when the min/max cooling state is specified as THERMAL_NO_LIMIT (-1UL) as there is a mis-match between the value read from the device tree (32bit) and the pre-processor define (64bit). As we're unlikely to need cooling states larger than 32 bits, and for consistency with the size of phandle arguments, explicitly limit THERMAL_NO_LIMIT to 32 bits. Signed-off-by: Punit Agrawal --- include/dt-bindings/thermal/thermal.h | 2 +- include/linux/thermal.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/include/dt-bindings/thermal/thermal.h b/include/dt-bindings/thermal/thermal.h index 59822a9..b5e6b00 100644 --- a/include/dt-bindings/thermal/thermal.h +++ b/include/dt-bindings/thermal/thermal.h @@ -11,7 +11,7 @@ #define _DT_BINDINGS_THERMAL_THERMAL_H /* On cooling devices upper and lower limits */ -#define THERMAL_NO_LIMIT (-1UL) +#define THERMAL_NO_LIMIT (~0) #endif diff --git a/include/linux/thermal.h b/include/linux/thermal.h index ef90838..005586f 100644 --- a/include/linux/thermal.h +++ b/include/linux/thermal.h @@ -38,7 +38,7 @@ #define THERMAL_CSTATE_INVALID -1UL /* No upper/lower limit requirement */ -#define THERMAL_NO_LIMIT THERMAL_CSTATE_INVALID +#define THERMAL_NO_LIMIT ((u32)~0) /* Unit conversion macros */ #define KELVIN_TO_CELSIUS(t) (long)(((long)t-2732 >= 0) ?\ -- 2.1.1 -- To unsubscribe from this list: send the line "unsubscribe devicetree" in the body of a message to majord...@vger.kernel.org More majordomo info at http://vger.kernel.org/majordomo-info.html