Commit ced255c0 authored by Linus Torvalds's avatar Linus Torvalds

Merge branch 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux

Pull thermal management fixes from Zhang Rui:

 - Power allocator governor changes to allow binding on thermal zones
   with missing power estimates information.  From Javi Merino.

 - Add compile test flags on thermal drivers that allow it without
   producing compilation errors.  From Eduardo Valentin.

 - Fixes around memory allocation on cpu_cooling.  From Javi Merino.

 - Fix on db8500 cpufreq code to allow autoload.  From Luis de
   Bethencourt.

 - Maintainer entries for cpu cooling device

* 'next' of git://git.kernel.org/pub/scm/linux/kernel/git/rzhang/linux:
  thermal: power_allocator: exit early if there are no cooling devices
  thermal: power_allocator: don't require tzp to be present for the thermal zone
  thermal: power_allocator: relax the requirement of two passive trip points
  thermal: power_allocator: relax the requirement of a sustainable_power in tzp
  thermal: Add a function to get the minimum power
  thermal: cpu_cooling: free power table on error or when unregistering
  thermal: cpu_cooling: don't call kcalloc() under rcu_read_lock
  thermal: db8500_cpufreq_cooling: Fix module autoload for OF platform driver
  thermal: cpu_cooling: Add MAINTAINERS entry
  thermal: ti-soc: Kconfig fix to avoid menu showing wrongly
  thermal: ti-soc: allow compile test
  thermal: qcom_spmi: allow compile test
  thermal: exynos: allow compile test
  thermal: armada: allow compile test
  thermal: dove: allow compile test
  thermal: kirkwood: allow compile test
  thermal: rockchip: allow compile test
  thermal: spear: allow compile test
  thermal: hisi: allow compile test
  thermal: Fix thermal_zone_of_sensor_register to match documentation
parents 4401555a 97584d18
...@@ -4,7 +4,7 @@ Power allocator governor tunables ...@@ -4,7 +4,7 @@ Power allocator governor tunables
Trip points Trip points
----------- -----------
The governor requires the following two passive trip points: The governor works optimally with the following two passive trip points:
1. "switch on" trip point: temperature above which the governor 1. "switch on" trip point: temperature above which the governor
control loop starts operating. This is the first passive trip control loop starts operating. This is the first passive trip
......
...@@ -10338,6 +10338,16 @@ F: include/uapi/linux/thermal.h ...@@ -10338,6 +10338,16 @@ F: include/uapi/linux/thermal.h
F: include/linux/cpu_cooling.h F: include/linux/cpu_cooling.h
F: Documentation/devicetree/bindings/thermal/ F: Documentation/devicetree/bindings/thermal/
THERMAL/CPU_COOLING
M: Amit Daniel Kachhap <amit.kachhap@gmail.com>
M: Viresh Kumar <viresh.kumar@linaro.org>
M: Javi Merino <javi.merino@arm.com>
L: linux-pm@vger.kernel.org
S: Supported
F: Documentation/thermal/cpu-cooling-api.txt
F: drivers/thermal/cpu_cooling.c
F: include/linux/cpu_cooling.h
THINGM BLINK(1) USB RGB LED DRIVER THINGM BLINK(1) USB RGB LED DRIVER
M: Vivien Didelot <vivien.didelot@savoirfairelinux.com> M: Vivien Didelot <vivien.didelot@savoirfairelinux.com>
S: Maintained S: Maintained
......
...@@ -163,7 +163,7 @@ config THERMAL_EMULATION ...@@ -163,7 +163,7 @@ config THERMAL_EMULATION
config HISI_THERMAL config HISI_THERMAL
tristate "Hisilicon thermal driver" tristate "Hisilicon thermal driver"
depends on ARCH_HISI && CPU_THERMAL && OF depends on (ARCH_HISI && CPU_THERMAL && OF) || COMPILE_TEST
help help
Enable this to plug hisilicon's thermal sensor driver into the Linux Enable this to plug hisilicon's thermal sensor driver into the Linux
thermal framework. cpufreq is used as the cooling device to throttle thermal framework. cpufreq is used as the cooling device to throttle
...@@ -182,7 +182,7 @@ config IMX_THERMAL ...@@ -182,7 +182,7 @@ config IMX_THERMAL
config SPEAR_THERMAL config SPEAR_THERMAL
bool "SPEAr thermal sensor driver" bool "SPEAr thermal sensor driver"
depends on PLAT_SPEAR depends on PLAT_SPEAR || COMPILE_TEST
depends on OF depends on OF
help help
Enable this to plug the SPEAr thermal sensor driver into the Linux Enable this to plug the SPEAr thermal sensor driver into the Linux
...@@ -190,7 +190,7 @@ config SPEAR_THERMAL ...@@ -190,7 +190,7 @@ config SPEAR_THERMAL
config ROCKCHIP_THERMAL config ROCKCHIP_THERMAL
tristate "Rockchip thermal driver" tristate "Rockchip thermal driver"
depends on ARCH_ROCKCHIP depends on ARCH_ROCKCHIP || COMPILE_TEST
depends on RESET_CONTROLLER depends on RESET_CONTROLLER
help help
Rockchip thermal driver provides support for Temperature sensor Rockchip thermal driver provides support for Temperature sensor
...@@ -208,7 +208,7 @@ config RCAR_THERMAL ...@@ -208,7 +208,7 @@ config RCAR_THERMAL
config KIRKWOOD_THERMAL config KIRKWOOD_THERMAL
tristate "Temperature sensor on Marvell Kirkwood SoCs" tristate "Temperature sensor on Marvell Kirkwood SoCs"
depends on MACH_KIRKWOOD depends on MACH_KIRKWOOD || COMPILE_TEST
depends on OF depends on OF
help help
Support for the Kirkwood thermal sensor driver into the Linux thermal Support for the Kirkwood thermal sensor driver into the Linux thermal
...@@ -216,7 +216,7 @@ config KIRKWOOD_THERMAL ...@@ -216,7 +216,7 @@ config KIRKWOOD_THERMAL
config DOVE_THERMAL config DOVE_THERMAL
tristate "Temperature sensor on Marvell Dove SoCs" tristate "Temperature sensor on Marvell Dove SoCs"
depends on ARCH_DOVE || MACH_DOVE depends on ARCH_DOVE || MACH_DOVE || COMPILE_TEST
depends on OF depends on OF
help help
Support for the Dove thermal sensor driver in the Linux thermal Support for the Dove thermal sensor driver in the Linux thermal
...@@ -234,7 +234,7 @@ config DB8500_THERMAL ...@@ -234,7 +234,7 @@ config DB8500_THERMAL
config ARMADA_THERMAL config ARMADA_THERMAL
tristate "Armada 370/XP thermal management" tristate "Armada 370/XP thermal management"
depends on ARCH_MVEBU depends on ARCH_MVEBU || COMPILE_TEST
depends on OF depends on OF
help help
Enable this option if you want to have support for thermal management Enable this option if you want to have support for thermal management
...@@ -349,11 +349,12 @@ config INTEL_PCH_THERMAL ...@@ -349,11 +349,12 @@ config INTEL_PCH_THERMAL
programmable trip points and other information. programmable trip points and other information.
menu "Texas Instruments thermal drivers" menu "Texas Instruments thermal drivers"
depends on ARCH_HAS_BANDGAP || COMPILE_TEST
source "drivers/thermal/ti-soc-thermal/Kconfig" source "drivers/thermal/ti-soc-thermal/Kconfig"
endmenu endmenu
menu "Samsung thermal drivers" menu "Samsung thermal drivers"
depends on ARCH_EXYNOS depends on ARCH_EXYNOS || COMPILE_TEST
source "drivers/thermal/samsung/Kconfig" source "drivers/thermal/samsung/Kconfig"
endmenu endmenu
...@@ -364,7 +365,7 @@ endmenu ...@@ -364,7 +365,7 @@ endmenu
config QCOM_SPMI_TEMP_ALARM config QCOM_SPMI_TEMP_ALARM
tristate "Qualcomm SPMI PMIC Temperature Alarm" tristate "Qualcomm SPMI PMIC Temperature Alarm"
depends on OF && SPMI && IIO depends on OF && (SPMI || COMPILE_TEST) && IIO
select REGMAP_SPMI select REGMAP_SPMI
help help
This enables a thermal sysfs driver for Qualcomm plug-and-play (QPNP) This enables a thermal sysfs driver for Qualcomm plug-and-play (QPNP)
......
...@@ -262,7 +262,9 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb, ...@@ -262,7 +262,9 @@ static int cpufreq_thermal_notifier(struct notifier_block *nb,
* efficiently. Power is stored in mW, frequency in KHz. The * efficiently. Power is stored in mW, frequency in KHz. The
* resulting table is in ascending order. * resulting table is in ascending order.
* *
* Return: 0 on success, -E* on error. * Return: 0 on success, -EINVAL if there are no OPPs for any CPUs,
* -ENOMEM if we run out of memory or -EAGAIN if an OPP was
* added/enabled while the function was executing.
*/ */
static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device, static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device,
u32 capacitance) u32 capacitance)
...@@ -273,8 +275,6 @@ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device, ...@@ -273,8 +275,6 @@ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device,
int num_opps = 0, cpu, i, ret = 0; int num_opps = 0, cpu, i, ret = 0;
unsigned long freq; unsigned long freq;
rcu_read_lock();
for_each_cpu(cpu, &cpufreq_device->allowed_cpus) { for_each_cpu(cpu, &cpufreq_device->allowed_cpus) {
dev = get_cpu_device(cpu); dev = get_cpu_device(cpu);
if (!dev) { if (!dev) {
...@@ -284,24 +284,20 @@ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device, ...@@ -284,24 +284,20 @@ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device,
} }
num_opps = dev_pm_opp_get_opp_count(dev); num_opps = dev_pm_opp_get_opp_count(dev);
if (num_opps > 0) { if (num_opps > 0)
break; break;
} else if (num_opps < 0) { else if (num_opps < 0)
ret = num_opps; return num_opps;
goto unlock;
}
} }
if (num_opps == 0) { if (num_opps == 0)
ret = -EINVAL; return -EINVAL;
goto unlock;
}
power_table = kcalloc(num_opps, sizeof(*power_table), GFP_KERNEL); power_table = kcalloc(num_opps, sizeof(*power_table), GFP_KERNEL);
if (!power_table) { if (!power_table)
ret = -ENOMEM; return -ENOMEM;
goto unlock;
} rcu_read_lock();
for (freq = 0, i = 0; for (freq = 0, i = 0;
opp = dev_pm_opp_find_freq_ceil(dev, &freq), !IS_ERR(opp); opp = dev_pm_opp_find_freq_ceil(dev, &freq), !IS_ERR(opp);
...@@ -309,6 +305,12 @@ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device, ...@@ -309,6 +305,12 @@ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device,
u32 freq_mhz, voltage_mv; u32 freq_mhz, voltage_mv;
u64 power; u64 power;
if (i >= num_opps) {
rcu_read_unlock();
ret = -EAGAIN;
goto free_power_table;
}
freq_mhz = freq / 1000000; freq_mhz = freq / 1000000;
voltage_mv = dev_pm_opp_get_voltage(opp) / 1000; voltage_mv = dev_pm_opp_get_voltage(opp) / 1000;
...@@ -326,17 +328,22 @@ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device, ...@@ -326,17 +328,22 @@ static int build_dyn_power_table(struct cpufreq_cooling_device *cpufreq_device,
power_table[i].power = power; power_table[i].power = power;
} }
if (i == 0) { rcu_read_unlock();
if (i != num_opps) {
ret = PTR_ERR(opp); ret = PTR_ERR(opp);
goto unlock; goto free_power_table;
} }
cpufreq_device->cpu_dev = dev; cpufreq_device->cpu_dev = dev;
cpufreq_device->dyn_power_table = power_table; cpufreq_device->dyn_power_table = power_table;
cpufreq_device->dyn_power_table_entries = i; cpufreq_device->dyn_power_table_entries = i;
unlock: return 0;
rcu_read_unlock();
free_power_table:
kfree(power_table);
return ret; return ret;
} }
...@@ -847,7 +854,7 @@ __cpufreq_cooling_register(struct device_node *np, ...@@ -847,7 +854,7 @@ __cpufreq_cooling_register(struct device_node *np,
ret = get_idr(&cpufreq_idr, &cpufreq_dev->id); ret = get_idr(&cpufreq_idr, &cpufreq_dev->id);
if (ret) { if (ret) {
cool_dev = ERR_PTR(ret); cool_dev = ERR_PTR(ret);
goto free_table; goto free_power_table;
} }
snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d", snprintf(dev_name, sizeof(dev_name), "thermal-cpufreq-%d",
...@@ -889,6 +896,8 @@ __cpufreq_cooling_register(struct device_node *np, ...@@ -889,6 +896,8 @@ __cpufreq_cooling_register(struct device_node *np,
remove_idr: remove_idr:
release_idr(&cpufreq_idr, cpufreq_dev->id); release_idr(&cpufreq_idr, cpufreq_dev->id);
free_power_table:
kfree(cpufreq_dev->dyn_power_table);
free_table: free_table:
kfree(cpufreq_dev->freq_table); kfree(cpufreq_dev->freq_table);
free_time_in_idle_timestamp: free_time_in_idle_timestamp:
...@@ -1039,6 +1048,7 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev) ...@@ -1039,6 +1048,7 @@ void cpufreq_cooling_unregister(struct thermal_cooling_device *cdev)
thermal_cooling_device_unregister(cpufreq_dev->cool_dev); thermal_cooling_device_unregister(cpufreq_dev->cool_dev);
release_idr(&cpufreq_idr, cpufreq_dev->id); release_idr(&cpufreq_idr, cpufreq_dev->id);
kfree(cpufreq_dev->dyn_power_table);
kfree(cpufreq_dev->time_in_idle_timestamp); kfree(cpufreq_dev->time_in_idle_timestamp);
kfree(cpufreq_dev->time_in_idle); kfree(cpufreq_dev->time_in_idle);
kfree(cpufreq_dev->freq_table); kfree(cpufreq_dev->freq_table);
......
...@@ -72,6 +72,7 @@ static const struct of_device_id db8500_cpufreq_cooling_match[] = { ...@@ -72,6 +72,7 @@ static const struct of_device_id db8500_cpufreq_cooling_match[] = {
{ .compatible = "stericsson,db8500-cpufreq-cooling" }, { .compatible = "stericsson,db8500-cpufreq-cooling" },
{}, {},
}; };
MODULE_DEVICE_TABLE(of, db8500_cpufreq_cooling_match);
#endif #endif
static struct platform_driver db8500_cpufreq_cooling_driver = { static struct platform_driver db8500_cpufreq_cooling_driver = {
......
This diff is collapsed.
...@@ -1012,6 +1012,34 @@ int power_actor_get_max_power(struct thermal_cooling_device *cdev, ...@@ -1012,6 +1012,34 @@ int power_actor_get_max_power(struct thermal_cooling_device *cdev,
return cdev->ops->state2power(cdev, tz, 0, max_power); return cdev->ops->state2power(cdev, tz, 0, max_power);
} }
/**
* power_actor_get_min_power() - get the mainimum power that a cdev can consume
* @cdev: pointer to &thermal_cooling_device
* @tz: a valid thermal zone device pointer
* @min_power: pointer in which to store the minimum power
*
* Calculate the minimum power consumption in milliwatts that the
* cooling device can currently consume and store it in @min_power.
*
* Return: 0 on success, -EINVAL if @cdev doesn't support the
* power_actor API or -E* on other error.
*/
int power_actor_get_min_power(struct thermal_cooling_device *cdev,
struct thermal_zone_device *tz, u32 *min_power)
{
unsigned long max_state;
int ret;
if (!cdev_is_power_actor(cdev))
return -EINVAL;
ret = cdev->ops->get_max_state(cdev, &max_state);
if (ret)
return ret;
return cdev->ops->state2power(cdev, tz, max_state, min_power);
}
/** /**
* power_actor_set_power() - limit the maximum power that a cooling device can consume * power_actor_set_power() - limit the maximum power that a cooling device can consume
* @cdev: pointer to &thermal_cooling_device * @cdev: pointer to &thermal_cooling_device
......
config TI_SOC_THERMAL config TI_SOC_THERMAL
tristate "Texas Instruments SoCs temperature sensor driver" tristate "Texas Instruments SoCs temperature sensor driver"
depends on THERMAL
depends on ARCH_HAS_BANDGAP
help help
If you say yes here you get support for the Texas Instruments If you say yes here you get support for the Texas Instruments
OMAP4460+ on die bandgap temperature sensor support. The register OMAP4460+ on die bandgap temperature sensor support. The register
...@@ -24,7 +22,7 @@ config TI_THERMAL ...@@ -24,7 +22,7 @@ config TI_THERMAL
config OMAP4_THERMAL config OMAP4_THERMAL
bool "Texas Instruments OMAP4 thermal support" bool "Texas Instruments OMAP4 thermal support"
depends on TI_SOC_THERMAL depends on TI_SOC_THERMAL
depends on ARCH_OMAP4 depends on ARCH_OMAP4 || COMPILE_TEST
help help
If you say yes here you get thermal support for the Texas Instruments If you say yes here you get thermal support for the Texas Instruments
OMAP4 SoC family. The current chip supported are: OMAP4 SoC family. The current chip supported are:
...@@ -38,7 +36,7 @@ config OMAP4_THERMAL ...@@ -38,7 +36,7 @@ config OMAP4_THERMAL
config OMAP5_THERMAL config OMAP5_THERMAL
bool "Texas Instruments OMAP5 thermal support" bool "Texas Instruments OMAP5 thermal support"
depends on TI_SOC_THERMAL depends on TI_SOC_THERMAL
depends on SOC_OMAP5 depends on SOC_OMAP5 || COMPILE_TEST
help help
If you say yes here you get thermal support for the Texas Instruments If you say yes here you get thermal support for the Texas Instruments
OMAP5 SoC family. The current chip supported are: OMAP5 SoC family. The current chip supported are:
...@@ -50,7 +48,7 @@ config OMAP5_THERMAL ...@@ -50,7 +48,7 @@ config OMAP5_THERMAL
config DRA752_THERMAL config DRA752_THERMAL
bool "Texas Instruments DRA752 thermal support" bool "Texas Instruments DRA752 thermal support"
depends on TI_SOC_THERMAL depends on TI_SOC_THERMAL
depends on SOC_DRA7XX depends on SOC_DRA7XX || COMPILE_TEST
help help
If you say yes here you get thermal support for the Texas Instruments If you say yes here you get thermal support for the Texas Instruments
DRA752 SoC family. The current chip supported are: DRA752 SoC family. The current chip supported are:
......
...@@ -360,7 +360,7 @@ static inline struct thermal_zone_device * ...@@ -360,7 +360,7 @@ static inline struct thermal_zone_device *
thermal_zone_of_sensor_register(struct device *dev, int id, void *data, thermal_zone_of_sensor_register(struct device *dev, int id, void *data,
const struct thermal_zone_of_device_ops *ops) const struct thermal_zone_of_device_ops *ops)
{ {
return NULL; return ERR_PTR(-ENODEV);
} }
static inline static inline
...@@ -380,6 +380,8 @@ static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) ...@@ -380,6 +380,8 @@ static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev)
int power_actor_get_max_power(struct thermal_cooling_device *, int power_actor_get_max_power(struct thermal_cooling_device *,
struct thermal_zone_device *tz, u32 *max_power); struct thermal_zone_device *tz, u32 *max_power);
int power_actor_get_min_power(struct thermal_cooling_device *,
struct thermal_zone_device *tz, u32 *min_power);
int power_actor_set_power(struct thermal_cooling_device *, int power_actor_set_power(struct thermal_cooling_device *,
struct thermal_instance *, u32); struct thermal_instance *, u32);
struct thermal_zone_device *thermal_zone_device_register(const char *, int, int, struct thermal_zone_device *thermal_zone_device_register(const char *, int, int,
...@@ -415,6 +417,10 @@ static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev) ...@@ -415,6 +417,10 @@ static inline bool cdev_is_power_actor(struct thermal_cooling_device *cdev)
static inline int power_actor_get_max_power(struct thermal_cooling_device *cdev, static inline int power_actor_get_max_power(struct thermal_cooling_device *cdev,
struct thermal_zone_device *tz, u32 *max_power) struct thermal_zone_device *tz, u32 *max_power)
{ return 0; } { return 0; }
static inline int power_actor_get_min_power(struct thermal_cooling_device *cdev,
struct thermal_zone_device *tz,
u32 *min_power)
{ return -ENODEV; }
static inline int power_actor_set_power(struct thermal_cooling_device *cdev, static inline int power_actor_set_power(struct thermal_cooling_device *cdev,
struct thermal_instance *tz, u32 power) struct thermal_instance *tz, u32 power)
{ return 0; } { return 0; }
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment