All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH V4 00/13] Thermal: generic thermal layer enhancement
@ 2012-07-26  8:41 Zhang Rui
  2012-07-26  8:41 ` [PATCH V4 01/13] Thermal: Introduce multiple cooling states support Zhang Rui
                   ` (13 more replies)
  0 siblings, 14 replies; 45+ messages in thread
From: Zhang Rui @ 2012-07-26  8:41 UTC (permalink / raw)
  To: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, Zhang Rui
  Cc: linux-acpi, linux-pm


Hi, all,

This is the patch set for linux-next.

the changes includes:

V4:
- dropped three patches which have been already picked by Len.
- re-organize some piece of code based on Rafael's comments
- improve some changelog

V3: http://marc.info/?l=linux-acpi&m=134318254518940&w=2
- fixing a build error.
- making a couple of changes based on Rafael's comments
- removing the plist patch for now as I do not have validate data to show how much benefit it brings.

V2: http://marc.info/?l=linux-acpi&m=134267975014396&w=2
- a couple of changes based on Eduardo and Amit's comments.
- convert an internal list to plist to be more efficiency.

V1: http://marc.info/?l=linux-acpi&m=133938485224765&w=2
- 12 RFC patches to fix the problems discussed in http://marc.info/?l=linux-acpi&m=133836783425764&w=2

please kindly review.

Any comments are welcome.

thanks,
rui

---------------------------------------------------------------------------
Zhang Rui (13):
      Thermal: Introduce multiple cooling states support
      Thermal: Introduce cooling states range support
      Thermal: set upper and lower limits
      Thermal: Introduce .get_trend() callback.
      Thermal: Remove tc1/tc2 in generic thermal layer.
      Thermal: Introduce thermal_zone_trip_update()
      Thermal: rename structure thermal_cooling_device_instance to thermal_instance
      Thermal: Rename thermal_zone_device.cooling_devices to thermal_zone_device.instances
      Thermal: Rename thermal_instance.node to thermal_instance.tz_node.
      Thermal: List thermal_instance in thermal_cooling_device.
      Thermal: Introduce simple arbitrator for setting device cooling state
      Thermal: Unify the code for both active and passive cooling
      Thermal: Introduce locking for cdev.thermal_instances
---------------------------------------------------------------------------
 Documentation/thermal/sysfs-api.txt      |    9 +-
 drivers/acpi/thermal.c                   |   98 +++++++---
 drivers/platform/x86/acerhdf.c           |    5 +-
 drivers/platform/x86/intel_mid_thermal.c |    2 +-
 drivers/thermal/spear_thermal.c          |    2 +-
 drivers/thermal/thermal_sys.c            |  308 +++++++++++++++++++-----------
 include/linux/thermal.h                  |   28 ++-
 7 files changed, 300 insertions(+), 152 deletions(-)
---------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 45+ messages in thread

* [PATCH V4 01/13] Thermal: Introduce multiple cooling states support
  2012-07-26  8:41 [PATCH V4 00/13] Thermal: generic thermal layer enhancement Zhang Rui
@ 2012-07-26  8:41 ` Zhang Rui
  2012-08-08 12:02   ` Valentin, Eduardo
  2012-07-26  8:41 ` [PATCH V4 02/13] Thermal: Introduce cooling states range support Zhang Rui
                   ` (12 subsequent siblings)
  13 siblings, 1 reply; 45+ messages in thread
From: Zhang Rui @ 2012-07-26  8:41 UTC (permalink / raw)
  To: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, Zhang Rui
  Cc: linux-acpi, linux-pm

This is because general active cooling devices, like fans,
may have multiple speeds, which can be mapped to different cooling states.

Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/thermal/thermal_sys.c |   12 ++++++++++--
 1 file changed, 10 insertions(+), 2 deletions(-)

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 2d7a9fe..05f42cd 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -1059,6 +1059,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
 	enum thermal_trip_type trip_type;
 	struct thermal_cooling_device_instance *instance;
 	struct thermal_cooling_device *cdev;
+	unsigned long cur_state, max_state;
 
 	mutex_lock(&tz->lock);
 
@@ -1098,10 +1099,17 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
 
 				cdev = instance->cdev;
 
+				cdev->ops->get_cur_state(cdev, &cur_state);
+				cdev->ops->get_max_state(cdev, &max_state);
+
 				if (temp >= trip_temp)
-					cdev->ops->set_cur_state(cdev, 1);
+					cur_state = cur_state < max_state ?
+						(cur_state + 1) : max_state;
 				else
-					cdev->ops->set_cur_state(cdev, 0);
+					cur_state = cur_state > 0 ?
+						(cur_state - 1) : 0;
+
+				cdev->ops->set_cur_state(cdev, cur_state);
 			}
 			break;
 		case THERMAL_TRIP_PASSIVE:
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH V4 02/13] Thermal: Introduce cooling states range support
  2012-07-26  8:41 [PATCH V4 00/13] Thermal: generic thermal layer enhancement Zhang Rui
  2012-07-26  8:41 ` [PATCH V4 01/13] Thermal: Introduce multiple cooling states support Zhang Rui
@ 2012-07-26  8:41 ` Zhang Rui
  2012-08-20 15:51   ` Eduardo Valentin
  2012-07-26  8:41 ` [PATCH V4 03/13] Thermal: set upper and lower limits Zhang Rui
                   ` (11 subsequent siblings)
  13 siblings, 1 reply; 45+ messages in thread
From: Zhang Rui @ 2012-07-26  8:41 UTC (permalink / raw)
  To: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, Zhang Rui
  Cc: linux-acpi, linux-pm

As the active cooling devices can have multiple cooling states,
we may want only several cooling states for a certain trip point,
and other cooling states for other active trip points.

To do this, we should be able to describe the cooling device
behavior for a certain trip point, rather than for the entire thermal zone.
And when updating thermal zone, we need to check the upper and lower limit
to make sure the cooling device is set to the proper cooling state.

Note that this patch will not bring any different behavior as
upper limit is set to max_state and lower limit is set to 0
in this patch, for now.

Next patch will set these to real values.

Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/thermal/thermal_sys.c |   25 +++++++++++++++++++++----
 1 file changed, 21 insertions(+), 4 deletions(-)

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 05f42cd..008e2eb 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -41,12 +41,19 @@ MODULE_AUTHOR("Zhang Rui");
 MODULE_DESCRIPTION("Generic thermal management sysfs support");
 MODULE_LICENSE("GPL");
 
+/*
+ * This structure is used to describe the behavior of
+ * a certain cooling device on a certain trip point
+ * in a certain thermal zone
+ */
 struct thermal_cooling_device_instance {
 	int id;
 	char name[THERMAL_NAME_LENGTH];
 	struct thermal_zone_device *tz;
 	struct thermal_cooling_device *cdev;
 	int trip;
+	unsigned long upper;	/* Highest cooling state for this trip point */
+	unsigned long lower;	/* Lowest cooling state for this trip point */
 	char attr_name[THERMAL_NAME_LENGTH];
 	struct device_attribute attr;
 	struct list_head node;
@@ -800,6 +807,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
 	struct thermal_cooling_device_instance *pos;
 	struct thermal_zone_device *pos1;
 	struct thermal_cooling_device *pos2;
+	unsigned long max_state;
 	int result;
 
 	if (trip >= tz->trips || (trip < 0 && trip != THERMAL_TRIPS_NONE))
@@ -824,6 +832,11 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
 	dev->tz = tz;
 	dev->cdev = cdev;
 	dev->trip = trip;
+
+	cdev->ops->get_max_state(cdev, &max_state);
+	dev->upper = max_state;
+	dev->lower = 0;
+
 	result = get_idr(&tz->idr, &tz->lock, &dev->id);
 	if (result)
 		goto free_mem;
@@ -1103,11 +1116,15 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
 				cdev->ops->get_max_state(cdev, &max_state);
 
 				if (temp >= trip_temp)
-					cur_state = cur_state < max_state ?
-						(cur_state + 1) : max_state;
+					cur_state =
+						cur_state < instance->upper ?
+						(cur_state + 1) :
+						instance->upper;
 				else
-					cur_state = cur_state > 0 ?
-						(cur_state - 1) : 0;
+					cur_state =
+						cur_state > instance->lower ?
+						(cur_state - 1) :
+						instance->lower;
 
 				cdev->ops->set_cur_state(cdev, cur_state);
 			}
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH V4 03/13] Thermal: set upper and lower limits
  2012-07-26  8:41 [PATCH V4 00/13] Thermal: generic thermal layer enhancement Zhang Rui
  2012-07-26  8:41 ` [PATCH V4 01/13] Thermal: Introduce multiple cooling states support Zhang Rui
  2012-07-26  8:41 ` [PATCH V4 02/13] Thermal: Introduce cooling states range support Zhang Rui
@ 2012-07-26  8:41 ` Zhang Rui
  2012-08-20 15:50   ` Eduardo Valentin
  2012-07-26  8:41 ` [PATCH V4 04/13] Thermal: Introduce .get_trend() callback Zhang Rui
                   ` (10 subsequent siblings)
  13 siblings, 1 reply; 45+ messages in thread
From: Zhang Rui @ 2012-07-26  8:41 UTC (permalink / raw)
  To: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, Zhang Rui
  Cc: linux-acpi, linux-pm

set upper and lower limits when binding
a thermal cooling device to a thermal zone device.

Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 Documentation/thermal/sysfs-api.txt |    9 +++++-
 drivers/acpi/thermal.c              |   53 +++++++++++++++++++++++------------
 drivers/platform/x86/acerhdf.c      |    3 +-
 drivers/thermal/thermal_sys.c       |   23 ++++++++++-----
 include/linux/thermal.h             |    5 +++-
 5 files changed, 65 insertions(+), 28 deletions(-)

diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt
index c087dbc..ca1a1a3 100644
--- a/Documentation/thermal/sysfs-api.txt
+++ b/Documentation/thermal/sysfs-api.txt
@@ -84,7 +84,8 @@ temperature) and throttle appropriate devices.
 
 1.3 interface for binding a thermal zone device with a thermal cooling device
 1.3.1 int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
-		int trip, struct thermal_cooling_device *cdev);
+	int trip, struct thermal_cooling_device *cdev,
+	unsigned long upper, unsigned long lower);
 
     This interface function bind a thermal cooling device to the certain trip
     point of a thermal zone device.
@@ -93,6 +94,12 @@ temperature) and throttle appropriate devices.
     cdev: thermal cooling device
     trip: indicates which trip point the cooling devices is associated with
 	  in this thermal zone.
+    upper:the Maximum cooling state for this trip point.
+          THERMAL_NO_LIMIT means no upper limit,
+	  and the cooling device can be in max_state.
+    lower:the Minimum cooling state can be used for this trip point.
+          THERMAL_NO_LIMIT means no lower limit,
+	  and the cooling device can be in cooling state 0.
 
 1.3.2 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
 		int trip, struct thermal_cooling_device *cdev);
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 8275e7b..b48ec3e 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -727,11 +727,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;
@@ -755,11 +753,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;
 		}
 	}
 
@@ -772,11 +778,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;
 		}
 	}
 
@@ -784,7 +796,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;
 		}
@@ -798,16 +817,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 = {
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
index 39abb15..a207466 100644
--- a/drivers/platform/x86/acerhdf.c
+++ b/drivers/platform/x86/acerhdf.c
@@ -329,7 +329,8 @@ static int acerhdf_bind(struct thermal_zone_device *thermal,
 	if (cdev != cl_dev)
 		return 0;
 
-	if (thermal_zone_bind_cooling_device(thermal, 0, cdev)) {
+	if (thermal_zone_bind_cooling_device(thermal, 0, cdev,
+			THERMAL_NO_LIMIT, THERMAL_NO_LIMIT)) {
 		pr_err("error binding cooling dev\n");
 		return -EINVAL;
 	}
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 008e2eb..62b4279 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -315,8 +315,9 @@ passive_store(struct device *dev, struct device_attribute *attr,
 			if (!strncmp("Processor", cdev->type,
 				     sizeof("Processor")))
 				thermal_zone_bind_cooling_device(tz,
-								 THERMAL_TRIPS_NONE,
-								 cdev);
+						THERMAL_TRIPS_NONE, cdev,
+						THERMAL_NO_LIMIT,
+						THERMAL_NO_LIMIT);
 		}
 		mutex_unlock(&thermal_list_lock);
 		if (!tz->passive_delay)
@@ -801,7 +802,8 @@ static void thermal_zone_device_check(struct work_struct *work)
  */
 int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
 				     int trip,
-				     struct thermal_cooling_device *cdev)
+				     struct thermal_cooling_device *cdev,
+				     unsigned long upper, unsigned long lower)
 {
 	struct thermal_cooling_device_instance *dev;
 	struct thermal_cooling_device_instance *pos;
@@ -825,6 +827,15 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
 	if (tz != pos1 || cdev != pos2)
 		return -EINVAL;
 
+	cdev->ops->get_max_state(cdev, &max_state);
+
+	/* lower default 0, upper default max_state */
+	lower = lower == THERMAL_NO_LIMIT ? 0 : lower;
+	upper = upper == THERMAL_NO_LIMIT ? max_state : upper;
+
+	if (lower > upper || upper > max_state)
+		return -EINVAL;
+
 	dev =
 	    kzalloc(sizeof(struct thermal_cooling_device_instance), GFP_KERNEL);
 	if (!dev)
@@ -832,10 +843,8 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
 	dev->tz = tz;
 	dev->cdev = cdev;
 	dev->trip = trip;
-
-	cdev->ops->get_max_state(cdev, &max_state);
-	dev->upper = max_state;
-	dev->lower = 0;
+	dev->upper = upper;
+	dev->lower = lower;
 
 	result = get_idr(&tz->idr, &tz->lock, &dev->id);
 	if (result)
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index cfc8d90..a43b12c 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -75,6 +75,8 @@ struct thermal_cooling_device_ops {
 	int (*set_cur_state) (struct thermal_cooling_device *, unsigned long);
 };
 
+#define THERMAL_NO_LIMIT -1UL /* no upper/lower limit requirement */
+
 #define THERMAL_TRIPS_NONE -1
 #define THERMAL_MAX_TRIPS 12
 #define THERMAL_NAME_LENGTH 20
@@ -157,7 +159,8 @@ struct thermal_zone_device *thermal_zone_device_register(char *, int, int,
 void thermal_zone_device_unregister(struct thermal_zone_device *);
 
 int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
-				     struct thermal_cooling_device *);
+				     struct thermal_cooling_device *,
+				     unsigned long, unsigned long);
 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int,
 				       struct thermal_cooling_device *);
 void thermal_zone_device_update(struct thermal_zone_device *);
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH V4 04/13] Thermal: Introduce .get_trend() callback.
  2012-07-26  8:41 [PATCH V4 00/13] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (2 preceding siblings ...)
  2012-07-26  8:41 ` [PATCH V4 03/13] Thermal: set upper and lower limits Zhang Rui
@ 2012-07-26  8:41 ` Zhang Rui
  2012-07-26 20:11   ` Rafael J. Wysocki
  2012-08-08 13:44   ` Valentin, Eduardo
  2012-07-26  8:41 ` [PATCH V4 05/13] Thermal: Remove tc1/tc2 in generic thermal layer Zhang Rui
                   ` (9 subsequent siblings)
  13 siblings, 2 replies; 45+ messages in thread
From: Zhang Rui @ 2012-07-26  8:41 UTC (permalink / raw)
  To: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, Zhang Rui
  Cc: linux-acpi, linux-pm

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 <rui.zhang@intel.com>
---
 drivers/acpi/thermal.c        |   33 +++++++++++++++++++++++++++++++++
 drivers/thermal/thermal_sys.c |   19 +++++++++++++++++--
 include/linux/thermal.h       |    9 +++++++++
 3 files changed, 59 insertions(+), 2 deletions(-)

diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index b48ec3e..0c49e42 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -704,6 +704,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)
 {
@@ -836,6 +868,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,
 };
 
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 62b4279..68c93d4 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -723,6 +723,20 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
 	struct thermal_cooling_device *cdev;
 	long state, max_state;
 
+	if (!tz->ops->get_trend ||
+	    tz->ops->get_trend(tz, trip, (enum thermal_trend *)&trend)) {
+		/*
+		 * compare the current temperature and previous temperature
+		 * to get the thermal trend, if no special requirement
+		 */
+		if (tz->temperature > tz->last_temperature)
+			trend = THERMAL_TREND_RAISING;
+		else if (tz->temperature < tz->last_temperature)
+			trend = THERMAL_TREND_DROPPING;
+		else
+			trend = THERMAL_TREND_STABLE;
+	}
+
 	/*
 	 * Above Trip?
 	 * -----------
@@ -1091,6 +1105,9 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
 		goto leave;
 	}
 
+	tz->last_temperature = tz->temperature;
+	tz->temperature = temp;
+
 	for (count = 0; count < tz->trips; count++) {
 		tz->ops->get_trip_type(tz, count, &trip_type);
 		tz->ops->get_trip_temp(tz, count, &trip_temp);
@@ -1150,8 +1167,6 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
 		thermal_zone_device_passive(tz, temp, tz->forced_passive,
 					    THERMAL_TRIPS_NONE);
 
-	tz->last_temperature = temp;
-
 leave:
 	if (tz->passive)
 		thermal_zone_device_set_polling(tz, tz->passive_delay);
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index a43b12c..a01e3e6 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -44,6 +44,12 @@ enum thermal_trip_type {
 	THERMAL_TRIP_CRITICAL,
 };
 
+enum thermal_trend {
+	THERMAL_TREND_STABLE, /* temperature is stable */
+	THERMAL_TREND_RAISING, /* temperature is raising */
+	THERMAL_TREND_DROPPING, /* temperature is dropping */
+};
+
 struct thermal_zone_device_ops {
 	int (*bind) (struct thermal_zone_device *,
 		     struct thermal_cooling_device *);
@@ -65,6 +71,8 @@ struct thermal_zone_device_ops {
 	int (*set_trip_hyst) (struct thermal_zone_device *, int,
 			      unsigned long);
 	int (*get_crit_temp) (struct thermal_zone_device *, unsigned long *);
+	int (*get_trend) (struct thermal_zone_device *, int,
+			  enum thermal_trend *);
 	int (*notify) (struct thermal_zone_device *, int,
 		       enum thermal_trip_type);
 };
@@ -111,6 +119,7 @@ struct thermal_zone_device {
 	int tc2;
 	int passive_delay;
 	int polling_delay;
+	int temperature;
 	int last_temperature;
 	bool passive;
 	unsigned int forced_passive;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH V4 05/13] Thermal: Remove tc1/tc2 in generic thermal layer.
  2012-07-26  8:41 [PATCH V4 00/13] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (3 preceding siblings ...)
  2012-07-26  8:41 ` [PATCH V4 04/13] Thermal: Introduce .get_trend() callback Zhang Rui
@ 2012-07-26  8:41 ` Zhang Rui
  2012-07-26 20:11   ` Rafael J. Wysocki
  2012-08-08 14:06   ` Valentin, Eduardo
  2012-07-26  8:41 ` [PATCH V4 06/13] Thermal: Introduce thermal_zone_trip_update() Zhang Rui
                   ` (8 subsequent siblings)
  13 siblings, 2 replies; 45+ messages in thread
From: Zhang Rui @ 2012-07-26  8:41 UTC (permalink / raw)
  To: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, Zhang Rui
  Cc: linux-acpi, linux-pm

Remove tc1/tc2 in generic thermal layer.
.get_trend() callback starts to take effect from this patch.

Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/acpi/thermal.c                   |    5 +----
 drivers/platform/x86/acerhdf.c           |    2 +-
 drivers/platform/x86/intel_mid_thermal.c |    2 +-
 drivers/thermal/spear_thermal.c          |    2 +-
 drivers/thermal/thermal_sys.c            |   24 ++++++------------------
 include/linux/thermal.h                  |    5 +----
 6 files changed, 11 insertions(+), 29 deletions(-)

diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 0c49e42..0c755d2 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -895,15 +895,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;
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
index a207466..84c5688 100644
--- a/drivers/platform/x86/acerhdf.c
+++ b/drivers/platform/x86/acerhdf.c
@@ -662,7 +662,7 @@ static int acerhdf_register_thermal(void)
 		return -EINVAL;
 
 	thz_dev = thermal_zone_device_register("acerhdf", 1, 0, NULL,
-					      &acerhdf_dev_ops, 0, 0, 0,
+					      &acerhdf_dev_ops, 0,
 					      (kernelmode) ? interval*1000 : 0);
 	if (IS_ERR(thz_dev))
 		return -EINVAL;
diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c
index 2b2c212..6e309dd 100644
--- a/drivers/platform/x86/intel_mid_thermal.c
+++ b/drivers/platform/x86/intel_mid_thermal.c
@@ -499,7 +499,7 @@ static int mid_thermal_probe(struct platform_device *pdev)
 			goto err;
 		}
 		pinfo->tzd[i] = thermal_zone_device_register(name[i],
-				0, 0, td_info, &tzd_ops, 0, 0, 0, 0);
+				0, 0, td_info, &tzd_ops, 0, 0);
 		if (IS_ERR(pinfo->tzd[i])) {
 			kfree(td_info);
 			ret = PTR_ERR(pinfo->tzd[i]);
diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c
index 69a55d4..b55840a 100644
--- a/drivers/thermal/spear_thermal.c
+++ b/drivers/thermal/spear_thermal.c
@@ -148,7 +148,7 @@ static int spear_thermal_probe(struct platform_device *pdev)
 	writel_relaxed(stdev->flags, stdev->thermal_base);
 
 	spear_thermal = thermal_zone_device_register("spear_thermal", 0, 0,
-				stdev, &ops, 0, 0, 0, 0);
+				stdev, &ops, 0, 0);
 	if (IS_ERR(spear_thermal)) {
 		dev_err(&pdev->dev, "thermal zone device is NULL\n");
 		ret = PTR_ERR(spear_thermal);
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 68c93d4..a70ed4c 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -335,9 +335,6 @@ passive_store(struct device *dev, struct device_attribute *attr,
 		tz->passive_delay = 0;
 	}
 
-	tz->tc1 = 1;
-	tz->tc2 = 1;
-
 	tz->forced_passive = state;
 
 	thermal_zone_device_update(tz);
@@ -718,13 +715,12 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
 static void thermal_zone_device_passive(struct thermal_zone_device *tz,
 					int temp, int trip_temp, int trip)
 {
-	int trend = 0;
+	enum thermal_trend trend;
 	struct thermal_cooling_device_instance *instance;
 	struct thermal_cooling_device *cdev;
 	long state, max_state;
 
-	if (!tz->ops->get_trend ||
-	    tz->ops->get_trend(tz, trip, (enum thermal_trend *)&trend)) {
+	if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
 		/*
 		 * compare the current temperature and previous temperature
 		 * to get the thermal trend, if no special requirement
@@ -747,11 +743,8 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
 	if (temp >= trip_temp) {
 		tz->passive = true;
 
-		trend = (tz->tc1 * (temp - tz->last_temperature)) +
-			(tz->tc2 * (temp - trip_temp));
-
 		/* Heating up? */
-		if (trend > 0) {
+		if (trend == THERMAL_TREND_RAISING) {
 			list_for_each_entry(instance, &tz->cooling_devices,
 					    node) {
 				if (instance->trip != trip)
@@ -762,7 +755,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
 				if (state++ < max_state)
 					cdev->ops->set_cur_state(cdev, state);
 			}
-		} else if (trend < 0) { /* Cooling off? */
+		} else if (trend == THERMAL_TREND_DROPPING) { /* Cooling off? */
 			list_for_each_entry(instance, &tz->cooling_devices,
 					    node) {
 				if (instance->trip != trip)
@@ -1288,8 +1281,6 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
  * @mask:	a bit string indicating the writeablility of trip points
  * @devdata:	private device data
  * @ops:	standard thermal zone device callbacks
- * @tc1:	thermal coefficient 1 for passive calculations
- * @tc2:	thermal coefficient 2 for passive calculations
  * @passive_delay: number of milliseconds to wait between polls when
  *		   performing passive cooling
  * @polling_delay: number of milliseconds to wait between polls when checking
@@ -1297,13 +1288,12 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
  *		   driven systems)
  *
  * thermal_zone_device_unregister() must be called when the device is no
- * longer needed. The passive cooling formula uses tc1 and tc2 as described in
- * section 11.1.5.1 of the ACPI specification 3.0.
+ * longer needed. The passive cooling depends on the .get_trend() return value.
  */
 struct thermal_zone_device *thermal_zone_device_register(char *type,
 	int trips, int mask, void *devdata,
 	const struct thermal_zone_device_ops *ops,
-	int tc1, int tc2, int passive_delay, int polling_delay)
+	int passive_delay, int polling_delay)
 {
 	struct thermal_zone_device *tz;
 	struct thermal_cooling_device *pos;
@@ -1339,8 +1329,6 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
 	tz->device.class = &thermal_class;
 	tz->devdata = devdata;
 	tz->trips = trips;
-	tz->tc1 = tc1;
-	tz->tc2 = tc2;
 	tz->passive_delay = passive_delay;
 	tz->polling_delay = polling_delay;
 
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index a01e3e6..d18dcf6 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -115,8 +115,6 @@ struct thermal_zone_device {
 	struct thermal_attr *trip_hyst_attrs;
 	void *devdata;
 	int trips;
-	int tc1;
-	int tc2;
 	int passive_delay;
 	int polling_delay;
 	int temperature;
@@ -163,8 +161,7 @@ enum {
 #define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
 
 struct thermal_zone_device *thermal_zone_device_register(char *, int, int,
-		void *, const struct thermal_zone_device_ops *, int tc1,
-		int tc2, int passive_freq, int polling_freq);
+		void *, const struct thermal_zone_device_ops *, int, int);
 void thermal_zone_device_unregister(struct thermal_zone_device *);
 
 int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH V4 06/13] Thermal: Introduce thermal_zone_trip_update()
  2012-07-26  8:41 [PATCH V4 00/13] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (4 preceding siblings ...)
  2012-07-26  8:41 ` [PATCH V4 05/13] Thermal: Remove tc1/tc2 in generic thermal layer Zhang Rui
@ 2012-07-26  8:41 ` Zhang Rui
  2012-07-26 20:12   ` Rafael J. Wysocki
                     ` (2 more replies)
  2012-07-26  8:41 ` [PATCH V4 07/13] Thermal: rename structure thermal_cooling_device_instance to thermal_instance Zhang Rui
                   ` (7 subsequent siblings)
  13 siblings, 3 replies; 45+ messages in thread
From: Zhang Rui @ 2012-07-26  8:41 UTC (permalink / raw)
  To: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, Zhang Rui
  Cc: linux-acpi, linux-pm

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 <rui.zhang@intel.com>
---
 drivers/acpi/thermal.c        |    8 ++--
 drivers/thermal/thermal_sys.c |  102 ++++++++++++++++++++++++++++++-----------
 2 files changed, 81 insertions(+), 29 deletions(-)

diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 0c755d2..a0b1e88 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -714,9 +714,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,
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index a70ed4c..f3156c1 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -1076,6 +1076,81 @@ void thermal_cooling_device_unregister(struct
 }
 EXPORT_SYMBOL(thermal_cooling_device_unregister);
 
+/*
+ * Cooling algorithm for active trip points
+ *
+ * 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
+ *
+ * Note that this behaves the same as the previous passive cooling
+ * algorithm.
+ */
+
+static void thermal_zone_trip_update(struct thermal_zone_device *tz,
+				     int trip, long temp)
+{
+	struct thermal_cooling_device_instance *instance;
+	struct thermal_cooling_device *cdev = NULL;
+	unsigned long cur_state, max_state;
+	long trip_temp;
+	enum thermal_trend trend;
+
+	tz->ops->get_trip_temp(tz, trip, &trip_temp);
+
+	if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
+		/*
+		 * compare the current temperature and previous temperature
+		 * to get the thermal trend, if no special requirement
+		 */
+		if (tz->temperature > tz->last_temperature)
+			trend = THERMAL_TREND_RAISING;
+		else if (tz->temperature < tz->last_temperature)
+			trend = THERMAL_TREND_DROPPING;
+		else
+			trend = THERMAL_TREND_STABLE;
+	}
+
+	if (temp >= trip_temp) {
+		list_for_each_entry(instance, &tz->cooling_devices, node) {
+			if (instance->trip != trip)
+				continue;
+
+			cdev = instance->cdev;
+
+			cdev->ops->get_cur_state(cdev, &cur_state);
+			cdev->ops->get_max_state(cdev, &max_state);
+
+			if (trend == THERMAL_TREND_RAISING) {
+				cur_state = cur_state < instance->upper ?
+					    (cur_state + 1) : instance->upper;
+			} else if (trend == THERMAL_TREND_DROPPING) {
+				cur_state = cur_state > instance->lower ?
+				    (cur_state - 1) : instance->lower;
+			}
+			cdev->ops->set_cur_state(cdev, cur_state);
+		}
+	} else {	/* below trip */
+		list_for_each_entry(instance, &tz->cooling_devices, node) {
+			if (instance->trip != trip)
+				continue;
+
+			cdev = instance->cdev;
+			cdev->ops->get_cur_state(cdev, &cur_state);
+
+			cur_state = cur_state > instance->lower ?
+				    (cur_state - 1) : instance->lower;
+			cdev->ops->set_cur_state(cdev, cur_state);
+		}
+	}
+
+	return;
+}
 /**
  * thermal_zone_device_update - force an update of a thermal zone's state
  * @ttz:	the thermal zone to update
@@ -1086,9 +1161,6 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
 	int count, ret = 0;
 	long temp, trip_temp;
 	enum thermal_trip_type trip_type;
-	struct thermal_cooling_device_instance *instance;
-	struct thermal_cooling_device *cdev;
-	unsigned long cur_state, max_state;
 
 	mutex_lock(&tz->lock);
 
@@ -1124,29 +1196,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
 					tz->ops->notify(tz, count, trip_type);
 			break;
 		case THERMAL_TRIP_ACTIVE:
-			list_for_each_entry(instance, &tz->cooling_devices,
-					    node) {
-				if (instance->trip != count)
-					continue;
-
-				cdev = instance->cdev;
-
-				cdev->ops->get_cur_state(cdev, &cur_state);
-				cdev->ops->get_max_state(cdev, &max_state);
-
-				if (temp >= trip_temp)
-					cur_state =
-						cur_state < instance->upper ?
-						(cur_state + 1) :
-						instance->upper;
-				else
-					cur_state =
-						cur_state > instance->lower ?
-						(cur_state - 1) :
-						instance->lower;
-
-				cdev->ops->set_cur_state(cdev, cur_state);
-			}
+			thermal_zone_trip_update(tz, count, temp);
 			break;
 		case THERMAL_TRIP_PASSIVE:
 			if (temp >= trip_temp || tz->passive)
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH V4 07/13] Thermal: rename structure thermal_cooling_device_instance to thermal_instance
  2012-07-26  8:41 [PATCH V4 00/13] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (5 preceding siblings ...)
  2012-07-26  8:41 ` [PATCH V4 06/13] Thermal: Introduce thermal_zone_trip_update() Zhang Rui
@ 2012-07-26  8:41 ` Zhang Rui
  2012-08-20 15:47   ` Eduardo Valentin
  2012-07-26  8:41 ` [PATCH V4 08/13] Thermal: Rename thermal_zone_device.cooling_devices Zhang Rui
                   ` (6 subsequent siblings)
  13 siblings, 1 reply; 45+ messages in thread
From: Zhang Rui @ 2012-07-26  8:41 UTC (permalink / raw)
  To: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, Zhang Rui
  Cc: linux-acpi, linux-pm

This struct is used to describe the behavior for a thermal
cooling device on a certain trip point for a certain thremal zone.

thermal_cooling_device_instance is not accurate, as a cooling device
can be used for more than one trip point in one thermal zone device.

Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/thermal/thermal_sys.c |   18 +++++++++---------
 1 file changed, 9 insertions(+), 9 deletions(-)

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index f3156c1..3d931c8 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -46,7 +46,7 @@ MODULE_LICENSE("GPL");
  * a certain cooling device on a certain trip point
  * in a certain thermal zone
  */
-struct thermal_cooling_device_instance {
+struct thermal_instance {
 	int id;
 	char name[THERMAL_NAME_LENGTH];
 	struct thermal_zone_device *tz;
@@ -430,10 +430,10 @@ static ssize_t
 thermal_cooling_device_trip_point_show(struct device *dev,
 				       struct device_attribute *attr, char *buf)
 {
-	struct thermal_cooling_device_instance *instance;
+	struct thermal_instance *instance;
 
 	instance =
-	    container_of(attr, struct thermal_cooling_device_instance, attr);
+	    container_of(attr, struct thermal_instance, attr);
 
 	if (instance->trip == THERMAL_TRIPS_NONE)
 		return sprintf(buf, "-1\n");
@@ -716,7 +716,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
 					int temp, int trip_temp, int trip)
 {
 	enum thermal_trend trend;
-	struct thermal_cooling_device_instance *instance;
+	struct thermal_instance *instance;
 	struct thermal_cooling_device *cdev;
 	long state, max_state;
 
@@ -812,8 +812,8 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
 				     struct thermal_cooling_device *cdev,
 				     unsigned long upper, unsigned long lower)
 {
-	struct thermal_cooling_device_instance *dev;
-	struct thermal_cooling_device_instance *pos;
+	struct thermal_instance *dev;
+	struct thermal_instance *pos;
 	struct thermal_zone_device *pos1;
 	struct thermal_cooling_device *pos2;
 	unsigned long max_state;
@@ -844,7 +844,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
 		return -EINVAL;
 
 	dev =
-	    kzalloc(sizeof(struct thermal_cooling_device_instance), GFP_KERNEL);
+	    kzalloc(sizeof(struct thermal_instance), GFP_KERNEL);
 	if (!dev)
 		return -ENOMEM;
 	dev->tz = tz;
@@ -909,7 +909,7 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
 				       int trip,
 				       struct thermal_cooling_device *cdev)
 {
-	struct thermal_cooling_device_instance *pos, *next;
+	struct thermal_instance *pos, *next;
 
 	mutex_lock(&tz->lock);
 	list_for_each_entry_safe(pos, next, &tz->cooling_devices, node) {
@@ -1095,7 +1095,7 @@ EXPORT_SYMBOL(thermal_cooling_device_unregister);
 static void thermal_zone_trip_update(struct thermal_zone_device *tz,
 				     int trip, long temp)
 {
-	struct thermal_cooling_device_instance *instance;
+	struct thermal_instance *instance;
 	struct thermal_cooling_device *cdev = NULL;
 	unsigned long cur_state, max_state;
 	long trip_temp;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH V4 08/13] Thermal: Rename thermal_zone_device.cooling_devices
  2012-07-26  8:41 [PATCH V4 00/13] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (6 preceding siblings ...)
  2012-07-26  8:41 ` [PATCH V4 07/13] Thermal: rename structure thermal_cooling_device_instance to thermal_instance Zhang Rui
@ 2012-07-26  8:41 ` Zhang Rui
  2012-08-20 15:47   ` Eduardo Valentin
  2012-07-26  8:41 ` [PATCH V4 09/13] Thermal: Rename thermal_instance.node to thermal_instance.tz_node Zhang Rui
                   ` (5 subsequent siblings)
  13 siblings, 1 reply; 45+ messages in thread
From: Zhang Rui @ 2012-07-26  8:41 UTC (permalink / raw)
  To: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, Zhang Rui
  Cc: linux-acpi, linux-pm

Rename thermal_zone_device.cooling_devices
to thermal_zone_device.thermal_instances

thermal_zone_device.cooling_devices is not accurate
as this is a list for thermal instances, rather than cooling devices.

Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/thermal/thermal_sys.c |   18 +++++++++---------
 include/linux/thermal.h       |    4 ++--
 2 files changed, 11 insertions(+), 11 deletions(-)

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 3d931c8..112227e 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -745,7 +745,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
 
 		/* Heating up? */
 		if (trend == THERMAL_TREND_RAISING) {
-			list_for_each_entry(instance, &tz->cooling_devices,
+			list_for_each_entry(instance, &tz->thermal_instances,
 					    node) {
 				if (instance->trip != trip)
 					continue;
@@ -756,7 +756,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
 					cdev->ops->set_cur_state(cdev, state);
 			}
 		} else if (trend == THERMAL_TREND_DROPPING) { /* Cooling off? */
-			list_for_each_entry(instance, &tz->cooling_devices,
+			list_for_each_entry(instance, &tz->thermal_instances,
 					    node) {
 				if (instance->trip != trip)
 					continue;
@@ -777,7 +777,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
 	 * and avoid thrashing around the passive trip point.  Note that we
 	 * assume symmetry.
 	 */
-	list_for_each_entry(instance, &tz->cooling_devices, node) {
+	list_for_each_entry(instance, &tz->thermal_instances, node) {
 		if (instance->trip != trip)
 			continue;
 		cdev = instance->cdev;
@@ -873,13 +873,13 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
 		goto remove_symbol_link;
 
 	mutex_lock(&tz->lock);
-	list_for_each_entry(pos, &tz->cooling_devices, node)
+	list_for_each_entry(pos, &tz->thermal_instances, node)
 	    if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
 		result = -EEXIST;
 		break;
 	}
 	if (!result)
-		list_add_tail(&dev->node, &tz->cooling_devices);
+		list_add_tail(&dev->node, &tz->thermal_instances);
 	mutex_unlock(&tz->lock);
 
 	if (!result)
@@ -912,7 +912,7 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
 	struct thermal_instance *pos, *next;
 
 	mutex_lock(&tz->lock);
-	list_for_each_entry_safe(pos, next, &tz->cooling_devices, node) {
+	list_for_each_entry_safe(pos, next, &tz->thermal_instances, node) {
 		if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
 			list_del(&pos->node);
 			mutex_unlock(&tz->lock);
@@ -1117,7 +1117,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
 	}
 
 	if (temp >= trip_temp) {
-		list_for_each_entry(instance, &tz->cooling_devices, node) {
+		list_for_each_entry(instance, &tz->thermal_instances, node) {
 			if (instance->trip != trip)
 				continue;
 
@@ -1136,7 +1136,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
 			cdev->ops->set_cur_state(cdev, cur_state);
 		}
 	} else {	/* below trip */
-		list_for_each_entry(instance, &tz->cooling_devices, node) {
+		list_for_each_entry(instance, &tz->thermal_instances, node) {
 			if (instance->trip != trip)
 				continue;
 
@@ -1365,7 +1365,7 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
 	if (!tz)
 		return ERR_PTR(-ENOMEM);
 
-	INIT_LIST_HEAD(&tz->cooling_devices);
+	INIT_LIST_HEAD(&tz->thermal_instances);
 	idr_init(&tz->idr);
 	mutex_init(&tz->lock);
 	result = get_idr(&thermal_tz_idr, &thermal_idr_lock, &tz->id);
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index d18dcf6..b11db1e 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -122,9 +122,9 @@ struct thermal_zone_device {
 	bool passive;
 	unsigned int forced_passive;
 	const struct thermal_zone_device_ops *ops;
-	struct list_head cooling_devices;
+	struct list_head thermal_instances;
 	struct idr idr;
-	struct mutex lock;	/* protect cooling devices list */
+	struct mutex lock; /* protect thermal_instances list */
 	struct list_head node;
 	struct delayed_work poll_queue;
 };
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH V4 09/13] Thermal: Rename thermal_instance.node to thermal_instance.tz_node.
  2012-07-26  8:41 [PATCH V4 00/13] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (7 preceding siblings ...)
  2012-07-26  8:41 ` [PATCH V4 08/13] Thermal: Rename thermal_zone_device.cooling_devices Zhang Rui
@ 2012-07-26  8:41 ` Zhang Rui
  2012-08-20 15:47   ` Eduardo Valentin
  2012-07-26  8:41 ` [PATCH V4 10/13] Thermal: List thermal_instance in thermal_cooling_device Zhang Rui
                   ` (4 subsequent siblings)
  13 siblings, 1 reply; 45+ messages in thread
From: Zhang Rui @ 2012-07-26  8:41 UTC (permalink / raw)
  To: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, Zhang Rui
  Cc: linux-acpi, linux-pm

thermal_instance should be referenced by both thermal zone devices
and thermal cooling devices.

Rename thermal_instance.node to thermal_instance.tz_node in this patch
and thermal_instanace.cdev_node will be introduced in next patch.

Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/thermal/thermal_sys.c |   20 ++++++++++----------
 1 file changed, 10 insertions(+), 10 deletions(-)

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 112227e..b2a2d48 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -56,7 +56,7 @@ struct thermal_instance {
 	unsigned long lower;	/* Lowest cooling state for this trip point */
 	char attr_name[THERMAL_NAME_LENGTH];
 	struct device_attribute attr;
-	struct list_head node;
+	struct list_head tz_node; /* node in tz->thermal_instances */
 };
 
 static DEFINE_IDR(thermal_tz_idr);
@@ -746,7 +746,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
 		/* Heating up? */
 		if (trend == THERMAL_TREND_RAISING) {
 			list_for_each_entry(instance, &tz->thermal_instances,
-					    node) {
+					    tz_node) {
 				if (instance->trip != trip)
 					continue;
 				cdev = instance->cdev;
@@ -757,7 +757,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
 			}
 		} else if (trend == THERMAL_TREND_DROPPING) { /* Cooling off? */
 			list_for_each_entry(instance, &tz->thermal_instances,
-					    node) {
+					    tz_node) {
 				if (instance->trip != trip)
 					continue;
 				cdev = instance->cdev;
@@ -777,7 +777,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
 	 * and avoid thrashing around the passive trip point.  Note that we
 	 * assume symmetry.
 	 */
-	list_for_each_entry(instance, &tz->thermal_instances, node) {
+	list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
 		if (instance->trip != trip)
 			continue;
 		cdev = instance->cdev;
@@ -873,13 +873,13 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
 		goto remove_symbol_link;
 
 	mutex_lock(&tz->lock);
-	list_for_each_entry(pos, &tz->thermal_instances, node)
+	list_for_each_entry(pos, &tz->thermal_instances, tz_node)
 	    if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
 		result = -EEXIST;
 		break;
 	}
 	if (!result)
-		list_add_tail(&dev->node, &tz->thermal_instances);
+		list_add_tail(&dev->tz_node, &tz->thermal_instances);
 	mutex_unlock(&tz->lock);
 
 	if (!result)
@@ -912,9 +912,9 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
 	struct thermal_instance *pos, *next;
 
 	mutex_lock(&tz->lock);
-	list_for_each_entry_safe(pos, next, &tz->thermal_instances, node) {
+	list_for_each_entry_safe(pos, next, &tz->thermal_instances, tz_node) {
 		if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
-			list_del(&pos->node);
+			list_del(&pos->tz_node);
 			mutex_unlock(&tz->lock);
 			goto unbind;
 		}
@@ -1117,7 +1117,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
 	}
 
 	if (temp >= trip_temp) {
-		list_for_each_entry(instance, &tz->thermal_instances, node) {
+		list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
 			if (instance->trip != trip)
 				continue;
 
@@ -1136,7 +1136,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
 			cdev->ops->set_cur_state(cdev, cur_state);
 		}
 	} else {	/* below trip */
-		list_for_each_entry(instance, &tz->thermal_instances, node) {
+		list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
 			if (instance->trip != trip)
 				continue;
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH V4 10/13] Thermal: List thermal_instance in thermal_cooling_device.
  2012-07-26  8:41 [PATCH V4 00/13] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (8 preceding siblings ...)
  2012-07-26  8:41 ` [PATCH V4 09/13] Thermal: Rename thermal_instance.node to thermal_instance.tz_node Zhang Rui
@ 2012-07-26  8:41 ` Zhang Rui
  2012-08-20 15:46   ` Eduardo Valentin
  2012-07-26  8:41 ` [PATCH V4 11/13] Thermal: Introduce simple arbitrator for setting device cooling state Zhang Rui
                   ` (3 subsequent siblings)
  13 siblings, 1 reply; 45+ messages in thread
From: Zhang Rui @ 2012-07-26  8:41 UTC (permalink / raw)
  To: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, Zhang Rui
  Cc: linux-acpi, linux-pm

List thermal_instance in thermal_cooling_device so that
cooling device can know the cooling state requirement
of all the thermal instances.

Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/thermal/thermal_sys.c |    7 ++++++-
 include/linux/thermal.h       |    1 +
 2 files changed, 7 insertions(+), 1 deletion(-)

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index b2a2d48..9906717 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -57,6 +57,7 @@ struct thermal_instance {
 	char attr_name[THERMAL_NAME_LENGTH];
 	struct device_attribute attr;
 	struct list_head tz_node; /* node in tz->thermal_instances */
+	struct list_head cdev_node; /* node in cdev->thermal_instances */
 };
 
 static DEFINE_IDR(thermal_tz_idr);
@@ -878,8 +879,10 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
 		result = -EEXIST;
 		break;
 	}
-	if (!result)
+	if (!result) {
 		list_add_tail(&dev->tz_node, &tz->thermal_instances);
+		list_add_tail(&dev->cdev_node, &cdev->thermal_instances);
+	}
 	mutex_unlock(&tz->lock);
 
 	if (!result)
@@ -915,6 +918,7 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
 	list_for_each_entry_safe(pos, next, &tz->thermal_instances, tz_node) {
 		if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
 			list_del(&pos->tz_node);
+			list_del(&pos->cdev_node);
 			mutex_unlock(&tz->lock);
 			goto unbind;
 		}
@@ -984,6 +988,7 @@ thermal_cooling_device_register(char *type, void *devdata,
 	}
 
 	strcpy(cdev->type, type);
+	INIT_LIST_HEAD(&cdev->thermal_instances);
 	cdev->ops = ops;
 	cdev->device.class = &thermal_class;
 	cdev->devdata = devdata;
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index b11db1e..bcf3384 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -94,6 +94,7 @@ struct thermal_cooling_device {
 	struct device device;
 	void *devdata;
 	const struct thermal_cooling_device_ops *ops;
+	struct list_head thermal_instances;
 	struct list_head node;
 };
 
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH V4 11/13] Thermal: Introduce simple arbitrator for setting device cooling state
  2012-07-26  8:41 [PATCH V4 00/13] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (9 preceding siblings ...)
  2012-07-26  8:41 ` [PATCH V4 10/13] Thermal: List thermal_instance in thermal_cooling_device Zhang Rui
@ 2012-07-26  8:41 ` Zhang Rui
  2012-08-20 15:46   ` Eduardo Valentin
  2012-07-26  8:41 ` [PATCH V4 12/13] Thermal: Unify the code for both active and passive cooling Zhang Rui
                   ` (2 subsequent siblings)
  13 siblings, 1 reply; 45+ messages in thread
From: Zhang Rui @ 2012-07-26  8:41 UTC (permalink / raw)
  To: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, Zhang Rui
  Cc: linux-acpi, linux-pm

This fixes the problem that a cooling device may be referenced by
by multiple trip points in multiple thermal zones.

With this patch, we have two stages for updating a thermal zone,
1. check if a thermal_instance needs to be updated or not
2. update the cooling device, based on the target cooling state
   of all its instances.

Note that, currently, the cooling device is set to the deepest
cooling state required.

Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/thermal/thermal_sys.c |   44 ++++++++++++++++++++++++++++++++++++++---
 include/linux/thermal.h       |    1 +
 2 files changed, 42 insertions(+), 3 deletions(-)

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 9906717..027b8e2 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -41,6 +41,7 @@ MODULE_AUTHOR("Zhang Rui");
 MODULE_DESCRIPTION("Generic thermal management sysfs support");
 MODULE_LICENSE("GPL");
 
+#define THERMAL_NO_TARGET -1UL
 /*
  * This structure is used to describe the behavior of
  * a certain cooling device on a certain trip point
@@ -54,6 +55,7 @@ struct thermal_instance {
 	int trip;
 	unsigned long upper;	/* Highest cooling state for this trip point */
 	unsigned long lower;	/* Lowest cooling state for this trip point */
+	unsigned long target;	/* expected cooling state */
 	char attr_name[THERMAL_NAME_LENGTH];
 	struct device_attribute attr;
 	struct list_head tz_node; /* node in tz->thermal_instances */
@@ -853,6 +855,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
 	dev->trip = trip;
 	dev->upper = upper;
 	dev->lower = lower;
+	dev->target = THERMAL_NO_TARGET;
 
 	result = get_idr(&tz->idr, &tz->lock, &dev->id);
 	if (result)
@@ -990,6 +993,7 @@ thermal_cooling_device_register(char *type, void *devdata,
 	strcpy(cdev->type, type);
 	INIT_LIST_HEAD(&cdev->thermal_instances);
 	cdev->ops = ops;
+	cdev->updated = true;
 	cdev->device.class = &thermal_class;
 	cdev->devdata = devdata;
 	dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
@@ -1081,6 +1085,34 @@ void thermal_cooling_device_unregister(struct
 }
 EXPORT_SYMBOL(thermal_cooling_device_unregister);
 
+static void thermal_cdev_do_update(struct thermal_cooling_device *cdev)
+{
+	struct thermal_instance *instance;
+	unsigned long target = 0;
+
+	/* cooling device is updated*/
+	if (cdev->updated)
+		return;
+
+	/* Make sure cdev enters the deepest cooling state */
+	list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
+		if (instance->target == THERMAL_NO_TARGET)
+			continue;
+		if (instance->target > target)
+			target = instance->target;
+	}
+	cdev->ops->set_cur_state(cdev, target);
+	cdev->updated = true;
+}
+
+static void thermal_zone_do_update(struct thermal_zone_device *tz)
+{
+	struct thermal_instance *instance;
+
+	list_for_each_entry(instance, &tz->thermal_instances, tz_node)
+		thermal_cdev_do_update(instance->cdev);
+}
+
 /*
  * Cooling algorithm for active trip points
  *
@@ -1138,19 +1170,24 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
 				cur_state = cur_state > instance->lower ?
 				    (cur_state - 1) : instance->lower;
 			}
-			cdev->ops->set_cur_state(cdev, cur_state);
+			instance->target = cur_state;
+			cdev->updated = false; /* cooling device needs update */
 		}
 	} else {	/* below trip */
 		list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
 			if (instance->trip != trip)
 				continue;
 
+			/* Do not use the inactive thermal instance */
+			if (instance->target == THERMAL_NO_TARGET)
+				continue;
 			cdev = instance->cdev;
 			cdev->ops->get_cur_state(cdev, &cur_state);
 
 			cur_state = cur_state > instance->lower ?
-				    (cur_state - 1) : instance->lower;
-			cdev->ops->set_cur_state(cdev, cur_state);
+				    (cur_state - 1) : THERMAL_NO_TARGET;
+			instance->target = cur_state;
+			cdev->updated = false; /* cooling device needs update */
 		}
 	}
 
@@ -1211,6 +1248,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
 		}
 	}
 
+	thermal_zone_do_update(tz);
 	if (tz->forced_passive)
 		thermal_zone_device_passive(tz, temp, tz->forced_passive,
 					    THERMAL_TRIPS_NONE);
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index bcf3384..3e66214 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -94,6 +94,7 @@ struct thermal_cooling_device {
 	struct device device;
 	void *devdata;
 	const struct thermal_cooling_device_ops *ops;
+	bool updated; /* true if the cooling device does not need update */
 	struct list_head thermal_instances;
 	struct list_head node;
 };
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH V4 12/13] Thermal: Unify the code for both active and passive cooling
  2012-07-26  8:41 [PATCH V4 00/13] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (10 preceding siblings ...)
  2012-07-26  8:41 ` [PATCH V4 11/13] Thermal: Introduce simple arbitrator for setting device cooling state Zhang Rui
@ 2012-07-26  8:41 ` Zhang Rui
  2012-08-20 15:45   ` Eduardo Valentin
  2012-07-26  8:41 ` [PATCH V4 13/13] Thermal: Introduce locking for cdev.thermal_instances list Zhang Rui
  2012-08-20 15:53 ` [PATCH V4 00/13] Thermal: generic thermal layer enhancement Eduardo Valentin
  13 siblings, 1 reply; 45+ messages in thread
From: Zhang Rui @ 2012-07-26  8:41 UTC (permalink / raw)
  To: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, Zhang Rui
  Cc: linux-acpi, linux-pm

Remove thermal_zone_device_passive(). And use
thermal_zone_trip_update() and thermal_zone_do_update()
for both active and passive cooling.

Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/thermal/thermal_sys.c |  110 ++++++++++-------------------------------
 include/linux/thermal.h       |    2 +-
 2 files changed, 26 insertions(+), 86 deletions(-)

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 027b8e2..7f3a891 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -715,84 +715,6 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
 				      msecs_to_jiffies(delay));
 }
 
-static void thermal_zone_device_passive(struct thermal_zone_device *tz,
-					int temp, int trip_temp, int trip)
-{
-	enum thermal_trend trend;
-	struct thermal_instance *instance;
-	struct thermal_cooling_device *cdev;
-	long state, max_state;
-
-	if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
-		/*
-		 * compare the current temperature and previous temperature
-		 * to get the thermal trend, if no special requirement
-		 */
-		if (tz->temperature > tz->last_temperature)
-			trend = THERMAL_TREND_RAISING;
-		else if (tz->temperature < tz->last_temperature)
-			trend = THERMAL_TREND_DROPPING;
-		else
-			trend = THERMAL_TREND_STABLE;
-	}
-
-	/*
-	 * Above Trip?
-	 * -----------
-	 * Calculate the thermal trend (using the passive cooling equation)
-	 * and modify the performance limit for all passive cooling devices
-	 * accordingly.  Note that we assume symmetry.
-	 */
-	if (temp >= trip_temp) {
-		tz->passive = true;
-
-		/* Heating up? */
-		if (trend == THERMAL_TREND_RAISING) {
-			list_for_each_entry(instance, &tz->thermal_instances,
-					    tz_node) {
-				if (instance->trip != trip)
-					continue;
-				cdev = instance->cdev;
-				cdev->ops->get_cur_state(cdev, &state);
-				cdev->ops->get_max_state(cdev, &max_state);
-				if (state++ < max_state)
-					cdev->ops->set_cur_state(cdev, state);
-			}
-		} else if (trend == THERMAL_TREND_DROPPING) { /* Cooling off? */
-			list_for_each_entry(instance, &tz->thermal_instances,
-					    tz_node) {
-				if (instance->trip != trip)
-					continue;
-				cdev = instance->cdev;
-				cdev->ops->get_cur_state(cdev, &state);
-				cdev->ops->get_max_state(cdev, &max_state);
-				if (state > 0)
-					cdev->ops->set_cur_state(cdev, --state);
-			}
-		}
-		return;
-	}
-
-	/*
-	 * Below Trip?
-	 * -----------
-	 * Implement passive cooling hysteresis to slowly increase performance
-	 * and avoid thrashing around the passive trip point.  Note that we
-	 * assume symmetry.
-	 */
-	list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
-		if (instance->trip != trip)
-			continue;
-		cdev = instance->cdev;
-		cdev->ops->get_cur_state(cdev, &state);
-		cdev->ops->get_max_state(cdev, &max_state);
-		if (state > 0)
-			cdev->ops->set_cur_state(cdev, --state);
-		if (state == 0)
-			tz->passive = false;
-	}
-}
-
 static void thermal_zone_device_check(struct work_struct *work)
 {
 	struct thermal_zone_device *tz = container_of(work, struct
@@ -1114,7 +1036,7 @@ static void thermal_zone_do_update(struct thermal_zone_device *tz)
 }
 
 /*
- * Cooling algorithm for active trip points
+ * Cooling algorithm for both active and passive cooling
  *
  * 1. if the temperature is higher than a trip point,
  *    a. if the trend is THERMAL_TREND_RAISING, use higher cooling
@@ -1136,9 +1058,16 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
 	struct thermal_cooling_device *cdev = NULL;
 	unsigned long cur_state, max_state;
 	long trip_temp;
+	enum thermal_trip_type trip_type;
 	enum thermal_trend trend;
 
-	tz->ops->get_trip_temp(tz, trip, &trip_temp);
+	if (trip == THERMAL_TRIPS_NONE) {
+		trip_temp = tz->forced_passive;
+		trip_type = THERMAL_TRIPS_NONE;
+	} else {
+		tz->ops->get_trip_temp(tz, trip, &trip_temp);
+		tz->ops->get_trip_type(tz, trip, &trip_type);
+	}
 
 	if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
 		/*
@@ -1170,6 +1099,13 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
 				cur_state = cur_state > instance->lower ?
 				    (cur_state - 1) : instance->lower;
 			}
+
+			/* activate a passive thermal instance */
+			if ((trip_type == THERMAL_TRIP_PASSIVE ||
+			     trip_type == THERMAL_TRIPS_NONE) &&
+			     instance->target == THERMAL_NO_TARGET)
+				tz->passive++;
+
 			instance->target = cur_state;
 			cdev->updated = false; /* cooling device needs update */
 		}
@@ -1186,6 +1122,12 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
 
 			cur_state = cur_state > instance->lower ?
 				    (cur_state - 1) : THERMAL_NO_TARGET;
+
+			/* deactivate a passive thermal instance */
+			if ((trip_type == THERMAL_TRIP_PASSIVE ||
+			     trip_type == THERMAL_TRIPS_NONE) &&
+			     cur_state == THERMAL_NO_TARGET)
+				tz->passive--;
 			instance->target = cur_state;
 			cdev->updated = false; /* cooling device needs update */
 		}
@@ -1242,16 +1184,14 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
 			break;
 		case THERMAL_TRIP_PASSIVE:
 			if (temp >= trip_temp || tz->passive)
-				thermal_zone_device_passive(tz, temp,
-							    trip_temp, count);
+				thermal_zone_trip_update(tz, count, temp);
 			break;
 		}
 	}
 
-	thermal_zone_do_update(tz);
 	if (tz->forced_passive)
-		thermal_zone_device_passive(tz, temp, tz->forced_passive,
-					    THERMAL_TRIPS_NONE);
+		thermal_zone_trip_update(tz, THERMAL_TRIPS_NONE, temp);
+	thermal_zone_do_update(tz);
 
 leave:
 	if (tz->passive)
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 3e66214..06fd04d 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -121,7 +121,7 @@ struct thermal_zone_device {
 	int polling_delay;
 	int temperature;
 	int last_temperature;
-	bool passive;
+	int passive;
 	unsigned int forced_passive;
 	const struct thermal_zone_device_ops *ops;
 	struct list_head thermal_instances;
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* [PATCH V4 13/13] Thermal: Introduce locking for cdev.thermal_instances list.
  2012-07-26  8:41 [PATCH V4 00/13] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (11 preceding siblings ...)
  2012-07-26  8:41 ` [PATCH V4 12/13] Thermal: Unify the code for both active and passive cooling Zhang Rui
@ 2012-07-26  8:41 ` Zhang Rui
  2012-07-26 20:13   ` Rafael J. Wysocki
  2012-08-20 15:45   ` Eduardo Valentin
  2012-08-20 15:53 ` [PATCH V4 00/13] Thermal: generic thermal layer enhancement Eduardo Valentin
  13 siblings, 2 replies; 45+ messages in thread
From: Zhang Rui @ 2012-07-26  8:41 UTC (permalink / raw)
  To: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, Zhang Rui
  Cc: linux-acpi, linux-pm

we need to go over all the thermal_instance list of a cooling device
to decide which cooling state to put the cooling device to.

But at this time, as a cooling device may be referenced in multiple
thermal zones, we need to lock the list first in case
another thermal zone is updating this cooling device.

Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 drivers/thermal/thermal_sys.c |    8 ++++++++
 include/linux/thermal.h       |    1 +
 2 files changed, 9 insertions(+)

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 7f3a891..356a59d 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -799,6 +799,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
 		goto remove_symbol_link;
 
 	mutex_lock(&tz->lock);
+	mutex_lock(&cdev->lock);
 	list_for_each_entry(pos, &tz->thermal_instances, tz_node)
 	    if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
 		result = -EEXIST;
@@ -808,6 +809,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
 		list_add_tail(&dev->tz_node, &tz->thermal_instances);
 		list_add_tail(&dev->cdev_node, &cdev->thermal_instances);
 	}
+	mutex_unlock(&cdev->lock);
 	mutex_unlock(&tz->lock);
 
 	if (!result)
@@ -840,14 +842,17 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
 	struct thermal_instance *pos, *next;
 
 	mutex_lock(&tz->lock);
+	mutex_lock(&cdev->lock);
 	list_for_each_entry_safe(pos, next, &tz->thermal_instances, tz_node) {
 		if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
 			list_del(&pos->tz_node);
 			list_del(&pos->cdev_node);
+			mutex_unlock(&cdev->lock);
 			mutex_unlock(&tz->lock);
 			goto unbind;
 		}
 	}
+	mutex_unlock(&cdev->lock);
 	mutex_unlock(&tz->lock);
 
 	return -ENODEV;
@@ -913,6 +918,7 @@ thermal_cooling_device_register(char *type, void *devdata,
 	}
 
 	strcpy(cdev->type, type);
+	mutex_init(&cdev->lock);
 	INIT_LIST_HEAD(&cdev->thermal_instances);
 	cdev->ops = ops;
 	cdev->updated = true;
@@ -1016,6 +1022,7 @@ static void thermal_cdev_do_update(struct thermal_cooling_device *cdev)
 	if (cdev->updated)
 		return;
 
+	mutex_lock(&cdev->lock);
 	/* Make sure cdev enters the deepest cooling state */
 	list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
 		if (instance->target == THERMAL_NO_TARGET)
@@ -1023,6 +1030,7 @@ static void thermal_cdev_do_update(struct thermal_cooling_device *cdev)
 		if (instance->target > target)
 			target = instance->target;
 	}
+	mutex_unlock(&cdev->lock);
 	cdev->ops->set_cur_state(cdev, target);
 	cdev->updated = true;
 }
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 06fd04d..d02d06d 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -95,6 +95,7 @@ struct thermal_cooling_device {
 	void *devdata;
 	const struct thermal_cooling_device_ops *ops;
 	bool updated; /* true if the cooling device does not need update */
+	struct mutex lock; /* protect thermal_instances list */
 	struct list_head thermal_instances;
 	struct list_head node;
 };
-- 
1.7.9.5


^ permalink raw reply related	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 04/13] Thermal: Introduce .get_trend() callback.
  2012-07-26  8:41 ` [PATCH V4 04/13] Thermal: Introduce .get_trend() callback Zhang Rui
@ 2012-07-26 20:11   ` Rafael J. Wysocki
  2012-08-01  2:42     ` Zhang Rui
  2012-08-08 13:44   ` Valentin, Eduardo
  1 sibling, 1 reply; 45+ messages in thread
From: Rafael J. Wysocki @ 2012-07-26 20:11 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Matthew Garrett, Len Brown, R Durgadoss, Eduardo Valentin,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Thursday, July 26, 2012, Zhang Rui wrote:
> 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.

As far as the code is concerned:

Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>

I wonder, though, if there are any users of the thermal core currently in the
tree who should introduce their own .get_trend() callbacks?

Rafael


> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> ---
>  drivers/acpi/thermal.c        |   33 +++++++++++++++++++++++++++++++++
>  drivers/thermal/thermal_sys.c |   19 +++++++++++++++++--
>  include/linux/thermal.h       |    9 +++++++++
>  3 files changed, 59 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> index b48ec3e..0c49e42 100644
> --- a/drivers/acpi/thermal.c
> +++ b/drivers/acpi/thermal.c
> @@ -704,6 +704,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)
>  {
> @@ -836,6 +868,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,
>  };
>  
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index 62b4279..68c93d4 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -723,6 +723,20 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>  	struct thermal_cooling_device *cdev;
>  	long state, max_state;
>  
> +	if (!tz->ops->get_trend ||
> +	    tz->ops->get_trend(tz, trip, (enum thermal_trend *)&trend)) {
> +		/*
> +		 * compare the current temperature and previous temperature
> +		 * to get the thermal trend, if no special requirement
> +		 */
> +		if (tz->temperature > tz->last_temperature)
> +			trend = THERMAL_TREND_RAISING;
> +		else if (tz->temperature < tz->last_temperature)
> +			trend = THERMAL_TREND_DROPPING;
> +		else
> +			trend = THERMAL_TREND_STABLE;
> +	}
> +
>  	/*
>  	 * Above Trip?
>  	 * -----------
> @@ -1091,6 +1105,9 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>  		goto leave;
>  	}
>  
> +	tz->last_temperature = tz->temperature;
> +	tz->temperature = temp;
> +
>  	for (count = 0; count < tz->trips; count++) {
>  		tz->ops->get_trip_type(tz, count, &trip_type);
>  		tz->ops->get_trip_temp(tz, count, &trip_temp);
> @@ -1150,8 +1167,6 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>  		thermal_zone_device_passive(tz, temp, tz->forced_passive,
>  					    THERMAL_TRIPS_NONE);
>  
> -	tz->last_temperature = temp;
> -
>  leave:
>  	if (tz->passive)
>  		thermal_zone_device_set_polling(tz, tz->passive_delay);
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index a43b12c..a01e3e6 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -44,6 +44,12 @@ enum thermal_trip_type {
>  	THERMAL_TRIP_CRITICAL,
>  };
>  
> +enum thermal_trend {
> +	THERMAL_TREND_STABLE, /* temperature is stable */
> +	THERMAL_TREND_RAISING, /* temperature is raising */
> +	THERMAL_TREND_DROPPING, /* temperature is dropping */
> +};
> +
>  struct thermal_zone_device_ops {
>  	int (*bind) (struct thermal_zone_device *,
>  		     struct thermal_cooling_device *);
> @@ -65,6 +71,8 @@ struct thermal_zone_device_ops {
>  	int (*set_trip_hyst) (struct thermal_zone_device *, int,
>  			      unsigned long);
>  	int (*get_crit_temp) (struct thermal_zone_device *, unsigned long *);
> +	int (*get_trend) (struct thermal_zone_device *, int,
> +			  enum thermal_trend *);
>  	int (*notify) (struct thermal_zone_device *, int,
>  		       enum thermal_trip_type);
>  };
> @@ -111,6 +119,7 @@ struct thermal_zone_device {
>  	int tc2;
>  	int passive_delay;
>  	int polling_delay;
> +	int temperature;
>  	int last_temperature;
>  	bool passive;
>  	unsigned int forced_passive;
> 


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 05/13] Thermal: Remove tc1/tc2 in generic thermal layer.
  2012-07-26  8:41 ` [PATCH V4 05/13] Thermal: Remove tc1/tc2 in generic thermal layer Zhang Rui
@ 2012-07-26 20:11   ` Rafael J. Wysocki
  2012-08-08 14:06   ` Valentin, Eduardo
  1 sibling, 0 replies; 45+ messages in thread
From: Rafael J. Wysocki @ 2012-07-26 20:11 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Matthew Garrett, Len Brown, R Durgadoss, Eduardo Valentin,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Thursday, July 26, 2012, Zhang Rui wrote:
> Remove tc1/tc2 in generic thermal layer.
> .get_trend() callback starts to take effect from this patch.
> 
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>

> ---
>  drivers/acpi/thermal.c                   |    5 +----
>  drivers/platform/x86/acerhdf.c           |    2 +-
>  drivers/platform/x86/intel_mid_thermal.c |    2 +-
>  drivers/thermal/spear_thermal.c          |    2 +-
>  drivers/thermal/thermal_sys.c            |   24 ++++++------------------
>  include/linux/thermal.h                  |    5 +----
>  6 files changed, 11 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> index 0c49e42..0c755d2 100644
> --- a/drivers/acpi/thermal.c
> +++ b/drivers/acpi/thermal.c
> @@ -895,15 +895,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;
> diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
> index a207466..84c5688 100644
> --- a/drivers/platform/x86/acerhdf.c
> +++ b/drivers/platform/x86/acerhdf.c
> @@ -662,7 +662,7 @@ static int acerhdf_register_thermal(void)
>  		return -EINVAL;
>  
>  	thz_dev = thermal_zone_device_register("acerhdf", 1, 0, NULL,
> -					      &acerhdf_dev_ops, 0, 0, 0,
> +					      &acerhdf_dev_ops, 0,
>  					      (kernelmode) ? interval*1000 : 0);
>  	if (IS_ERR(thz_dev))
>  		return -EINVAL;
> diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c
> index 2b2c212..6e309dd 100644
> --- a/drivers/platform/x86/intel_mid_thermal.c
> +++ b/drivers/platform/x86/intel_mid_thermal.c
> @@ -499,7 +499,7 @@ static int mid_thermal_probe(struct platform_device *pdev)
>  			goto err;
>  		}
>  		pinfo->tzd[i] = thermal_zone_device_register(name[i],
> -				0, 0, td_info, &tzd_ops, 0, 0, 0, 0);
> +				0, 0, td_info, &tzd_ops, 0, 0);
>  		if (IS_ERR(pinfo->tzd[i])) {
>  			kfree(td_info);
>  			ret = PTR_ERR(pinfo->tzd[i]);
> diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c
> index 69a55d4..b55840a 100644
> --- a/drivers/thermal/spear_thermal.c
> +++ b/drivers/thermal/spear_thermal.c
> @@ -148,7 +148,7 @@ static int spear_thermal_probe(struct platform_device *pdev)
>  	writel_relaxed(stdev->flags, stdev->thermal_base);
>  
>  	spear_thermal = thermal_zone_device_register("spear_thermal", 0, 0,
> -				stdev, &ops, 0, 0, 0, 0);
> +				stdev, &ops, 0, 0);
>  	if (IS_ERR(spear_thermal)) {
>  		dev_err(&pdev->dev, "thermal zone device is NULL\n");
>  		ret = PTR_ERR(spear_thermal);
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index 68c93d4..a70ed4c 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -335,9 +335,6 @@ passive_store(struct device *dev, struct device_attribute *attr,
>  		tz->passive_delay = 0;
>  	}
>  
> -	tz->tc1 = 1;
> -	tz->tc2 = 1;
> -
>  	tz->forced_passive = state;
>  
>  	thermal_zone_device_update(tz);
> @@ -718,13 +715,12 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
>  static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>  					int temp, int trip_temp, int trip)
>  {
> -	int trend = 0;
> +	enum thermal_trend trend;
>  	struct thermal_cooling_device_instance *instance;
>  	struct thermal_cooling_device *cdev;
>  	long state, max_state;
>  
> -	if (!tz->ops->get_trend ||
> -	    tz->ops->get_trend(tz, trip, (enum thermal_trend *)&trend)) {
> +	if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
>  		/*
>  		 * compare the current temperature and previous temperature
>  		 * to get the thermal trend, if no special requirement
> @@ -747,11 +743,8 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>  	if (temp >= trip_temp) {
>  		tz->passive = true;
>  
> -		trend = (tz->tc1 * (temp - tz->last_temperature)) +
> -			(tz->tc2 * (temp - trip_temp));
> -
>  		/* Heating up? */
> -		if (trend > 0) {
> +		if (trend == THERMAL_TREND_RAISING) {
>  			list_for_each_entry(instance, &tz->cooling_devices,
>  					    node) {
>  				if (instance->trip != trip)
> @@ -762,7 +755,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>  				if (state++ < max_state)
>  					cdev->ops->set_cur_state(cdev, state);
>  			}
> -		} else if (trend < 0) { /* Cooling off? */
> +		} else if (trend == THERMAL_TREND_DROPPING) { /* Cooling off? */
>  			list_for_each_entry(instance, &tz->cooling_devices,
>  					    node) {
>  				if (instance->trip != trip)
> @@ -1288,8 +1281,6 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
>   * @mask:	a bit string indicating the writeablility of trip points
>   * @devdata:	private device data
>   * @ops:	standard thermal zone device callbacks
> - * @tc1:	thermal coefficient 1 for passive calculations
> - * @tc2:	thermal coefficient 2 for passive calculations
>   * @passive_delay: number of milliseconds to wait between polls when
>   *		   performing passive cooling
>   * @polling_delay: number of milliseconds to wait between polls when checking
> @@ -1297,13 +1288,12 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
>   *		   driven systems)
>   *
>   * thermal_zone_device_unregister() must be called when the device is no
> - * longer needed. The passive cooling formula uses tc1 and tc2 as described in
> - * section 11.1.5.1 of the ACPI specification 3.0.
> + * longer needed. The passive cooling depends on the .get_trend() return value.
>   */
>  struct thermal_zone_device *thermal_zone_device_register(char *type,
>  	int trips, int mask, void *devdata,
>  	const struct thermal_zone_device_ops *ops,
> -	int tc1, int tc2, int passive_delay, int polling_delay)
> +	int passive_delay, int polling_delay)
>  {
>  	struct thermal_zone_device *tz;
>  	struct thermal_cooling_device *pos;
> @@ -1339,8 +1329,6 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
>  	tz->device.class = &thermal_class;
>  	tz->devdata = devdata;
>  	tz->trips = trips;
> -	tz->tc1 = tc1;
> -	tz->tc2 = tc2;
>  	tz->passive_delay = passive_delay;
>  	tz->polling_delay = polling_delay;
>  
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index a01e3e6..d18dcf6 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -115,8 +115,6 @@ struct thermal_zone_device {
>  	struct thermal_attr *trip_hyst_attrs;
>  	void *devdata;
>  	int trips;
> -	int tc1;
> -	int tc2;
>  	int passive_delay;
>  	int polling_delay;
>  	int temperature;
> @@ -163,8 +161,7 @@ enum {
>  #define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
>  
>  struct thermal_zone_device *thermal_zone_device_register(char *, int, int,
> -		void *, const struct thermal_zone_device_ops *, int tc1,
> -		int tc2, int passive_freq, int polling_freq);
> +		void *, const struct thermal_zone_device_ops *, int, int);
>  void thermal_zone_device_unregister(struct thermal_zone_device *);
>  
>  int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
> 


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 06/13] Thermal: Introduce thermal_zone_trip_update()
  2012-07-26  8:41 ` [PATCH V4 06/13] Thermal: Introduce thermal_zone_trip_update() Zhang Rui
@ 2012-07-26 20:12   ` Rafael J. Wysocki
  2012-08-20 15:47   ` Eduardo Valentin
  2012-08-20 15:48   ` Eduardo Valentin
  2 siblings, 0 replies; 45+ messages in thread
From: Rafael J. Wysocki @ 2012-07-26 20:12 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Matthew Garrett, Len Brown, R Durgadoss, Eduardo Valentin,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Thursday, July 26, 2012, Zhang Rui wrote:
> 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 <rui.zhang@intel.com>

Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>

> ---
>  drivers/acpi/thermal.c        |    8 ++--
>  drivers/thermal/thermal_sys.c |  102 ++++++++++++++++++++++++++++++-----------
>  2 files changed, 81 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> index 0c755d2..a0b1e88 100644
> --- a/drivers/acpi/thermal.c
> +++ b/drivers/acpi/thermal.c
> @@ -714,9 +714,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,
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index a70ed4c..f3156c1 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -1076,6 +1076,81 @@ void thermal_cooling_device_unregister(struct
>  }
>  EXPORT_SYMBOL(thermal_cooling_device_unregister);
>  
> +/*
> + * Cooling algorithm for active trip points
> + *
> + * 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
> + *
> + * Note that this behaves the same as the previous passive cooling
> + * algorithm.
> + */
> +
> +static void thermal_zone_trip_update(struct thermal_zone_device *tz,
> +				     int trip, long temp)
> +{
> +	struct thermal_cooling_device_instance *instance;
> +	struct thermal_cooling_device *cdev = NULL;
> +	unsigned long cur_state, max_state;
> +	long trip_temp;
> +	enum thermal_trend trend;
> +
> +	tz->ops->get_trip_temp(tz, trip, &trip_temp);
> +
> +	if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
> +		/*
> +		 * compare the current temperature and previous temperature
> +		 * to get the thermal trend, if no special requirement
> +		 */
> +		if (tz->temperature > tz->last_temperature)
> +			trend = THERMAL_TREND_RAISING;
> +		else if (tz->temperature < tz->last_temperature)
> +			trend = THERMAL_TREND_DROPPING;
> +		else
> +			trend = THERMAL_TREND_STABLE;
> +	}
> +
> +	if (temp >= trip_temp) {
> +		list_for_each_entry(instance, &tz->cooling_devices, node) {
> +			if (instance->trip != trip)
> +				continue;
> +
> +			cdev = instance->cdev;
> +
> +			cdev->ops->get_cur_state(cdev, &cur_state);
> +			cdev->ops->get_max_state(cdev, &max_state);
> +
> +			if (trend == THERMAL_TREND_RAISING) {
> +				cur_state = cur_state < instance->upper ?
> +					    (cur_state + 1) : instance->upper;
> +			} else if (trend == THERMAL_TREND_DROPPING) {
> +				cur_state = cur_state > instance->lower ?
> +				    (cur_state - 1) : instance->lower;
> +			}
> +			cdev->ops->set_cur_state(cdev, cur_state);
> +		}
> +	} else {	/* below trip */
> +		list_for_each_entry(instance, &tz->cooling_devices, node) {
> +			if (instance->trip != trip)
> +				continue;
> +
> +			cdev = instance->cdev;
> +			cdev->ops->get_cur_state(cdev, &cur_state);
> +
> +			cur_state = cur_state > instance->lower ?
> +				    (cur_state - 1) : instance->lower;
> +			cdev->ops->set_cur_state(cdev, cur_state);
> +		}
> +	}
> +
> +	return;
> +}
>  /**
>   * thermal_zone_device_update - force an update of a thermal zone's state
>   * @ttz:	the thermal zone to update
> @@ -1086,9 +1161,6 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>  	int count, ret = 0;
>  	long temp, trip_temp;
>  	enum thermal_trip_type trip_type;
> -	struct thermal_cooling_device_instance *instance;
> -	struct thermal_cooling_device *cdev;
> -	unsigned long cur_state, max_state;
>  
>  	mutex_lock(&tz->lock);
>  
> @@ -1124,29 +1196,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>  					tz->ops->notify(tz, count, trip_type);
>  			break;
>  		case THERMAL_TRIP_ACTIVE:
> -			list_for_each_entry(instance, &tz->cooling_devices,
> -					    node) {
> -				if (instance->trip != count)
> -					continue;
> -
> -				cdev = instance->cdev;
> -
> -				cdev->ops->get_cur_state(cdev, &cur_state);
> -				cdev->ops->get_max_state(cdev, &max_state);
> -
> -				if (temp >= trip_temp)
> -					cur_state =
> -						cur_state < instance->upper ?
> -						(cur_state + 1) :
> -						instance->upper;
> -				else
> -					cur_state =
> -						cur_state > instance->lower ?
> -						(cur_state - 1) :
> -						instance->lower;
> -
> -				cdev->ops->set_cur_state(cdev, cur_state);
> -			}
> +			thermal_zone_trip_update(tz, count, temp);
>  			break;
>  		case THERMAL_TRIP_PASSIVE:
>  			if (temp >= trip_temp || tz->passive)
> 


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 13/13] Thermal: Introduce locking for cdev.thermal_instances list.
  2012-07-26  8:41 ` [PATCH V4 13/13] Thermal: Introduce locking for cdev.thermal_instances list Zhang Rui
@ 2012-07-26 20:13   ` Rafael J. Wysocki
  2012-08-20 15:45   ` Eduardo Valentin
  1 sibling, 0 replies; 45+ messages in thread
From: Rafael J. Wysocki @ 2012-07-26 20:13 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Matthew Garrett, Len Brown, R Durgadoss, Eduardo Valentin,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Thursday, July 26, 2012, Zhang Rui wrote:
> we need to go over all the thermal_instance list of a cooling device
> to decide which cooling state to put the cooling device to.
> 
> But at this time, as a cooling device may be referenced in multiple
> thermal zones, we need to lock the list first in case
> another thermal zone is updating this cooling device.
> 
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>

> ---
>  drivers/thermal/thermal_sys.c |    8 ++++++++
>  include/linux/thermal.h       |    1 +
>  2 files changed, 9 insertions(+)
> 
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index 7f3a891..356a59d 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -799,6 +799,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
>  		goto remove_symbol_link;
>  
>  	mutex_lock(&tz->lock);
> +	mutex_lock(&cdev->lock);
>  	list_for_each_entry(pos, &tz->thermal_instances, tz_node)
>  	    if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
>  		result = -EEXIST;
> @@ -808,6 +809,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
>  		list_add_tail(&dev->tz_node, &tz->thermal_instances);
>  		list_add_tail(&dev->cdev_node, &cdev->thermal_instances);
>  	}
> +	mutex_unlock(&cdev->lock);
>  	mutex_unlock(&tz->lock);
>  
>  	if (!result)
> @@ -840,14 +842,17 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
>  	struct thermal_instance *pos, *next;
>  
>  	mutex_lock(&tz->lock);
> +	mutex_lock(&cdev->lock);
>  	list_for_each_entry_safe(pos, next, &tz->thermal_instances, tz_node) {
>  		if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
>  			list_del(&pos->tz_node);
>  			list_del(&pos->cdev_node);
> +			mutex_unlock(&cdev->lock);
>  			mutex_unlock(&tz->lock);
>  			goto unbind;
>  		}
>  	}
> +	mutex_unlock(&cdev->lock);
>  	mutex_unlock(&tz->lock);
>  
>  	return -ENODEV;
> @@ -913,6 +918,7 @@ thermal_cooling_device_register(char *type, void *devdata,
>  	}
>  
>  	strcpy(cdev->type, type);
> +	mutex_init(&cdev->lock);
>  	INIT_LIST_HEAD(&cdev->thermal_instances);
>  	cdev->ops = ops;
>  	cdev->updated = true;
> @@ -1016,6 +1022,7 @@ static void thermal_cdev_do_update(struct thermal_cooling_device *cdev)
>  	if (cdev->updated)
>  		return;
>  
> +	mutex_lock(&cdev->lock);
>  	/* Make sure cdev enters the deepest cooling state */
>  	list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
>  		if (instance->target == THERMAL_NO_TARGET)
> @@ -1023,6 +1030,7 @@ static void thermal_cdev_do_update(struct thermal_cooling_device *cdev)
>  		if (instance->target > target)
>  			target = instance->target;
>  	}
> +	mutex_unlock(&cdev->lock);
>  	cdev->ops->set_cur_state(cdev, target);
>  	cdev->updated = true;
>  }
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index 06fd04d..d02d06d 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -95,6 +95,7 @@ struct thermal_cooling_device {
>  	void *devdata;
>  	const struct thermal_cooling_device_ops *ops;
>  	bool updated; /* true if the cooling device does not need update */
> +	struct mutex lock; /* protect thermal_instances list */
>  	struct list_head thermal_instances;
>  	struct list_head node;
>  };
> 


^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 04/13] Thermal: Introduce .get_trend() callback.
  2012-07-26 20:11   ` Rafael J. Wysocki
@ 2012-08-01  2:42     ` Zhang Rui
  2012-08-08 13:46       ` Valentin, Eduardo
  0 siblings, 1 reply; 45+ messages in thread
From: Zhang Rui @ 2012-08-01  2:42 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Matthew Garrett, Len Brown, R Durgadoss, Eduardo Valentin,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On 四, 2012-07-26 at 22:11 +0200, Rafael J. Wysocki wrote:
> On Thursday, July 26, 2012, Zhang Rui wrote:
> > 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.
> 
> As far as the code is concerned:
> 
> Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
> 
> I wonder, though, if there are any users of the thermal core currently in the
> tree who should introduce their own .get_trend() callbacks?
> 
No, for now.
But there will be soon. :)

thanks,
rui
> Rafael
> 
> 
> > Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> > ---
> >  drivers/acpi/thermal.c        |   33 +++++++++++++++++++++++++++++++++
> >  drivers/thermal/thermal_sys.c |   19 +++++++++++++++++--
> >  include/linux/thermal.h       |    9 +++++++++
> >  3 files changed, 59 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> > index b48ec3e..0c49e42 100644
> > --- a/drivers/acpi/thermal.c
> > +++ b/drivers/acpi/thermal.c
> > @@ -704,6 +704,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)
> >  {
> > @@ -836,6 +868,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,
> >  };
> >  
> > diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> > index 62b4279..68c93d4 100644
> > --- a/drivers/thermal/thermal_sys.c
> > +++ b/drivers/thermal/thermal_sys.c
> > @@ -723,6 +723,20 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
> >  	struct thermal_cooling_device *cdev;
> >  	long state, max_state;
> >  
> > +	if (!tz->ops->get_trend ||
> > +	    tz->ops->get_trend(tz, trip, (enum thermal_trend *)&trend)) {
> > +		/*
> > +		 * compare the current temperature and previous temperature
> > +		 * to get the thermal trend, if no special requirement
> > +		 */
> > +		if (tz->temperature > tz->last_temperature)
> > +			trend = THERMAL_TREND_RAISING;
> > +		else if (tz->temperature < tz->last_temperature)
> > +			trend = THERMAL_TREND_DROPPING;
> > +		else
> > +			trend = THERMAL_TREND_STABLE;
> > +	}
> > +
> >  	/*
> >  	 * Above Trip?
> >  	 * -----------
> > @@ -1091,6 +1105,9 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
> >  		goto leave;
> >  	}
> >  
> > +	tz->last_temperature = tz->temperature;
> > +	tz->temperature = temp;
> > +
> >  	for (count = 0; count < tz->trips; count++) {
> >  		tz->ops->get_trip_type(tz, count, &trip_type);
> >  		tz->ops->get_trip_temp(tz, count, &trip_temp);
> > @@ -1150,8 +1167,6 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
> >  		thermal_zone_device_passive(tz, temp, tz->forced_passive,
> >  					    THERMAL_TRIPS_NONE);
> >  
> > -	tz->last_temperature = temp;
> > -
> >  leave:
> >  	if (tz->passive)
> >  		thermal_zone_device_set_polling(tz, tz->passive_delay);
> > diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> > index a43b12c..a01e3e6 100644
> > --- a/include/linux/thermal.h
> > +++ b/include/linux/thermal.h
> > @@ -44,6 +44,12 @@ enum thermal_trip_type {
> >  	THERMAL_TRIP_CRITICAL,
> >  };
> >  
> > +enum thermal_trend {
> > +	THERMAL_TREND_STABLE, /* temperature is stable */
> > +	THERMAL_TREND_RAISING, /* temperature is raising */
> > +	THERMAL_TREND_DROPPING, /* temperature is dropping */
> > +};
> > +
> >  struct thermal_zone_device_ops {
> >  	int (*bind) (struct thermal_zone_device *,
> >  		     struct thermal_cooling_device *);
> > @@ -65,6 +71,8 @@ struct thermal_zone_device_ops {
> >  	int (*set_trip_hyst) (struct thermal_zone_device *, int,
> >  			      unsigned long);
> >  	int (*get_crit_temp) (struct thermal_zone_device *, unsigned long *);
> > +	int (*get_trend) (struct thermal_zone_device *, int,
> > +			  enum thermal_trend *);
> >  	int (*notify) (struct thermal_zone_device *, int,
> >  		       enum thermal_trip_type);
> >  };
> > @@ -111,6 +119,7 @@ struct thermal_zone_device {
> >  	int tc2;
> >  	int passive_delay;
> >  	int polling_delay;
> > +	int temperature;
> >  	int last_temperature;
> >  	bool passive;
> >  	unsigned int forced_passive;
> > 
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 01/13] Thermal: Introduce multiple cooling states support
  2012-07-26  8:41 ` [PATCH V4 01/13] Thermal: Introduce multiple cooling states support Zhang Rui
@ 2012-08-08 12:02   ` Valentin, Eduardo
  2012-08-09  0:58     ` Zhang Rui
  0 siblings, 1 reply; 45+ messages in thread
From: Valentin, Eduardo @ 2012-08-08 12:02 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

Hello Rui,

On Thu, Jul 26, 2012 at 11:41 AM, Zhang Rui <rui.zhang@intel.com> wrote:
> This is because general active cooling devices, like fans,
> may have multiple speeds, which can be mapped to different cooling states.
>
> Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>

> ---
>  drivers/thermal/thermal_sys.c |   12 ++++++++++--
>  1 file changed, 10 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index 2d7a9fe..05f42cd 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -1059,6 +1059,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>         enum thermal_trip_type trip_type;
>         struct thermal_cooling_device_instance *instance;
>         struct thermal_cooling_device *cdev;
> +       unsigned long cur_state, max_state;
>
>         mutex_lock(&tz->lock);
>
> @@ -1098,10 +1099,17 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>
>                                 cdev = instance->cdev;
>
> +                               cdev->ops->get_cur_state(cdev, &cur_state);
> +                               cdev->ops->get_max_state(cdev, &max_state);
> +
>                                 if (temp >= trip_temp)
> -                                       cdev->ops->set_cur_state(cdev, 1);
> +                                       cur_state = cur_state < max_state ?
> +                                               (cur_state + 1) : max_state;
>                                 else
> -                                       cdev->ops->set_cur_state(cdev, 0);
> +                                       cur_state = cur_state > 0 ?
> +                                               (cur_state - 1) : 0;
> +
> +                               cdev->ops->set_cur_state(cdev, cur_state);
>                         }
>                         break;
>                 case THERMAL_TRIP_PASSIVE:
> --
> 1.7.9.5
>



-- 

Eduardo Valentin

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 04/13] Thermal: Introduce .get_trend() callback.
  2012-07-26  8:41 ` [PATCH V4 04/13] Thermal: Introduce .get_trend() callback Zhang Rui
  2012-07-26 20:11   ` Rafael J. Wysocki
@ 2012-08-08 13:44   ` Valentin, Eduardo
  1 sibling, 0 replies; 45+ messages in thread
From: Valentin, Eduardo @ 2012-08-08 13:44 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

Hello,

On Thu, Jul 26, 2012 at 11:41 AM, Zhang Rui <rui.zhang@intel.com> wrote:
> 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 <rui.zhang@intel.com>

Looks good to me.

Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>

> ---
>  drivers/acpi/thermal.c        |   33 +++++++++++++++++++++++++++++++++
>  drivers/thermal/thermal_sys.c |   19 +++++++++++++++++--
>  include/linux/thermal.h       |    9 +++++++++
>  3 files changed, 59 insertions(+), 2 deletions(-)
>
> diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> index b48ec3e..0c49e42 100644
> --- a/drivers/acpi/thermal.c
> +++ b/drivers/acpi/thermal.c
> @@ -704,6 +704,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)
>  {
> @@ -836,6 +868,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,
>  };
>
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index 62b4279..68c93d4 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -723,6 +723,20 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>         struct thermal_cooling_device *cdev;
>         long state, max_state;
>
> +       if (!tz->ops->get_trend ||
> +           tz->ops->get_trend(tz, trip, (enum thermal_trend *)&trend)) {
> +               /*
> +                * compare the current temperature and previous temperature
> +                * to get the thermal trend, if no special requirement
> +                */
> +               if (tz->temperature > tz->last_temperature)
> +                       trend = THERMAL_TREND_RAISING;
> +               else if (tz->temperature < tz->last_temperature)
> +                       trend = THERMAL_TREND_DROPPING;
> +               else
> +                       trend = THERMAL_TREND_STABLE;
> +       }
> +
>         /*
>          * Above Trip?
>          * -----------
> @@ -1091,6 +1105,9 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>                 goto leave;
>         }
>
> +       tz->last_temperature = tz->temperature;
> +       tz->temperature = temp;
> +
>         for (count = 0; count < tz->trips; count++) {
>                 tz->ops->get_trip_type(tz, count, &trip_type);
>                 tz->ops->get_trip_temp(tz, count, &trip_temp);
> @@ -1150,8 +1167,6 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>                 thermal_zone_device_passive(tz, temp, tz->forced_passive,
>                                             THERMAL_TRIPS_NONE);
>
> -       tz->last_temperature = temp;
> -
>  leave:
>         if (tz->passive)
>                 thermal_zone_device_set_polling(tz, tz->passive_delay);
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index a43b12c..a01e3e6 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -44,6 +44,12 @@ enum thermal_trip_type {
>         THERMAL_TRIP_CRITICAL,
>  };
>
> +enum thermal_trend {
> +       THERMAL_TREND_STABLE, /* temperature is stable */
> +       THERMAL_TREND_RAISING, /* temperature is raising */
> +       THERMAL_TREND_DROPPING, /* temperature is dropping */
> +};
> +
>  struct thermal_zone_device_ops {
>         int (*bind) (struct thermal_zone_device *,
>                      struct thermal_cooling_device *);
> @@ -65,6 +71,8 @@ struct thermal_zone_device_ops {
>         int (*set_trip_hyst) (struct thermal_zone_device *, int,
>                               unsigned long);
>         int (*get_crit_temp) (struct thermal_zone_device *, unsigned long *);
> +       int (*get_trend) (struct thermal_zone_device *, int,
> +                         enum thermal_trend *);
>         int (*notify) (struct thermal_zone_device *, int,
>                        enum thermal_trip_type);
>  };
> @@ -111,6 +119,7 @@ struct thermal_zone_device {
>         int tc2;
>         int passive_delay;
>         int polling_delay;
> +       int temperature;
>         int last_temperature;
>         bool passive;
>         unsigned int forced_passive;
> --
> 1.7.9.5
>



-- 

Eduardo Valentin

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 04/13] Thermal: Introduce .get_trend() callback.
  2012-08-01  2:42     ` Zhang Rui
@ 2012-08-08 13:46       ` Valentin, Eduardo
  0 siblings, 0 replies; 45+ messages in thread
From: Valentin, Eduardo @ 2012-08-08 13:46 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

Hello Rui and Rafael,

On Wed, Aug 1, 2012 at 5:42 AM, Zhang Rui <rui.zhang@intel.com> wrote:
> On 四, 2012-07-26 at 22:11 +0200, Rafael J. Wysocki wrote:
>> On Thursday, July 26, 2012, Zhang Rui wrote:
>> > 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.
>>
>> As far as the code is concerned:
>>
>> Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
>>
>> I wonder, though, if there are any users of the thermal core currently in the
>> tree who should introduce their own .get_trend() callbacks?
>>
> No, for now.
> But there will be soon. :)

Yeah, one of them would be the OMAP5 thermal driver. But the code is
not implemented yet. Currently driver under staging area already
though: drivers/staging/omap-thermal/

>
> thanks,
> rui
>> Rafael
>>
>>
>> > Signed-off-by: Zhang Rui <rui.zhang@intel.com>
>> > ---
>> >  drivers/acpi/thermal.c        |   33 +++++++++++++++++++++++++++++++++
>> >  drivers/thermal/thermal_sys.c |   19 +++++++++++++++++--
>> >  include/linux/thermal.h       |    9 +++++++++
>> >  3 files changed, 59 insertions(+), 2 deletions(-)
>> >
>> > diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
>> > index b48ec3e..0c49e42 100644
>> > --- a/drivers/acpi/thermal.c
>> > +++ b/drivers/acpi/thermal.c
>> > @@ -704,6 +704,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)
>> >  {
>> > @@ -836,6 +868,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,
>> >  };
>> >
>> > diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
>> > index 62b4279..68c93d4 100644
>> > --- a/drivers/thermal/thermal_sys.c
>> > +++ b/drivers/thermal/thermal_sys.c
>> > @@ -723,6 +723,20 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>> >     struct thermal_cooling_device *cdev;
>> >     long state, max_state;
>> >
>> > +   if (!tz->ops->get_trend ||
>> > +       tz->ops->get_trend(tz, trip, (enum thermal_trend *)&trend)) {
>> > +           /*
>> > +            * compare the current temperature and previous temperature
>> > +            * to get the thermal trend, if no special requirement
>> > +            */
>> > +           if (tz->temperature > tz->last_temperature)
>> > +                   trend = THERMAL_TREND_RAISING;
>> > +           else if (tz->temperature < tz->last_temperature)
>> > +                   trend = THERMAL_TREND_DROPPING;
>> > +           else
>> > +                   trend = THERMAL_TREND_STABLE;
>> > +   }
>> > +
>> >     /*
>> >      * Above Trip?
>> >      * -----------
>> > @@ -1091,6 +1105,9 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>> >             goto leave;
>> >     }
>> >
>> > +   tz->last_temperature = tz->temperature;
>> > +   tz->temperature = temp;
>> > +
>> >     for (count = 0; count < tz->trips; count++) {
>> >             tz->ops->get_trip_type(tz, count, &trip_type);
>> >             tz->ops->get_trip_temp(tz, count, &trip_temp);
>> > @@ -1150,8 +1167,6 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>> >             thermal_zone_device_passive(tz, temp, tz->forced_passive,
>> >                                         THERMAL_TRIPS_NONE);
>> >
>> > -   tz->last_temperature = temp;
>> > -
>> >  leave:
>> >     if (tz->passive)
>> >             thermal_zone_device_set_polling(tz, tz->passive_delay);
>> > diff --git a/include/linux/thermal.h b/include/linux/thermal.h
>> > index a43b12c..a01e3e6 100644
>> > --- a/include/linux/thermal.h
>> > +++ b/include/linux/thermal.h
>> > @@ -44,6 +44,12 @@ enum thermal_trip_type {
>> >     THERMAL_TRIP_CRITICAL,
>> >  };
>> >
>> > +enum thermal_trend {
>> > +   THERMAL_TREND_STABLE, /* temperature is stable */
>> > +   THERMAL_TREND_RAISING, /* temperature is raising */
>> > +   THERMAL_TREND_DROPPING, /* temperature is dropping */
>> > +};
>> > +
>> >  struct thermal_zone_device_ops {
>> >     int (*bind) (struct thermal_zone_device *,
>> >                  struct thermal_cooling_device *);
>> > @@ -65,6 +71,8 @@ struct thermal_zone_device_ops {
>> >     int (*set_trip_hyst) (struct thermal_zone_device *, int,
>> >                           unsigned long);
>> >     int (*get_crit_temp) (struct thermal_zone_device *, unsigned long *);
>> > +   int (*get_trend) (struct thermal_zone_device *, int,
>> > +                     enum thermal_trend *);
>> >     int (*notify) (struct thermal_zone_device *, int,
>> >                    enum thermal_trip_type);
>> >  };
>> > @@ -111,6 +119,7 @@ struct thermal_zone_device {
>> >     int tc2;
>> >     int passive_delay;
>> >     int polling_delay;
>> > +   int temperature;
>> >     int last_temperature;
>> >     bool passive;
>> >     unsigned int forced_passive;
>> >
>>
>
>



-- 

Eduardo Valentin
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 05/13] Thermal: Remove tc1/tc2 in generic thermal layer.
  2012-07-26  8:41 ` [PATCH V4 05/13] Thermal: Remove tc1/tc2 in generic thermal layer Zhang Rui
  2012-07-26 20:11   ` Rafael J. Wysocki
@ 2012-08-08 14:06   ` Valentin, Eduardo
  2012-08-09  0:57     ` Zhang Rui
  1 sibling, 1 reply; 45+ messages in thread
From: Valentin, Eduardo @ 2012-08-08 14:06 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

Hello Rui,

On Thu, Jul 26, 2012 at 11:41 AM, Zhang Rui <rui.zhang@intel.com> wrote:
> Remove tc1/tc2 in generic thermal layer.
> .get_trend() callback starts to take effect from this patch.
>
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

I believe you have to refresh this patch. At least it is not applying
on 3.6-rc1. With minor changes I could check it though.

> ---
>  drivers/acpi/thermal.c                   |    5 +----
>  drivers/platform/x86/acerhdf.c           |    2 +-
>  drivers/platform/x86/intel_mid_thermal.c |    2 +-
>  drivers/thermal/spear_thermal.c          |    2 +-
>  drivers/thermal/thermal_sys.c            |   24 ++++++------------------
>  include/linux/thermal.h                  |    5 +----

Again, simple thing here is that it would be good if you include in
your patch the change on omap-thermal-common.c:
drivers/staging/omap-thermal/omap-thermal-common.c: In function
'omap_thermal_expose_sensor':
drivers/staging/omap-thermal/omap-thermal-common.c:251: error: too
many arguments to function 'thermal_zone_device_register'
make[3]: *** [drivers/staging/omap-thermal/omap-thermal-common.o] Error 1
make[2]: *** [drivers/staging/omap-thermal] Error 2
make[1]: *** [drivers/staging] Error 2
make[1]: *** Waiting for unfinished jobs....

And looks like you missed the psy_register_thermal (power_supply_core.c):

drivers/power/power_supply_core.c: In function 'psy_register_thermal':
drivers/power/power_supply_core.c:204: error: too many arguments to
function 'thermal_zone_device_register'
make[2]: *** [drivers/power/power_supply_core.o] Error 1
make[1]: *** [drivers/power] Error 2
make[1]: *** Waiting for unfinished jobs....
make: *** [drivers] Error 2
make: *** Waiting for unfinished jobs....


FYR:
diff --git a/drivers/power/power_supply_core.c
b/drivers/power/power_supply_core.c
index 08cc8a3..2436f13 100644
--- a/drivers/power/power_supply_core.c
+++ b/drivers/power/power_supply_core.c
@@ -201,7 +201,7 @@ static int psy_register_thermal(struct power_supply *psy)
        for (i = 0; i < psy->num_properties; i++) {
                if (psy->properties[i] == POWER_SUPPLY_PROP_TEMP) {
                        psy->tzd = thermal_zone_device_register(psy->name, 0, 0,
-                                       psy, &psy_tzd_ops, 0, 0, 0, 0);
+                                       psy, &psy_tzd_ops, 0, 0);
                        if (IS_ERR(psy->tzd))
                                return PTR_ERR(psy->tzd);
                        break;
diff --git a/drivers/staging/omap-thermal/omap-thermal-common.c
b/drivers/staging/omap-thermal/omap-thermal-common.c
index c1f00c6..b4cd6cc 100644
--- a/drivers/staging/omap-thermal/omap-thermal-common.c
+++ b/drivers/staging/omap-thermal/omap-thermal-common.c
@@ -248,7 +248,7 @@ int omap_thermal_expose_sensor(struct omap_bandgap
*bg_ptr, int id,
        /* Create thermal zone */
        data->omap_thermal = thermal_zone_device_register(domain,
                                OMAP_TRIP_NUMBER, 0, data, &omap_thermal_ops,
-                               0, FAST_TEMP_MONITORING_RATE, 0, 0);
+                               0, FAST_TEMP_MONITORING_RATE);
        if (IS_ERR_OR_NULL(data->omap_thermal)) {
                dev_err(bg_ptr->dev, "thermal zone device is NULL\n");
                return PTR_ERR(data->omap_thermal);

Apart from the compilation issues and the needed patch refresh, I am
good with the patch. And thanks for pushing this forward.

>  6 files changed, 11 insertions(+), 29 deletions(-)
>
> diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> index 0c49e42..0c755d2 100644
> --- a/drivers/acpi/thermal.c
> +++ b/drivers/acpi/thermal.c
> @@ -895,15 +895,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;
> diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
> index a207466..84c5688 100644
> --- a/drivers/platform/x86/acerhdf.c
> +++ b/drivers/platform/x86/acerhdf.c
> @@ -662,7 +662,7 @@ static int acerhdf_register_thermal(void)
>                 return -EINVAL;
>
>         thz_dev = thermal_zone_device_register("acerhdf", 1, 0, NULL,
> -                                             &acerhdf_dev_ops, 0, 0, 0,
> +                                             &acerhdf_dev_ops, 0,
>                                               (kernelmode) ? interval*1000 : 0);
>         if (IS_ERR(thz_dev))
>                 return -EINVAL;
> diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c
> index 2b2c212..6e309dd 100644
> --- a/drivers/platform/x86/intel_mid_thermal.c
> +++ b/drivers/platform/x86/intel_mid_thermal.c
> @@ -499,7 +499,7 @@ static int mid_thermal_probe(struct platform_device *pdev)
>                         goto err;
>                 }
>                 pinfo->tzd[i] = thermal_zone_device_register(name[i],
> -                               0, 0, td_info, &tzd_ops, 0, 0, 0, 0);
> +                               0, 0, td_info, &tzd_ops, 0, 0);
>                 if (IS_ERR(pinfo->tzd[i])) {
>                         kfree(td_info);
>                         ret = PTR_ERR(pinfo->tzd[i]);
> diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c
> index 69a55d4..b55840a 100644
> --- a/drivers/thermal/spear_thermal.c
> +++ b/drivers/thermal/spear_thermal.c
> @@ -148,7 +148,7 @@ static int spear_thermal_probe(struct platform_device *pdev)
>         writel_relaxed(stdev->flags, stdev->thermal_base);
>
>         spear_thermal = thermal_zone_device_register("spear_thermal", 0, 0,
> -                               stdev, &ops, 0, 0, 0, 0);
> +                               stdev, &ops, 0, 0);
>         if (IS_ERR(spear_thermal)) {
>                 dev_err(&pdev->dev, "thermal zone device is NULL\n");
>                 ret = PTR_ERR(spear_thermal);
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index 68c93d4..a70ed4c 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -335,9 +335,6 @@ passive_store(struct device *dev, struct device_attribute *attr,
>                 tz->passive_delay = 0;
>         }
>
> -       tz->tc1 = 1;
> -       tz->tc2 = 1;
> -
>         tz->forced_passive = state;
>
>         thermal_zone_device_update(tz);
> @@ -718,13 +715,12 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
>  static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>                                         int temp, int trip_temp, int trip)
>  {
> -       int trend = 0;
> +       enum thermal_trend trend;
>         struct thermal_cooling_device_instance *instance;
>         struct thermal_cooling_device *cdev;
>         long state, max_state;
>
> -       if (!tz->ops->get_trend ||
> -           tz->ops->get_trend(tz, trip, (enum thermal_trend *)&trend)) {
> +       if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
>                 /*
>                  * compare the current temperature and previous temperature
>                  * to get the thermal trend, if no special requirement
> @@ -747,11 +743,8 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>         if (temp >= trip_temp) {
>                 tz->passive = true;
>
> -               trend = (tz->tc1 * (temp - tz->last_temperature)) +
> -                       (tz->tc2 * (temp - trip_temp));
> -
>                 /* Heating up? */
> -               if (trend > 0) {
> +               if (trend == THERMAL_TREND_RAISING) {
>                         list_for_each_entry(instance, &tz->cooling_devices,
>                                             node) {
>                                 if (instance->trip != trip)
> @@ -762,7 +755,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>                                 if (state++ < max_state)
>                                         cdev->ops->set_cur_state(cdev, state);
>                         }
> -               } else if (trend < 0) { /* Cooling off? */
> +               } else if (trend == THERMAL_TREND_DROPPING) { /* Cooling off? */
>                         list_for_each_entry(instance, &tz->cooling_devices,
>                                             node) {
>                                 if (instance->trip != trip)
> @@ -1288,8 +1281,6 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
>   * @mask:      a bit string indicating the writeablility of trip points
>   * @devdata:   private device data
>   * @ops:       standard thermal zone device callbacks
> - * @tc1:       thermal coefficient 1 for passive calculations
> - * @tc2:       thermal coefficient 2 for passive calculations
>   * @passive_delay: number of milliseconds to wait between polls when
>   *                performing passive cooling
>   * @polling_delay: number of milliseconds to wait between polls when checking
> @@ -1297,13 +1288,12 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
>   *                driven systems)
>   *
>   * thermal_zone_device_unregister() must be called when the device is no
> - * longer needed. The passive cooling formula uses tc1 and tc2 as described in
> - * section 11.1.5.1 of the ACPI specification 3.0.
> + * longer needed. The passive cooling depends on the .get_trend() return value.
>   */
>  struct thermal_zone_device *thermal_zone_device_register(char *type,
>         int trips, int mask, void *devdata,
>         const struct thermal_zone_device_ops *ops,
> -       int tc1, int tc2, int passive_delay, int polling_delay)
> +       int passive_delay, int polling_delay)
>  {
>         struct thermal_zone_device *tz;
>         struct thermal_cooling_device *pos;
> @@ -1339,8 +1329,6 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
>         tz->device.class = &thermal_class;
>         tz->devdata = devdata;
>         tz->trips = trips;
> -       tz->tc1 = tc1;
> -       tz->tc2 = tc2;
>         tz->passive_delay = passive_delay;
>         tz->polling_delay = polling_delay;
>
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index a01e3e6..d18dcf6 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -115,8 +115,6 @@ struct thermal_zone_device {
>         struct thermal_attr *trip_hyst_attrs;
>         void *devdata;
>         int trips;
> -       int tc1;
> -       int tc2;
>         int passive_delay;
>         int polling_delay;
>         int temperature;
> @@ -163,8 +161,7 @@ enum {
>  #define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
>
>  struct thermal_zone_device *thermal_zone_device_register(char *, int, int,
> -               void *, const struct thermal_zone_device_ops *, int tc1,
> -               int tc2, int passive_freq, int polling_freq);
> +               void *, const struct thermal_zone_device_ops *, int, int);
>  void thermal_zone_device_unregister(struct thermal_zone_device *);
>
>  int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
> --
> 1.7.9.5
>



-- 

Eduardo Valentin

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 05/13] Thermal: Remove tc1/tc2 in generic thermal layer.
  2012-08-08 14:06   ` Valentin, Eduardo
@ 2012-08-09  0:57     ` Zhang Rui
  2012-08-09  8:05       ` Valentin, Eduardo
  2012-08-09 15:10       ` Valentin, Eduardo
  0 siblings, 2 replies; 45+ messages in thread
From: Zhang Rui @ 2012-08-09  0:57 UTC (permalink / raw)
  To: Valentin, Eduardo
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On 三, 2012-08-08 at 17:06 +0300, Valentin, Eduardo wrote:
> Hello Rui,
> 
> On Thu, Jul 26, 2012 at 11:41 AM, Zhang Rui <rui.zhang@intel.com> wrote:
> > Remove tc1/tc2 in generic thermal layer.
> > .get_trend() callback starts to take effect from this patch.
> >
> > Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> 
> I believe you have to refresh this patch. At least it is not applying
> on 3.6-rc1. With minor changes I could check it though.
> 
> > ---
> >  drivers/acpi/thermal.c                   |    5 +----
> >  drivers/platform/x86/acerhdf.c           |    2 +-
> >  drivers/platform/x86/intel_mid_thermal.c |    2 +-
> >  drivers/thermal/spear_thermal.c          |    2 +-
> >  drivers/thermal/thermal_sys.c            |   24 ++++++------------------
> >  include/linux/thermal.h                  |    5 +----
> 
> Again, simple thing here is that it would be good if you include in
> your patch the change on omap-thermal-common.c:
> drivers/staging/omap-thermal/omap-thermal-common.c: In function
> 'omap_thermal_expose_sensor':
> drivers/staging/omap-thermal/omap-thermal-common.c:251: error: too
> many arguments to function 'thermal_zone_device_register'
> make[3]: *** [drivers/staging/omap-thermal/omap-thermal-common.o] Error 1
> make[2]: *** [drivers/staging/omap-thermal] Error 2
> make[1]: *** [drivers/staging] Error 2
> make[1]: *** Waiting for unfinished jobs....
> 
> And looks like you missed the psy_register_thermal (power_supply_core.c):
> 
> drivers/power/power_supply_core.c: In function 'psy_register_thermal':
> drivers/power/power_supply_core.c:204: error: too many arguments to
> function 'thermal_zone_device_register'
> make[2]: *** [drivers/power/power_supply_core.o] Error 1
> make[1]: *** [drivers/power] Error 2
> make[1]: *** Waiting for unfinished jobs....
> make: *** [drivers] Error 2
> make: *** Waiting for unfinished jobs....
> 
> 
> FYR:
> diff --git a/drivers/power/power_supply_core.c
> b/drivers/power/power_supply_core.c
> index 08cc8a3..2436f13 100644
> --- a/drivers/power/power_supply_core.c
> +++ b/drivers/power/power_supply_core.c
> @@ -201,7 +201,7 @@ static int psy_register_thermal(struct power_supply *psy)
>         for (i = 0; i < psy->num_properties; i++) {
>                 if (psy->properties[i] == POWER_SUPPLY_PROP_TEMP) {
>                         psy->tzd = thermal_zone_device_register(psy->name, 0, 0,
> -                                       psy, &psy_tzd_ops, 0, 0, 0, 0);
> +                                       psy, &psy_tzd_ops, 0, 0);
>                         if (IS_ERR(psy->tzd))
>                                 return PTR_ERR(psy->tzd);
>                         break;

I have fixed this one in my git tree.

> diff --git a/drivers/staging/omap-thermal/omap-thermal-common.c
> b/drivers/staging/omap-thermal/omap-thermal-common.c
> index c1f00c6..b4cd6cc 100644
> --- a/drivers/staging/omap-thermal/omap-thermal-common.c
> +++ b/drivers/staging/omap-thermal/omap-thermal-common.c
> @@ -248,7 +248,7 @@ int omap_thermal_expose_sensor(struct omap_bandgap
> *bg_ptr, int id,
>         /* Create thermal zone */
>         data->omap_thermal = thermal_zone_device_register(domain,
>                                 OMAP_TRIP_NUMBER, 0, data, &omap_thermal_ops,
> -                               0, FAST_TEMP_MONITORING_RATE, 0, 0);
> +                               0, FAST_TEMP_MONITORING_RATE);
hmm, FAST_TEMP_MONITORING_RATE is the polling frequency and you put it
in the wrong place in your original code, right?

>         if (IS_ERR_OR_NULL(data->omap_thermal)) {
>                 dev_err(bg_ptr->dev, "thermal zone device is NULL\n");
>                 return PTR_ERR(data->omap_thermal);
> 
I missed this one. :)
I'll fixed it in my tree.

thanks,
rui
> Apart from the compilation issues and the needed patch refresh, I am
> good with the patch. And thanks for pushing this forward.
> 
> >  6 files changed, 11 insertions(+), 29 deletions(-)
> >
> > diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> > index 0c49e42..0c755d2 100644
> > --- a/drivers/acpi/thermal.c
> > +++ b/drivers/acpi/thermal.c
> > @@ -895,15 +895,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;
> > diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
> > index a207466..84c5688 100644
> > --- a/drivers/platform/x86/acerhdf.c
> > +++ b/drivers/platform/x86/acerhdf.c
> > @@ -662,7 +662,7 @@ static int acerhdf_register_thermal(void)
> >                 return -EINVAL;
> >
> >         thz_dev = thermal_zone_device_register("acerhdf", 1, 0, NULL,
> > -                                             &acerhdf_dev_ops, 0, 0, 0,
> > +                                             &acerhdf_dev_ops, 0,
> >                                               (kernelmode) ? interval*1000 : 0);
> >         if (IS_ERR(thz_dev))
> >                 return -EINVAL;
> > diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c
> > index 2b2c212..6e309dd 100644
> > --- a/drivers/platform/x86/intel_mid_thermal.c
> > +++ b/drivers/platform/x86/intel_mid_thermal.c
> > @@ -499,7 +499,7 @@ static int mid_thermal_probe(struct platform_device *pdev)
> >                         goto err;
> >                 }
> >                 pinfo->tzd[i] = thermal_zone_device_register(name[i],
> > -                               0, 0, td_info, &tzd_ops, 0, 0, 0, 0);
> > +                               0, 0, td_info, &tzd_ops, 0, 0);
> >                 if (IS_ERR(pinfo->tzd[i])) {
> >                         kfree(td_info);
> >                         ret = PTR_ERR(pinfo->tzd[i]);
> > diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c
> > index 69a55d4..b55840a 100644
> > --- a/drivers/thermal/spear_thermal.c
> > +++ b/drivers/thermal/spear_thermal.c
> > @@ -148,7 +148,7 @@ static int spear_thermal_probe(struct platform_device *pdev)
> >         writel_relaxed(stdev->flags, stdev->thermal_base);
> >
> >         spear_thermal = thermal_zone_device_register("spear_thermal", 0, 0,
> > -                               stdev, &ops, 0, 0, 0, 0);
> > +                               stdev, &ops, 0, 0);
> >         if (IS_ERR(spear_thermal)) {
> >                 dev_err(&pdev->dev, "thermal zone device is NULL\n");
> >                 ret = PTR_ERR(spear_thermal);
> > diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> > index 68c93d4..a70ed4c 100644
> > --- a/drivers/thermal/thermal_sys.c
> > +++ b/drivers/thermal/thermal_sys.c
> > @@ -335,9 +335,6 @@ passive_store(struct device *dev, struct device_attribute *attr,
> >                 tz->passive_delay = 0;
> >         }
> >
> > -       tz->tc1 = 1;
> > -       tz->tc2 = 1;
> > -
> >         tz->forced_passive = state;
> >
> >         thermal_zone_device_update(tz);
> > @@ -718,13 +715,12 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
> >  static void thermal_zone_device_passive(struct thermal_zone_device *tz,
> >                                         int temp, int trip_temp, int trip)
> >  {
> > -       int trend = 0;
> > +       enum thermal_trend trend;
> >         struct thermal_cooling_device_instance *instance;
> >         struct thermal_cooling_device *cdev;
> >         long state, max_state;
> >
> > -       if (!tz->ops->get_trend ||
> > -           tz->ops->get_trend(tz, trip, (enum thermal_trend *)&trend)) {
> > +       if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
> >                 /*
> >                  * compare the current temperature and previous temperature
> >                  * to get the thermal trend, if no special requirement
> > @@ -747,11 +743,8 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
> >         if (temp >= trip_temp) {
> >                 tz->passive = true;
> >
> > -               trend = (tz->tc1 * (temp - tz->last_temperature)) +
> > -                       (tz->tc2 * (temp - trip_temp));
> > -
> >                 /* Heating up? */
> > -               if (trend > 0) {
> > +               if (trend == THERMAL_TREND_RAISING) {
> >                         list_for_each_entry(instance, &tz->cooling_devices,
> >                                             node) {
> >                                 if (instance->trip != trip)
> > @@ -762,7 +755,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
> >                                 if (state++ < max_state)
> >                                         cdev->ops->set_cur_state(cdev, state);
> >                         }
> > -               } else if (trend < 0) { /* Cooling off? */
> > +               } else if (trend == THERMAL_TREND_DROPPING) { /* Cooling off? */
> >                         list_for_each_entry(instance, &tz->cooling_devices,
> >                                             node) {
> >                                 if (instance->trip != trip)
> > @@ -1288,8 +1281,6 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
> >   * @mask:      a bit string indicating the writeablility of trip points
> >   * @devdata:   private device data
> >   * @ops:       standard thermal zone device callbacks
> > - * @tc1:       thermal coefficient 1 for passive calculations
> > - * @tc2:       thermal coefficient 2 for passive calculations
> >   * @passive_delay: number of milliseconds to wait between polls when
> >   *                performing passive cooling
> >   * @polling_delay: number of milliseconds to wait between polls when checking
> > @@ -1297,13 +1288,12 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
> >   *                driven systems)
> >   *
> >   * thermal_zone_device_unregister() must be called when the device is no
> > - * longer needed. The passive cooling formula uses tc1 and tc2 as described in
> > - * section 11.1.5.1 of the ACPI specification 3.0.
> > + * longer needed. The passive cooling depends on the .get_trend() return value.
> >   */
> >  struct thermal_zone_device *thermal_zone_device_register(char *type,
> >         int trips, int mask, void *devdata,
> >         const struct thermal_zone_device_ops *ops,
> > -       int tc1, int tc2, int passive_delay, int polling_delay)
> > +       int passive_delay, int polling_delay)
> >  {
> >         struct thermal_zone_device *tz;
> >         struct thermal_cooling_device *pos;
> > @@ -1339,8 +1329,6 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
> >         tz->device.class = &thermal_class;
> >         tz->devdata = devdata;
> >         tz->trips = trips;
> > -       tz->tc1 = tc1;
> > -       tz->tc2 = tc2;
> >         tz->passive_delay = passive_delay;
> >         tz->polling_delay = polling_delay;
> >
> > diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> > index a01e3e6..d18dcf6 100644
> > --- a/include/linux/thermal.h
> > +++ b/include/linux/thermal.h
> > @@ -115,8 +115,6 @@ struct thermal_zone_device {
> >         struct thermal_attr *trip_hyst_attrs;
> >         void *devdata;
> >         int trips;
> > -       int tc1;
> > -       int tc2;
> >         int passive_delay;
> >         int polling_delay;
> >         int temperature;
> > @@ -163,8 +161,7 @@ enum {
> >  #define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
> >
> >  struct thermal_zone_device *thermal_zone_device_register(char *, int, int,
> > -               void *, const struct thermal_zone_device_ops *, int tc1,
> > -               int tc2, int passive_freq, int polling_freq);
> > +               void *, const struct thermal_zone_device_ops *, int, int);
> >  void thermal_zone_device_unregister(struct thermal_zone_device *);
> >
> >  int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
> > --
> > 1.7.9.5
> >
> 
> 
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 01/13] Thermal: Introduce multiple cooling states support
  2012-08-08 12:02   ` Valentin, Eduardo
@ 2012-08-09  0:58     ` Zhang Rui
  0 siblings, 0 replies; 45+ messages in thread
From: Zhang Rui @ 2012-08-09  0:58 UTC (permalink / raw)
  To: Valentin, Eduardo
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On 三, 2012-08-08 at 15:02 +0300, Valentin, Eduardo wrote:
> Hello Rui,
> 
> On Thu, Jul 26, 2012 at 11:41 AM, Zhang Rui <rui.zhang@intel.com> wrote:
> > This is because general active cooling devices, like fans,
> > may have multiple speeds, which can be mapped to different cooling states.
> >
> > Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
> > Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> 
> Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>
> 
thanks!

-rui
> > ---
> >  drivers/thermal/thermal_sys.c |   12 ++++++++++--
> >  1 file changed, 10 insertions(+), 2 deletions(-)
> >
> > diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> > index 2d7a9fe..05f42cd 100644
> > --- a/drivers/thermal/thermal_sys.c
> > +++ b/drivers/thermal/thermal_sys.c
> > @@ -1059,6 +1059,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
> >         enum thermal_trip_type trip_type;
> >         struct thermal_cooling_device_instance *instance;
> >         struct thermal_cooling_device *cdev;
> > +       unsigned long cur_state, max_state;
> >
> >         mutex_lock(&tz->lock);
> >
> > @@ -1098,10 +1099,17 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
> >
> >                                 cdev = instance->cdev;
> >
> > +                               cdev->ops->get_cur_state(cdev, &cur_state);
> > +                               cdev->ops->get_max_state(cdev, &max_state);
> > +
> >                                 if (temp >= trip_temp)
> > -                                       cdev->ops->set_cur_state(cdev, 1);
> > +                                       cur_state = cur_state < max_state ?
> > +                                               (cur_state + 1) : max_state;
> >                                 else
> > -                                       cdev->ops->set_cur_state(cdev, 0);
> > +                                       cur_state = cur_state > 0 ?
> > +                                               (cur_state - 1) : 0;
> > +
> > +                               cdev->ops->set_cur_state(cdev, cur_state);
> >                         }
> >                         break;
> >                 case THERMAL_TRIP_PASSIVE:
> > --
> > 1.7.9.5
> >
> 
> 
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 05/13] Thermal: Remove tc1/tc2 in generic thermal layer.
  2012-08-09  0:57     ` Zhang Rui
@ 2012-08-09  8:05       ` Valentin, Eduardo
  2012-08-09 15:10       ` Valentin, Eduardo
  1 sibling, 0 replies; 45+ messages in thread
From: Valentin, Eduardo @ 2012-08-09  8:05 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

Hello,

On Thu, Aug 9, 2012 at 3:57 AM, Zhang Rui <rui.zhang@intel.com> wrote:
> On 三, 2012-08-08 at 17:06 +0300, Valentin, Eduardo wrote:
>> Hello Rui,
>>
>> On Thu, Jul 26, 2012 at 11:41 AM, Zhang Rui <rui.zhang@intel.com> wrote:
>> > Remove tc1/tc2 in generic thermal layer.
>> > .get_trend() callback starts to take effect from this patch.
>> >
>> > Signed-off-by: Zhang Rui <rui.zhang@intel.com>
>>
>> I believe you have to refresh this patch. At least it is not applying
>> on 3.6-rc1. With minor changes I could check it though.
>>
>> > ---
>> >  drivers/acpi/thermal.c                   |    5 +----
>> >  drivers/platform/x86/acerhdf.c           |    2 +-
>> >  drivers/platform/x86/intel_mid_thermal.c |    2 +-
>> >  drivers/thermal/spear_thermal.c          |    2 +-
>> >  drivers/thermal/thermal_sys.c            |   24 ++++++------------------
>> >  include/linux/thermal.h                  |    5 +----
>>
>> Again, simple thing here is that it would be good if you include in
>> your patch the change on omap-thermal-common.c:
>> drivers/staging/omap-thermal/omap-thermal-common.c: In function
>> 'omap_thermal_expose_sensor':
>> drivers/staging/omap-thermal/omap-thermal-common.c:251: error: too
>> many arguments to function 'thermal_zone_device_register'
>> make[3]: *** [drivers/staging/omap-thermal/omap-thermal-common.o] Error 1
>> make[2]: *** [drivers/staging/omap-thermal] Error 2
>> make[1]: *** [drivers/staging] Error 2
>> make[1]: *** Waiting for unfinished jobs....
>>
>> And looks like you missed the psy_register_thermal (power_supply_core.c):
>>
>> drivers/power/power_supply_core.c: In function 'psy_register_thermal':
>> drivers/power/power_supply_core.c:204: error: too many arguments to
>> function 'thermal_zone_device_register'
>> make[2]: *** [drivers/power/power_supply_core.o] Error 1
>> make[1]: *** [drivers/power] Error 2
>> make[1]: *** Waiting for unfinished jobs....
>> make: *** [drivers] Error 2
>> make: *** Waiting for unfinished jobs....
>>
>>
>> FYR:
>> diff --git a/drivers/power/power_supply_core.c
>> b/drivers/power/power_supply_core.c
>> index 08cc8a3..2436f13 100644
>> --- a/drivers/power/power_supply_core.c
>> +++ b/drivers/power/power_supply_core.c
>> @@ -201,7 +201,7 @@ static int psy_register_thermal(struct power_supply *psy)
>>         for (i = 0; i < psy->num_properties; i++) {
>>                 if (psy->properties[i] == POWER_SUPPLY_PROP_TEMP) {
>>                         psy->tzd = thermal_zone_device_register(psy->name, 0, 0,
>> -                                       psy, &psy_tzd_ops, 0, 0, 0, 0);
>> +                                       psy, &psy_tzd_ops, 0, 0);
>>                         if (IS_ERR(psy->tzd))
>>                                 return PTR_ERR(psy->tzd);
>>                         break;
>
> I have fixed this one in my git tree.
>
>> diff --git a/drivers/staging/omap-thermal/omap-thermal-common.c
>> b/drivers/staging/omap-thermal/omap-thermal-common.c
>> index c1f00c6..b4cd6cc 100644
>> --- a/drivers/staging/omap-thermal/omap-thermal-common.c
>> +++ b/drivers/staging/omap-thermal/omap-thermal-common.c
>> @@ -248,7 +248,7 @@ int omap_thermal_expose_sensor(struct omap_bandgap
>> *bg_ptr, int id,
>>         /* Create thermal zone */
>>         data->omap_thermal = thermal_zone_device_register(domain,
>>                                 OMAP_TRIP_NUMBER, 0, data, &omap_thermal_ops,
>> -                               0, FAST_TEMP_MONITORING_RATE, 0, 0);
>> +                               0, FAST_TEMP_MONITORING_RATE);
> hmm, FAST_TEMP_MONITORING_RATE is the polling frequency and you put it
> in the wrong place in your original code, right?

Yeah, you are right. That was a bug.

>
>>         if (IS_ERR_OR_NULL(data->omap_thermal)) {
>>                 dev_err(bg_ptr->dev, "thermal zone device is NULL\n");
>>                 return PTR_ERR(data->omap_thermal);
>>
> I missed this one. :)
> I'll fixed it in my tree.
>
> thanks,
> rui
>> Apart from the compilation issues and the needed patch refresh, I am
>> good with the patch. And thanks for pushing this forward.
>>
>> >  6 files changed, 11 insertions(+), 29 deletions(-)
>> >
>> > diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
>> > index 0c49e42..0c755d2 100644
>> > --- a/drivers/acpi/thermal.c
>> > +++ b/drivers/acpi/thermal.c
>> > @@ -895,15 +895,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;
>> > diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
>> > index a207466..84c5688 100644
>> > --- a/drivers/platform/x86/acerhdf.c
>> > +++ b/drivers/platform/x86/acerhdf.c
>> > @@ -662,7 +662,7 @@ static int acerhdf_register_thermal(void)
>> >                 return -EINVAL;
>> >
>> >         thz_dev = thermal_zone_device_register("acerhdf", 1, 0, NULL,
>> > -                                             &acerhdf_dev_ops, 0, 0, 0,
>> > +                                             &acerhdf_dev_ops, 0,
>> >                                               (kernelmode) ? interval*1000 : 0);
>> >         if (IS_ERR(thz_dev))
>> >                 return -EINVAL;
>> > diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c
>> > index 2b2c212..6e309dd 100644
>> > --- a/drivers/platform/x86/intel_mid_thermal.c
>> > +++ b/drivers/platform/x86/intel_mid_thermal.c
>> > @@ -499,7 +499,7 @@ static int mid_thermal_probe(struct platform_device *pdev)
>> >                         goto err;
>> >                 }
>> >                 pinfo->tzd[i] = thermal_zone_device_register(name[i],
>> > -                               0, 0, td_info, &tzd_ops, 0, 0, 0, 0);
>> > +                               0, 0, td_info, &tzd_ops, 0, 0);
>> >                 if (IS_ERR(pinfo->tzd[i])) {
>> >                         kfree(td_info);
>> >                         ret = PTR_ERR(pinfo->tzd[i]);
>> > diff --git a/drivers/thermal/spear_thermal.c b/drivers/thermal/spear_thermal.c
>> > index 69a55d4..b55840a 100644
>> > --- a/drivers/thermal/spear_thermal.c
>> > +++ b/drivers/thermal/spear_thermal.c
>> > @@ -148,7 +148,7 @@ static int spear_thermal_probe(struct platform_device *pdev)
>> >         writel_relaxed(stdev->flags, stdev->thermal_base);
>> >
>> >         spear_thermal = thermal_zone_device_register("spear_thermal", 0, 0,
>> > -                               stdev, &ops, 0, 0, 0, 0);
>> > +                               stdev, &ops, 0, 0);
>> >         if (IS_ERR(spear_thermal)) {
>> >                 dev_err(&pdev->dev, "thermal zone device is NULL\n");
>> >                 ret = PTR_ERR(spear_thermal);
>> > diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
>> > index 68c93d4..a70ed4c 100644
>> > --- a/drivers/thermal/thermal_sys.c
>> > +++ b/drivers/thermal/thermal_sys.c
>> > @@ -335,9 +335,6 @@ passive_store(struct device *dev, struct device_attribute *attr,
>> >                 tz->passive_delay = 0;
>> >         }
>> >
>> > -       tz->tc1 = 1;
>> > -       tz->tc2 = 1;
>> > -
>> >         tz->forced_passive = state;
>> >
>> >         thermal_zone_device_update(tz);
>> > @@ -718,13 +715,12 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
>> >  static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>> >                                         int temp, int trip_temp, int trip)
>> >  {
>> > -       int trend = 0;
>> > +       enum thermal_trend trend;
>> >         struct thermal_cooling_device_instance *instance;
>> >         struct thermal_cooling_device *cdev;
>> >         long state, max_state;
>> >
>> > -       if (!tz->ops->get_trend ||
>> > -           tz->ops->get_trend(tz, trip, (enum thermal_trend *)&trend)) {
>> > +       if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
>> >                 /*
>> >                  * compare the current temperature and previous temperature
>> >                  * to get the thermal trend, if no special requirement
>> > @@ -747,11 +743,8 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>> >         if (temp >= trip_temp) {
>> >                 tz->passive = true;
>> >
>> > -               trend = (tz->tc1 * (temp - tz->last_temperature)) +
>> > -                       (tz->tc2 * (temp - trip_temp));
>> > -
>> >                 /* Heating up? */
>> > -               if (trend > 0) {
>> > +               if (trend == THERMAL_TREND_RAISING) {
>> >                         list_for_each_entry(instance, &tz->cooling_devices,
>> >                                             node) {
>> >                                 if (instance->trip != trip)
>> > @@ -762,7 +755,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>> >                                 if (state++ < max_state)
>> >                                         cdev->ops->set_cur_state(cdev, state);
>> >                         }
>> > -               } else if (trend < 0) { /* Cooling off? */
>> > +               } else if (trend == THERMAL_TREND_DROPPING) { /* Cooling off? */
>> >                         list_for_each_entry(instance, &tz->cooling_devices,
>> >                                             node) {
>> >                                 if (instance->trip != trip)
>> > @@ -1288,8 +1281,6 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
>> >   * @mask:      a bit string indicating the writeablility of trip points
>> >   * @devdata:   private device data
>> >   * @ops:       standard thermal zone device callbacks
>> > - * @tc1:       thermal coefficient 1 for passive calculations
>> > - * @tc2:       thermal coefficient 2 for passive calculations
>> >   * @passive_delay: number of milliseconds to wait between polls when
>> >   *                performing passive cooling
>> >   * @polling_delay: number of milliseconds to wait between polls when checking
>> > @@ -1297,13 +1288,12 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
>> >   *                driven systems)
>> >   *
>> >   * thermal_zone_device_unregister() must be called when the device is no
>> > - * longer needed. The passive cooling formula uses tc1 and tc2 as described in
>> > - * section 11.1.5.1 of the ACPI specification 3.0.
>> > + * longer needed. The passive cooling depends on the .get_trend() return value.
>> >   */
>> >  struct thermal_zone_device *thermal_zone_device_register(char *type,
>> >         int trips, int mask, void *devdata,
>> >         const struct thermal_zone_device_ops *ops,
>> > -       int tc1, int tc2, int passive_delay, int polling_delay)
>> > +       int passive_delay, int polling_delay)
>> >  {
>> >         struct thermal_zone_device *tz;
>> >         struct thermal_cooling_device *pos;
>> > @@ -1339,8 +1329,6 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
>> >         tz->device.class = &thermal_class;
>> >         tz->devdata = devdata;
>> >         tz->trips = trips;
>> > -       tz->tc1 = tc1;
>> > -       tz->tc2 = tc2;
>> >         tz->passive_delay = passive_delay;
>> >         tz->polling_delay = polling_delay;
>> >
>> > diff --git a/include/linux/thermal.h b/include/linux/thermal.h
>> > index a01e3e6..d18dcf6 100644
>> > --- a/include/linux/thermal.h
>> > +++ b/include/linux/thermal.h
>> > @@ -115,8 +115,6 @@ struct thermal_zone_device {
>> >         struct thermal_attr *trip_hyst_attrs;
>> >         void *devdata;
>> >         int trips;
>> > -       int tc1;
>> > -       int tc2;
>> >         int passive_delay;
>> >         int polling_delay;
>> >         int temperature;
>> > @@ -163,8 +161,7 @@ enum {
>> >  #define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
>> >
>> >  struct thermal_zone_device *thermal_zone_device_register(char *, int, int,
>> > -               void *, const struct thermal_zone_device_ops *, int tc1,
>> > -               int tc2, int passive_freq, int polling_freq);
>> > +               void *, const struct thermal_zone_device_ops *, int, int);
>> >  void thermal_zone_device_unregister(struct thermal_zone_device *);
>> >
>> >  int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
>> > --
>> > 1.7.9.5
>> >
>>
>>
>>
>
>



-- 

Eduardo Valentin
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 05/13] Thermal: Remove tc1/tc2 in generic thermal layer.
  2012-08-09  0:57     ` Zhang Rui
  2012-08-09  8:05       ` Valentin, Eduardo
@ 2012-08-09 15:10       ` Valentin, Eduardo
  2012-08-20 12:18         ` Eduardo Valentin
  1 sibling, 1 reply; 45+ messages in thread
From: Valentin, Eduardo @ 2012-08-09 15:10 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

Hello,

On Thu, Aug 9, 2012 at 3:57 AM, Zhang Rui <rui.zhang@intel.com> wrote:
>
> On 三, 2012-08-08 at 17:06 +0300, Valentin, Eduardo wrote:
> > Hello Rui,
> >
> > On Thu, Jul 26, 2012 at 11:41 AM, Zhang Rui <rui.zhang@intel.com> wrote:
> > > Remove tc1/tc2 in generic thermal layer.
> > > .get_trend() callback starts to take effect from this patch.
> > >
> > > Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> >
> > I believe you have to refresh this patch. At least it is not applying
> > on 3.6-rc1. With minor changes I could check it though.
> >
> > > ---
> > >  drivers/acpi/thermal.c                   |    5 +----
> > >  drivers/platform/x86/acerhdf.c           |    2 +-
> > >  drivers/platform/x86/intel_mid_thermal.c |    2 +-
> > >  drivers/thermal/spear_thermal.c          |    2 +-
> > >  drivers/thermal/thermal_sys.c            |   24
> > > ++++++------------------
> > >  include/linux/thermal.h                  |    5 +----
> >
> > Again, simple thing here is that it would be good if you include in
> > your patch the change on omap-thermal-common.c:
> > drivers/staging/omap-thermal/omap-thermal-common.c: In function
> > 'omap_thermal_expose_sensor':
> > drivers/staging/omap-thermal/omap-thermal-common.c:251: error: too
> > many arguments to function 'thermal_zone_device_register'
> > make[3]: *** [drivers/staging/omap-thermal/omap-thermal-common.o] Error
> > 1
> > make[2]: *** [drivers/staging/omap-thermal] Error 2
> > make[1]: *** [drivers/staging] Error 2
> > make[1]: *** Waiting for unfinished jobs....
> >
> > And looks like you missed the psy_register_thermal
> > (power_supply_core.c):
> >
> > drivers/power/power_supply_core.c: In function 'psy_register_thermal':
> > drivers/power/power_supply_core.c:204: error: too many arguments to
> > function 'thermal_zone_device_register'
> > make[2]: *** [drivers/power/power_supply_core.o] Error 1
> > make[1]: *** [drivers/power] Error 2
> > make[1]: *** Waiting for unfinished jobs....
> > make: *** [drivers] Error 2
> > make: *** Waiting for unfinished jobs....
> >
> >
> > FYR:
> > diff --git a/drivers/power/power_supply_core.c
> > b/drivers/power/power_supply_core.c
> > index 08cc8a3..2436f13 100644
> > --- a/drivers/power/power_supply_core.c
> > +++ b/drivers/power/power_supply_core.c
> > @@ -201,7 +201,7 @@ static int psy_register_thermal(struct power_supply
> > *psy)
> >         for (i = 0; i < psy->num_properties; i++) {
> >                 if (psy->properties[i] == POWER_SUPPLY_PROP_TEMP) {
> >                         psy->tzd =
> > thermal_zone_device_register(psy->name, 0, 0,
> > -                                       psy, &psy_tzd_ops, 0, 0, 0, 0);
> > +                                       psy, &psy_tzd_ops, 0, 0);
> >                         if (IS_ERR(psy->tzd))
> >                                 return PTR_ERR(psy->tzd);
> >                         break;
>
> I have fixed this one in my git tree.
>
> > diff --git a/drivers/staging/omap-thermal/omap-thermal-common.c
> > b/drivers/staging/omap-thermal/omap-thermal-common.c
> > index c1f00c6..b4cd6cc 100644
> > --- a/drivers/staging/omap-thermal/omap-thermal-common.c
> > +++ b/drivers/staging/omap-thermal/omap-thermal-common.c
> > @@ -248,7 +248,7 @@ int omap_thermal_expose_sensor(struct omap_bandgap
> > *bg_ptr, int id,
> >         /* Create thermal zone */
> >         data->omap_thermal = thermal_zone_device_register(domain,
> >                                 OMAP_TRIP_NUMBER, 0, data,
> > &omap_thermal_ops,
> > -                               0, FAST_TEMP_MONITORING_RATE, 0, 0);
> > +                               0, FAST_TEMP_MONITORING_RATE);
> hmm, FAST_TEMP_MONITORING_RATE is the polling frequency and you put it
> in the wrong place in your original code, right?
>
> >         if (IS_ERR_OR_NULL(data->omap_thermal)) {
> >                 dev_err(bg_ptr->dev, "thermal zone device is NULL\n");
> >                 return PTR_ERR(data->omap_thermal);
> >
> I missed this one. :)
> I'll fixed it in my tree.

(resending the mail so that it reaches the mailing lists)

Nice, I checked your tree and this patch is fine for me. Next time you
send it out, you may want to add my reviewed-by:

Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>


>
> thanks,
> rui
> > Apart from the compilation issues and the needed patch refresh, I am
> > good with the patch. And thanks for pushing this forward.
> >
> > >  6 files changed, 11 insertions(+), 29 deletions(-)
> > >
> > > diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> > > index 0c49e42..0c755d2 100644
> > > --- a/drivers/acpi/thermal.c
> > > +++ b/drivers/acpi/thermal.c
> > > @@ -895,15 +895,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;
> > > diff --git a/drivers/platform/x86/acerhdf.c
> > > b/drivers/platform/x86/acerhdf.c
> > > index a207466..84c5688 100644
> > > --- a/drivers/platform/x86/acerhdf.c
> > > +++ b/drivers/platform/x86/acerhdf.c
> > > @@ -662,7 +662,7 @@ static int acerhdf_register_thermal(void)
> > >                 return -EINVAL;
> > >
> > >         thz_dev = thermal_zone_device_register("acerhdf", 1, 0, NULL,
> > > -                                             &acerhdf_dev_ops, 0, 0,
> > > 0,
> > > +                                             &acerhdf_dev_ops, 0,
> > >                                               (kernelmode) ?
> > > interval*1000 : 0);
> > >         if (IS_ERR(thz_dev))
> > >                 return -EINVAL;
> > > diff --git a/drivers/platform/x86/intel_mid_thermal.c
> > > b/drivers/platform/x86/intel_mid_thermal.c
> > > index 2b2c212..6e309dd 100644
> > > --- a/drivers/platform/x86/intel_mid_thermal.c
> > > +++ b/drivers/platform/x86/intel_mid_thermal.c
> > > @@ -499,7 +499,7 @@ static int mid_thermal_probe(struct
> > > platform_device *pdev)
> > >                         goto err;
> > >                 }
> > >                 pinfo->tzd[i] = thermal_zone_device_register(name[i],
> > > -                               0, 0, td_info, &tzd_ops, 0, 0, 0, 0);
> > > +                               0, 0, td_info, &tzd_ops, 0, 0);
> > >                 if (IS_ERR(pinfo->tzd[i])) {
> > >                         kfree(td_info);
> > >                         ret = PTR_ERR(pinfo->tzd[i]);
> > > diff --git a/drivers/thermal/spear_thermal.c
> > > b/drivers/thermal/spear_thermal.c
> > > index 69a55d4..b55840a 100644
> > > --- a/drivers/thermal/spear_thermal.c
> > > +++ b/drivers/thermal/spear_thermal.c
> > > @@ -148,7 +148,7 @@ static int spear_thermal_probe(struct
> > > platform_device *pdev)
> > >         writel_relaxed(stdev->flags, stdev->thermal_base);
> > >
> > >         spear_thermal = thermal_zone_device_register("spear_thermal",
> > > 0, 0,
> > > -                               stdev, &ops, 0, 0, 0, 0);
> > > +                               stdev, &ops, 0, 0);
> > >         if (IS_ERR(spear_thermal)) {
> > >                 dev_err(&pdev->dev, "thermal zone device is NULL\n");
> > >                 ret = PTR_ERR(spear_thermal);
> > > diff --git a/drivers/thermal/thermal_sys.c
> > > b/drivers/thermal/thermal_sys.c
> > > index 68c93d4..a70ed4c 100644
> > > --- a/drivers/thermal/thermal_sys.c
> > > +++ b/drivers/thermal/thermal_sys.c
> > > @@ -335,9 +335,6 @@ passive_store(struct device *dev, struct
> > > device_attribute *attr,
> > >                 tz->passive_delay = 0;
> > >         }
> > >
> > > -       tz->tc1 = 1;
> > > -       tz->tc2 = 1;
> > > -
> > >         tz->forced_passive = state;
> > >
> > >         thermal_zone_device_update(tz);
> > > @@ -718,13 +715,12 @@ static void
> > > thermal_zone_device_set_polling(struct thermal_zone_device *tz,
> > >  static void thermal_zone_device_passive(struct thermal_zone_device
> > > *tz,
> > >                                         int temp, int trip_temp, int
> > > trip)
> > >  {
> > > -       int trend = 0;
> > > +       enum thermal_trend trend;
> > >         struct thermal_cooling_device_instance *instance;
> > >         struct thermal_cooling_device *cdev;
> > >         long state, max_state;
> > >
> > > -       if (!tz->ops->get_trend ||
> > > -           tz->ops->get_trend(tz, trip, (enum thermal_trend
> > > *)&trend)) {
> > > +       if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip,
> > > &trend)) {
> > >                 /*
> > >                  * compare the current temperature and previous
> > > temperature
> > >                  * to get the thermal trend, if no special requirement
> > > @@ -747,11 +743,8 @@ static void thermal_zone_device_passive(struct
> > > thermal_zone_device *tz,
> > >         if (temp >= trip_temp) {
> > >                 tz->passive = true;
> > >
> > > -               trend = (tz->tc1 * (temp - tz->last_temperature)) +
> > > -                       (tz->tc2 * (temp - trip_temp));
> > > -
> > >                 /* Heating up? */
> > > -               if (trend > 0) {
> > > +               if (trend == THERMAL_TREND_RAISING) {
> > >                         list_for_each_entry(instance,
> > > &tz->cooling_devices,
> > >                                             node) {
> > >                                 if (instance->trip != trip)
> > > @@ -762,7 +755,7 @@ static void thermal_zone_device_passive(struct
> > > thermal_zone_device *tz,
> > >                                 if (state++ < max_state)
> > >                                         cdev->ops->set_cur_state(cdev,
> > > state);
> > >                         }
> > > -               } else if (trend < 0) { /* Cooling off? */
> > > +               } else if (trend == THERMAL_TREND_DROPPING) { /*
> > > Cooling off? */
> > >                         list_for_each_entry(instance,
> > > &tz->cooling_devices,
> > >                                             node) {
> > >                                 if (instance->trip != trip)
> > > @@ -1288,8 +1281,6 @@ static void remove_trip_attrs(struct
> > > thermal_zone_device *tz)
> > >   * @mask:      a bit string indicating the writeablility of trip
> > > points
> > >   * @devdata:   private device data
> > >   * @ops:       standard thermal zone device callbacks
> > > - * @tc1:       thermal coefficient 1 for passive calculations
> > > - * @tc2:       thermal coefficient 2 for passive calculations
> > >   * @passive_delay: number of milliseconds to wait between polls when
> > >   *                performing passive cooling
> > >   * @polling_delay: number of milliseconds to wait between polls when
> > > checking
> > > @@ -1297,13 +1288,12 @@ static void remove_trip_attrs(struct
> > > thermal_zone_device *tz)
> > >   *                driven systems)
> > >   *
> > >   * thermal_zone_device_unregister() must be called when the device is
> > > no
> > > - * longer needed. The passive cooling formula uses tc1 and tc2 as
> > > described in
> > > - * section 11.1.5.1 of the ACPI specification 3.0.
> > > + * longer needed. The passive cooling depends on the .get_trend()
> > > return value.
> > >   */
> > >  struct thermal_zone_device *thermal_zone_device_register(char *type,
> > >         int trips, int mask, void *devdata,
> > >         const struct thermal_zone_device_ops *ops,
> > > -       int tc1, int tc2, int passive_delay, int polling_delay)
> > > +       int passive_delay, int polling_delay)
> > >  {
> > >         struct thermal_zone_device *tz;
> > >         struct thermal_cooling_device *pos;
> > > @@ -1339,8 +1329,6 @@ struct thermal_zone_device
> > > *thermal_zone_device_register(char *type,
> > >         tz->device.class = &thermal_class;
> > >         tz->devdata = devdata;
> > >         tz->trips = trips;
> > > -       tz->tc1 = tc1;
> > > -       tz->tc2 = tc2;
> > >         tz->passive_delay = passive_delay;
> > >         tz->polling_delay = polling_delay;
> > >
> > > diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> > > index a01e3e6..d18dcf6 100644
> > > --- a/include/linux/thermal.h
> > > +++ b/include/linux/thermal.h
> > > @@ -115,8 +115,6 @@ struct thermal_zone_device {
> > >         struct thermal_attr *trip_hyst_attrs;
> > >         void *devdata;
> > >         int trips;
> > > -       int tc1;
> > > -       int tc2;
> > >         int passive_delay;
> > >         int polling_delay;
> > >         int temperature;
> > > @@ -163,8 +161,7 @@ enum {
> > >  #define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
> > >
> > >  struct thermal_zone_device *thermal_zone_device_register(char *, int,
> > > int,
> > > -               void *, const struct thermal_zone_device_ops *, int
> > > tc1,
> > > -               int tc2, int passive_freq, int polling_freq);
> > > +               void *, const struct thermal_zone_device_ops *, int,
> > > int);
> > >  void thermal_zone_device_unregister(struct thermal_zone_device *);
> > >
> > >  int thermal_zone_bind_cooling_device(struct thermal_zone_device *,
> > > int,
> > > --
> > > 1.7.9.5
> > >
> >
> >
> >
>
>



--

Eduardo Valentin
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 05/13] Thermal: Remove tc1/tc2 in generic thermal layer.
  2012-08-09 15:10       ` Valentin, Eduardo
@ 2012-08-20 12:18         ` Eduardo Valentin
  2012-08-21  0:49           ` Zhang Rui
  0 siblings, 1 reply; 45+ messages in thread
From: Eduardo Valentin @ 2012-08-20 12:18 UTC (permalink / raw)
  To: Valentin, Eduardo
  Cc: Zhang Rui, Rafael J. Wysocki, Matthew Garrett, Len Brown,
	R Durgadoss, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

Hello,

On Thu, Aug 09, 2012 at 06:10:04PM +0300, Valentin, Eduardo wrote:
> 
> (resending the mail so that it reaches the mailing lists)
> 
> Nice, I checked your tree and this patch is fine for me. Next time you
> send it out, you may want to add my reviewed-by:

Except that in your tree it is still introducing compilation issues under omap-thermal-common.c

> 
> Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>

So, apart from the above comment, this patch is still fine for me.

> 
> 
> >
> > thanks,
> > rui
> > > Apart from the compilation issues and the needed patch refresh, I am
> > > good with the patch. And thanks for pushing this forward.
> > >
> > > >  6 files changed, 11 insertions(+), 29 deletions(-)
> > > >
> > > > diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> > > > index 0c49e42..0c755d2 100644
> > > > --- a/drivers/acpi/thermal.c
> > > > +++ b/drivers/acpi/thermal.c
> > > > @@ -895,15 +895,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;
> > > > diff --git a/drivers/platform/x86/acerhdf.c
> > > > b/drivers/platform/x86/acerhdf.c
> > > > index a207466..84c5688 100644
> > > > --- a/drivers/platform/x86/acerhdf.c
> > > > +++ b/drivers/platform/x86/acerhdf.c
> > > > @@ -662,7 +662,7 @@ static int acerhdf_register_thermal(void)
> > > >                 return -EINVAL;
> > > >
> > > >         thz_dev = thermal_zone_device_register("acerhdf", 1, 0, NULL,
> > > > -                                             &acerhdf_dev_ops, 0, 0,
> > > > 0,
> > > > +                                             &acerhdf_dev_ops, 0,
> > > >                                               (kernelmode) ?
> > > > interval*1000 : 0);
> > > >         if (IS_ERR(thz_dev))
> > > >                 return -EINVAL;
> > > > diff --git a/drivers/platform/x86/intel_mid_thermal.c
> > > > b/drivers/platform/x86/intel_mid_thermal.c
> > > > index 2b2c212..6e309dd 100644
> > > > --- a/drivers/platform/x86/intel_mid_thermal.c
> > > > +++ b/drivers/platform/x86/intel_mid_thermal.c
> > > > @@ -499,7 +499,7 @@ static int mid_thermal_probe(struct
> > > > platform_device *pdev)
> > > >                         goto err;
> > > >                 }
> > > >                 pinfo->tzd[i] = thermal_zone_device_register(name[i],
> > > > -                               0, 0, td_info, &tzd_ops, 0, 0, 0, 0);
> > > > +                               0, 0, td_info, &tzd_ops, 0, 0);
> > > >                 if (IS_ERR(pinfo->tzd[i])) {
> > > >                         kfree(td_info);
> > > >                         ret = PTR_ERR(pinfo->tzd[i]);
> > > > diff --git a/drivers/thermal/spear_thermal.c
> > > > b/drivers/thermal/spear_thermal.c
> > > > index 69a55d4..b55840a 100644
> > > > --- a/drivers/thermal/spear_thermal.c
> > > > +++ b/drivers/thermal/spear_thermal.c
> > > > @@ -148,7 +148,7 @@ static int spear_thermal_probe(struct
> > > > platform_device *pdev)
> > > >         writel_relaxed(stdev->flags, stdev->thermal_base);
> > > >
> > > >         spear_thermal = thermal_zone_device_register("spear_thermal",
> > > > 0, 0,
> > > > -                               stdev, &ops, 0, 0, 0, 0);
> > > > +                               stdev, &ops, 0, 0);
> > > >         if (IS_ERR(spear_thermal)) {
> > > >                 dev_err(&pdev->dev, "thermal zone device is NULL\n");
> > > >                 ret = PTR_ERR(spear_thermal);
> > > > diff --git a/drivers/thermal/thermal_sys.c
> > > > b/drivers/thermal/thermal_sys.c
> > > > index 68c93d4..a70ed4c 100644
> > > > --- a/drivers/thermal/thermal_sys.c
> > > > +++ b/drivers/thermal/thermal_sys.c
> > > > @@ -335,9 +335,6 @@ passive_store(struct device *dev, struct
> > > > device_attribute *attr,
> > > >                 tz->passive_delay = 0;
> > > >         }
> > > >
> > > > -       tz->tc1 = 1;
> > > > -       tz->tc2 = 1;
> > > > -
> > > >         tz->forced_passive = state;
> > > >
> > > >         thermal_zone_device_update(tz);
> > > > @@ -718,13 +715,12 @@ static void
> > > > thermal_zone_device_set_polling(struct thermal_zone_device *tz,
> > > >  static void thermal_zone_device_passive(struct thermal_zone_device
> > > > *tz,
> > > >                                         int temp, int trip_temp, int
> > > > trip)
> > > >  {
> > > > -       int trend = 0;
> > > > +       enum thermal_trend trend;
> > > >         struct thermal_cooling_device_instance *instance;
> > > >         struct thermal_cooling_device *cdev;
> > > >         long state, max_state;
> > > >
> > > > -       if (!tz->ops->get_trend ||
> > > > -           tz->ops->get_trend(tz, trip, (enum thermal_trend
> > > > *)&trend)) {
> > > > +       if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip,
> > > > &trend)) {
> > > >                 /*
> > > >                  * compare the current temperature and previous
> > > > temperature
> > > >                  * to get the thermal trend, if no special requirement
> > > > @@ -747,11 +743,8 @@ static void thermal_zone_device_passive(struct
> > > > thermal_zone_device *tz,
> > > >         if (temp >= trip_temp) {
> > > >                 tz->passive = true;
> > > >
> > > > -               trend = (tz->tc1 * (temp - tz->last_temperature)) +
> > > > -                       (tz->tc2 * (temp - trip_temp));
> > > > -
> > > >                 /* Heating up? */
> > > > -               if (trend > 0) {
> > > > +               if (trend == THERMAL_TREND_RAISING) {
> > > >                         list_for_each_entry(instance,
> > > > &tz->cooling_devices,
> > > >                                             node) {
> > > >                                 if (instance->trip != trip)
> > > > @@ -762,7 +755,7 @@ static void thermal_zone_device_passive(struct
> > > > thermal_zone_device *tz,
> > > >                                 if (state++ < max_state)
> > > >                                         cdev->ops->set_cur_state(cdev,
> > > > state);
> > > >                         }
> > > > -               } else if (trend < 0) { /* Cooling off? */
> > > > +               } else if (trend == THERMAL_TREND_DROPPING) { /*
> > > > Cooling off? */
> > > >                         list_for_each_entry(instance,
> > > > &tz->cooling_devices,
> > > >                                             node) {
> > > >                                 if (instance->trip != trip)
> > > > @@ -1288,8 +1281,6 @@ static void remove_trip_attrs(struct
> > > > thermal_zone_device *tz)
> > > >   * @mask:      a bit string indicating the writeablility of trip
> > > > points
> > > >   * @devdata:   private device data
> > > >   * @ops:       standard thermal zone device callbacks
> > > > - * @tc1:       thermal coefficient 1 for passive calculations
> > > > - * @tc2:       thermal coefficient 2 for passive calculations
> > > >   * @passive_delay: number of milliseconds to wait between polls when
> > > >   *                performing passive cooling
> > > >   * @polling_delay: number of milliseconds to wait between polls when
> > > > checking
> > > > @@ -1297,13 +1288,12 @@ static void remove_trip_attrs(struct
> > > > thermal_zone_device *tz)
> > > >   *                driven systems)
> > > >   *
> > > >   * thermal_zone_device_unregister() must be called when the device is
> > > > no
> > > > - * longer needed. The passive cooling formula uses tc1 and tc2 as
> > > > described in
> > > > - * section 11.1.5.1 of the ACPI specification 3.0.
> > > > + * longer needed. The passive cooling depends on the .get_trend()
> > > > return value.
> > > >   */
> > > >  struct thermal_zone_device *thermal_zone_device_register(char *type,
> > > >         int trips, int mask, void *devdata,
> > > >         const struct thermal_zone_device_ops *ops,
> > > > -       int tc1, int tc2, int passive_delay, int polling_delay)
> > > > +       int passive_delay, int polling_delay)
> > > >  {
> > > >         struct thermal_zone_device *tz;
> > > >         struct thermal_cooling_device *pos;
> > > > @@ -1339,8 +1329,6 @@ struct thermal_zone_device
> > > > *thermal_zone_device_register(char *type,
> > > >         tz->device.class = &thermal_class;
> > > >         tz->devdata = devdata;
> > > >         tz->trips = trips;
> > > > -       tz->tc1 = tc1;
> > > > -       tz->tc2 = tc2;
> > > >         tz->passive_delay = passive_delay;
> > > >         tz->polling_delay = polling_delay;
> > > >
> > > > diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> > > > index a01e3e6..d18dcf6 100644
> > > > --- a/include/linux/thermal.h
> > > > +++ b/include/linux/thermal.h
> > > > @@ -115,8 +115,6 @@ struct thermal_zone_device {
> > > >         struct thermal_attr *trip_hyst_attrs;
> > > >         void *devdata;
> > > >         int trips;
> > > > -       int tc1;
> > > > -       int tc2;
> > > >         int passive_delay;
> > > >         int polling_delay;
> > > >         int temperature;
> > > > @@ -163,8 +161,7 @@ enum {
> > > >  #define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
> > > >
> > > >  struct thermal_zone_device *thermal_zone_device_register(char *, int,
> > > > int,
> > > > -               void *, const struct thermal_zone_device_ops *, int
> > > > tc1,
> > > > -               int tc2, int passive_freq, int polling_freq);
> > > > +               void *, const struct thermal_zone_device_ops *, int,
> > > > int);
> > > >  void thermal_zone_device_unregister(struct thermal_zone_device *);
> > > >
> > > >  int thermal_zone_bind_cooling_device(struct thermal_zone_device *,
> > > > int,
> > > > --
> > > > 1.7.9.5
> > > >
> > >
> > >
> > >
> >
> >
> 
> 
> 
> --
> 
> Eduardo Valentin

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 13/13] Thermal: Introduce locking for cdev.thermal_instances list.
  2012-07-26  8:41 ` [PATCH V4 13/13] Thermal: Introduce locking for cdev.thermal_instances list Zhang Rui
  2012-07-26 20:13   ` Rafael J. Wysocki
@ 2012-08-20 15:45   ` Eduardo Valentin
  2012-08-21  0:53     ` Zhang Rui
  1 sibling, 1 reply; 45+ messages in thread
From: Eduardo Valentin @ 2012-08-20 15:45 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

Hello Rui,

On Thu, Jul 26, 2012 at 04:41:23PM +0800, Zhang Rui wrote:
> we need to go over all the thermal_instance list of a cooling device
> to decide which cooling state to put the cooling device to.
> 
> But at this time, as a cooling device may be referenced in multiple
> thermal zones, we need to lock the list first in case
> another thermal zone is updating this cooling device.
> 
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>

A minor comment bellow.

> ---
>  drivers/thermal/thermal_sys.c |    8 ++++++++
>  include/linux/thermal.h       |    1 +
>  2 files changed, 9 insertions(+)
> 
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index 7f3a891..356a59d 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -799,6 +799,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
>  		goto remove_symbol_link;
>  
>  	mutex_lock(&tz->lock);
> +	mutex_lock(&cdev->lock);

Why do you need to lock while going through the tz thermal_instances?

>  	list_for_each_entry(pos, &tz->thermal_instances, tz_node)
>  	    if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
>  		result = -EEXIST;
> @@ -808,6 +809,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
>  		list_add_tail(&dev->tz_node, &tz->thermal_instances);
>  		list_add_tail(&dev->cdev_node, &cdev->thermal_instances);

Locking the above operation should be enough, no?

>  	}
> +	mutex_unlock(&cdev->lock);
>  	mutex_unlock(&tz->lock);
>  
>  	if (!result)
> @@ -840,14 +842,17 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
>  	struct thermal_instance *pos, *next;
>  
>  	mutex_lock(&tz->lock);
> +	mutex_lock(&cdev->lock);
>  	list_for_each_entry_safe(pos, next, &tz->thermal_instances, tz_node) {
>  		if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
>  			list_del(&pos->tz_node);
>  			list_del(&pos->cdev_node);
> +			mutex_unlock(&cdev->lock);
>  			mutex_unlock(&tz->lock);
>  			goto unbind;
>  		}
>  	}
> +	mutex_unlock(&cdev->lock);
>  	mutex_unlock(&tz->lock);
>  
>  	return -ENODEV;
> @@ -913,6 +918,7 @@ thermal_cooling_device_register(char *type, void *devdata,
>  	}
>  
>  	strcpy(cdev->type, type);
> +	mutex_init(&cdev->lock);
>  	INIT_LIST_HEAD(&cdev->thermal_instances);
>  	cdev->ops = ops;
>  	cdev->updated = true;
> @@ -1016,6 +1022,7 @@ static void thermal_cdev_do_update(struct thermal_cooling_device *cdev)
>  	if (cdev->updated)
>  		return;
>  
> +	mutex_lock(&cdev->lock);
>  	/* Make sure cdev enters the deepest cooling state */
>  	list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
>  		if (instance->target == THERMAL_NO_TARGET)
> @@ -1023,6 +1030,7 @@ static void thermal_cdev_do_update(struct thermal_cooling_device *cdev)
>  		if (instance->target > target)
>  			target = instance->target;
>  	}
> +	mutex_unlock(&cdev->lock);
>  	cdev->ops->set_cur_state(cdev, target);
>  	cdev->updated = true;
>  }
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index 06fd04d..d02d06d 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -95,6 +95,7 @@ struct thermal_cooling_device {
>  	void *devdata;
>  	const struct thermal_cooling_device_ops *ops;
>  	bool updated; /* true if the cooling device does not need update */
> +	struct mutex lock; /* protect thermal_instances list */
>  	struct list_head thermal_instances;
>  	struct list_head node;
>  };
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 12/13] Thermal: Unify the code for both active and passive cooling
  2012-07-26  8:41 ` [PATCH V4 12/13] Thermal: Unify the code for both active and passive cooling Zhang Rui
@ 2012-08-20 15:45   ` Eduardo Valentin
  0 siblings, 0 replies; 45+ messages in thread
From: Eduardo Valentin @ 2012-08-20 15:45 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Thu, Jul 26, 2012 at 04:41:22PM +0800, Zhang Rui wrote:
> Remove thermal_zone_device_passive(). And use
> thermal_zone_trip_update() and thermal_zone_do_update()
> for both active and passive cooling.
> 
> Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>

> ---
>  drivers/thermal/thermal_sys.c |  110 ++++++++++-------------------------------
>  include/linux/thermal.h       |    2 +-
>  2 files changed, 26 insertions(+), 86 deletions(-)
> 
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index 027b8e2..7f3a891 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -715,84 +715,6 @@ static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
>  				      msecs_to_jiffies(delay));
>  }
>  
> -static void thermal_zone_device_passive(struct thermal_zone_device *tz,
> -					int temp, int trip_temp, int trip)
> -{
> -	enum thermal_trend trend;
> -	struct thermal_instance *instance;
> -	struct thermal_cooling_device *cdev;
> -	long state, max_state;
> -
> -	if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
> -		/*
> -		 * compare the current temperature and previous temperature
> -		 * to get the thermal trend, if no special requirement
> -		 */
> -		if (tz->temperature > tz->last_temperature)
> -			trend = THERMAL_TREND_RAISING;
> -		else if (tz->temperature < tz->last_temperature)
> -			trend = THERMAL_TREND_DROPPING;
> -		else
> -			trend = THERMAL_TREND_STABLE;
> -	}
> -
> -	/*
> -	 * Above Trip?
> -	 * -----------
> -	 * Calculate the thermal trend (using the passive cooling equation)
> -	 * and modify the performance limit for all passive cooling devices
> -	 * accordingly.  Note that we assume symmetry.
> -	 */
> -	if (temp >= trip_temp) {
> -		tz->passive = true;
> -
> -		/* Heating up? */
> -		if (trend == THERMAL_TREND_RAISING) {
> -			list_for_each_entry(instance, &tz->thermal_instances,
> -					    tz_node) {
> -				if (instance->trip != trip)
> -					continue;
> -				cdev = instance->cdev;
> -				cdev->ops->get_cur_state(cdev, &state);
> -				cdev->ops->get_max_state(cdev, &max_state);
> -				if (state++ < max_state)
> -					cdev->ops->set_cur_state(cdev, state);
> -			}
> -		} else if (trend == THERMAL_TREND_DROPPING) { /* Cooling off? */
> -			list_for_each_entry(instance, &tz->thermal_instances,
> -					    tz_node) {
> -				if (instance->trip != trip)
> -					continue;
> -				cdev = instance->cdev;
> -				cdev->ops->get_cur_state(cdev, &state);
> -				cdev->ops->get_max_state(cdev, &max_state);
> -				if (state > 0)
> -					cdev->ops->set_cur_state(cdev, --state);
> -			}
> -		}
> -		return;
> -	}
> -
> -	/*
> -	 * Below Trip?
> -	 * -----------
> -	 * Implement passive cooling hysteresis to slowly increase performance
> -	 * and avoid thrashing around the passive trip point.  Note that we
> -	 * assume symmetry.
> -	 */
> -	list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
> -		if (instance->trip != trip)
> -			continue;
> -		cdev = instance->cdev;
> -		cdev->ops->get_cur_state(cdev, &state);
> -		cdev->ops->get_max_state(cdev, &max_state);
> -		if (state > 0)
> -			cdev->ops->set_cur_state(cdev, --state);
> -		if (state == 0)
> -			tz->passive = false;
> -	}
> -}
> -
>  static void thermal_zone_device_check(struct work_struct *work)
>  {
>  	struct thermal_zone_device *tz = container_of(work, struct
> @@ -1114,7 +1036,7 @@ static void thermal_zone_do_update(struct thermal_zone_device *tz)
>  }
>  
>  /*
> - * Cooling algorithm for active trip points
> + * Cooling algorithm for both active and passive cooling
>   *
>   * 1. if the temperature is higher than a trip point,
>   *    a. if the trend is THERMAL_TREND_RAISING, use higher cooling
> @@ -1136,9 +1058,16 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
>  	struct thermal_cooling_device *cdev = NULL;
>  	unsigned long cur_state, max_state;
>  	long trip_temp;
> +	enum thermal_trip_type trip_type;
>  	enum thermal_trend trend;
>  
> -	tz->ops->get_trip_temp(tz, trip, &trip_temp);
> +	if (trip == THERMAL_TRIPS_NONE) {
> +		trip_temp = tz->forced_passive;
> +		trip_type = THERMAL_TRIPS_NONE;
> +	} else {
> +		tz->ops->get_trip_temp(tz, trip, &trip_temp);
> +		tz->ops->get_trip_type(tz, trip, &trip_type);
> +	}
>  
>  	if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
>  		/*
> @@ -1170,6 +1099,13 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
>  				cur_state = cur_state > instance->lower ?
>  				    (cur_state - 1) : instance->lower;
>  			}
> +
> +			/* activate a passive thermal instance */
> +			if ((trip_type == THERMAL_TRIP_PASSIVE ||
> +			     trip_type == THERMAL_TRIPS_NONE) &&
> +			     instance->target == THERMAL_NO_TARGET)
> +				tz->passive++;
> +
>  			instance->target = cur_state;
>  			cdev->updated = false; /* cooling device needs update */
>  		}
> @@ -1186,6 +1122,12 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
>  
>  			cur_state = cur_state > instance->lower ?
>  				    (cur_state - 1) : THERMAL_NO_TARGET;
> +
> +			/* deactivate a passive thermal instance */
> +			if ((trip_type == THERMAL_TRIP_PASSIVE ||
> +			     trip_type == THERMAL_TRIPS_NONE) &&
> +			     cur_state == THERMAL_NO_TARGET)
> +				tz->passive--;
>  			instance->target = cur_state;
>  			cdev->updated = false; /* cooling device needs update */
>  		}
> @@ -1242,16 +1184,14 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>  			break;
>  		case THERMAL_TRIP_PASSIVE:
>  			if (temp >= trip_temp || tz->passive)
> -				thermal_zone_device_passive(tz, temp,
> -							    trip_temp, count);
> +				thermal_zone_trip_update(tz, count, temp);
>  			break;
>  		}
>  	}
>  
> -	thermal_zone_do_update(tz);
>  	if (tz->forced_passive)
> -		thermal_zone_device_passive(tz, temp, tz->forced_passive,
> -					    THERMAL_TRIPS_NONE);
> +		thermal_zone_trip_update(tz, THERMAL_TRIPS_NONE, temp);
> +	thermal_zone_do_update(tz);
>  
>  leave:
>  	if (tz->passive)
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index 3e66214..06fd04d 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -121,7 +121,7 @@ struct thermal_zone_device {
>  	int polling_delay;
>  	int temperature;
>  	int last_temperature;
> -	bool passive;
> +	int passive;
>  	unsigned int forced_passive;
>  	const struct thermal_zone_device_ops *ops;
>  	struct list_head thermal_instances;
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 11/13] Thermal: Introduce simple arbitrator for setting device cooling state
  2012-07-26  8:41 ` [PATCH V4 11/13] Thermal: Introduce simple arbitrator for setting device cooling state Zhang Rui
@ 2012-08-20 15:46   ` Eduardo Valentin
  0 siblings, 0 replies; 45+ messages in thread
From: Eduardo Valentin @ 2012-08-20 15:46 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Thu, Jul 26, 2012 at 04:41:21PM +0800, Zhang Rui wrote:
> This fixes the problem that a cooling device may be referenced by
> by multiple trip points in multiple thermal zones.
> 
> With this patch, we have two stages for updating a thermal zone,
> 1. check if a thermal_instance needs to be updated or not
> 2. update the cooling device, based on the target cooling state
>    of all its instances.
> 
> Note that, currently, the cooling device is set to the deepest
> cooling state required.
> 
> Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>

> ---
>  drivers/thermal/thermal_sys.c |   44 ++++++++++++++++++++++++++++++++++++++---
>  include/linux/thermal.h       |    1 +
>  2 files changed, 42 insertions(+), 3 deletions(-)
> 
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index 9906717..027b8e2 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -41,6 +41,7 @@ MODULE_AUTHOR("Zhang Rui");
>  MODULE_DESCRIPTION("Generic thermal management sysfs support");
>  MODULE_LICENSE("GPL");
>  
> +#define THERMAL_NO_TARGET -1UL
>  /*
>   * This structure is used to describe the behavior of
>   * a certain cooling device on a certain trip point
> @@ -54,6 +55,7 @@ struct thermal_instance {
>  	int trip;
>  	unsigned long upper;	/* Highest cooling state for this trip point */
>  	unsigned long lower;	/* Lowest cooling state for this trip point */
> +	unsigned long target;	/* expected cooling state */
>  	char attr_name[THERMAL_NAME_LENGTH];
>  	struct device_attribute attr;
>  	struct list_head tz_node; /* node in tz->thermal_instances */
> @@ -853,6 +855,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
>  	dev->trip = trip;
>  	dev->upper = upper;
>  	dev->lower = lower;
> +	dev->target = THERMAL_NO_TARGET;
>  
>  	result = get_idr(&tz->idr, &tz->lock, &dev->id);
>  	if (result)
> @@ -990,6 +993,7 @@ thermal_cooling_device_register(char *type, void *devdata,
>  	strcpy(cdev->type, type);
>  	INIT_LIST_HEAD(&cdev->thermal_instances);
>  	cdev->ops = ops;
> +	cdev->updated = true;
>  	cdev->device.class = &thermal_class;
>  	cdev->devdata = devdata;
>  	dev_set_name(&cdev->device, "cooling_device%d", cdev->id);
> @@ -1081,6 +1085,34 @@ void thermal_cooling_device_unregister(struct
>  }
>  EXPORT_SYMBOL(thermal_cooling_device_unregister);
>  
> +static void thermal_cdev_do_update(struct thermal_cooling_device *cdev)
> +{
> +	struct thermal_instance *instance;
> +	unsigned long target = 0;
> +
> +	/* cooling device is updated*/
> +	if (cdev->updated)
> +		return;
> +
> +	/* Make sure cdev enters the deepest cooling state */
> +	list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
> +		if (instance->target == THERMAL_NO_TARGET)
> +			continue;
> +		if (instance->target > target)
> +			target = instance->target;
> +	}
> +	cdev->ops->set_cur_state(cdev, target);
> +	cdev->updated = true;
> +}
> +
> +static void thermal_zone_do_update(struct thermal_zone_device *tz)
> +{
> +	struct thermal_instance *instance;
> +
> +	list_for_each_entry(instance, &tz->thermal_instances, tz_node)
> +		thermal_cdev_do_update(instance->cdev);
> +}
> +
>  /*
>   * Cooling algorithm for active trip points
>   *
> @@ -1138,19 +1170,24 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
>  				cur_state = cur_state > instance->lower ?
>  				    (cur_state - 1) : instance->lower;
>  			}
> -			cdev->ops->set_cur_state(cdev, cur_state);
> +			instance->target = cur_state;
> +			cdev->updated = false; /* cooling device needs update */
>  		}
>  	} else {	/* below trip */
>  		list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
>  			if (instance->trip != trip)
>  				continue;
>  
> +			/* Do not use the inactive thermal instance */
> +			if (instance->target == THERMAL_NO_TARGET)
> +				continue;
>  			cdev = instance->cdev;
>  			cdev->ops->get_cur_state(cdev, &cur_state);
>  
>  			cur_state = cur_state > instance->lower ?
> -				    (cur_state - 1) : instance->lower;
> -			cdev->ops->set_cur_state(cdev, cur_state);
> +				    (cur_state - 1) : THERMAL_NO_TARGET;
> +			instance->target = cur_state;
> +			cdev->updated = false; /* cooling device needs update */
>  		}
>  	}
>  
> @@ -1211,6 +1248,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>  		}
>  	}
>  
> +	thermal_zone_do_update(tz);
>  	if (tz->forced_passive)
>  		thermal_zone_device_passive(tz, temp, tz->forced_passive,
>  					    THERMAL_TRIPS_NONE);
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index bcf3384..3e66214 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -94,6 +94,7 @@ struct thermal_cooling_device {
>  	struct device device;
>  	void *devdata;
>  	const struct thermal_cooling_device_ops *ops;
> +	bool updated; /* true if the cooling device does not need update */
>  	struct list_head thermal_instances;
>  	struct list_head node;
>  };
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 10/13] Thermal: List thermal_instance in thermal_cooling_device.
  2012-07-26  8:41 ` [PATCH V4 10/13] Thermal: List thermal_instance in thermal_cooling_device Zhang Rui
@ 2012-08-20 15:46   ` Eduardo Valentin
  0 siblings, 0 replies; 45+ messages in thread
From: Eduardo Valentin @ 2012-08-20 15:46 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Thu, Jul 26, 2012 at 04:41:20PM +0800, Zhang Rui wrote:
> List thermal_instance in thermal_cooling_device so that
> cooling device can know the cooling state requirement
> of all the thermal instances.
> 
> Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>

> ---
>  drivers/thermal/thermal_sys.c |    7 ++++++-
>  include/linux/thermal.h       |    1 +
>  2 files changed, 7 insertions(+), 1 deletion(-)
> 
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index b2a2d48..9906717 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -57,6 +57,7 @@ struct thermal_instance {
>  	char attr_name[THERMAL_NAME_LENGTH];
>  	struct device_attribute attr;
>  	struct list_head tz_node; /* node in tz->thermal_instances */
> +	struct list_head cdev_node; /* node in cdev->thermal_instances */
>  };
>  
>  static DEFINE_IDR(thermal_tz_idr);
> @@ -878,8 +879,10 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
>  		result = -EEXIST;
>  		break;
>  	}
> -	if (!result)
> +	if (!result) {
>  		list_add_tail(&dev->tz_node, &tz->thermal_instances);
> +		list_add_tail(&dev->cdev_node, &cdev->thermal_instances);
> +	}
>  	mutex_unlock(&tz->lock);
>  
>  	if (!result)
> @@ -915,6 +918,7 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
>  	list_for_each_entry_safe(pos, next, &tz->thermal_instances, tz_node) {
>  		if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
>  			list_del(&pos->tz_node);
> +			list_del(&pos->cdev_node);
>  			mutex_unlock(&tz->lock);
>  			goto unbind;
>  		}
> @@ -984,6 +988,7 @@ thermal_cooling_device_register(char *type, void *devdata,
>  	}
>  
>  	strcpy(cdev->type, type);
> +	INIT_LIST_HEAD(&cdev->thermal_instances);
>  	cdev->ops = ops;
>  	cdev->device.class = &thermal_class;
>  	cdev->devdata = devdata;
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index b11db1e..bcf3384 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -94,6 +94,7 @@ struct thermal_cooling_device {
>  	struct device device;
>  	void *devdata;
>  	const struct thermal_cooling_device_ops *ops;
> +	struct list_head thermal_instances;
>  	struct list_head node;
>  };
>  
> -- 
> 1.7.9.5
> 
> --
> To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
> the body of a message to majordomo@vger.kernel.org
> More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 09/13] Thermal: Rename thermal_instance.node to thermal_instance.tz_node.
  2012-07-26  8:41 ` [PATCH V4 09/13] Thermal: Rename thermal_instance.node to thermal_instance.tz_node Zhang Rui
@ 2012-08-20 15:47   ` Eduardo Valentin
  0 siblings, 0 replies; 45+ messages in thread
From: Eduardo Valentin @ 2012-08-20 15:47 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Thu, Jul 26, 2012 at 04:41:19PM +0800, Zhang Rui wrote:
> thermal_instance should be referenced by both thermal zone devices
> and thermal cooling devices.
> 
> Rename thermal_instance.node to thermal_instance.tz_node in this patch
> and thermal_instanace.cdev_node will be introduced in next patch.
> 
> Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>

> ---
>  drivers/thermal/thermal_sys.c |   20 ++++++++++----------
>  1 file changed, 10 insertions(+), 10 deletions(-)
> 
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index 112227e..b2a2d48 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -56,7 +56,7 @@ struct thermal_instance {
>  	unsigned long lower;	/* Lowest cooling state for this trip point */
>  	char attr_name[THERMAL_NAME_LENGTH];
>  	struct device_attribute attr;
> -	struct list_head node;
> +	struct list_head tz_node; /* node in tz->thermal_instances */
>  };
>  
>  static DEFINE_IDR(thermal_tz_idr);
> @@ -746,7 +746,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>  		/* Heating up? */
>  		if (trend == THERMAL_TREND_RAISING) {
>  			list_for_each_entry(instance, &tz->thermal_instances,
> -					    node) {
> +					    tz_node) {
>  				if (instance->trip != trip)
>  					continue;
>  				cdev = instance->cdev;
> @@ -757,7 +757,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>  			}
>  		} else if (trend == THERMAL_TREND_DROPPING) { /* Cooling off? */
>  			list_for_each_entry(instance, &tz->thermal_instances,
> -					    node) {
> +					    tz_node) {
>  				if (instance->trip != trip)
>  					continue;
>  				cdev = instance->cdev;
> @@ -777,7 +777,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>  	 * and avoid thrashing around the passive trip point.  Note that we
>  	 * assume symmetry.
>  	 */
> -	list_for_each_entry(instance, &tz->thermal_instances, node) {
> +	list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
>  		if (instance->trip != trip)
>  			continue;
>  		cdev = instance->cdev;
> @@ -873,13 +873,13 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
>  		goto remove_symbol_link;
>  
>  	mutex_lock(&tz->lock);
> -	list_for_each_entry(pos, &tz->thermal_instances, node)
> +	list_for_each_entry(pos, &tz->thermal_instances, tz_node)
>  	    if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
>  		result = -EEXIST;
>  		break;
>  	}
>  	if (!result)
> -		list_add_tail(&dev->node, &tz->thermal_instances);
> +		list_add_tail(&dev->tz_node, &tz->thermal_instances);
>  	mutex_unlock(&tz->lock);
>  
>  	if (!result)
> @@ -912,9 +912,9 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
>  	struct thermal_instance *pos, *next;
>  
>  	mutex_lock(&tz->lock);
> -	list_for_each_entry_safe(pos, next, &tz->thermal_instances, node) {
> +	list_for_each_entry_safe(pos, next, &tz->thermal_instances, tz_node) {
>  		if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
> -			list_del(&pos->node);
> +			list_del(&pos->tz_node);
>  			mutex_unlock(&tz->lock);
>  			goto unbind;
>  		}
> @@ -1117,7 +1117,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
>  	}
>  
>  	if (temp >= trip_temp) {
> -		list_for_each_entry(instance, &tz->thermal_instances, node) {
> +		list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
>  			if (instance->trip != trip)
>  				continue;
>  
> @@ -1136,7 +1136,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
>  			cdev->ops->set_cur_state(cdev, cur_state);
>  		}
>  	} else {	/* below trip */
> -		list_for_each_entry(instance, &tz->thermal_instances, node) {
> +		list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
>  			if (instance->trip != trip)
>  				continue;
>  
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 08/13] Thermal: Rename thermal_zone_device.cooling_devices
  2012-07-26  8:41 ` [PATCH V4 08/13] Thermal: Rename thermal_zone_device.cooling_devices Zhang Rui
@ 2012-08-20 15:47   ` Eduardo Valentin
  0 siblings, 0 replies; 45+ messages in thread
From: Eduardo Valentin @ 2012-08-20 15:47 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Thu, Jul 26, 2012 at 04:41:18PM +0800, Zhang Rui wrote:
> Rename thermal_zone_device.cooling_devices
> to thermal_zone_device.thermal_instances
> 
> thermal_zone_device.cooling_devices is not accurate
> as this is a list for thermal instances, rather than cooling devices.
> 
> Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>

> ---
>  drivers/thermal/thermal_sys.c |   18 +++++++++---------
>  include/linux/thermal.h       |    4 ++--
>  2 files changed, 11 insertions(+), 11 deletions(-)
> 
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index 3d931c8..112227e 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -745,7 +745,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>  
>  		/* Heating up? */
>  		if (trend == THERMAL_TREND_RAISING) {
> -			list_for_each_entry(instance, &tz->cooling_devices,
> +			list_for_each_entry(instance, &tz->thermal_instances,
>  					    node) {
>  				if (instance->trip != trip)
>  					continue;
> @@ -756,7 +756,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>  					cdev->ops->set_cur_state(cdev, state);
>  			}
>  		} else if (trend == THERMAL_TREND_DROPPING) { /* Cooling off? */
> -			list_for_each_entry(instance, &tz->cooling_devices,
> +			list_for_each_entry(instance, &tz->thermal_instances,
>  					    node) {
>  				if (instance->trip != trip)
>  					continue;
> @@ -777,7 +777,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>  	 * and avoid thrashing around the passive trip point.  Note that we
>  	 * assume symmetry.
>  	 */
> -	list_for_each_entry(instance, &tz->cooling_devices, node) {
> +	list_for_each_entry(instance, &tz->thermal_instances, node) {
>  		if (instance->trip != trip)
>  			continue;
>  		cdev = instance->cdev;
> @@ -873,13 +873,13 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
>  		goto remove_symbol_link;
>  
>  	mutex_lock(&tz->lock);
> -	list_for_each_entry(pos, &tz->cooling_devices, node)
> +	list_for_each_entry(pos, &tz->thermal_instances, node)
>  	    if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
>  		result = -EEXIST;
>  		break;
>  	}
>  	if (!result)
> -		list_add_tail(&dev->node, &tz->cooling_devices);
> +		list_add_tail(&dev->node, &tz->thermal_instances);
>  	mutex_unlock(&tz->lock);
>  
>  	if (!result)
> @@ -912,7 +912,7 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
>  	struct thermal_instance *pos, *next;
>  
>  	mutex_lock(&tz->lock);
> -	list_for_each_entry_safe(pos, next, &tz->cooling_devices, node) {
> +	list_for_each_entry_safe(pos, next, &tz->thermal_instances, node) {
>  		if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
>  			list_del(&pos->node);
>  			mutex_unlock(&tz->lock);
> @@ -1117,7 +1117,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
>  	}
>  
>  	if (temp >= trip_temp) {
> -		list_for_each_entry(instance, &tz->cooling_devices, node) {
> +		list_for_each_entry(instance, &tz->thermal_instances, node) {
>  			if (instance->trip != trip)
>  				continue;
>  
> @@ -1136,7 +1136,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
>  			cdev->ops->set_cur_state(cdev, cur_state);
>  		}
>  	} else {	/* below trip */
> -		list_for_each_entry(instance, &tz->cooling_devices, node) {
> +		list_for_each_entry(instance, &tz->thermal_instances, node) {
>  			if (instance->trip != trip)
>  				continue;
>  
> @@ -1365,7 +1365,7 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
>  	if (!tz)
>  		return ERR_PTR(-ENOMEM);
>  
> -	INIT_LIST_HEAD(&tz->cooling_devices);
> +	INIT_LIST_HEAD(&tz->thermal_instances);
>  	idr_init(&tz->idr);
>  	mutex_init(&tz->lock);
>  	result = get_idr(&thermal_tz_idr, &thermal_idr_lock, &tz->id);
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index d18dcf6..b11db1e 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -122,9 +122,9 @@ struct thermal_zone_device {
>  	bool passive;
>  	unsigned int forced_passive;
>  	const struct thermal_zone_device_ops *ops;
> -	struct list_head cooling_devices;
> +	struct list_head thermal_instances;
>  	struct idr idr;
> -	struct mutex lock;	/* protect cooling devices list */
> +	struct mutex lock; /* protect thermal_instances list */
>  	struct list_head node;
>  	struct delayed_work poll_queue;
>  };
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 07/13] Thermal: rename structure thermal_cooling_device_instance to thermal_instance
  2012-07-26  8:41 ` [PATCH V4 07/13] Thermal: rename structure thermal_cooling_device_instance to thermal_instance Zhang Rui
@ 2012-08-20 15:47   ` Eduardo Valentin
  0 siblings, 0 replies; 45+ messages in thread
From: Eduardo Valentin @ 2012-08-20 15:47 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Thu, Jul 26, 2012 at 04:41:17PM +0800, Zhang Rui wrote:
> This struct is used to describe the behavior for a thermal
> cooling device on a certain trip point for a certain thremal zone.
> 
> thermal_cooling_device_instance is not accurate, as a cooling device
> can be used for more than one trip point in one thermal zone device.
> 
> Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>

> ---
>  drivers/thermal/thermal_sys.c |   18 +++++++++---------
>  1 file changed, 9 insertions(+), 9 deletions(-)
> 
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index f3156c1..3d931c8 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -46,7 +46,7 @@ MODULE_LICENSE("GPL");
>   * a certain cooling device on a certain trip point
>   * in a certain thermal zone
>   */
> -struct thermal_cooling_device_instance {
> +struct thermal_instance {
>  	int id;
>  	char name[THERMAL_NAME_LENGTH];
>  	struct thermal_zone_device *tz;
> @@ -430,10 +430,10 @@ static ssize_t
>  thermal_cooling_device_trip_point_show(struct device *dev,
>  				       struct device_attribute *attr, char *buf)
>  {
> -	struct thermal_cooling_device_instance *instance;
> +	struct thermal_instance *instance;
>  
>  	instance =
> -	    container_of(attr, struct thermal_cooling_device_instance, attr);
> +	    container_of(attr, struct thermal_instance, attr);
>  
>  	if (instance->trip == THERMAL_TRIPS_NONE)
>  		return sprintf(buf, "-1\n");
> @@ -716,7 +716,7 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>  					int temp, int trip_temp, int trip)
>  {
>  	enum thermal_trend trend;
> -	struct thermal_cooling_device_instance *instance;
> +	struct thermal_instance *instance;
>  	struct thermal_cooling_device *cdev;
>  	long state, max_state;
>  
> @@ -812,8 +812,8 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
>  				     struct thermal_cooling_device *cdev,
>  				     unsigned long upper, unsigned long lower)
>  {
> -	struct thermal_cooling_device_instance *dev;
> -	struct thermal_cooling_device_instance *pos;
> +	struct thermal_instance *dev;
> +	struct thermal_instance *pos;
>  	struct thermal_zone_device *pos1;
>  	struct thermal_cooling_device *pos2;
>  	unsigned long max_state;
> @@ -844,7 +844,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
>  		return -EINVAL;
>  
>  	dev =
> -	    kzalloc(sizeof(struct thermal_cooling_device_instance), GFP_KERNEL);
> +	    kzalloc(sizeof(struct thermal_instance), GFP_KERNEL);
>  	if (!dev)
>  		return -ENOMEM;
>  	dev->tz = tz;
> @@ -909,7 +909,7 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
>  				       int trip,
>  				       struct thermal_cooling_device *cdev)
>  {
> -	struct thermal_cooling_device_instance *pos, *next;
> +	struct thermal_instance *pos, *next;
>  
>  	mutex_lock(&tz->lock);
>  	list_for_each_entry_safe(pos, next, &tz->cooling_devices, node) {
> @@ -1095,7 +1095,7 @@ EXPORT_SYMBOL(thermal_cooling_device_unregister);
>  static void thermal_zone_trip_update(struct thermal_zone_device *tz,
>  				     int trip, long temp)
>  {
> -	struct thermal_cooling_device_instance *instance;
> +	struct thermal_instance *instance;
>  	struct thermal_cooling_device *cdev = NULL;
>  	unsigned long cur_state, max_state;
>  	long trip_temp;
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 06/13] Thermal: Introduce thermal_zone_trip_update()
  2012-07-26  8:41 ` [PATCH V4 06/13] Thermal: Introduce thermal_zone_trip_update() Zhang Rui
  2012-07-26 20:12   ` Rafael J. Wysocki
@ 2012-08-20 15:47   ` Eduardo Valentin
  2012-08-20 15:48   ` Eduardo Valentin
  2 siblings, 0 replies; 45+ messages in thread
From: Eduardo Valentin @ 2012-08-20 15:47 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Thu, Jul 26, 2012 at 04:41:16PM +0800, Zhang Rui wrote:
> 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 <rui.zhang@intel.com>

Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>

> ---
>  drivers/acpi/thermal.c        |    8 ++--
>  drivers/thermal/thermal_sys.c |  102 ++++++++++++++++++++++++++++++-----------
>  2 files changed, 81 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> index 0c755d2..a0b1e88 100644
> --- a/drivers/acpi/thermal.c
> +++ b/drivers/acpi/thermal.c
> @@ -714,9 +714,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,
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index a70ed4c..f3156c1 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -1076,6 +1076,81 @@ void thermal_cooling_device_unregister(struct
>  }
>  EXPORT_SYMBOL(thermal_cooling_device_unregister);
>  
> +/*
> + * Cooling algorithm for active trip points
> + *
> + * 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
> + *
> + * Note that this behaves the same as the previous passive cooling
> + * algorithm.
> + */
> +
> +static void thermal_zone_trip_update(struct thermal_zone_device *tz,
> +				     int trip, long temp)
> +{
> +	struct thermal_cooling_device_instance *instance;
> +	struct thermal_cooling_device *cdev = NULL;
> +	unsigned long cur_state, max_state;
> +	long trip_temp;
> +	enum thermal_trend trend;
> +
> +	tz->ops->get_trip_temp(tz, trip, &trip_temp);
> +
> +	if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
> +		/*
> +		 * compare the current temperature and previous temperature
> +		 * to get the thermal trend, if no special requirement
> +		 */
> +		if (tz->temperature > tz->last_temperature)
> +			trend = THERMAL_TREND_RAISING;
> +		else if (tz->temperature < tz->last_temperature)
> +			trend = THERMAL_TREND_DROPPING;
> +		else
> +			trend = THERMAL_TREND_STABLE;
> +	}
> +
> +	if (temp >= trip_temp) {
> +		list_for_each_entry(instance, &tz->cooling_devices, node) {
> +			if (instance->trip != trip)
> +				continue;
> +
> +			cdev = instance->cdev;
> +
> +			cdev->ops->get_cur_state(cdev, &cur_state);
> +			cdev->ops->get_max_state(cdev, &max_state);
> +
> +			if (trend == THERMAL_TREND_RAISING) {
> +				cur_state = cur_state < instance->upper ?
> +					    (cur_state + 1) : instance->upper;
> +			} else if (trend == THERMAL_TREND_DROPPING) {
> +				cur_state = cur_state > instance->lower ?
> +				    (cur_state - 1) : instance->lower;
> +			}
> +			cdev->ops->set_cur_state(cdev, cur_state);
> +		}
> +	} else {	/* below trip */
> +		list_for_each_entry(instance, &tz->cooling_devices, node) {
> +			if (instance->trip != trip)
> +				continue;
> +
> +			cdev = instance->cdev;
> +			cdev->ops->get_cur_state(cdev, &cur_state);
> +
> +			cur_state = cur_state > instance->lower ?
> +				    (cur_state - 1) : instance->lower;
> +			cdev->ops->set_cur_state(cdev, cur_state);
> +		}
> +	}
> +
> +	return;
> +}
>  /**
>   * thermal_zone_device_update - force an update of a thermal zone's state
>   * @ttz:	the thermal zone to update
> @@ -1086,9 +1161,6 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>  	int count, ret = 0;
>  	long temp, trip_temp;
>  	enum thermal_trip_type trip_type;
> -	struct thermal_cooling_device_instance *instance;
> -	struct thermal_cooling_device *cdev;
> -	unsigned long cur_state, max_state;
>  
>  	mutex_lock(&tz->lock);
>  
> @@ -1124,29 +1196,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>  					tz->ops->notify(tz, count, trip_type);
>  			break;
>  		case THERMAL_TRIP_ACTIVE:
> -			list_for_each_entry(instance, &tz->cooling_devices,
> -					    node) {
> -				if (instance->trip != count)
> -					continue;
> -
> -				cdev = instance->cdev;
> -
> -				cdev->ops->get_cur_state(cdev, &cur_state);
> -				cdev->ops->get_max_state(cdev, &max_state);
> -
> -				if (temp >= trip_temp)
> -					cur_state =
> -						cur_state < instance->upper ?
> -						(cur_state + 1) :
> -						instance->upper;
> -				else
> -					cur_state =
> -						cur_state > instance->lower ?
> -						(cur_state - 1) :
> -						instance->lower;
> -
> -				cdev->ops->set_cur_state(cdev, cur_state);
> -			}
> +			thermal_zone_trip_update(tz, count, temp);
>  			break;
>  		case THERMAL_TRIP_PASSIVE:
>  			if (temp >= trip_temp || tz->passive)
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 06/13] Thermal: Introduce thermal_zone_trip_update()
  2012-07-26  8:41 ` [PATCH V4 06/13] Thermal: Introduce thermal_zone_trip_update() Zhang Rui
  2012-07-26 20:12   ` Rafael J. Wysocki
  2012-08-20 15:47   ` Eduardo Valentin
@ 2012-08-20 15:48   ` Eduardo Valentin
  2 siblings, 0 replies; 45+ messages in thread
From: Eduardo Valentin @ 2012-08-20 15:48 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Thu, Jul 26, 2012 at 04:41:16PM +0800, Zhang Rui wrote:
> 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 <rui.zhang@intel.com>

Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>

> ---
>  drivers/acpi/thermal.c        |    8 ++--
>  drivers/thermal/thermal_sys.c |  102 ++++++++++++++++++++++++++++++-----------
>  2 files changed, 81 insertions(+), 29 deletions(-)
> 
> diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> index 0c755d2..a0b1e88 100644
> --- a/drivers/acpi/thermal.c
> +++ b/drivers/acpi/thermal.c
> @@ -714,9 +714,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,
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index a70ed4c..f3156c1 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -1076,6 +1076,81 @@ void thermal_cooling_device_unregister(struct
>  }
>  EXPORT_SYMBOL(thermal_cooling_device_unregister);
>  
> +/*
> + * Cooling algorithm for active trip points
> + *
> + * 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
> + *
> + * Note that this behaves the same as the previous passive cooling
> + * algorithm.
> + */
> +
> +static void thermal_zone_trip_update(struct thermal_zone_device *tz,
> +				     int trip, long temp)
> +{
> +	struct thermal_cooling_device_instance *instance;
> +	struct thermal_cooling_device *cdev = NULL;
> +	unsigned long cur_state, max_state;
> +	long trip_temp;
> +	enum thermal_trend trend;
> +
> +	tz->ops->get_trip_temp(tz, trip, &trip_temp);
> +
> +	if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip, &trend)) {
> +		/*
> +		 * compare the current temperature and previous temperature
> +		 * to get the thermal trend, if no special requirement
> +		 */
> +		if (tz->temperature > tz->last_temperature)
> +			trend = THERMAL_TREND_RAISING;
> +		else if (tz->temperature < tz->last_temperature)
> +			trend = THERMAL_TREND_DROPPING;
> +		else
> +			trend = THERMAL_TREND_STABLE;
> +	}
> +
> +	if (temp >= trip_temp) {
> +		list_for_each_entry(instance, &tz->cooling_devices, node) {
> +			if (instance->trip != trip)
> +				continue;
> +
> +			cdev = instance->cdev;
> +
> +			cdev->ops->get_cur_state(cdev, &cur_state);
> +			cdev->ops->get_max_state(cdev, &max_state);
> +
> +			if (trend == THERMAL_TREND_RAISING) {
> +				cur_state = cur_state < instance->upper ?
> +					    (cur_state + 1) : instance->upper;
> +			} else if (trend == THERMAL_TREND_DROPPING) {
> +				cur_state = cur_state > instance->lower ?
> +				    (cur_state - 1) : instance->lower;
> +			}
> +			cdev->ops->set_cur_state(cdev, cur_state);
> +		}
> +	} else {	/* below trip */
> +		list_for_each_entry(instance, &tz->cooling_devices, node) {
> +			if (instance->trip != trip)
> +				continue;
> +
> +			cdev = instance->cdev;
> +			cdev->ops->get_cur_state(cdev, &cur_state);
> +
> +			cur_state = cur_state > instance->lower ?
> +				    (cur_state - 1) : instance->lower;
> +			cdev->ops->set_cur_state(cdev, cur_state);
> +		}
> +	}
> +
> +	return;
> +}
>  /**
>   * thermal_zone_device_update - force an update of a thermal zone's state
>   * @ttz:	the thermal zone to update
> @@ -1086,9 +1161,6 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>  	int count, ret = 0;
>  	long temp, trip_temp;
>  	enum thermal_trip_type trip_type;
> -	struct thermal_cooling_device_instance *instance;
> -	struct thermal_cooling_device *cdev;
> -	unsigned long cur_state, max_state;
>  
>  	mutex_lock(&tz->lock);
>  
> @@ -1124,29 +1196,7 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>  					tz->ops->notify(tz, count, trip_type);
>  			break;
>  		case THERMAL_TRIP_ACTIVE:
> -			list_for_each_entry(instance, &tz->cooling_devices,
> -					    node) {
> -				if (instance->trip != count)
> -					continue;
> -
> -				cdev = instance->cdev;
> -
> -				cdev->ops->get_cur_state(cdev, &cur_state);
> -				cdev->ops->get_max_state(cdev, &max_state);
> -
> -				if (temp >= trip_temp)
> -					cur_state =
> -						cur_state < instance->upper ?
> -						(cur_state + 1) :
> -						instance->upper;
> -				else
> -					cur_state =
> -						cur_state > instance->lower ?
> -						(cur_state - 1) :
> -						instance->lower;
> -
> -				cdev->ops->set_cur_state(cdev, cur_state);
> -			}
> +			thermal_zone_trip_update(tz, count, temp);
>  			break;
>  		case THERMAL_TRIP_PASSIVE:
>  			if (temp >= trip_temp || tz->passive)
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 03/13] Thermal: set upper and lower limits
  2012-07-26  8:41 ` [PATCH V4 03/13] Thermal: set upper and lower limits Zhang Rui
@ 2012-08-20 15:50   ` Eduardo Valentin
  0 siblings, 0 replies; 45+ messages in thread
From: Eduardo Valentin @ 2012-08-20 15:50 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Thu, Jul 26, 2012 at 04:41:13PM +0800, Zhang Rui wrote:
> set upper and lower limits when binding
> a thermal cooling device to a thermal zone device.
> 
> Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

This patch still generates issues on omap-thermal-common.c, even on your thermal branch

A part from that, the patch is fine for me.

Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>


> ---
>  Documentation/thermal/sysfs-api.txt |    9 +++++-
>  drivers/acpi/thermal.c              |   53 +++++++++++++++++++++++------------
>  drivers/platform/x86/acerhdf.c      |    3 +-
>  drivers/thermal/thermal_sys.c       |   23 ++++++++++-----
>  include/linux/thermal.h             |    5 +++-
>  5 files changed, 65 insertions(+), 28 deletions(-)
> 
> diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt
> index c087dbc..ca1a1a3 100644
> --- a/Documentation/thermal/sysfs-api.txt
> +++ b/Documentation/thermal/sysfs-api.txt
> @@ -84,7 +84,8 @@ temperature) and throttle appropriate devices.
>  
>  1.3 interface for binding a thermal zone device with a thermal cooling device
>  1.3.1 int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
> -		int trip, struct thermal_cooling_device *cdev);
> +	int trip, struct thermal_cooling_device *cdev,
> +	unsigned long upper, unsigned long lower);
>  
>      This interface function bind a thermal cooling device to the certain trip
>      point of a thermal zone device.
> @@ -93,6 +94,12 @@ temperature) and throttle appropriate devices.
>      cdev: thermal cooling device
>      trip: indicates which trip point the cooling devices is associated with
>  	  in this thermal zone.
> +    upper:the Maximum cooling state for this trip point.
> +          THERMAL_NO_LIMIT means no upper limit,
> +	  and the cooling device can be in max_state.
> +    lower:the Minimum cooling state can be used for this trip point.
> +          THERMAL_NO_LIMIT means no lower limit,
> +	  and the cooling device can be in cooling state 0.
>  
>  1.3.2 int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
>  		int trip, struct thermal_cooling_device *cdev);
> diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> index 8275e7b..b48ec3e 100644
> --- a/drivers/acpi/thermal.c
> +++ b/drivers/acpi/thermal.c
> @@ -727,11 +727,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;
> @@ -755,11 +753,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;
>  		}
>  	}
>  
> @@ -772,11 +778,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;
>  		}
>  	}
>  
> @@ -784,7 +796,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;
>  		}
> @@ -798,16 +817,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 = {
> diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
> index 39abb15..a207466 100644
> --- a/drivers/platform/x86/acerhdf.c
> +++ b/drivers/platform/x86/acerhdf.c
> @@ -329,7 +329,8 @@ static int acerhdf_bind(struct thermal_zone_device *thermal,
>  	if (cdev != cl_dev)
>  		return 0;
>  
> -	if (thermal_zone_bind_cooling_device(thermal, 0, cdev)) {
> +	if (thermal_zone_bind_cooling_device(thermal, 0, cdev,
> +			THERMAL_NO_LIMIT, THERMAL_NO_LIMIT)) {
>  		pr_err("error binding cooling dev\n");
>  		return -EINVAL;
>  	}
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index 008e2eb..62b4279 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -315,8 +315,9 @@ passive_store(struct device *dev, struct device_attribute *attr,
>  			if (!strncmp("Processor", cdev->type,
>  				     sizeof("Processor")))
>  				thermal_zone_bind_cooling_device(tz,
> -								 THERMAL_TRIPS_NONE,
> -								 cdev);
> +						THERMAL_TRIPS_NONE, cdev,
> +						THERMAL_NO_LIMIT,
> +						THERMAL_NO_LIMIT);
>  		}
>  		mutex_unlock(&thermal_list_lock);
>  		if (!tz->passive_delay)
> @@ -801,7 +802,8 @@ static void thermal_zone_device_check(struct work_struct *work)
>   */
>  int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
>  				     int trip,
> -				     struct thermal_cooling_device *cdev)
> +				     struct thermal_cooling_device *cdev,
> +				     unsigned long upper, unsigned long lower)
>  {
>  	struct thermal_cooling_device_instance *dev;
>  	struct thermal_cooling_device_instance *pos;
> @@ -825,6 +827,15 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
>  	if (tz != pos1 || cdev != pos2)
>  		return -EINVAL;
>  
> +	cdev->ops->get_max_state(cdev, &max_state);
> +
> +	/* lower default 0, upper default max_state */
> +	lower = lower == THERMAL_NO_LIMIT ? 0 : lower;
> +	upper = upper == THERMAL_NO_LIMIT ? max_state : upper;
> +
> +	if (lower > upper || upper > max_state)
> +		return -EINVAL;
> +
>  	dev =
>  	    kzalloc(sizeof(struct thermal_cooling_device_instance), GFP_KERNEL);
>  	if (!dev)
> @@ -832,10 +843,8 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
>  	dev->tz = tz;
>  	dev->cdev = cdev;
>  	dev->trip = trip;
> -
> -	cdev->ops->get_max_state(cdev, &max_state);
> -	dev->upper = max_state;
> -	dev->lower = 0;
> +	dev->upper = upper;
> +	dev->lower = lower;
>  
>  	result = get_idr(&tz->idr, &tz->lock, &dev->id);
>  	if (result)
> diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> index cfc8d90..a43b12c 100644
> --- a/include/linux/thermal.h
> +++ b/include/linux/thermal.h
> @@ -75,6 +75,8 @@ struct thermal_cooling_device_ops {
>  	int (*set_cur_state) (struct thermal_cooling_device *, unsigned long);
>  };
>  
> +#define THERMAL_NO_LIMIT -1UL /* no upper/lower limit requirement */
> +
>  #define THERMAL_TRIPS_NONE -1
>  #define THERMAL_MAX_TRIPS 12
>  #define THERMAL_NAME_LENGTH 20
> @@ -157,7 +159,8 @@ struct thermal_zone_device *thermal_zone_device_register(char *, int, int,
>  void thermal_zone_device_unregister(struct thermal_zone_device *);
>  
>  int thermal_zone_bind_cooling_device(struct thermal_zone_device *, int,
> -				     struct thermal_cooling_device *);
> +				     struct thermal_cooling_device *,
> +				     unsigned long, unsigned long);
>  int thermal_zone_unbind_cooling_device(struct thermal_zone_device *, int,
>  				       struct thermal_cooling_device *);
>  void thermal_zone_device_update(struct thermal_zone_device *);
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 02/13] Thermal: Introduce cooling states range support
  2012-07-26  8:41 ` [PATCH V4 02/13] Thermal: Introduce cooling states range support Zhang Rui
@ 2012-08-20 15:51   ` Eduardo Valentin
  0 siblings, 0 replies; 45+ messages in thread
From: Eduardo Valentin @ 2012-08-20 15:51 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Thu, Jul 26, 2012 at 04:41:12PM +0800, Zhang Rui wrote:
> As the active cooling devices can have multiple cooling states,
> we may want only several cooling states for a certain trip point,
> and other cooling states for other active trip points.
> 
> To do this, we should be able to describe the cooling device
> behavior for a certain trip point, rather than for the entire thermal zone.
> And when updating thermal zone, we need to check the upper and lower limit
> to make sure the cooling device is set to the proper cooling state.
> 
> Note that this patch will not bring any different behavior as
> upper limit is set to max_state and lower limit is set to 0
> in this patch, for now.
> 
> Next patch will set these to real values.
> 
> Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>

> ---
>  drivers/thermal/thermal_sys.c |   25 +++++++++++++++++++++----
>  1 file changed, 21 insertions(+), 4 deletions(-)
> 
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index 05f42cd..008e2eb 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -41,12 +41,19 @@ MODULE_AUTHOR("Zhang Rui");
>  MODULE_DESCRIPTION("Generic thermal management sysfs support");
>  MODULE_LICENSE("GPL");
>  
> +/*
> + * This structure is used to describe the behavior of
> + * a certain cooling device on a certain trip point
> + * in a certain thermal zone
> + */
>  struct thermal_cooling_device_instance {
>  	int id;
>  	char name[THERMAL_NAME_LENGTH];
>  	struct thermal_zone_device *tz;
>  	struct thermal_cooling_device *cdev;
>  	int trip;
> +	unsigned long upper;	/* Highest cooling state for this trip point */
> +	unsigned long lower;	/* Lowest cooling state for this trip point */
>  	char attr_name[THERMAL_NAME_LENGTH];
>  	struct device_attribute attr;
>  	struct list_head node;
> @@ -800,6 +807,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
>  	struct thermal_cooling_device_instance *pos;
>  	struct thermal_zone_device *pos1;
>  	struct thermal_cooling_device *pos2;
> +	unsigned long max_state;
>  	int result;
>  
>  	if (trip >= tz->trips || (trip < 0 && trip != THERMAL_TRIPS_NONE))
> @@ -824,6 +832,11 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
>  	dev->tz = tz;
>  	dev->cdev = cdev;
>  	dev->trip = trip;
> +
> +	cdev->ops->get_max_state(cdev, &max_state);
> +	dev->upper = max_state;
> +	dev->lower = 0;
> +
>  	result = get_idr(&tz->idr, &tz->lock, &dev->id);
>  	if (result)
>  		goto free_mem;
> @@ -1103,11 +1116,15 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
>  				cdev->ops->get_max_state(cdev, &max_state);
>  
>  				if (temp >= trip_temp)
> -					cur_state = cur_state < max_state ?
> -						(cur_state + 1) : max_state;
> +					cur_state =
> +						cur_state < instance->upper ?
> +						(cur_state + 1) :
> +						instance->upper;
>  				else
> -					cur_state = cur_state > 0 ?
> -						(cur_state - 1) : 0;
> +					cur_state =
> +						cur_state > instance->lower ?
> +						(cur_state - 1) :
> +						instance->lower;
>  
>  				cdev->ops->set_cur_state(cdev, cur_state);
>  			}
> -- 
> 1.7.9.5
> 

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 00/13] Thermal: generic thermal layer enhancement
  2012-07-26  8:41 [PATCH V4 00/13] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (12 preceding siblings ...)
  2012-07-26  8:41 ` [PATCH V4 13/13] Thermal: Introduce locking for cdev.thermal_instances list Zhang Rui
@ 2012-08-20 15:53 ` Eduardo Valentin
  2012-08-21  5:10   ` Eduardo Valentin
  13 siblings, 1 reply; 45+ messages in thread
From: Eduardo Valentin @ 2012-08-20 15:53 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

Hello Rui,

On Thu, Jul 26, 2012 at 04:41:10PM +0800, Zhang Rui wrote:
> 
> Hi, all,
> 
> This is the patch set for linux-next.

The patch series looks good to me. The only issue is that, as now the omap-thermal
driver is under staging directory, you might want to update the series to cover it as
well (patches 03 and 05). I can provide you patches if you wish, but I'd recommend to
write atomic patches so that we always keep the tree in one piece.

Let me know what you think.

> 
> the changes includes:
> 
> V4:
> - dropped three patches which have been already picked by Len.
> - re-organize some piece of code based on Rafael's comments
> - improve some changelog
> 
> V3: http://marc.info/?l=linux-acpi&m=134318254518940&w=2
> - fixing a build error.
> - making a couple of changes based on Rafael's comments
> - removing the plist patch for now as I do not have validate data to show how much benefit it brings.
> 
> V2: http://marc.info/?l=linux-acpi&m=134267975014396&w=2
> - a couple of changes based on Eduardo and Amit's comments.
> - convert an internal list to plist to be more efficiency.
> 
> V1: http://marc.info/?l=linux-acpi&m=133938485224765&w=2
> - 12 RFC patches to fix the problems discussed in http://marc.info/?l=linux-acpi&m=133836783425764&w=2
> 
> please kindly review.
> 
> Any comments are welcome.
> 
> thanks,
> rui
> 
> ---------------------------------------------------------------------------
> Zhang Rui (13):
>       Thermal: Introduce multiple cooling states support
>       Thermal: Introduce cooling states range support
>       Thermal: set upper and lower limits
>       Thermal: Introduce .get_trend() callback.
>       Thermal: Remove tc1/tc2 in generic thermal layer.
>       Thermal: Introduce thermal_zone_trip_update()
>       Thermal: rename structure thermal_cooling_device_instance to thermal_instance
>       Thermal: Rename thermal_zone_device.cooling_devices to thermal_zone_device.instances
>       Thermal: Rename thermal_instance.node to thermal_instance.tz_node.
>       Thermal: List thermal_instance in thermal_cooling_device.
>       Thermal: Introduce simple arbitrator for setting device cooling state
>       Thermal: Unify the code for both active and passive cooling
>       Thermal: Introduce locking for cdev.thermal_instances
> ---------------------------------------------------------------------------
>  Documentation/thermal/sysfs-api.txt      |    9 +-
>  drivers/acpi/thermal.c                   |   98 +++++++---
>  drivers/platform/x86/acerhdf.c           |    5 +-
>  drivers/platform/x86/intel_mid_thermal.c |    2 +-
>  drivers/thermal/spear_thermal.c          |    2 +-
>  drivers/thermal/thermal_sys.c            |  308 +++++++++++++++++++-----------
>  include/linux/thermal.h                  |   28 ++-
>  7 files changed, 300 insertions(+), 152 deletions(-)
> ---------------------------------------------------------------------------

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 05/13] Thermal: Remove tc1/tc2 in generic thermal layer.
  2012-08-20 12:18         ` Eduardo Valentin
@ 2012-08-21  0:49           ` Zhang Rui
  2012-08-21 14:20             ` Eduardo Valentin
  0 siblings, 1 reply; 45+ messages in thread
From: Zhang Rui @ 2012-08-21  0:49 UTC (permalink / raw)
  To: eduardo.valentin
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On 一, 2012-08-20 at 15:18 +0300, Eduardo Valentin wrote:
> Hello,
> 
> On Thu, Aug 09, 2012 at 06:10:04PM +0300, Valentin, Eduardo wrote:
> > 
> > (resending the mail so that it reaches the mailing lists)
> > 
> > Nice, I checked your tree and this patch is fine for me. Next time you
> > send it out, you may want to add my reviewed-by:
> 
> Except that in your tree it is still introducing compilation issues under omap-thermal-common.c
> 
why, I think I have fixed that already.
would you please send an incremental patch so that I can apply it?

thanks,
rui
> > 
> > Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>
> 
> So, apart from the above comment, this patch is still fine for me.
> 
> > 
> > 
> > >
> > > thanks,
> > > rui
> > > > Apart from the compilation issues and the needed patch refresh, I am
> > > > good with the patch. And thanks for pushing this forward.
> > > >
> > > > >  6 files changed, 11 insertions(+), 29 deletions(-)
> > > > >
> > > > > diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> > > > > index 0c49e42..0c755d2 100644
> > > > > --- a/drivers/acpi/thermal.c
> > > > > +++ b/drivers/acpi/thermal.c
> > > > > @@ -895,15 +895,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;
> > > > > diff --git a/drivers/platform/x86/acerhdf.c
> > > > > b/drivers/platform/x86/acerhdf.c
> > > > > index a207466..84c5688 100644
> > > > > --- a/drivers/platform/x86/acerhdf.c
> > > > > +++ b/drivers/platform/x86/acerhdf.c
> > > > > @@ -662,7 +662,7 @@ static int acerhdf_register_thermal(void)
> > > > >                 return -EINVAL;
> > > > >
> > > > >         thz_dev = thermal_zone_device_register("acerhdf", 1, 0, NULL,
> > > > > -                                             &acerhdf_dev_ops, 0, 0,
> > > > > 0,
> > > > > +                                             &acerhdf_dev_ops, 0,
> > > > >                                               (kernelmode) ?
> > > > > interval*1000 : 0);
> > > > >         if (IS_ERR(thz_dev))
> > > > >                 return -EINVAL;
> > > > > diff --git a/drivers/platform/x86/intel_mid_thermal.c
> > > > > b/drivers/platform/x86/intel_mid_thermal.c
> > > > > index 2b2c212..6e309dd 100644
> > > > > --- a/drivers/platform/x86/intel_mid_thermal.c
> > > > > +++ b/drivers/platform/x86/intel_mid_thermal.c
> > > > > @@ -499,7 +499,7 @@ static int mid_thermal_probe(struct
> > > > > platform_device *pdev)
> > > > >                         goto err;
> > > > >                 }
> > > > >                 pinfo->tzd[i] = thermal_zone_device_register(name[i],
> > > > > -                               0, 0, td_info, &tzd_ops, 0, 0, 0, 0);
> > > > > +                               0, 0, td_info, &tzd_ops, 0, 0);
> > > > >                 if (IS_ERR(pinfo->tzd[i])) {
> > > > >                         kfree(td_info);
> > > > >                         ret = PTR_ERR(pinfo->tzd[i]);
> > > > > diff --git a/drivers/thermal/spear_thermal.c
> > > > > b/drivers/thermal/spear_thermal.c
> > > > > index 69a55d4..b55840a 100644
> > > > > --- a/drivers/thermal/spear_thermal.c
> > > > > +++ b/drivers/thermal/spear_thermal.c
> > > > > @@ -148,7 +148,7 @@ static int spear_thermal_probe(struct
> > > > > platform_device *pdev)
> > > > >         writel_relaxed(stdev->flags, stdev->thermal_base);
> > > > >
> > > > >         spear_thermal = thermal_zone_device_register("spear_thermal",
> > > > > 0, 0,
> > > > > -                               stdev, &ops, 0, 0, 0, 0);
> > > > > +                               stdev, &ops, 0, 0);
> > > > >         if (IS_ERR(spear_thermal)) {
> > > > >                 dev_err(&pdev->dev, "thermal zone device is NULL\n");
> > > > >                 ret = PTR_ERR(spear_thermal);
> > > > > diff --git a/drivers/thermal/thermal_sys.c
> > > > > b/drivers/thermal/thermal_sys.c
> > > > > index 68c93d4..a70ed4c 100644
> > > > > --- a/drivers/thermal/thermal_sys.c
> > > > > +++ b/drivers/thermal/thermal_sys.c
> > > > > @@ -335,9 +335,6 @@ passive_store(struct device *dev, struct
> > > > > device_attribute *attr,
> > > > >                 tz->passive_delay = 0;
> > > > >         }
> > > > >
> > > > > -       tz->tc1 = 1;
> > > > > -       tz->tc2 = 1;
> > > > > -
> > > > >         tz->forced_passive = state;
> > > > >
> > > > >         thermal_zone_device_update(tz);
> > > > > @@ -718,13 +715,12 @@ static void
> > > > > thermal_zone_device_set_polling(struct thermal_zone_device *tz,
> > > > >  static void thermal_zone_device_passive(struct thermal_zone_device
> > > > > *tz,
> > > > >                                         int temp, int trip_temp, int
> > > > > trip)
> > > > >  {
> > > > > -       int trend = 0;
> > > > > +       enum thermal_trend trend;
> > > > >         struct thermal_cooling_device_instance *instance;
> > > > >         struct thermal_cooling_device *cdev;
> > > > >         long state, max_state;
> > > > >
> > > > > -       if (!tz->ops->get_trend ||
> > > > > -           tz->ops->get_trend(tz, trip, (enum thermal_trend
> > > > > *)&trend)) {
> > > > > +       if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip,
> > > > > &trend)) {
> > > > >                 /*
> > > > >                  * compare the current temperature and previous
> > > > > temperature
> > > > >                  * to get the thermal trend, if no special requirement
> > > > > @@ -747,11 +743,8 @@ static void thermal_zone_device_passive(struct
> > > > > thermal_zone_device *tz,
> > > > >         if (temp >= trip_temp) {
> > > > >                 tz->passive = true;
> > > > >
> > > > > -               trend = (tz->tc1 * (temp - tz->last_temperature)) +
> > > > > -                       (tz->tc2 * (temp - trip_temp));
> > > > > -
> > > > >                 /* Heating up? */
> > > > > -               if (trend > 0) {
> > > > > +               if (trend == THERMAL_TREND_RAISING) {
> > > > >                         list_for_each_entry(instance,
> > > > > &tz->cooling_devices,
> > > > >                                             node) {
> > > > >                                 if (instance->trip != trip)
> > > > > @@ -762,7 +755,7 @@ static void thermal_zone_device_passive(struct
> > > > > thermal_zone_device *tz,
> > > > >                                 if (state++ < max_state)
> > > > >                                         cdev->ops->set_cur_state(cdev,
> > > > > state);
> > > > >                         }
> > > > > -               } else if (trend < 0) { /* Cooling off? */
> > > > > +               } else if (trend == THERMAL_TREND_DROPPING) { /*
> > > > > Cooling off? */
> > > > >                         list_for_each_entry(instance,
> > > > > &tz->cooling_devices,
> > > > >                                             node) {
> > > > >                                 if (instance->trip != trip)
> > > > > @@ -1288,8 +1281,6 @@ static void remove_trip_attrs(struct
> > > > > thermal_zone_device *tz)
> > > > >   * @mask:      a bit string indicating the writeablility of trip
> > > > > points
> > > > >   * @devdata:   private device data
> > > > >   * @ops:       standard thermal zone device callbacks
> > > > > - * @tc1:       thermal coefficient 1 for passive calculations
> > > > > - * @tc2:       thermal coefficient 2 for passive calculations
> > > > >   * @passive_delay: number of milliseconds to wait between polls when
> > > > >   *                performing passive cooling
> > > > >   * @polling_delay: number of milliseconds to wait between polls when
> > > > > checking
> > > > > @@ -1297,13 +1288,12 @@ static void remove_trip_attrs(struct
> > > > > thermal_zone_device *tz)
> > > > >   *                driven systems)
> > > > >   *
> > > > >   * thermal_zone_device_unregister() must be called when the device is
> > > > > no
> > > > > - * longer needed. The passive cooling formula uses tc1 and tc2 as
> > > > > described in
> > > > > - * section 11.1.5.1 of the ACPI specification 3.0.
> > > > > + * longer needed. The passive cooling depends on the .get_trend()
> > > > > return value.
> > > > >   */
> > > > >  struct thermal_zone_device *thermal_zone_device_register(char *type,
> > > > >         int trips, int mask, void *devdata,
> > > > >         const struct thermal_zone_device_ops *ops,
> > > > > -       int tc1, int tc2, int passive_delay, int polling_delay)
> > > > > +       int passive_delay, int polling_delay)
> > > > >  {
> > > > >         struct thermal_zone_device *tz;
> > > > >         struct thermal_cooling_device *pos;
> > > > > @@ -1339,8 +1329,6 @@ struct thermal_zone_device
> > > > > *thermal_zone_device_register(char *type,
> > > > >         tz->device.class = &thermal_class;
> > > > >         tz->devdata = devdata;
> > > > >         tz->trips = trips;
> > > > > -       tz->tc1 = tc1;
> > > > > -       tz->tc2 = tc2;
> > > > >         tz->passive_delay = passive_delay;
> > > > >         tz->polling_delay = polling_delay;
> > > > >
> > > > > diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> > > > > index a01e3e6..d18dcf6 100644
> > > > > --- a/include/linux/thermal.h
> > > > > +++ b/include/linux/thermal.h
> > > > > @@ -115,8 +115,6 @@ struct thermal_zone_device {
> > > > >         struct thermal_attr *trip_hyst_attrs;
> > > > >         void *devdata;
> > > > >         int trips;
> > > > > -       int tc1;
> > > > > -       int tc2;
> > > > >         int passive_delay;
> > > > >         int polling_delay;
> > > > >         int temperature;
> > > > > @@ -163,8 +161,7 @@ enum {
> > > > >  #define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
> > > > >
> > > > >  struct thermal_zone_device *thermal_zone_device_register(char *, int,
> > > > > int,
> > > > > -               void *, const struct thermal_zone_device_ops *, int
> > > > > tc1,
> > > > > -               int tc2, int passive_freq, int polling_freq);
> > > > > +               void *, const struct thermal_zone_device_ops *, int,
> > > > > int);
> > > > >  void thermal_zone_device_unregister(struct thermal_zone_device *);
> > > > >
> > > > >  int thermal_zone_bind_cooling_device(struct thermal_zone_device *,
> > > > > int,
> > > > > --
> > > > > 1.7.9.5
> > > > >
> > > >
> > > >
> > > >
> > >
> > >
> > 
> > 
> > 
> > --
> > 
> > Eduardo Valentin


--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 13/13] Thermal: Introduce locking for cdev.thermal_instances list.
  2012-08-20 15:45   ` Eduardo Valentin
@ 2012-08-21  0:53     ` Zhang Rui
  2012-08-21  5:01       ` Eduardo Valentin
  0 siblings, 1 reply; 45+ messages in thread
From: Zhang Rui @ 2012-08-21  0:53 UTC (permalink / raw)
  To: eduardo.valentin
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On 一, 2012-08-20 at 18:45 +0300, Eduardo Valentin wrote:
> Hello Rui,
> 
> On Thu, Jul 26, 2012 at 04:41:23PM +0800, Zhang Rui wrote:
> > we need to go over all the thermal_instance list of a cooling device
> > to decide which cooling state to put the cooling device to.
> > 
> > But at this time, as a cooling device may be referenced in multiple
> > thermal zones, we need to lock the list first in case
> > another thermal zone is updating this cooling device.
> > 
> > Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> 
> Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>
> 
> A minor comment bellow.
> 
> > ---
> >  drivers/thermal/thermal_sys.c |    8 ++++++++
> >  include/linux/thermal.h       |    1 +
> >  2 files changed, 9 insertions(+)
> > 
> > diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> > index 7f3a891..356a59d 100644
> > --- a/drivers/thermal/thermal_sys.c
> > +++ b/drivers/thermal/thermal_sys.c
> > @@ -799,6 +799,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
> >  		goto remove_symbol_link;
> >  
> >  	mutex_lock(&tz->lock);
> > +	mutex_lock(&cdev->lock);
> 
> Why do you need to lock while going through the tz thermal_instances?
> 
> >  	list_for_each_entry(pos, &tz->thermal_instances, tz_node)
> >  	    if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
> >  		result = -EEXIST;
> > @@ -808,6 +809,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
> >  		list_add_tail(&dev->tz_node, &tz->thermal_instances);
> >  		list_add_tail(&dev->cdev_node, &cdev->thermal_instances);
> 
> Locking the above operation should be enough, no?
> 
we need to add this thermal_instance to the cooling device
thermal_instance list.
say, what if another thermal zone that references this cooling device is
being unregistered at the same time?

thanks,
rui

> >  	}
> > +	mutex_unlock(&cdev->lock);
> >  	mutex_unlock(&tz->lock);
> >  
> >  	if (!result)
> > @@ -840,14 +842,17 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
> >  	struct thermal_instance *pos, *next;
> >  
> >  	mutex_lock(&tz->lock);
> > +	mutex_lock(&cdev->lock);
> >  	list_for_each_entry_safe(pos, next, &tz->thermal_instances, tz_node) {
> >  		if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
> >  			list_del(&pos->tz_node);
> >  			list_del(&pos->cdev_node);
> > +			mutex_unlock(&cdev->lock);
> >  			mutex_unlock(&tz->lock);
> >  			goto unbind;
> >  		}
> >  	}
> > +	mutex_unlock(&cdev->lock);
> >  	mutex_unlock(&tz->lock);
> >  
> >  	return -ENODEV;
> > @@ -913,6 +918,7 @@ thermal_cooling_device_register(char *type, void *devdata,
> >  	}
> >  
> >  	strcpy(cdev->type, type);
> > +	mutex_init(&cdev->lock);
> >  	INIT_LIST_HEAD(&cdev->thermal_instances);
> >  	cdev->ops = ops;
> >  	cdev->updated = true;
> > @@ -1016,6 +1022,7 @@ static void thermal_cdev_do_update(struct thermal_cooling_device *cdev)
> >  	if (cdev->updated)
> >  		return;
> >  
> > +	mutex_lock(&cdev->lock);
> >  	/* Make sure cdev enters the deepest cooling state */
> >  	list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
> >  		if (instance->target == THERMAL_NO_TARGET)
> > @@ -1023,6 +1030,7 @@ static void thermal_cdev_do_update(struct thermal_cooling_device *cdev)
> >  		if (instance->target > target)
> >  			target = instance->target;
> >  	}
> > +	mutex_unlock(&cdev->lock);
> >  	cdev->ops->set_cur_state(cdev, target);
> >  	cdev->updated = true;
> >  }
> > diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> > index 06fd04d..d02d06d 100644
> > --- a/include/linux/thermal.h
> > +++ b/include/linux/thermal.h
> > @@ -95,6 +95,7 @@ struct thermal_cooling_device {
> >  	void *devdata;
> >  	const struct thermal_cooling_device_ops *ops;
> >  	bool updated; /* true if the cooling device does not need update */
> > +	struct mutex lock; /* protect thermal_instances list */
> >  	struct list_head thermal_instances;
> >  	struct list_head node;
> >  };
> > -- 
> > 1.7.9.5
> > 


--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 13/13] Thermal: Introduce locking for cdev.thermal_instances list.
  2012-08-21  0:53     ` Zhang Rui
@ 2012-08-21  5:01       ` Eduardo Valentin
  0 siblings, 0 replies; 45+ messages in thread
From: Eduardo Valentin @ 2012-08-21  5:01 UTC (permalink / raw)
  To: Zhang Rui
  Cc: eduardo.valentin, Rafael J. Wysocki, Matthew Garrett, Len Brown,
	R Durgadoss, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

Hello,

On Tue, Aug 21, 2012 at 08:53:27AM +0800, Zhang Rui wrote:
> On 一, 2012-08-20 at 18:45 +0300, Eduardo Valentin wrote:
> > Hello Rui,
> > 
> > On Thu, Jul 26, 2012 at 04:41:23PM +0800, Zhang Rui wrote:
> > > we need to go over all the thermal_instance list of a cooling device
> > > to decide which cooling state to put the cooling device to.
> > > 
> > > But at this time, as a cooling device may be referenced in multiple
> > > thermal zones, we need to lock the list first in case
> > > another thermal zone is updating this cooling device.
> > > 
> > > Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> > 
> > Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>
> > 
> > A minor comment bellow.
> > 
> > > ---
> > >  drivers/thermal/thermal_sys.c |    8 ++++++++
> > >  include/linux/thermal.h       |    1 +
> > >  2 files changed, 9 insertions(+)
> > > 
> > > diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> > > index 7f3a891..356a59d 100644
> > > --- a/drivers/thermal/thermal_sys.c
> > > +++ b/drivers/thermal/thermal_sys.c
> > > @@ -799,6 +799,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
> > >  		goto remove_symbol_link;
> > >  
> > >  	mutex_lock(&tz->lock);
> > > +	mutex_lock(&cdev->lock);
> > 
> > Why do you need to lock while going through the tz thermal_instances?
> > 
> > >  	list_for_each_entry(pos, &tz->thermal_instances, tz_node)
> > >  	    if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
> > >  		result = -EEXIST;
> > > @@ -808,6 +809,7 @@ int thermal_zone_bind_cooling_device(struct thermal_zone_device *tz,
> > >  		list_add_tail(&dev->tz_node, &tz->thermal_instances);
> > >  		list_add_tail(&dev->cdev_node, &cdev->thermal_instances);
> > 
> > Locking the above operation should be enough, no?
> > 
> we need to add this thermal_instance to the cooling device
> thermal_instance list.
> say, what if another thermal zone that references this cooling device is
> being unregistered at the same time?

Well yes, that part I got it. But do you need to lock the cdev->lock
while doing the search under tz->thermal_instances?

I believe you need to lock it only while adding it to cdev->thermal_instances.
That would cover the situation you are talking about.

> 
> thanks,
> rui
> 
> > >  	}
> > > +	mutex_unlock(&cdev->lock);
> > >  	mutex_unlock(&tz->lock);
> > >  
> > >  	if (!result)
> > > @@ -840,14 +842,17 @@ int thermal_zone_unbind_cooling_device(struct thermal_zone_device *tz,
> > >  	struct thermal_instance *pos, *next;
> > >  
> > >  	mutex_lock(&tz->lock);
> > > +	mutex_lock(&cdev->lock);
> > >  	list_for_each_entry_safe(pos, next, &tz->thermal_instances, tz_node) {
> > >  		if (pos->tz == tz && pos->trip == trip && pos->cdev == cdev) {
> > >  			list_del(&pos->tz_node);
> > >  			list_del(&pos->cdev_node);
> > > +			mutex_unlock(&cdev->lock);
> > >  			mutex_unlock(&tz->lock);
> > >  			goto unbind;
> > >  		}
> > >  	}
> > > +	mutex_unlock(&cdev->lock);
> > >  	mutex_unlock(&tz->lock);
> > >  
> > >  	return -ENODEV;
> > > @@ -913,6 +918,7 @@ thermal_cooling_device_register(char *type, void *devdata,
> > >  	}
> > >  
> > >  	strcpy(cdev->type, type);
> > > +	mutex_init(&cdev->lock);
> > >  	INIT_LIST_HEAD(&cdev->thermal_instances);
> > >  	cdev->ops = ops;
> > >  	cdev->updated = true;
> > > @@ -1016,6 +1022,7 @@ static void thermal_cdev_do_update(struct thermal_cooling_device *cdev)
> > >  	if (cdev->updated)
> > >  		return;
> > >  
> > > +	mutex_lock(&cdev->lock);
> > >  	/* Make sure cdev enters the deepest cooling state */
> > >  	list_for_each_entry(instance, &cdev->thermal_instances, cdev_node) {
> > >  		if (instance->target == THERMAL_NO_TARGET)
> > > @@ -1023,6 +1030,7 @@ static void thermal_cdev_do_update(struct thermal_cooling_device *cdev)
> > >  		if (instance->target > target)
> > >  			target = instance->target;
> > >  	}
> > > +	mutex_unlock(&cdev->lock);
> > >  	cdev->ops->set_cur_state(cdev, target);
> > >  	cdev->updated = true;
> > >  }
> > > diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> > > index 06fd04d..d02d06d 100644
> > > --- a/include/linux/thermal.h
> > > +++ b/include/linux/thermal.h
> > > @@ -95,6 +95,7 @@ struct thermal_cooling_device {
> > >  	void *devdata;
> > >  	const struct thermal_cooling_device_ops *ops;
> > >  	bool updated; /* true if the cooling device does not need update */
> > > +	struct mutex lock; /* protect thermal_instances list */
> > >  	struct list_head thermal_instances;
> > >  	struct list_head node;
> > >  };
> > > -- 
> > > 1.7.9.5
> > > 
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 00/13] Thermal: generic thermal layer enhancement
  2012-08-20 15:53 ` [PATCH V4 00/13] Thermal: generic thermal layer enhancement Eduardo Valentin
@ 2012-08-21  5:10   ` Eduardo Valentin
  0 siblings, 0 replies; 45+ messages in thread
From: Eduardo Valentin @ 2012-08-21  5:10 UTC (permalink / raw)
  To: Eduardo Valentin
  Cc: Zhang Rui, Rafael J. Wysocki, Matthew Garrett, Len Brown,
	R Durgadoss, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

Hello Rui,

On Mon, Aug 20, 2012 at 06:53:36PM +0300, Eduardo Valentin wrote:
> Hello Rui,
> 
> On Thu, Jul 26, 2012 at 04:41:10PM +0800, Zhang Rui wrote:
> > 
> > Hi, all,
> > 
> > This is the patch set for linux-next.
> 
> The patch series looks good to me. The only issue is that, as now the omap-thermal
> driver is under staging directory, you might want to update the series to cover it as
> well (patches 03 and 05). I can provide you patches if you wish, but I'd recommend to
> write atomic patches so that we always keep the tree in one piece.
> 
> Let me know what you think.

Here is the differential diff on omap-thermal-common.c, on top of this series, which pretty much same diff
compared to your branch. First hunk is on patch 03/13. Second one on patch 05/13. Feel free to include
those on your patches.

diff --git a/drivers/staging/omap-thermal/omap-thermal-common.c b/drivers/staging/omap-thermal/omap-thermal-common.c
index 0675a5e..b4cd6cc 100644
--- a/drivers/staging/omap-thermal/omap-thermal-common.c
+++ b/drivers/staging/omap-thermal/omap-thermal-common.c
@@ -120,7 +120,9 @@ static int omap_thermal_bind(struct thermal_zone_device *thermal,
 
        /* TODO: bind with min and max states */
        /* Simple thing, two trips, one passive another critical */
-       return thermal_zone_bind_cooling_device(thermal, 0, cdev);
+       return thermal_zone_bind_cooling_device(thermal, 0, cdev,
+                                               THERMAL_NO_LIMIT,
+                                               THERMAL_NO_LIMIT);
 }
 
 /* Unbind callback functions for thermal zone */
@@ -246,7 +248,7 @@ int omap_thermal_expose_sensor(struct omap_bandgap *bg_ptr, int id,
        /* Create thermal zone */
        data->omap_thermal = thermal_zone_device_register(domain,
                                OMAP_TRIP_NUMBER, 0, data, &omap_thermal_ops,
-                               0, FAST_TEMP_MONITORING_RATE, 0, 0);
+                               0, FAST_TEMP_MONITORING_RATE);
        if (IS_ERR_OR_NULL(data->omap_thermal)) {
                dev_err(bg_ptr->dev, "thermal zone device is NULL\n");
                return PTR_ERR(data->omap_thermal);


> 
> > 
> > the changes includes:
> > 
> > V4:
> > - dropped three patches which have been already picked by Len.
> > - re-organize some piece of code based on Rafael's comments
> > - improve some changelog
> > 
> > V3: http://marc.info/?l=linux-acpi&m=134318254518940&w=2
> > - fixing a build error.
> > - making a couple of changes based on Rafael's comments
> > - removing the plist patch for now as I do not have validate data to show how much benefit it brings.
> > 
> > V2: http://marc.info/?l=linux-acpi&m=134267975014396&w=2
> > - a couple of changes based on Eduardo and Amit's comments.
> > - convert an internal list to plist to be more efficiency.
> > 
> > V1: http://marc.info/?l=linux-acpi&m=133938485224765&w=2
> > - 12 RFC patches to fix the problems discussed in http://marc.info/?l=linux-acpi&m=133836783425764&w=2
> > 
> > please kindly review.
> > 
> > Any comments are welcome.
> > 
> > thanks,
> > rui
> > 
> > ---------------------------------------------------------------------------
> > Zhang Rui (13):
> >       Thermal: Introduce multiple cooling states support
> >       Thermal: Introduce cooling states range support
> >       Thermal: set upper and lower limits
> >       Thermal: Introduce .get_trend() callback.
> >       Thermal: Remove tc1/tc2 in generic thermal layer.
> >       Thermal: Introduce thermal_zone_trip_update()
> >       Thermal: rename structure thermal_cooling_device_instance to thermal_instance
> >       Thermal: Rename thermal_zone_device.cooling_devices to thermal_zone_device.instances
> >       Thermal: Rename thermal_instance.node to thermal_instance.tz_node.
> >       Thermal: List thermal_instance in thermal_cooling_device.
> >       Thermal: Introduce simple arbitrator for setting device cooling state
> >       Thermal: Unify the code for both active and passive cooling
> >       Thermal: Introduce locking for cdev.thermal_instances
> > ---------------------------------------------------------------------------
> >  Documentation/thermal/sysfs-api.txt      |    9 +-
> >  drivers/acpi/thermal.c                   |   98 +++++++---
> >  drivers/platform/x86/acerhdf.c           |    5 +-
> >  drivers/platform/x86/intel_mid_thermal.c |    2 +-
> >  drivers/thermal/spear_thermal.c          |    2 +-
> >  drivers/thermal/thermal_sys.c            |  308 +++++++++++++++++++-----------
> >  include/linux/thermal.h                  |   28 ++-
> >  7 files changed, 300 insertions(+), 152 deletions(-)
> > ---------------------------------------------------------------------------

^ permalink raw reply related	[flat|nested] 45+ messages in thread

* Re: [PATCH V4 05/13] Thermal: Remove tc1/tc2 in generic thermal layer.
  2012-08-21  0:49           ` Zhang Rui
@ 2012-08-21 14:20             ` Eduardo Valentin
  0 siblings, 0 replies; 45+ messages in thread
From: Eduardo Valentin @ 2012-08-21 14:20 UTC (permalink / raw)
  To: Zhang Rui
  Cc: eduardo.valentin, Rafael J. Wysocki, Matthew Garrett, Len Brown,
	R Durgadoss, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

Hello,

On Tue, Aug 21, 2012 at 08:49:42AM +0800, Zhang Rui wrote:
> On 一, 2012-08-20 at 15:18 +0300, Eduardo Valentin wrote:
> > Hello,
> > 
> > On Thu, Aug 09, 2012 at 06:10:04PM +0300, Valentin, Eduardo wrote:
> > > 
> > > (resending the mail so that it reaches the mailing lists)
> > > 
> > > Nice, I checked your tree and this patch is fine for me. Next time you
> > > send it out, you may want to add my reviewed-by:
> > 
> > Except that in your tree it is still introducing compilation issues under omap-thermal-common.c
> > 
> why, I think I have fixed that already.
> would you please send an incremental patch so that I can apply it?


FYI, I sent as reply to your patch 0/13 a plain diff of including the needed changes in order to keep the code
in one piece after this series.

But as the driver is under staging, maybe it makes sense to send this change separately, to Greg K.

Posting here anyway:
diff --git a/drivers/staging/omap-thermal/omap-thermal-common.c b/drivers/staging/omap-thermal/omap-thermal-common.c
index 0675a5e..b4cd6cc 100644
--- a/drivers/staging/omap-thermal/omap-thermal-common.c
+++ b/drivers/staging/omap-thermal/omap-thermal-common.c
@@ -120,7 +120,9 @@ static int omap_thermal_bind(struct thermal_zone_device *thermal,
 
        /* TODO: bind with min and max states */
        /* Simple thing, two trips, one passive another critical */
-       return thermal_zone_bind_cooling_device(thermal, 0, cdev);
+       return thermal_zone_bind_cooling_device(thermal, 0, cdev,
+                                               THERMAL_NO_LIMIT,
+                                               THERMAL_NO_LIMIT);
 }
 
 /* Unbind callback functions for thermal zone */
@@ -246,7 +248,7 @@ int omap_thermal_expose_sensor(struct omap_bandgap *bg_ptr, int id,
        /* Create thermal zone */
        data->omap_thermal = thermal_zone_device_register(domain,
                                OMAP_TRIP_NUMBER, 0, data, &omap_thermal_ops,
-                               0, FAST_TEMP_MONITORING_RATE, 0, 0);
+                               0, FAST_TEMP_MONITORING_RATE);
        if (IS_ERR_OR_NULL(data->omap_thermal)) {
                dev_err(bg_ptr->dev, "thermal zone device is NULL\n");
                return PTR_ERR(data->omap_thermal);



> 
> thanks,
> rui
> > > 
> > > Reviewed-by: Eduardo Valentin <eduardo.valentin@ti.com>
> > 
> > So, apart from the above comment, this patch is still fine for me.
> > 
> > > 
> > > 
> > > >
> > > > thanks,
> > > > rui
> > > > > Apart from the compilation issues and the needed patch refresh, I am
> > > > > good with the patch. And thanks for pushing this forward.
> > > > >
> > > > > >  6 files changed, 11 insertions(+), 29 deletions(-)
> > > > > >
> > > > > > diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> > > > > > index 0c49e42..0c755d2 100644
> > > > > > --- a/drivers/acpi/thermal.c
> > > > > > +++ b/drivers/acpi/thermal.c
> > > > > > @@ -895,15 +895,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;
> > > > > > diff --git a/drivers/platform/x86/acerhdf.c
> > > > > > b/drivers/platform/x86/acerhdf.c
> > > > > > index a207466..84c5688 100644
> > > > > > --- a/drivers/platform/x86/acerhdf.c
> > > > > > +++ b/drivers/platform/x86/acerhdf.c
> > > > > > @@ -662,7 +662,7 @@ static int acerhdf_register_thermal(void)
> > > > > >                 return -EINVAL;
> > > > > >
> > > > > >         thz_dev = thermal_zone_device_register("acerhdf", 1, 0, NULL,
> > > > > > -                                             &acerhdf_dev_ops, 0, 0,
> > > > > > 0,
> > > > > > +                                             &acerhdf_dev_ops, 0,
> > > > > >                                               (kernelmode) ?
> > > > > > interval*1000 : 0);
> > > > > >         if (IS_ERR(thz_dev))
> > > > > >                 return -EINVAL;
> > > > > > diff --git a/drivers/platform/x86/intel_mid_thermal.c
> > > > > > b/drivers/platform/x86/intel_mid_thermal.c
> > > > > > index 2b2c212..6e309dd 100644
> > > > > > --- a/drivers/platform/x86/intel_mid_thermal.c
> > > > > > +++ b/drivers/platform/x86/intel_mid_thermal.c
> > > > > > @@ -499,7 +499,7 @@ static int mid_thermal_probe(struct
> > > > > > platform_device *pdev)
> > > > > >                         goto err;
> > > > > >                 }
> > > > > >                 pinfo->tzd[i] = thermal_zone_device_register(name[i],
> > > > > > -                               0, 0, td_info, &tzd_ops, 0, 0, 0, 0);
> > > > > > +                               0, 0, td_info, &tzd_ops, 0, 0);
> > > > > >                 if (IS_ERR(pinfo->tzd[i])) {
> > > > > >                         kfree(td_info);
> > > > > >                         ret = PTR_ERR(pinfo->tzd[i]);
> > > > > > diff --git a/drivers/thermal/spear_thermal.c
> > > > > > b/drivers/thermal/spear_thermal.c
> > > > > > index 69a55d4..b55840a 100644
> > > > > > --- a/drivers/thermal/spear_thermal.c
> > > > > > +++ b/drivers/thermal/spear_thermal.c
> > > > > > @@ -148,7 +148,7 @@ static int spear_thermal_probe(struct
> > > > > > platform_device *pdev)
> > > > > >         writel_relaxed(stdev->flags, stdev->thermal_base);
> > > > > >
> > > > > >         spear_thermal = thermal_zone_device_register("spear_thermal",
> > > > > > 0, 0,
> > > > > > -                               stdev, &ops, 0, 0, 0, 0);
> > > > > > +                               stdev, &ops, 0, 0);
> > > > > >         if (IS_ERR(spear_thermal)) {
> > > > > >                 dev_err(&pdev->dev, "thermal zone device is NULL\n");
> > > > > >                 ret = PTR_ERR(spear_thermal);
> > > > > > diff --git a/drivers/thermal/thermal_sys.c
> > > > > > b/drivers/thermal/thermal_sys.c
> > > > > > index 68c93d4..a70ed4c 100644
> > > > > > --- a/drivers/thermal/thermal_sys.c
> > > > > > +++ b/drivers/thermal/thermal_sys.c
> > > > > > @@ -335,9 +335,6 @@ passive_store(struct device *dev, struct
> > > > > > device_attribute *attr,
> > > > > >                 tz->passive_delay = 0;
> > > > > >         }
> > > > > >
> > > > > > -       tz->tc1 = 1;
> > > > > > -       tz->tc2 = 1;
> > > > > > -
> > > > > >         tz->forced_passive = state;
> > > > > >
> > > > > >         thermal_zone_device_update(tz);
> > > > > > @@ -718,13 +715,12 @@ static void
> > > > > > thermal_zone_device_set_polling(struct thermal_zone_device *tz,
> > > > > >  static void thermal_zone_device_passive(struct thermal_zone_device
> > > > > > *tz,
> > > > > >                                         int temp, int trip_temp, int
> > > > > > trip)
> > > > > >  {
> > > > > > -       int trend = 0;
> > > > > > +       enum thermal_trend trend;
> > > > > >         struct thermal_cooling_device_instance *instance;
> > > > > >         struct thermal_cooling_device *cdev;
> > > > > >         long state, max_state;
> > > > > >
> > > > > > -       if (!tz->ops->get_trend ||
> > > > > > -           tz->ops->get_trend(tz, trip, (enum thermal_trend
> > > > > > *)&trend)) {
> > > > > > +       if (!tz->ops->get_trend || tz->ops->get_trend(tz, trip,
> > > > > > &trend)) {
> > > > > >                 /*
> > > > > >                  * compare the current temperature and previous
> > > > > > temperature
> > > > > >                  * to get the thermal trend, if no special requirement
> > > > > > @@ -747,11 +743,8 @@ static void thermal_zone_device_passive(struct
> > > > > > thermal_zone_device *tz,
> > > > > >         if (temp >= trip_temp) {
> > > > > >                 tz->passive = true;
> > > > > >
> > > > > > -               trend = (tz->tc1 * (temp - tz->last_temperature)) +
> > > > > > -                       (tz->tc2 * (temp - trip_temp));
> > > > > > -
> > > > > >                 /* Heating up? */
> > > > > > -               if (trend > 0) {
> > > > > > +               if (trend == THERMAL_TREND_RAISING) {
> > > > > >                         list_for_each_entry(instance,
> > > > > > &tz->cooling_devices,
> > > > > >                                             node) {
> > > > > >                                 if (instance->trip != trip)
> > > > > > @@ -762,7 +755,7 @@ static void thermal_zone_device_passive(struct
> > > > > > thermal_zone_device *tz,
> > > > > >                                 if (state++ < max_state)
> > > > > >                                         cdev->ops->set_cur_state(cdev,
> > > > > > state);
> > > > > >                         }
> > > > > > -               } else if (trend < 0) { /* Cooling off? */
> > > > > > +               } else if (trend == THERMAL_TREND_DROPPING) { /*
> > > > > > Cooling off? */
> > > > > >                         list_for_each_entry(instance,
> > > > > > &tz->cooling_devices,
> > > > > >                                             node) {
> > > > > >                                 if (instance->trip != trip)
> > > > > > @@ -1288,8 +1281,6 @@ static void remove_trip_attrs(struct
> > > > > > thermal_zone_device *tz)
> > > > > >   * @mask:      a bit string indicating the writeablility of trip
> > > > > > points
> > > > > >   * @devdata:   private device data
> > > > > >   * @ops:       standard thermal zone device callbacks
> > > > > > - * @tc1:       thermal coefficient 1 for passive calculations
> > > > > > - * @tc2:       thermal coefficient 2 for passive calculations
> > > > > >   * @passive_delay: number of milliseconds to wait between polls when
> > > > > >   *                performing passive cooling
> > > > > >   * @polling_delay: number of milliseconds to wait between polls when
> > > > > > checking
> > > > > > @@ -1297,13 +1288,12 @@ static void remove_trip_attrs(struct
> > > > > > thermal_zone_device *tz)
> > > > > >   *                driven systems)
> > > > > >   *
> > > > > >   * thermal_zone_device_unregister() must be called when the device is
> > > > > > no
> > > > > > - * longer needed. The passive cooling formula uses tc1 and tc2 as
> > > > > > described in
> > > > > > - * section 11.1.5.1 of the ACPI specification 3.0.
> > > > > > + * longer needed. The passive cooling depends on the .get_trend()
> > > > > > return value.
> > > > > >   */
> > > > > >  struct thermal_zone_device *thermal_zone_device_register(char *type,
> > > > > >         int trips, int mask, void *devdata,
> > > > > >         const struct thermal_zone_device_ops *ops,
> > > > > > -       int tc1, int tc2, int passive_delay, int polling_delay)
> > > > > > +       int passive_delay, int polling_delay)
> > > > > >  {
> > > > > >         struct thermal_zone_device *tz;
> > > > > >         struct thermal_cooling_device *pos;
> > > > > > @@ -1339,8 +1329,6 @@ struct thermal_zone_device
> > > > > > *thermal_zone_device_register(char *type,
> > > > > >         tz->device.class = &thermal_class;
> > > > > >         tz->devdata = devdata;
> > > > > >         tz->trips = trips;
> > > > > > -       tz->tc1 = tc1;
> > > > > > -       tz->tc2 = tc2;
> > > > > >         tz->passive_delay = passive_delay;
> > > > > >         tz->polling_delay = polling_delay;
> > > > > >
> > > > > > diff --git a/include/linux/thermal.h b/include/linux/thermal.h
> > > > > > index a01e3e6..d18dcf6 100644
> > > > > > --- a/include/linux/thermal.h
> > > > > > +++ b/include/linux/thermal.h
> > > > > > @@ -115,8 +115,6 @@ struct thermal_zone_device {
> > > > > >         struct thermal_attr *trip_hyst_attrs;
> > > > > >         void *devdata;
> > > > > >         int trips;
> > > > > > -       int tc1;
> > > > > > -       int tc2;
> > > > > >         int passive_delay;
> > > > > >         int polling_delay;
> > > > > >         int temperature;
> > > > > > @@ -163,8 +161,7 @@ enum {
> > > > > >  #define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
> > > > > >
> > > > > >  struct thermal_zone_device *thermal_zone_device_register(char *, int,
> > > > > > int,
> > > > > > -               void *, const struct thermal_zone_device_ops *, int
> > > > > > tc1,
> > > > > > -               int tc2, int passive_freq, int polling_freq);
> > > > > > +               void *, const struct thermal_zone_device_ops *, int,
> > > > > > int);
> > > > > >  void thermal_zone_device_unregister(struct thermal_zone_device *);
> > > > > >
> > > > > >  int thermal_zone_bind_cooling_device(struct thermal_zone_device *,
> > > > > > int,
> > > > > > --
> > > > > > 1.7.9.5
> > > > > >
> > > > >
> > > > >
> > > > >
> > > >
> > > >
> > > 
> > > 
> > > 
> > > --
> > > 
> > > Eduardo Valentin
> 
> 
--
To unsubscribe from this list: send the line "unsubscribe linux-acpi" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html

^ permalink raw reply related	[flat|nested] 45+ messages in thread

end of thread, other threads:[~2012-08-21 14:20 UTC | newest]

Thread overview: 45+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-26  8:41 [PATCH V4 00/13] Thermal: generic thermal layer enhancement Zhang Rui
2012-07-26  8:41 ` [PATCH V4 01/13] Thermal: Introduce multiple cooling states support Zhang Rui
2012-08-08 12:02   ` Valentin, Eduardo
2012-08-09  0:58     ` Zhang Rui
2012-07-26  8:41 ` [PATCH V4 02/13] Thermal: Introduce cooling states range support Zhang Rui
2012-08-20 15:51   ` Eduardo Valentin
2012-07-26  8:41 ` [PATCH V4 03/13] Thermal: set upper and lower limits Zhang Rui
2012-08-20 15:50   ` Eduardo Valentin
2012-07-26  8:41 ` [PATCH V4 04/13] Thermal: Introduce .get_trend() callback Zhang Rui
2012-07-26 20:11   ` Rafael J. Wysocki
2012-08-01  2:42     ` Zhang Rui
2012-08-08 13:46       ` Valentin, Eduardo
2012-08-08 13:44   ` Valentin, Eduardo
2012-07-26  8:41 ` [PATCH V4 05/13] Thermal: Remove tc1/tc2 in generic thermal layer Zhang Rui
2012-07-26 20:11   ` Rafael J. Wysocki
2012-08-08 14:06   ` Valentin, Eduardo
2012-08-09  0:57     ` Zhang Rui
2012-08-09  8:05       ` Valentin, Eduardo
2012-08-09 15:10       ` Valentin, Eduardo
2012-08-20 12:18         ` Eduardo Valentin
2012-08-21  0:49           ` Zhang Rui
2012-08-21 14:20             ` Eduardo Valentin
2012-07-26  8:41 ` [PATCH V4 06/13] Thermal: Introduce thermal_zone_trip_update() Zhang Rui
2012-07-26 20:12   ` Rafael J. Wysocki
2012-08-20 15:47   ` Eduardo Valentin
2012-08-20 15:48   ` Eduardo Valentin
2012-07-26  8:41 ` [PATCH V4 07/13] Thermal: rename structure thermal_cooling_device_instance to thermal_instance Zhang Rui
2012-08-20 15:47   ` Eduardo Valentin
2012-07-26  8:41 ` [PATCH V4 08/13] Thermal: Rename thermal_zone_device.cooling_devices Zhang Rui
2012-08-20 15:47   ` Eduardo Valentin
2012-07-26  8:41 ` [PATCH V4 09/13] Thermal: Rename thermal_instance.node to thermal_instance.tz_node Zhang Rui
2012-08-20 15:47   ` Eduardo Valentin
2012-07-26  8:41 ` [PATCH V4 10/13] Thermal: List thermal_instance in thermal_cooling_device Zhang Rui
2012-08-20 15:46   ` Eduardo Valentin
2012-07-26  8:41 ` [PATCH V4 11/13] Thermal: Introduce simple arbitrator for setting device cooling state Zhang Rui
2012-08-20 15:46   ` Eduardo Valentin
2012-07-26  8:41 ` [PATCH V4 12/13] Thermal: Unify the code for both active and passive cooling Zhang Rui
2012-08-20 15:45   ` Eduardo Valentin
2012-07-26  8:41 ` [PATCH V4 13/13] Thermal: Introduce locking for cdev.thermal_instances list Zhang Rui
2012-07-26 20:13   ` Rafael J. Wysocki
2012-08-20 15:45   ` Eduardo Valentin
2012-08-21  0:53     ` Zhang Rui
2012-08-21  5:01       ` Eduardo Valentin
2012-08-20 15:53 ` [PATCH V4 00/13] Thermal: generic thermal layer enhancement Eduardo Valentin
2012-08-21  5:10   ` Eduardo Valentin

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.