From f5f263fed66f75a4482d7ad49392b4283a05885a Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 5 Dec 2017 11:02:43 +0530 Subject: [PATCH 1/5] cpu_cooling: Make of_cpufreq_power_cooling_register() parse DT All the callers of of_cpufreq_power_cooling_register() have almost identical code and it makes more sense to move that code into the helper as its all about reading DT properties. This got rid of lot of redundant code. Acked-by: Eduardo Valentin Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- Documentation/thermal/cpu-cooling-api.txt | 7 ++-- drivers/cpufreq/arm_big_little.c | 23 +---------- drivers/cpufreq/cpufreq-dt.c | 27 +------------ drivers/cpufreq/mediatek-cpufreq.c | 22 +--------- drivers/cpufreq/qoriq-cpufreq.c | 14 +------ drivers/thermal/cpu_cooling.c | 49 ++++++++++++++--------- include/linux/cpu_cooling.h | 15 ++----- 7 files changed, 41 insertions(+), 116 deletions(-) diff --git a/Documentation/thermal/cpu-cooling-api.txt b/Documentation/thermal/cpu-cooling-api.txt index 71653584cd03..4f6f5e9bb4d6 100644 --- a/Documentation/thermal/cpu-cooling-api.txt +++ b/Documentation/thermal/cpu-cooling-api.txt @@ -51,8 +51,7 @@ Dynamic power). "plat_static_func" is a function to calculate the static power consumed by these cpus (See 2.2 Static power). 1.1.4 struct thermal_cooling_device *of_cpufreq_power_cooling_register( - struct device_node *np, const struct cpumask *clip_cpus, u32 capacitance, - get_static_t plat_static_func) + struct cpufreq_policy *policy) Similar to cpufreq_power_cooling_register, this function register a cpufreq cooling device with power extensions using the device tree @@ -76,8 +75,8 @@ cpu. If you are using CONFIG_CPUFREQ_DT then the device. The `plat_static_func` parameter of `cpufreq_power_cooling_register()` -and `of_cpufreq_power_cooling_register()` is optional. If you don't -provide it, only dynamic power will be considered. +is optional. If you don't provide it, only dynamic power will be +considered. 2.1 Dynamic power diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index 65ec5f01aa8d..3d5ed4ef3927 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -526,34 +526,13 @@ static int bL_cpufreq_exit(struct cpufreq_policy *policy) 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, 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); + cdev[cur_cluster] = of_cpufreq_power_cooling_register(policy); } static struct cpufreq_driver bL_cpufreq_driver = { diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 545946ad0752..1e7bec7694ab 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -319,33 +319,8 @@ static int cpufreq_exit(struct cpufreq_policy *policy) static void cpufreq_ready(struct cpufreq_policy *policy) { struct private_data *priv = policy->driver_data; - struct device_node *np = of_node_get(priv->cpu_dev->of_node); - if (WARN_ON(!np)) - return; - - /* - * For now, just loading the cooling device; - * thermal DT code takes care of matching them. - */ - 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, power_coefficient, NULL); - if (IS_ERR(priv->cdev)) { - dev_err(priv->cpu_dev, - "running cpufreq without cooling device: %ld\n", - PTR_ERR(priv->cdev)); - - priv->cdev = NULL; - } - } - - of_node_put(np); + priv->cdev = of_cpufreq_power_cooling_register(policy); } static struct cpufreq_driver dt_cpufreq_driver = { diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c index e0d5090b303d..6ff783e1b18a 100644 --- a/drivers/cpufreq/mediatek-cpufreq.c +++ b/drivers/cpufreq/mediatek-cpufreq.c @@ -310,28 +310,8 @@ static int mtk_cpufreq_set_target(struct cpufreq_policy *policy, static void mtk_cpufreq_ready(struct cpufreq_policy *policy) { struct mtk_cpu_dvfs_info *info = policy->driver_data; - struct device_node *np = of_node_get(info->cpu_dev->of_node); - u32 capacitance = 0; - if (WARN_ON(!np)) - return; - - if (of_find_property(np, "#cooling-cells", NULL)) { - of_property_read_u32(np, DYNAMIC_POWER, &capacitance); - - info->cdev = of_cpufreq_power_cooling_register(np, - policy, capacitance, NULL); - - if (IS_ERR(info->cdev)) { - dev_err(info->cpu_dev, - "running cpufreq without cooling device: %ld\n", - PTR_ERR(info->cdev)); - - info->cdev = NULL; - } - } - - of_node_put(np); + info->cdev = of_cpufreq_power_cooling_register(policy); } static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) diff --git a/drivers/cpufreq/qoriq-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c index 4ada55b8856e..3a665c18e14e 100644 --- a/drivers/cpufreq/qoriq-cpufreq.c +++ b/drivers/cpufreq/qoriq-cpufreq.c @@ -275,20 +275,8 @@ static int qoriq_cpufreq_target(struct cpufreq_policy *policy, static void qoriq_cpufreq_ready(struct cpufreq_policy *policy) { struct cpu_data *cpud = policy->driver_data; - struct device_node *np = of_get_cpu_node(policy->cpu, NULL); - if (of_find_property(np, "#cooling-cells", NULL)) { - cpud->cdev = of_cpufreq_cooling_register(np, policy); - - if (IS_ERR(cpud->cdev) && PTR_ERR(cpud->cdev) != -ENOSYS) { - pr_err("cpu%d is not running as cooling device: %ld\n", - policy->cpu, PTR_ERR(cpud->cdev)); - - cpud->cdev = NULL; - } - } - - of_node_put(np); + cpud->cdev = of_cpufreq_power_cooling_register(policy); } static struct cpufreq_driver qoriq_cpufreq_driver = { diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index dc63aba092e4..a31eb03c788e 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c @@ -873,38 +873,51 @@ EXPORT_SYMBOL(cpufreq_power_cooling_register); /** * of_cpufreq_power_cooling_register() - create cpufreq cooling device with power extensions - * @np: a valid struct device_node to the cooling device device tree node - * @policy: cpufreq policy - * @capacitance: dynamic power coefficient for these cpus - * @plat_static_func: function to calculate the static power consumed by these - * cpus (optional) + * @policy: CPUFreq policy. * * This interface function registers the cpufreq cooling device with * the name "thermal-cpufreq-%x". This api can support multiple * instances of cpufreq cooling devices. Using this API, the cpufreq - * cooling device will be linked to the device tree node provided. + * cooling device will be linked to the device tree node of the provided + * policy's CPU. * Using this function, the cooling device will implement the power * extensions by using a simple cpu power model. The cpus must have * registered their OPPs using the OPP library. * - * An optional @plat_static_func may be provided to calculate the - * static power consumed by these cpus. If the platform's static - * power consumption is unknown or negligible, make it NULL. + * It also takes into account, if property present in policy CPU node, the + * static power consumed by the cpu. * * Return: a valid struct thermal_cooling_device pointer on success, - * on failure, it returns a corresponding ERR_PTR(). + * and NULL on failure. */ struct thermal_cooling_device * -of_cpufreq_power_cooling_register(struct device_node *np, - struct cpufreq_policy *policy, - u32 capacitance, - get_static_t plat_static_func) +of_cpufreq_power_cooling_register(struct cpufreq_policy *policy) { - if (!np) - return ERR_PTR(-EINVAL); + struct device_node *np = of_get_cpu_node(policy->cpu, NULL); + struct thermal_cooling_device *cdev = NULL; + u32 capacitance = 0; - return __cpufreq_cooling_register(np, policy, capacitance, - plat_static_func); + if (!np) { + pr_err("cpu_cooling: OF node not available for cpu%d\n", + policy->cpu); + return NULL; + } + + if (of_find_property(np, "#cooling-cells", NULL)) { + of_property_read_u32(np, "dynamic-power-coefficient", + &capacitance); + + cdev = __cpufreq_cooling_register(np, policy, capacitance, + NULL); + if (IS_ERR(cdev)) { + pr_err("cpu_cooling: cpu%d is not running as cooling device: %ld\n", + policy->cpu, PTR_ERR(cdev)); + cdev = NULL; + } + } + + of_node_put(np); + return cdev; } EXPORT_SYMBOL(of_cpufreq_power_cooling_register); diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h index d4292ebc5c8b..f09d4feb34f4 100644 --- a/include/linux/cpu_cooling.h +++ b/include/linux/cpu_cooling.h @@ -56,10 +56,7 @@ of_cpufreq_cooling_register(struct device_node *np, struct cpufreq_policy *policy); struct thermal_cooling_device * -of_cpufreq_power_cooling_register(struct device_node *np, - struct cpufreq_policy *policy, - u32 capacitance, - get_static_t plat_static_func); +of_cpufreq_power_cooling_register(struct cpufreq_policy *policy); #else static inline struct thermal_cooling_device * of_cpufreq_cooling_register(struct device_node *np, @@ -69,10 +66,7 @@ of_cpufreq_cooling_register(struct device_node *np, } static inline struct thermal_cooling_device * -of_cpufreq_power_cooling_register(struct device_node *np, - struct cpufreq_policy *policy, - u32 capacitance, - get_static_t plat_static_func) +of_cpufreq_power_cooling_register(struct cpufreq_policy *policy) { return NULL; } @@ -105,10 +99,7 @@ of_cpufreq_cooling_register(struct device_node *np, } static inline struct thermal_cooling_device * -of_cpufreq_power_cooling_register(struct device_node *np, - struct cpufreq_policy *policy, - u32 capacitance, - get_static_t plat_static_func) +of_cpufreq_power_cooling_register(struct cpufreq_policy *policy) { return NULL; } From ba0966da208ef0793486502a0e6b929fbd6d4223 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 5 Dec 2017 11:02:44 +0530 Subject: [PATCH 2/5] cpu_cooling: Remove unused cpufreq_power_cooling_register() It isn't used by anyone, drop it. Acked-by: Eduardo Valentin Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- Documentation/thermal/cpu-cooling-api.txt | 24 +++--------------- drivers/thermal/cpu_cooling.c | 30 ----------------------- include/linux/cpu_cooling.h | 10 -------- 3 files changed, 3 insertions(+), 61 deletions(-) diff --git a/Documentation/thermal/cpu-cooling-api.txt b/Documentation/thermal/cpu-cooling-api.txt index 4f6f5e9bb4d6..ea61e8bf7e2b 100644 --- a/Documentation/thermal/cpu-cooling-api.txt +++ b/Documentation/thermal/cpu-cooling-api.txt @@ -36,28 +36,14 @@ the user. The registration APIs returns the cooling device pointer. np: pointer to the cooling device device tree node clip_cpus: cpumask of cpus where the frequency constraints will happen. -1.1.3 struct thermal_cooling_device *cpufreq_power_cooling_register( - const struct cpumask *clip_cpus, u32 capacitance, - get_static_t plat_static_func) - -Similar to cpufreq_cooling_register, this function registers a cpufreq -cooling device. Using this function, the cooling device will -implement the power extensions by using a simple cpu power model. The -cpus must have registered their OPPs using the OPP library. - -The additional parameters are needed for the power model (See 2. Power -models). "capacitance" is the dynamic power coefficient (See 2.1 -Dynamic power). "plat_static_func" is a function to calculate the -static power consumed by these cpus (See 2.2 Static power). - -1.1.4 struct thermal_cooling_device *of_cpufreq_power_cooling_register( +1.1.3 struct thermal_cooling_device *of_cpufreq_power_cooling_register( struct cpufreq_policy *policy) -Similar to cpufreq_power_cooling_register, this function register a +Similar to cpufreq_cooling_register, this function register a cpufreq cooling device with power extensions using the device tree information supplied by the np parameter. -1.1.5 void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) +1.1.4 void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) This interface function unregisters the "thermal-cpufreq-%x" cooling device. @@ -74,10 +60,6 @@ cpu. If you are using CONFIG_CPUFREQ_DT then the `cpufreq_frequency_table` should already be assigned to the cpu device. -The `plat_static_func` parameter of `cpufreq_power_cooling_register()` -is optional. If you don't provide it, only dynamic power will be -considered. - 2.1 Dynamic power The dynamic power consumption of a processor depends on many factors. diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index a31eb03c788e..10199f7e1196 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c @@ -841,36 +841,6 @@ of_cpufreq_cooling_register(struct device_node *np, } EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register); -/** - * cpufreq_power_cooling_register() - create cpufreq cooling device with power extensions - * @policy: cpufreq policy - * @capacitance: dynamic power coefficient for these cpus - * @plat_static_func: function to calculate the static power consumed by these - * cpus (optional) - * - * This interface function registers the cpufreq cooling device with - * the name "thermal-cpufreq-%x". This api can support multiple - * instances of cpufreq cooling devices. Using this function, the - * cooling device will implement the power extensions by using a - * simple cpu power model. The cpus must have registered their OPPs - * using the OPP library. - * - * An optional @plat_static_func may be provided to calculate the - * static power consumed by these cpus. If the platform's static - * power consumption is unknown or negligible, make it NULL. - * - * Return: a valid struct thermal_cooling_device pointer on success, - * on failure, it returns a corresponding ERR_PTR(). - */ -struct thermal_cooling_device * -cpufreq_power_cooling_register(struct cpufreq_policy *policy, u32 capacitance, - get_static_t plat_static_func) -{ - return __cpufreq_cooling_register(NULL, policy, capacitance, - plat_static_func); -} -EXPORT_SYMBOL(cpufreq_power_cooling_register); - /** * of_cpufreq_power_cooling_register() - create cpufreq cooling device with power extensions * @policy: CPUFreq policy. diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h index f09d4feb34f4..c35778960a9c 100644 --- a/include/linux/cpu_cooling.h +++ b/include/linux/cpu_cooling.h @@ -41,10 +41,6 @@ typedef int (*get_static_t)(cpumask_t *cpumask, int interval, struct thermal_cooling_device * cpufreq_cooling_register(struct cpufreq_policy *policy); -struct thermal_cooling_device * -cpufreq_power_cooling_register(struct cpufreq_policy *policy, - u32 capacitance, get_static_t plat_static_func); - /** * of_cpufreq_cooling_register - create cpufreq cooling device based on DT. * @np: a valid struct device_node to the cooling device device tree node. @@ -84,12 +80,6 @@ cpufreq_cooling_register(struct cpufreq_policy *policy) { return ERR_PTR(-ENOSYS); } -static inline struct thermal_cooling_device * -cpufreq_power_cooling_register(struct cpufreq_policy *policy, - u32 capacitance, get_static_t plat_static_func) -{ - return NULL; -} static inline struct thermal_cooling_device * of_cpufreq_cooling_register(struct device_node *np, From 3ebb62ffc4e4817c3288cdf7ed67ccaf453385e3 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 5 Dec 2017 11:02:45 +0530 Subject: [PATCH 3/5] cpu_cooling: Keep only one of_cpufreq*cooling_register() helper of_cpufreq_cooling_register() isn't used by anyone and so can be removed, but then we would be left with two routines: cpufreq_cooling_register() and of_cpufreq_power_cooling_register() that would look odd. Remove current implementation of of_cpufreq_cooling_register() and rename of_cpufreq_power_cooling_register() as of_cpufreq_cooling_register(). This simplifies lots of stuff. Acked-by: Eduardo Valentin Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- Documentation/thermal/cpu-cooling-api.txt | 14 ++---- drivers/cpufreq/arm_big_little.c | 2 +- drivers/cpufreq/cpufreq-dt.c | 2 +- drivers/cpufreq/mediatek-cpufreq.c | 2 +- drivers/cpufreq/qoriq-cpufreq.c | 2 +- drivers/thermal/cpu_cooling.c | 28 +----------- include/linux/cpu_cooling.h | 55 +++++++---------------- 7 files changed, 24 insertions(+), 81 deletions(-) diff --git a/Documentation/thermal/cpu-cooling-api.txt b/Documentation/thermal/cpu-cooling-api.txt index ea61e8bf7e2b..7a1c89db0419 100644 --- a/Documentation/thermal/cpu-cooling-api.txt +++ b/Documentation/thermal/cpu-cooling-api.txt @@ -26,24 +26,16 @@ the user. The registration APIs returns the cooling device pointer. clip_cpus: cpumask of cpus where the frequency constraints will happen. 1.1.2 struct thermal_cooling_device *of_cpufreq_cooling_register( - struct device_node *np, const struct cpumask *clip_cpus) + struct cpufreq_policy *policy) This interface function registers the cpufreq cooling device with the name "thermal-cpufreq-%x" linking it with a device tree node, in order to bind it via the thermal DT code. This api can support multiple instances of cpufreq cooling devices. - np: pointer to the cooling device device tree node - clip_cpus: cpumask of cpus where the frequency constraints will happen. + policy: CPUFreq policy. -1.1.3 struct thermal_cooling_device *of_cpufreq_power_cooling_register( - struct cpufreq_policy *policy) - -Similar to cpufreq_cooling_register, this function register a -cpufreq cooling device with power extensions using the device tree -information supplied by the np parameter. - -1.1.4 void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) +1.1.3 void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) This interface function unregisters the "thermal-cpufreq-%x" cooling device. diff --git a/drivers/cpufreq/arm_big_little.c b/drivers/cpufreq/arm_big_little.c index 3d5ed4ef3927..c56b57dcfda5 100644 --- a/drivers/cpufreq/arm_big_little.c +++ b/drivers/cpufreq/arm_big_little.c @@ -532,7 +532,7 @@ static void bL_cpufreq_ready(struct cpufreq_policy *policy) if (cur_cluster >= MAX_CLUSTERS) return; - cdev[cur_cluster] = of_cpufreq_power_cooling_register(policy); + cdev[cur_cluster] = of_cpufreq_cooling_register(policy); } static struct cpufreq_driver bL_cpufreq_driver = { diff --git a/drivers/cpufreq/cpufreq-dt.c b/drivers/cpufreq/cpufreq-dt.c index 1e7bec7694ab..de3d104c25d7 100644 --- a/drivers/cpufreq/cpufreq-dt.c +++ b/drivers/cpufreq/cpufreq-dt.c @@ -320,7 +320,7 @@ static void cpufreq_ready(struct cpufreq_policy *policy) { struct private_data *priv = policy->driver_data; - priv->cdev = of_cpufreq_power_cooling_register(policy); + priv->cdev = of_cpufreq_cooling_register(policy); } static struct cpufreq_driver dt_cpufreq_driver = { diff --git a/drivers/cpufreq/mediatek-cpufreq.c b/drivers/cpufreq/mediatek-cpufreq.c index 6ff783e1b18a..f95975b76d98 100644 --- a/drivers/cpufreq/mediatek-cpufreq.c +++ b/drivers/cpufreq/mediatek-cpufreq.c @@ -311,7 +311,7 @@ static void mtk_cpufreq_ready(struct cpufreq_policy *policy) { struct mtk_cpu_dvfs_info *info = policy->driver_data; - info->cdev = of_cpufreq_power_cooling_register(policy); + info->cdev = of_cpufreq_cooling_register(policy); } static int mtk_cpu_dvfs_info_init(struct mtk_cpu_dvfs_info *info, int cpu) diff --git a/drivers/cpufreq/qoriq-cpufreq.c b/drivers/cpufreq/qoriq-cpufreq.c index 3a665c18e14e..0562761a3dec 100644 --- a/drivers/cpufreq/qoriq-cpufreq.c +++ b/drivers/cpufreq/qoriq-cpufreq.c @@ -276,7 +276,7 @@ static void qoriq_cpufreq_ready(struct cpufreq_policy *policy) { struct cpu_data *cpud = policy->driver_data; - cpud->cdev = of_cpufreq_power_cooling_register(policy); + cpud->cdev = of_cpufreq_cooling_register(policy); } static struct cpufreq_driver qoriq_cpufreq_driver = { diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index 10199f7e1196..3371caf3095c 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c @@ -819,7 +819,6 @@ EXPORT_SYMBOL_GPL(cpufreq_cooling_register); /** * of_cpufreq_cooling_register - function to create cpufreq cooling device. - * @np: a valid struct device_node to the cooling device device tree node * @policy: cpufreq policy * * This interface function registers the cpufreq cooling device with the name @@ -827,29 +826,6 @@ EXPORT_SYMBOL_GPL(cpufreq_cooling_register); * cooling devices. Using this API, the cpufreq cooling device will be * linked to the device tree node provided. * - * Return: a valid struct thermal_cooling_device pointer on success, - * on failure, it returns a corresponding ERR_PTR(). - */ -struct thermal_cooling_device * -of_cpufreq_cooling_register(struct device_node *np, - struct cpufreq_policy *policy) -{ - if (!np) - return ERR_PTR(-EINVAL); - - return __cpufreq_cooling_register(np, policy, 0, NULL); -} -EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register); - -/** - * of_cpufreq_power_cooling_register() - create cpufreq cooling device with power extensions - * @policy: CPUFreq policy. - * - * This interface function registers the cpufreq cooling device with - * the name "thermal-cpufreq-%x". This api can support multiple - * instances of cpufreq cooling devices. Using this API, the cpufreq - * cooling device will be linked to the device tree node of the provided - * policy's CPU. * Using this function, the cooling device will implement the power * extensions by using a simple cpu power model. The cpus must have * registered their OPPs using the OPP library. @@ -861,7 +837,7 @@ EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register); * and NULL on failure. */ struct thermal_cooling_device * -of_cpufreq_power_cooling_register(struct cpufreq_policy *policy) +of_cpufreq_cooling_register(struct cpufreq_policy *policy) { struct device_node *np = of_get_cpu_node(policy->cpu, NULL); struct thermal_cooling_device *cdev = NULL; @@ -889,7 +865,7 @@ of_cpufreq_power_cooling_register(struct cpufreq_policy *policy) of_node_put(np); return cdev; } -EXPORT_SYMBOL(of_cpufreq_power_cooling_register); +EXPORT_SYMBOL_GPL(of_cpufreq_cooling_register); /** * cpufreq_cooling_unregister - function to remove cpufreq cooling device. diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h index c35778960a9c..fd0ea8ddca93 100644 --- a/include/linux/cpu_cooling.h +++ b/include/linux/cpu_cooling.h @@ -41,33 +41,6 @@ typedef int (*get_static_t)(cpumask_t *cpumask, int interval, struct thermal_cooling_device * cpufreq_cooling_register(struct cpufreq_policy *policy); -/** - * of_cpufreq_cooling_register - create cpufreq cooling device based on DT. - * @np: a valid struct device_node to the cooling device device tree node. - * @policy: cpufreq policy. - */ -#ifdef CONFIG_THERMAL_OF -struct thermal_cooling_device * -of_cpufreq_cooling_register(struct device_node *np, - struct cpufreq_policy *policy); - -struct thermal_cooling_device * -of_cpufreq_power_cooling_register(struct cpufreq_policy *policy); -#else -static inline struct thermal_cooling_device * -of_cpufreq_cooling_register(struct device_node *np, - struct cpufreq_policy *policy) -{ - return ERR_PTR(-ENOSYS); -} - -static inline struct thermal_cooling_device * -of_cpufreq_power_cooling_register(struct cpufreq_policy *policy) -{ - return NULL; -} -#endif - /** * cpufreq_cooling_unregister - function to remove cpufreq cooling device. * @cdev: thermal cooling device pointer. @@ -81,19 +54,6 @@ cpufreq_cooling_register(struct cpufreq_policy *policy) return ERR_PTR(-ENOSYS); } -static inline struct thermal_cooling_device * -of_cpufreq_cooling_register(struct device_node *np, - struct cpufreq_policy *policy) -{ - return ERR_PTR(-ENOSYS); -} - -static inline struct thermal_cooling_device * -of_cpufreq_power_cooling_register(struct cpufreq_policy *policy) -{ - return NULL; -} - static inline void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) { @@ -101,4 +61,19 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) } #endif /* CONFIG_CPU_THERMAL */ +#if defined(CONFIG_THERMAL_OF) && defined(CONFIG_CPU_THERMAL) +/** + * of_cpufreq_cooling_register - create cpufreq cooling device based on DT. + * @policy: cpufreq policy. + */ +struct thermal_cooling_device * +of_cpufreq_cooling_register(struct cpufreq_policy *policy); +#else +static inline struct thermal_cooling_device * +of_cpufreq_cooling_register(struct cpufreq_policy *policy) +{ + return NULL; +} +#endif /* defined(CONFIG_THERMAL_OF) && defined(CONFIG_CPU_THERMAL) */ + #endif /* __CPU_COOLING_H__ */ From 84fe2cab48590e4373978e4ef2031c977de98995 Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 5 Dec 2017 11:02:46 +0530 Subject: [PATCH 4/5] cpu_cooling: Drop static-power related stuff No one has used it for the last two and half years (since it was introduced by commit c36cf0717631 (thermal: cpu_cooling: implement the power cooling device API), get rid of it. Acked-by: Eduardo Valentin Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- drivers/thermal/cpu_cooling.c | 106 ++++----------------------------- include/linux/cpu_cooling.h | 3 - include/trace/events/thermal.h | 10 ++-- 3 files changed, 16 insertions(+), 103 deletions(-) diff --git a/drivers/thermal/cpu_cooling.c b/drivers/thermal/cpu_cooling.c index 3371caf3095c..dfd23245f778 100644 --- a/drivers/thermal/cpu_cooling.c +++ b/drivers/thermal/cpu_cooling.c @@ -88,7 +88,6 @@ struct time_in_idle { * @policy: cpufreq policy. * @node: list_head to link all cpufreq_cooling_device together. * @idle_time: idle time stats - * @plat_get_static_power: callback to calculate the static power * * This structure is required for keeping information of each registered * cpufreq_cooling_device. @@ -104,7 +103,6 @@ struct cpufreq_cooling_device { struct cpufreq_policy *policy; struct list_head node; struct time_in_idle *idle_time; - get_static_t plat_get_static_power; }; static DEFINE_IDA(cpufreq_ida); @@ -318,60 +316,6 @@ static u32 get_load(struct cpufreq_cooling_device *cpufreq_cdev, int cpu, return load; } -/** - * get_static_power() - calculate the static power consumed by the cpus - * @cpufreq_cdev: struct &cpufreq_cooling_device for this cpu cdev - * @tz: thermal zone device in which we're operating - * @freq: frequency in KHz - * @power: pointer in which to store the calculated static power - * - * Calculate the static power consumed by the cpus described by - * @cpu_actor running at frequency @freq. This function relies on a - * platform specific function that should have been provided when the - * actor was registered. If it wasn't, the static power is assumed to - * be negligible. The calculated static power is stored in @power. - * - * Return: 0 on success, -E* on failure. - */ -static int get_static_power(struct cpufreq_cooling_device *cpufreq_cdev, - struct thermal_zone_device *tz, unsigned long freq, - u32 *power) -{ - struct dev_pm_opp *opp; - unsigned long voltage; - struct cpufreq_policy *policy = cpufreq_cdev->policy; - struct cpumask *cpumask = policy->related_cpus; - unsigned long freq_hz = freq * 1000; - struct device *dev; - - if (!cpufreq_cdev->plat_get_static_power) { - *power = 0; - return 0; - } - - dev = get_cpu_device(policy->cpu); - WARN_ON(!dev); - - opp = dev_pm_opp_find_freq_exact(dev, freq_hz, true); - if (IS_ERR(opp)) { - dev_warn_ratelimited(dev, "Failed to find OPP for frequency %lu: %ld\n", - freq_hz, PTR_ERR(opp)); - return -EINVAL; - } - - voltage = dev_pm_opp_get_voltage(opp); - dev_pm_opp_put(opp); - - if (voltage == 0) { - dev_err_ratelimited(dev, "Failed to get voltage for frequency %lu\n", - freq_hz); - return -EINVAL; - } - - return cpufreq_cdev->plat_get_static_power(cpumask, tz->passive_delay, - voltage, power); -} - /** * get_dynamic_power() - calculate the dynamic power * @cpufreq_cdev: &cpufreq_cooling_device for this cdev @@ -491,8 +435,8 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev, u32 *power) { unsigned long freq; - int i = 0, cpu, ret; - u32 static_power, dynamic_power, total_load = 0; + int i = 0, cpu; + u32 total_load = 0; struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata; struct cpufreq_policy *policy = cpufreq_cdev->policy; u32 *load_cpu = NULL; @@ -522,22 +466,15 @@ static int cpufreq_get_requested_power(struct thermal_cooling_device *cdev, cpufreq_cdev->last_load = total_load; - dynamic_power = get_dynamic_power(cpufreq_cdev, freq); - ret = get_static_power(cpufreq_cdev, tz, freq, &static_power); - if (ret) { - kfree(load_cpu); - return ret; - } + *power = get_dynamic_power(cpufreq_cdev, freq); if (load_cpu) { trace_thermal_power_cpu_get_power(policy->related_cpus, freq, - load_cpu, i, dynamic_power, - static_power); + load_cpu, i, *power); kfree(load_cpu); } - *power = static_power + dynamic_power; return 0; } @@ -561,8 +498,6 @@ static int cpufreq_state2power(struct thermal_cooling_device *cdev, unsigned long state, u32 *power) { unsigned int freq, num_cpus; - u32 static_power, dynamic_power; - int ret; struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata; /* Request state should be less than max_level */ @@ -572,13 +507,9 @@ static int cpufreq_state2power(struct thermal_cooling_device *cdev, num_cpus = cpumask_weight(cpufreq_cdev->policy->cpus); freq = cpufreq_cdev->freq_table[state].frequency; - dynamic_power = cpu_freq_to_power(cpufreq_cdev, freq) * num_cpus; - ret = get_static_power(cpufreq_cdev, tz, freq, &static_power); - if (ret) - return ret; + *power = cpu_freq_to_power(cpufreq_cdev, freq) * num_cpus; - *power = static_power + dynamic_power; - return ret; + return 0; } /** @@ -606,21 +537,14 @@ static int cpufreq_power2state(struct thermal_cooling_device *cdev, unsigned long *state) { unsigned int cur_freq, target_freq; - int ret; - s32 dyn_power; - u32 last_load, normalised_power, static_power; + u32 last_load, normalised_power; struct cpufreq_cooling_device *cpufreq_cdev = cdev->devdata; struct cpufreq_policy *policy = cpufreq_cdev->policy; cur_freq = cpufreq_quick_get(policy->cpu); - ret = get_static_power(cpufreq_cdev, tz, cur_freq, &static_power); - if (ret) - return ret; - - dyn_power = power - static_power; - dyn_power = dyn_power > 0 ? dyn_power : 0; + power = power > 0 ? power : 0; last_load = cpufreq_cdev->last_load ?: 1; - normalised_power = (dyn_power * 100) / last_load; + normalised_power = (power * 100) / last_load; target_freq = cpu_power_to_freq(cpufreq_cdev, normalised_power); *state = get_level(cpufreq_cdev, target_freq); @@ -671,8 +595,6 @@ static unsigned int find_next_max(struct cpufreq_frequency_table *table, * @policy: cpufreq policy * Normally this should be same as cpufreq policy->related_cpus. * @capacitance: dynamic power coefficient for these cpus - * @plat_static_func: function to calculate the static power consumed by these - * cpus (optional) * * This interface function registers the cpufreq cooling device with the name * "thermal-cpufreq-%x". This api can support multiple instances of cpufreq @@ -684,8 +606,7 @@ static unsigned int find_next_max(struct cpufreq_frequency_table *table, */ static struct thermal_cooling_device * __cpufreq_cooling_register(struct device_node *np, - struct cpufreq_policy *policy, u32 capacitance, - get_static_t plat_static_func) + struct cpufreq_policy *policy, u32 capacitance) { struct thermal_cooling_device *cdev; struct cpufreq_cooling_device *cpufreq_cdev; @@ -755,8 +676,6 @@ __cpufreq_cooling_register(struct device_node *np, } if (capacitance) { - cpufreq_cdev->plat_get_static_power = plat_static_func; - ret = update_freq_table(cpufreq_cdev, capacitance); if (ret) { cdev = ERR_PTR(ret); @@ -813,7 +732,7 @@ free_cdev: struct thermal_cooling_device * cpufreq_cooling_register(struct cpufreq_policy *policy) { - return __cpufreq_cooling_register(NULL, policy, 0, NULL); + return __cpufreq_cooling_register(NULL, policy, 0); } EXPORT_SYMBOL_GPL(cpufreq_cooling_register); @@ -853,8 +772,7 @@ of_cpufreq_cooling_register(struct cpufreq_policy *policy) of_property_read_u32(np, "dynamic-power-coefficient", &capacitance); - cdev = __cpufreq_cooling_register(np, policy, capacitance, - NULL); + cdev = __cpufreq_cooling_register(np, policy, capacitance); if (IS_ERR(cdev)) { pr_err("cpu_cooling: cpu%d is not running as cooling device: %ld\n", policy->cpu, PTR_ERR(cdev)); diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h index fd0ea8ddca93..de0dafb9399d 100644 --- a/include/linux/cpu_cooling.h +++ b/include/linux/cpu_cooling.h @@ -30,9 +30,6 @@ struct cpufreq_policy; -typedef int (*get_static_t)(cpumask_t *cpumask, int interval, - unsigned long voltage, u32 *power); - #ifdef CONFIG_CPU_THERMAL /** * cpufreq_cooling_register - function to create cpufreq cooling device. diff --git a/include/trace/events/thermal.h b/include/trace/events/thermal.h index 78946640fe03..135e5421f003 100644 --- a/include/trace/events/thermal.h +++ b/include/trace/events/thermal.h @@ -94,9 +94,9 @@ TRACE_EVENT(thermal_zone_trip, #ifdef CONFIG_CPU_THERMAL TRACE_EVENT(thermal_power_cpu_get_power, TP_PROTO(const struct cpumask *cpus, unsigned long freq, u32 *load, - size_t load_len, u32 dynamic_power, u32 static_power), + size_t load_len, u32 dynamic_power), - TP_ARGS(cpus, freq, load, load_len, dynamic_power, static_power), + TP_ARGS(cpus, freq, load, load_len, dynamic_power), TP_STRUCT__entry( __bitmask(cpumask, num_possible_cpus()) @@ -104,7 +104,6 @@ TRACE_EVENT(thermal_power_cpu_get_power, __dynamic_array(u32, load, load_len) __field(size_t, load_len ) __field(u32, dynamic_power ) - __field(u32, static_power ) ), TP_fast_assign( @@ -115,13 +114,12 @@ TRACE_EVENT(thermal_power_cpu_get_power, load_len * sizeof(*load)); __entry->load_len = load_len; __entry->dynamic_power = dynamic_power; - __entry->static_power = static_power; ), - TP_printk("cpus=%s freq=%lu load={%s} dynamic_power=%d static_power=%d", + TP_printk("cpus=%s freq=%lu load={%s} dynamic_power=%d", __get_bitmask(cpumask), __entry->freq, __print_array(__get_dynamic_array(load), __entry->load_len, 4), - __entry->dynamic_power, __entry->static_power) + __entry->dynamic_power) ); TRACE_EVENT(thermal_power_cpu_limit, From ac89c400ebb146604e718b3fa168c15592e73a8c Mon Sep 17 00:00:00 2001 From: Viresh Kumar Date: Tue, 2 Jan 2018 10:51:34 +0530 Subject: [PATCH 5/5] cpu_cooling: Remove static-power related documentation commit 84fe2cab4859 ("cpu_cooling: Drop static-power related stuff") removed support for static-power in kernel, but it missed reflecting the same in documentation. Remove the static power related documentation bits as well. Reported-by: Javi Merino Signed-off-by: Viresh Kumar Signed-off-by: Rafael J. Wysocki --- Documentation/thermal/cpu-cooling-api.txt | 82 +---------------------- 1 file changed, 2 insertions(+), 80 deletions(-) diff --git a/Documentation/thermal/cpu-cooling-api.txt b/Documentation/thermal/cpu-cooling-api.txt index 7a1c89db0419..7df567eaea1a 100644 --- a/Documentation/thermal/cpu-cooling-api.txt +++ b/Documentation/thermal/cpu-cooling-api.txt @@ -44,16 +44,14 @@ the user. The registration APIs returns the cooling device pointer. 2. Power models The power API registration functions provide a simple power model for -CPUs. The current power is calculated as dynamic + (optionally) -static power. This power model requires that the operating-points of +CPUs. The current power is calculated as dynamic power (static power isn't +supported currently). This power model 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. If you are using CONFIG_CPUFREQ_DT then the `cpufreq_frequency_table` should already be assigned to the cpu device. -2.1 Dynamic power - The dynamic power consumption of a processor depends on many factors. For a given processor implementation the primary factors are: @@ -92,79 +90,3 @@ mW/MHz/uVolt^2. Typical values for mobile CPUs might lie in range from 100 to 500. For reference, the approximate values for the SoC in ARM's Juno Development Platform are 530 for the Cortex-A57 cluster and 140 for the Cortex-A53 cluster. - - -2.2 Static power - -Static leakage power consumption depends on a number of factors. For a -given circuit implementation the primary factors are: - -- Time the circuit spends in each 'power state' -- Temperature -- Operating voltage -- Process grade - -The time the circuit spends in each 'power state' for a given -evaluation period at first order means OFF or ON. However, -'retention' states can also be supported that reduce power during -inactive periods without loss of context. - -Note: The visibility of state entries to the OS can vary, according to -platform specifics, and this can then impact the accuracy of a model -based on OS state information alone. It might be possible in some -cases to extract more accurate information from system resources. - -The temperature, operating voltage and process 'grade' (slow to fast) -of the circuit are all significant factors in static leakage power -consumption. All of these have complex relationships to static power. - -Circuit implementation specific factors include the chosen silicon -process as well as the type, number and size of transistors in both -the logic gates and any RAM elements included. - -The static power consumption modelling must take into account the -power managed regions that are implemented. Taking the example of an -ARM processor cluster, the modelling would take into account whether -each CPU can be powered OFF separately or if only a single power -region is implemented for the complete cluster. - -In one view, there are others, a static power consumption model can -then start from a set of reference values for each power managed -region (e.g. CPU, Cluster/L2) in each state (e.g. ON, OFF) at an -arbitrary process grade, voltage and temperature point. These values -are then scaled for all of the following: the time in each state, the -process grade, the current temperature and the operating voltage. -However, since both implementation specific and complex relationships -dominate the estimate, the appropriate interface to the model from the -cpu cooling device is to provide a function callback that calculates -the static power in this platform. When registering the cpu cooling -device pass a function pointer that follows the `get_static_t` -prototype: - - int plat_get_static(cpumask_t *cpumask, int interval, - unsigned long voltage, u32 &power); - -`cpumask` is the cpumask of the cpus involved in the calculation. -`voltage` is the voltage at which they are operating. The function -should calculate the average static power for the last `interval` -milliseconds. It returns 0 on success, -E* on error. If it -succeeds, it should store the static power in `power`. Reading the -temperature of the cpus described by `cpumask` is left for -plat_get_static() to do as the platform knows best which thermal -sensor is closest to the cpu. - -If `plat_static_func` is NULL, static power is considered to be -negligible for this platform and only dynamic power is considered. - -The platform specific callback can then use any combination of tables -and/or equations to permute the estimated value. Process grade -information is not passed to the model since access to such data, from -on-chip measurement capability or manufacture time data, is platform -specific. - -Note: the significance of static power for CPUs in comparison to -dynamic power is highly dependent on implementation. Given the -potential complexity in implementation, the importance and accuracy of -its inclusion when using cpu cooling devices should be assessed on a -case by case basis. -