Message ID | 20191202202815.22731-1-daniel.lezcano@linaro.org |
---|---|
State | Superseded |
Headers | show |
Series | [V2,1/4] thermal/drivers/Kconfig: Convert the CPU cooling device to a choice | expand |
On 02-12-19, 21:28, Daniel Lezcano wrote: > The next changes will add a new way to cool down a CPU by injecting > idle cycles. With the current configuration, a CPU cooling device is > the cpufreq cooling device. As we want to add a new CPU cooling > device, let's convert the CPU cooling to a choice giving a list of CPU > cooling devices. At this point, there is obviously only one CPU > cooling device. > > There is no functional changes. > > Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> > --- > V2: > - Default CPU_FREQ_COOLING when CPU_THERMAL is set (Viresh Kumar) > --- > drivers/thermal/Kconfig | 14 ++++++++++++-- > drivers/thermal/Makefile | 2 +- > include/linux/cpu_cooling.h | 6 +++--- > 3 files changed, 16 insertions(+), 6 deletions(-) Acked-by: Viresh Kumar <viresh.kumar@linaro.org> -- viresh
On 02-12-19, 21:28, Daniel Lezcano wrote: > +/** > + * cpuidle_of_cooling_register - Idle cooling device initialization function > + * @drv: a cpuidle driver structure pointer @np missing here. > + * > + * This function is in charge of creating a cooling device per cpuidle > + * driver and register it to thermal framework. > + * > + * Returns a valid pointer to a thermal cooling device, a PTR_ERR s/, a/, or a/ ? > + * corresponding to the error detected in the underlying subsystems. > + */ > +struct thermal_cooling_device * > +__init cpuidle_of_cooling_register(struct device_node *np, > + struct cpuidle_driver *drv) > +{ > + struct idle_inject_device *ii_dev; > + struct cpuidle_cooling_device *idle_cdev; > + struct thermal_cooling_device *cdev; > + char dev_name[THERMAL_NAME_LENGTH]; > + int id, ret; > + > + idle_cdev = kzalloc(sizeof(*idle_cdev), GFP_KERNEL); > + if (!idle_cdev) { > + ret = -ENOMEM; > + goto out; > + } > + > + id = ida_simple_get(&cpuidle_ida, 0, 0, GFP_KERNEL); > + if (id < 0) { > + ret = id; > + goto out_kfree; > + } > + > + ii_dev = idle_inject_register(drv->cpumask); > + if (IS_ERR(ii_dev)) { > + ret = PTR_ERR(ii_dev); > + goto out_id; > + } > + > + idle_inject_set_duration(ii_dev, 0, TICK_USEC); > + > + idle_cdev->ii_dev = ii_dev; > + > + snprintf(dev_name, sizeof(dev_name), "thermal-idle-%d", id); > + > + cdev = thermal_of_cooling_device_register(np, dev_name, idle_cdev, > + &cpuidle_cooling_ops); > + if (IS_ERR(cdev)) { > + ret = PTR_ERR(cdev); > + goto out_unregister; > + } > + > + return cdev; > + > +out_unregister: > + idle_inject_unregister(ii_dev); > +out_id: > + ida_simple_remove(&cpuidle_ida, id); > +out_kfree: > + kfree(idle_cdev); > +out: > + return ERR_PTR(ret); > +} > + > +/** > + * cpuidle_cooling_register - Idle cooling device initialization function > + * @drv: a cpuidle driver structure pointer > + * > + * This function is in charge of creating a cooling device per cpuidle > + * driver and register it to thermal framework. > + * > + * Returns a valid pointer to a thermal cooling device, a PTR_ERR > + * corresponding to the error detected in the underlying subsystems. > + */ > +struct thermal_cooling_device * > +__init cpuidle_cooling_register(struct cpuidle_driver *drv) > +{ > + return cpuidle_of_cooling_register(NULL, drv); > +} > diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h > index 3cdd85f987d7..da0970183d1f 100644 > --- a/include/linux/cpu_cooling.h > +++ b/include/linux/cpu_cooling.h > @@ -60,4 +60,26 @@ of_cpufreq_cooling_register(struct cpufreq_policy *policy) > } > #endif /* CONFIG_CPU_FREQ_THERMAL */ > > +struct cpuidle_driver; > + > +#ifdef CONFIG_CPU_IDLE_THERMAL > +extern struct thermal_cooling_device * > +__init cpuidle_cooling_register(struct cpuidle_driver *drv); > +extern struct thermal_cooling_device * > +__init cpuidle_of_cooling_register(struct device_node *np, > + struct cpuidle_driver *drv); Maybe just drop the "extern" thing here as it is redundant really. > +#else /* CONFIG_CPU_IDLE_THERMAL */ > +static inline struct thermal_cooling_device * > +__init cpuidle_cooling_register(struct cpuidle_driver *drv) > +{ > + return ERR_PTR(-EINVAL); > +} > +static inline struct thermal_cooling_device * > +__init cpuidle_of_cooling_register(struct device_node *np, > + struct cpuidle_driver *drv) > +{ > + return ERR_PTR(-EINVAL); > +} > +#endif /* CONFIG_CPU_IDLE_THERMAL */ > + > #endif /* __CPU_COOLING_H__ */ Acked-by: Viresh Kumar <viresh.kumar@linaro.org> -- viresh
On 02-12-19, 21:28, Daniel Lezcano wrote: > The cpu idle cooling device offers a new method to cool down a CPU by > injecting idle cycles at runtime. > > It has some similarities with the intel power clamp driver but it is > actually designed to be more generic and relying on the idle injection > powercap framework. > > The idle injection cycle is fixed while the running cycle is variable. That > allows to have control on the device reactivity for the user experience. > > An idle state powering down the CPU or the cluster will allow to drop > the static leakage, thus restoring the heat capacity of the SoC. It > can be set with a trip point between the hot and the critical points, > giving the opportunity to prevent a hard reset of the system when the > cpufreq cooling fails to cool down the CPU. > > With more sophisticated boards having a per core sensor, the idle > cooling device allows to cool down a single core without throttling > the compute capacity of several cpus belonging to the same clock line, > so it could be used in collaboration with the cpufreq cooling device. > > Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> > --- > V2: > - Remove idle_duration_us field and use idle_inject API instead (Viresh Kumar) > - Fixed function definition wheh CPU_IDLE_COOLING is not set > - Inverted the initialization in the init function (Viresh Kumar) > --- > drivers/thermal/cpuidle_cooling.c | 233 ++++++++++++++++++++++++++++++ This needs to go in MAINTAINERS file btw :) -- viresh
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig index 001a21abcc28..4e3ee036938b 100644 --- a/drivers/thermal/Kconfig +++ b/drivers/thermal/Kconfig @@ -150,8 +150,18 @@ config THERMAL_GOV_POWER_ALLOCATOR config CPU_THERMAL bool "Generic cpu cooling support" - depends on CPU_FREQ depends on THERMAL_OF + help + Enable the CPU cooling features. If the system has no active + cooling device available, this option allows to use the CPU + as a cooling device. + +if CPU_THERMAL + +config CPU_FREQ_THERMAL + bool "CPU frequency cooling device" + depends on CPU_FREQ + default y help This implements the generic cpu cooling mechanism through frequency reduction. An ACPI version of this already exists @@ -159,7 +169,7 @@ config CPU_THERMAL This will be useful for platforms using the generic thermal interface and not the ACPI interface. - If you want this support, you should say Y here. +endif config CLOCK_THERMAL bool "Generic clock cooling support" diff --git a/drivers/thermal/Makefile b/drivers/thermal/Makefile index 74a37c7f847a..d3b01cc96981 100644 --- a/drivers/thermal/Makefile +++ b/drivers/thermal/Makefile @@ -19,7 +19,7 @@ thermal_sys-$(CONFIG_THERMAL_GOV_USER_SPACE) += user_space.o thermal_sys-$(CONFIG_THERMAL_GOV_POWER_ALLOCATOR) += power_allocator.o # cpufreq cooling -thermal_sys-$(CONFIG_CPU_THERMAL) += cpu_cooling.o +thermal_sys-$(CONFIG_CPU_FREQ_THERMAL) += cpu_cooling.o # clock cooling thermal_sys-$(CONFIG_CLOCK_THERMAL) += clock_cooling.o diff --git a/include/linux/cpu_cooling.h b/include/linux/cpu_cooling.h index b74732535e4b..3cdd85f987d7 100644 --- a/include/linux/cpu_cooling.h +++ b/include/linux/cpu_cooling.h @@ -19,7 +19,7 @@ struct cpufreq_policy; -#ifdef CONFIG_CPU_THERMAL +#ifdef CONFIG_CPU_FREQ_THERMAL /** * cpufreq_cooling_register - function to create cpufreq cooling device. * @policy: cpufreq policy. @@ -40,7 +40,7 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev); struct thermal_cooling_device * of_cpufreq_cooling_register(struct cpufreq_policy *policy); -#else /* !CONFIG_CPU_THERMAL */ +#else /* !CONFIG_CPU_FREQ_THERMAL */ static inline struct thermal_cooling_device * cpufreq_cooling_register(struct cpufreq_policy *policy) { @@ -58,6 +58,6 @@ of_cpufreq_cooling_register(struct cpufreq_policy *policy) { return NULL; } -#endif /* CONFIG_CPU_THERMAL */ +#endif /* CONFIG_CPU_FREQ_THERMAL */ #endif /* __CPU_COOLING_H__ */
The next changes will add a new way to cool down a CPU by injecting idle cycles. With the current configuration, a CPU cooling device is the cpufreq cooling device. As we want to add a new CPU cooling device, let's convert the CPU cooling to a choice giving a list of CPU cooling devices. At this point, there is obviously only one CPU cooling device. There is no functional changes. Signed-off-by: Daniel Lezcano <daniel.lezcano@linaro.org> --- V2: - Default CPU_FREQ_COOLING when CPU_THERMAL is set (Viresh Kumar) --- drivers/thermal/Kconfig | 14 ++++++++++++-- drivers/thermal/Makefile | 2 +- include/linux/cpu_cooling.h | 6 +++--- 3 files changed, 16 insertions(+), 6 deletions(-) -- 2.17.1