From 9d99842f99d847191ebd0c28469d2c70fcc5bf9e Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Tue, 26 Jun 2012 16:35:57 +0800 Subject: Thermal: set upper and lower limits set upper and lower limits when binding a thermal cooling device to a thermal zone device. Signed-off-by: Zhang Rui Reviewed-by: Rafael J. Wysocki Reviewed-by: Eduardo Valentin --- drivers/acpi/thermal.c | 53 +++++++++++++++++++++++++++++++++----------------- 1 file changed, 35 insertions(+), 18 deletions(-) (limited to 'drivers/acpi/thermal.c') diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 9fe90e9fecb5..d7ef69d835f2 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -729,11 +729,9 @@ static int thermal_notify(struct thermal_zone_device *thermal, int trip, return 0; } -typedef int (*cb)(struct thermal_zone_device *, int, - struct thermal_cooling_device *); static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev, - cb action) + bool bind) { struct acpi_device *device = cdev->devdata; struct acpi_thermal *tz = thermal->devdata; @@ -757,11 +755,19 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, i++) { handle = tz->trips.passive.devices.handles[i]; status = acpi_bus_get_device(handle, &dev); - if (ACPI_SUCCESS(status) && (dev == device)) { - result = action(thermal, trip, cdev); - if (result) - goto failed; - } + if (ACPI_FAILURE(status) || dev != device) + continue; + if (bind) + result = + thermal_zone_bind_cooling_device + (thermal, trip, cdev, + THERMAL_NO_LIMIT, THERMAL_NO_LIMIT); + else + result = + thermal_zone_unbind_cooling_device + (thermal, trip, cdev); + if (result) + goto failed; } } @@ -774,11 +780,17 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, j++) { handle = tz->trips.active[i].devices.handles[j]; status = acpi_bus_get_device(handle, &dev); - if (ACPI_SUCCESS(status) && (dev == device)) { - result = action(thermal, trip, cdev); - if (result) - goto failed; - } + if (ACPI_FAILURE(status) || dev != device) + continue; + if (bind) + result = thermal_zone_bind_cooling_device + (thermal, trip, cdev, + THERMAL_NO_LIMIT, THERMAL_NO_LIMIT); + else + result = thermal_zone_unbind_cooling_device + (thermal, trip, cdev); + if (result) + goto failed; } } @@ -786,7 +798,14 @@ static int acpi_thermal_cooling_device_cb(struct thermal_zone_device *thermal, handle = tz->devices.handles[i]; status = acpi_bus_get_device(handle, &dev); if (ACPI_SUCCESS(status) && (dev == device)) { - result = action(thermal, -1, cdev); + if (bind) + result = thermal_zone_bind_cooling_device + (thermal, -1, cdev, + THERMAL_NO_LIMIT, + THERMAL_NO_LIMIT); + else + result = thermal_zone_unbind_cooling_device + (thermal, -1, cdev); if (result) goto failed; } @@ -800,16 +819,14 @@ static int acpi_thermal_bind_cooling_device(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev) { - return acpi_thermal_cooling_device_cb(thermal, cdev, - thermal_zone_bind_cooling_device); + return acpi_thermal_cooling_device_cb(thermal, cdev, true); } static int acpi_thermal_unbind_cooling_device(struct thermal_zone_device *thermal, struct thermal_cooling_device *cdev) { - return acpi_thermal_cooling_device_cb(thermal, cdev, - thermal_zone_unbind_cooling_device); + return acpi_thermal_cooling_device_cb(thermal, cdev, false); } static const struct thermal_zone_device_ops acpi_thermal_zone_ops = { -- cgit v1.2.3 From 601f3d4242be6ed6f72a2aadabc91e8255dad811 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 27 Jun 2012 09:54:33 +0800 Subject: Thermal: Introduce .get_trend() callback. According to ACPI spec, tc1 and tc2 are used by OSPM to anticipate the temperature trends. We introduced the same concept to the generic thermal layer for passive cooling, but now it seems that these values are hard to be used on other platforms. So We introduce .get_trend() as a more general solution. For the platform thermal drivers that have their own way to anticipate the temperature trends, they should provide their own .get_trend() callback. Or else, we will calculate the temperature trends by simply comparing the current temperature and the cached previous temperature reading. Signed-off-by: Zhang Rui Reviewed-by: Rafael J. Wysocki Reviewed-by: Valentin, Eduardo --- drivers/acpi/thermal.c | 33 +++++++++++++++++++++++++++++++++ 1 file changed, 33 insertions(+) (limited to 'drivers/acpi/thermal.c') diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index d7ef69d835f2..bb95709a6be8 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -706,6 +706,38 @@ static int thermal_get_crit_temp(struct thermal_zone_device *thermal, return -EINVAL; } +static int thermal_get_trend(struct thermal_zone_device *thermal, + int trip, enum thermal_trend *trend) +{ + struct acpi_thermal *tz = thermal->devdata; + enum thermal_trip_type type; + int i; + + if (thermal_get_trip_type(thermal, trip, &type)) + return -EINVAL; + + /* Only PASSIVE trip points need TREND */ + if (type != THERMAL_TRIP_PASSIVE) + return -EINVAL; + + /* + * tz->temperature has already been updated by generic thermal layer, + * before this callback being invoked + */ + i = (tz->trips.passive.tc1 * (tz->temperature - tz->last_temperature)) + + (tz->trips.passive.tc2 + * (tz->temperature - tz->trips.passive.temperature)); + + if (i > 0) + *trend = THERMAL_TREND_RAISING; + else if (i < 0) + *trend = THERMAL_TREND_DROPPING; + else + *trend = THERMAL_TREND_STABLE; + return 0; +} + + static int thermal_notify(struct thermal_zone_device *thermal, int trip, enum thermal_trip_type trip_type) { @@ -838,6 +870,7 @@ static const struct thermal_zone_device_ops acpi_thermal_zone_ops = { .get_trip_type = thermal_get_trip_type, .get_trip_temp = thermal_get_trip_temp, .get_crit_temp = thermal_get_crit_temp, + .get_trend = thermal_get_trend, .notify = thermal_notify, }; -- cgit v1.2.3 From 1b7ddb840c3908464b19d4aa4f6dc4c463302442 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 27 Jun 2012 09:51:12 +0800 Subject: Thermal: Remove tc1/tc2 in generic thermal layer. Remove tc1/tc2 in generic thermal layer. .get_trend() callback starts to take effect from this patch. Signed-off-by: Zhang Rui Reviewed-by: Rafael J. Wysocki Reviewed-by: Valentin, Eduardo --- drivers/acpi/thermal.c | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'drivers/acpi/thermal.c') diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index bb95709a6be8..07cb2172bd09 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -897,15 +897,12 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz) tz->thermal_zone = thermal_zone_device_register("acpitz", trips, 0, tz, &acpi_thermal_zone_ops, - tz->trips.passive.tc1, - tz->trips.passive.tc2, tz->trips.passive.tsp*100, tz->polling_frequency*100); else tz->thermal_zone = thermal_zone_device_register("acpitz", trips, 0, tz, - &acpi_thermal_zone_ops, - 0, 0, 0, + &acpi_thermal_zone_ops, 0, tz->polling_frequency*100); if (IS_ERR(tz->thermal_zone)) return -ENODEV; -- cgit v1.2.3 From 4ae46befb49d4173122e0afa995c4e93d01948a2 Mon Sep 17 00:00:00 2001 From: Zhang Rui Date: Wed, 27 Jun 2012 10:05:39 +0800 Subject: Thermal: Introduce thermal_zone_trip_update() This function is used to update the cooling state of all the cooling devices that are bound to an active trip point. This will be used for passive cooling as well, in the future patches. as both active and passive cooling can share the same algorithm, which is 1. if the temperature is higher than a trip point, a. if the trend is THERMAL_TREND_RAISING, use higher cooling state for this trip point b. if the trend is THERMAL_TREND_DROPPING, use lower cooling state for this trip point 2. if the temperature is lower than a trip point, use lower cooling state for this trip point. Signed-off-by: Zhang Rui Reviewed-by: Rafael J. Wysocki Reviewed-by: Eduardo Valentin --- drivers/acpi/thermal.c | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) (limited to 'drivers/acpi/thermal.c') diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c index 07cb2172bd09..bd66bd28a43f 100644 --- a/drivers/acpi/thermal.c +++ b/drivers/acpi/thermal.c @@ -716,9 +716,11 @@ static int thermal_get_trend(struct thermal_zone_device *thermal, if (thermal_get_trip_type(thermal, trip, &type)) return -EINVAL; - /* Only PASSIVE trip points need TREND */ - if (type != THERMAL_TRIP_PASSIVE) - return -EINVAL; + if (type == THERMAL_TRIP_ACTIVE) { + /* aggressive active cooling */ + *trend = THERMAL_TREND_RAISING; + return 0; + } /* * tz->temperature has already been updated by generic thermal layer, -- cgit v1.2.3