All of lore.kernel.org
 help / color / mirror / Atom feed
* [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement
@ 2012-07-25  2:10 Zhang Rui
  2012-07-25  2:10 ` [PATCH RESEND 01/16] Thermal: Make Thermal trip points writeable Zhang Rui
                   ` (15 more replies)
  0 siblings, 16 replies; 41+ messages in thread
From: Zhang Rui @ 2012-07-25  2:10 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 refreshed patch set for linux-next.

the changes includes
- 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.

This patch set contains two patches from Durga,
one patch for documentation update,
and 13 patches to fix the problems discussed in
http://marc.info/?l=linux-acpi&m=133836783425764&w=2

please kindly review.

1) patch 1, 2, introduce the writeable trip point,
   and introduce hysterisis information for each trip point.
2) patch 3 is a Documentation update.
3) patch 4, 5, 6, introduce the multiple cooling states support
   for both active and passive trip points.
4) patch 7, 8, remove passive specific requirement, aka, tc1/tc2, and
   introduce .get_trend() instead, for both active and passive cooling
   algorithm.
5) patch 9 introduces new function thermal_zone_trip_update(),
   which contains the code for general cooling algorithm.
6) patch 10, 11, 12, 13 rename some thermal structures.
7) patch 14 introduces a simple cooling state arbitrator.
8) patch 15 unifies the code for both passive and active cooling.
9) patch 16 add lock for cdev.thermal_instances list.

Any comments are welcome.

thanks,
rui

---------------------------------------------------------------------------
Durgadoss R (2):
      Thermal: Make Thermal trip points writeable
      Thermal: Add Hysteresis attributes

Zhang Rui (14):
      Thermal: Documentation update
      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      |   39 ++-
 drivers/acpi/thermal.c                   |  106 ++++--
 drivers/platform/x86/acerhdf.c           |    7 +-
 drivers/platform/x86/intel_mid_thermal.c |    2 +-
 drivers/thermal/spear_thermal.c          |    4 +-
 drivers/thermal/thermal_sys.c            |  533 +++++++++++++++++++++---------
 include/linux/thermal.h                  |   44 ++-
 7 files changed, 521 insertions(+), 214 deletions(-)
---------------------------------------------------------------------------

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

* [PATCH RESEND 01/16] Thermal: Make Thermal trip points writeable
  2012-07-25  2:10 [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement Zhang Rui
@ 2012-07-25  2:10 ` Zhang Rui
  2012-07-25  3:18   ` Len Brown
  2012-07-25  2:10 ` [PATCH RESEND 02/16] Thermal: Add Hysteresis attributes Zhang Rui
                   ` (14 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Zhang Rui @ 2012-07-25  2:10 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

From: Durgadoss R <dugardoss.r@intel.com>

Some of the thermal drivers using the Generic Thermal Framework
require (all/some) trip points to be writeable. This patch makes
the trip point temperatures writeable on a per-trip point basis,
and modifies the required function call in thermal.c. This patch
also updates the Documentation to reflect the new change.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 Documentation/thermal/sysfs-api.txt      |    4 +-
 drivers/acpi/thermal.c                   |    4 +-
 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            |  145 +++++++++++++++++++++---------
 include/linux/thermal.h                  |   15 +++-
 7 files changed, 121 insertions(+), 53 deletions(-)

diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt
index 1733ab9..4c10593 100644
--- a/Documentation/thermal/sysfs-api.txt
+++ b/Documentation/thermal/sysfs-api.txt
@@ -32,7 +32,8 @@ temperature) and throttle appropriate devices.
 
 1.1 thermal zone device interface
 1.1.1 struct thermal_zone_device *thermal_zone_device_register(char *name,
-		int trips, void *devdata, struct thermal_zone_device_ops *ops)
+		int trips, int mask, void *devdata,
+		struct thermal_zone_device_ops *ops)
 
     This interface function adds a new thermal zone device (sensor) to
     /sys/class/thermal folder as thermal_zone[0-*]. It tries to bind all the
@@ -40,6 +41,7 @@ temperature) and throttle appropriate devices.
 
     name: the thermal zone name.
     trips: the total number of trip points this thermal zone supports.
+    mask: Bit string: If 'n'th bit is set, then trip point 'n' is writeable.
     devdata: device private data
     ops: thermal zone device call-backs.
 	.bind: bind the thermal zone device with a thermal cooling device.
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 7dbebea..2107d1b 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -845,7 +845,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
 
 	if (tz->trips.passive.flags.valid)
 		tz->thermal_zone =
-			thermal_zone_device_register("acpitz", trips, tz,
+			thermal_zone_device_register("acpitz", trips, 0, tz,
 						     &acpi_thermal_zone_ops,
 						     tz->trips.passive.tc1,
 						     tz->trips.passive.tc2,
@@ -853,7 +853,7 @@ static int acpi_thermal_register_thermal_zone(struct acpi_thermal *tz)
 						     tz->polling_frequency*100);
 	else
 		tz->thermal_zone =
-			thermal_zone_device_register("acpitz", trips, tz,
+			thermal_zone_device_register("acpitz", trips, 0, tz,
 						     &acpi_thermal_zone_ops,
 						     0, 0, 0,
 						     tz->polling_frequency*100);
diff --git a/drivers/platform/x86/acerhdf.c b/drivers/platform/x86/acerhdf.c
index 2fd9d36..39abb15 100644
--- a/drivers/platform/x86/acerhdf.c
+++ b/drivers/platform/x86/acerhdf.c
@@ -660,7 +660,7 @@ static int acerhdf_register_thermal(void)
 	if (IS_ERR(cl_dev))
 		return -EINVAL;
 
-	thz_dev = thermal_zone_device_register("acerhdf", 1, NULL,
+	thz_dev = thermal_zone_device_register("acerhdf", 1, 0, NULL,
 					      &acerhdf_dev_ops, 0, 0, 0,
 					      (kernelmode) ? interval*1000 : 0);
 	if (IS_ERR(thz_dev))
diff --git a/drivers/platform/x86/intel_mid_thermal.c b/drivers/platform/x86/intel_mid_thermal.c
index 5ae9cd9..2b2c212 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, td_info, &tzd_ops, 0, 0, 0, 0);
+				0, 0, td_info, &tzd_ops, 0, 0, 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 c2e32df..69a55d4 100644
--- a/drivers/thermal/spear_thermal.c
+++ b/drivers/thermal/spear_thermal.c
@@ -147,7 +147,7 @@ static int spear_thermal_probe(struct platform_device *pdev)
 	stdev->flags = pdata->thermal_flags;
 	writel_relaxed(stdev->flags, stdev->thermal_base);
 
-	spear_thermal = thermal_zone_device_register("spear_thermal", 0,
+	spear_thermal = thermal_zone_device_register("spear_thermal", 0, 0,
 				stdev, &ops, 0, 0, 0, 0);
 	if (IS_ERR(spear_thermal)) {
 		dev_err(&pdev->dev, "thermal zone device is NULL\n");
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 022bacb..5feb335 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -196,6 +196,28 @@ trip_point_type_show(struct device *dev, struct device_attribute *attr,
 }
 
 static ssize_t
+trip_point_temp_store(struct device *dev, struct device_attribute *attr,
+		     const char *buf, size_t count)
+{
+	struct thermal_zone_device *tz = to_thermal_zone(dev);
+	int trip, ret;
+	unsigned long temperature;
+
+	if (!tz->ops->set_trip_temp)
+		return -EPERM;
+
+	if (!sscanf(attr->attr.name, "trip_point_%d_temp", &trip))
+		return -EINVAL;
+
+	if (kstrtoul(buf, 10, &temperature))
+		return -EINVAL;
+
+	ret = tz->ops->set_trip_temp(tz, trip, temperature);
+
+	return ret ? ret : count;
+}
+
+static ssize_t
 trip_point_temp_show(struct device *dev, struct device_attribute *attr,
 		     char *buf)
 {
@@ -283,33 +305,6 @@ static DEVICE_ATTR(temp, 0444, temp_show, NULL);
 static DEVICE_ATTR(mode, 0644, mode_show, mode_store);
 static DEVICE_ATTR(passive, S_IRUGO | S_IWUSR, passive_show, passive_store);
 
-static struct device_attribute trip_point_attrs[] = {
-	__ATTR(trip_point_0_type, 0444, trip_point_type_show, NULL),
-	__ATTR(trip_point_0_temp, 0444, trip_point_temp_show, NULL),
-	__ATTR(trip_point_1_type, 0444, trip_point_type_show, NULL),
-	__ATTR(trip_point_1_temp, 0444, trip_point_temp_show, NULL),
-	__ATTR(trip_point_2_type, 0444, trip_point_type_show, NULL),
-	__ATTR(trip_point_2_temp, 0444, trip_point_temp_show, NULL),
-	__ATTR(trip_point_3_type, 0444, trip_point_type_show, NULL),
-	__ATTR(trip_point_3_temp, 0444, trip_point_temp_show, NULL),
-	__ATTR(trip_point_4_type, 0444, trip_point_type_show, NULL),
-	__ATTR(trip_point_4_temp, 0444, trip_point_temp_show, NULL),
-	__ATTR(trip_point_5_type, 0444, trip_point_type_show, NULL),
-	__ATTR(trip_point_5_temp, 0444, trip_point_temp_show, NULL),
-	__ATTR(trip_point_6_type, 0444, trip_point_type_show, NULL),
-	__ATTR(trip_point_6_temp, 0444, trip_point_temp_show, NULL),
-	__ATTR(trip_point_7_type, 0444, trip_point_type_show, NULL),
-	__ATTR(trip_point_7_temp, 0444, trip_point_temp_show, NULL),
-	__ATTR(trip_point_8_type, 0444, trip_point_type_show, NULL),
-	__ATTR(trip_point_8_temp, 0444, trip_point_temp_show, NULL),
-	__ATTR(trip_point_9_type, 0444, trip_point_type_show, NULL),
-	__ATTR(trip_point_9_temp, 0444, trip_point_temp_show, NULL),
-	__ATTR(trip_point_10_type, 0444, trip_point_type_show, NULL),
-	__ATTR(trip_point_10_temp, 0444, trip_point_temp_show, NULL),
-	__ATTR(trip_point_11_type, 0444, trip_point_type_show, NULL),
-	__ATTR(trip_point_11_temp, 0444, trip_point_temp_show, NULL),
-};
-
 /* sys I/F for cooling device */
 #define to_cooling_device(_dev)	\
 	container_of(_dev, struct thermal_cooling_device, device)
@@ -1089,9 +1084,81 @@ void thermal_zone_device_update(struct thermal_zone_device *tz)
 EXPORT_SYMBOL(thermal_zone_device_update);
 
 /**
+ * create_trip_attrs - create attributes for trip points
+ * @tz:		the thermal zone device
+ * @mask:	Writeable trip point bitmap.
+ */
+static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
+{
+	int indx;
+
+	tz->trip_type_attrs =
+		kzalloc(sizeof(struct thermal_attr) * tz->trips, GFP_KERNEL);
+	if (!tz->trip_type_attrs)
+		return -ENOMEM;
+
+	tz->trip_temp_attrs =
+		kzalloc(sizeof(struct thermal_attr) * tz->trips, GFP_KERNEL);
+	if (!tz->trip_temp_attrs) {
+		kfree(tz->trip_type_attrs);
+		return -ENOMEM;
+	}
+
+	for (indx = 0; indx < tz->trips; indx++) {
+
+		/* create trip type attribute */
+		snprintf(tz->trip_type_attrs[indx].name, THERMAL_NAME_LENGTH,
+			 "trip_point_%d_type", indx);
+
+		sysfs_attr_init(&tz->trip_type_attrs[indx].attr.attr);
+		tz->trip_type_attrs[indx].attr.attr.name =
+						tz->trip_type_attrs[indx].name;
+		tz->trip_type_attrs[indx].attr.attr.mode = S_IRUGO;
+		tz->trip_type_attrs[indx].attr.show = trip_point_type_show;
+
+		device_create_file(&tz->device,
+				   &tz->trip_type_attrs[indx].attr);
+
+		/* create trip temp attribute */
+		snprintf(tz->trip_temp_attrs[indx].name, THERMAL_NAME_LENGTH,
+			 "trip_point_%d_temp", indx);
+
+		sysfs_attr_init(&tz->trip_temp_attrs[indx].attr.attr);
+		tz->trip_temp_attrs[indx].attr.attr.name =
+						tz->trip_temp_attrs[indx].name;
+		tz->trip_temp_attrs[indx].attr.attr.mode = S_IRUGO;
+		tz->trip_temp_attrs[indx].attr.show = trip_point_temp_show;
+		if (mask & (1 << indx)) {
+			tz->trip_temp_attrs[indx].attr.attr.mode |= S_IWUSR;
+			tz->trip_temp_attrs[indx].attr.store =
+							trip_point_temp_store;
+		}
+
+		device_create_file(&tz->device,
+				   &tz->trip_temp_attrs[indx].attr);
+	}
+	return 0;
+}
+
+static void remove_trip_attrs(struct thermal_zone_device *tz)
+{
+	int indx;
+
+	for (indx = 0; indx < tz->trips; indx++) {
+		device_remove_file(&tz->device,
+				   &tz->trip_type_attrs[indx].attr);
+		device_remove_file(&tz->device,
+				   &tz->trip_temp_attrs[indx].attr);
+	}
+	kfree(tz->trip_type_attrs);
+	kfree(tz->trip_temp_attrs);
+}
+
+/**
  * thermal_zone_device_register - register a new thermal zone device
  * @type:	the thermal zone device type
  * @trips:	the number of trip points the thermal zone support
+ * @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
@@ -1107,7 +1174,7 @@ EXPORT_SYMBOL(thermal_zone_device_update);
  * section 11.1.5.1 of the ACPI specification 3.0.
  */
 struct thermal_zone_device *thermal_zone_device_register(char *type,
-	int trips, void *devdata,
+	int trips, int mask, void *devdata,
 	const struct thermal_zone_device_ops *ops,
 	int tc1, int tc2, int passive_delay, int polling_delay)
 {
@@ -1121,7 +1188,7 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
 	if (strlen(type) >= THERMAL_NAME_LENGTH)
 		return ERR_PTR(-EINVAL);
 
-	if (trips > THERMAL_MAX_TRIPS || trips < 0)
+	if (trips > THERMAL_MAX_TRIPS || trips < 0 || mask >> trips)
 		return ERR_PTR(-EINVAL);
 
 	if (!ops || !ops->get_temp)
@@ -1175,15 +1242,11 @@ struct thermal_zone_device *thermal_zone_device_register(char *type,
 			goto unregister;
 	}
 
+	result = create_trip_attrs(tz, mask);
+	if (result)
+		goto unregister;
+
 	for (count = 0; count < trips; count++) {
-		result = device_create_file(&tz->device,
-					    &trip_point_attrs[count * 2]);
-		if (result)
-			break;
-		result = device_create_file(&tz->device,
-					    &trip_point_attrs[count * 2 + 1]);
-		if (result)
-			goto unregister;
 		tz->ops->get_trip_type(tz, count, &trip_type);
 		if (trip_type == THERMAL_TRIP_PASSIVE)
 			passive = 1;
@@ -1232,7 +1295,6 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
 {
 	struct thermal_cooling_device *cdev;
 	struct thermal_zone_device *pos = NULL;
-	int count;
 
 	if (!tz)
 		return;
@@ -1259,13 +1321,8 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
 	device_remove_file(&tz->device, &dev_attr_temp);
 	if (tz->ops->get_mode)
 		device_remove_file(&tz->device, &dev_attr_mode);
+	remove_trip_attrs(tz);
 
-	for (count = 0; count < tz->trips; count++) {
-		device_remove_file(&tz->device,
-				   &trip_point_attrs[count * 2]);
-		device_remove_file(&tz->device,
-				   &trip_point_attrs[count * 2 + 1]);
-	}
 	thermal_remove_hwmon_sysfs(tz);
 	release_idr(&thermal_tz_idr, &thermal_idr_lock, tz->id);
 	idr_destroy(&tz->idr);
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 796f1ff..6eaf914 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -58,6 +58,8 @@ struct thermal_zone_device_ops {
 		enum thermal_trip_type *);
 	int (*get_trip_temp) (struct thermal_zone_device *, int,
 			      unsigned long *);
+	int (*set_trip_temp) (struct thermal_zone_device *, int,
+			      unsigned long);
 	int (*get_crit_temp) (struct thermal_zone_device *, unsigned long *);
 	int (*notify) (struct thermal_zone_device *, int,
 		       enum thermal_trip_type);
@@ -85,10 +87,17 @@ struct thermal_cooling_device {
 				((long)t-2732+5)/10 : ((long)t-2732-5)/10)
 #define CELSIUS_TO_KELVIN(t)	((t)*10+2732)
 
+struct thermal_attr {
+	struct device_attribute attr;
+	char name[THERMAL_NAME_LENGTH];
+};
+
 struct thermal_zone_device {
 	int id;
 	char type[THERMAL_NAME_LENGTH];
 	struct device device;
+	struct thermal_attr *trip_temp_attrs;
+	struct thermal_attr *trip_type_attrs;
 	void *devdata;
 	int trips;
 	int tc1;
@@ -137,9 +146,9 @@ enum {
 };
 #define THERMAL_GENL_CMD_MAX (__THERMAL_GENL_CMD_MAX - 1)
 
-struct thermal_zone_device *thermal_zone_device_register(char *, int, void *,
-		const struct thermal_zone_device_ops *, int tc1, int tc2,
-		int passive_freq, int polling_freq);
+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 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] 41+ messages in thread

* [PATCH RESEND 02/16] Thermal: Add Hysteresis attributes
  2012-07-25  2:10 [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement Zhang Rui
  2012-07-25  2:10 ` [PATCH RESEND 01/16] Thermal: Make Thermal trip points writeable Zhang Rui
@ 2012-07-25  2:10 ` Zhang Rui
  2012-07-25  3:19   ` Len Brown
  2012-07-25  2:11 ` [PATCH RESEND 03/16] Thermal: Documentation update Zhang Rui
                   ` (13 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Zhang Rui @ 2012-07-25  2:10 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

From: Durgadoss R <dugardoss.r@intel.com>

The Linux Thermal Framework does not support hysteresis
attributes. Most thermal sensors, today, have a
hysteresis value associated with trip points.

This patch adds hysteresis attributes on a per-trip-point
basis, to the Thermal Framework. These attributes are
optionally writable.

Signed-off-by: Durgadoss R <durgadoss.r@intel.com>
Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 Documentation/thermal/sysfs-api.txt |    6 +++
 drivers/thermal/thermal_sys.c       |   88 +++++++++++++++++++++++++++++++++--
 include/linux/thermal.h             |    5 ++
 3 files changed, 94 insertions(+), 5 deletions(-)

diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt
index 4c10593..2ba4c9b 100644
--- a/Documentation/thermal/sysfs-api.txt
+++ b/Documentation/thermal/sysfs-api.txt
@@ -121,6 +121,7 @@ if hwmon is compiled in or built as a module.
     |---mode:			Working mode of the thermal zone
     |---trip_point_[0-*]_temp:	Trip point temperature
     |---trip_point_[0-*]_type:	Trip point type
+    |---trip_point_[0-*]_hyst:	Hysteresis value for this trip point
 
 Thermal cooling device sys I/F, created once it's registered:
 /sys/class/thermal/cooling_device[0-*]:
@@ -190,6 +191,11 @@ trip_point_[0-*]_type
 	thermal zone.
 	RO, Optional
 
+trip_point_[0-*]_hyst
+	The hysteresis value for a trip point, represented as an integer
+	Unit: Celsius
+	RW, Optional
+
 cdev[0-*]
 	Sysfs link to the thermal cooling device node where the sys I/F
 	for cooling device throttling control represents.
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 5feb335..2d7a9fe 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -240,6 +240,52 @@ trip_point_temp_show(struct device *dev, struct device_attribute *attr,
 }
 
 static ssize_t
+trip_point_hyst_store(struct device *dev, struct device_attribute *attr,
+			const char *buf, size_t count)
+{
+	struct thermal_zone_device *tz = to_thermal_zone(dev);
+	int trip, ret;
+	unsigned long temperature;
+
+	if (!tz->ops->set_trip_hyst)
+		return -EPERM;
+
+	if (!sscanf(attr->attr.name, "trip_point_%d_hyst", &trip))
+		return -EINVAL;
+
+	if (kstrtoul(buf, 10, &temperature))
+		return -EINVAL;
+
+	/*
+	 * We are not doing any check on the 'temperature' value
+	 * here. The driver implementing 'set_trip_hyst' has to
+	 * take care of this.
+	 */
+	ret = tz->ops->set_trip_hyst(tz, trip, temperature);
+
+	return ret ? ret : count;
+}
+
+static ssize_t
+trip_point_hyst_show(struct device *dev, struct device_attribute *attr,
+			char *buf)
+{
+	struct thermal_zone_device *tz = to_thermal_zone(dev);
+	int trip, ret;
+	unsigned long temperature;
+
+	if (!tz->ops->get_trip_hyst)
+		return -EPERM;
+
+	if (!sscanf(attr->attr.name, "trip_point_%d_hyst", &trip))
+		return -EINVAL;
+
+	ret = tz->ops->get_trip_hyst(tz, trip, &temperature);
+
+	return ret ? ret : sprintf(buf, "%ld\n", temperature);
+}
+
+static ssize_t
 passive_store(struct device *dev, struct device_attribute *attr,
 		    const char *buf, size_t count)
 {
@@ -1091,21 +1137,29 @@ EXPORT_SYMBOL(thermal_zone_device_update);
 static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
 {
 	int indx;
+	int size = sizeof(struct thermal_attr) * tz->trips;
 
-	tz->trip_type_attrs =
-		kzalloc(sizeof(struct thermal_attr) * tz->trips, GFP_KERNEL);
+	tz->trip_type_attrs = kzalloc(size, GFP_KERNEL);
 	if (!tz->trip_type_attrs)
 		return -ENOMEM;
 
-	tz->trip_temp_attrs =
-		kzalloc(sizeof(struct thermal_attr) * tz->trips, GFP_KERNEL);
+	tz->trip_temp_attrs = kzalloc(size, GFP_KERNEL);
 	if (!tz->trip_temp_attrs) {
 		kfree(tz->trip_type_attrs);
 		return -ENOMEM;
 	}
 
-	for (indx = 0; indx < tz->trips; indx++) {
+	if (tz->ops->get_trip_hyst) {
+		tz->trip_hyst_attrs = kzalloc(size, GFP_KERNEL);
+		if (!tz->trip_hyst_attrs) {
+			kfree(tz->trip_type_attrs);
+			kfree(tz->trip_temp_attrs);
+			return -ENOMEM;
+		}
+	}
 
+
+	for (indx = 0; indx < tz->trips; indx++) {
 		/* create trip type attribute */
 		snprintf(tz->trip_type_attrs[indx].name, THERMAL_NAME_LENGTH,
 			 "trip_point_%d_type", indx);
@@ -1136,6 +1190,26 @@ static int create_trip_attrs(struct thermal_zone_device *tz, int mask)
 
 		device_create_file(&tz->device,
 				   &tz->trip_temp_attrs[indx].attr);
+
+		/* create Optional trip hyst attribute */
+		if (!tz->ops->get_trip_hyst)
+			continue;
+		snprintf(tz->trip_hyst_attrs[indx].name, THERMAL_NAME_LENGTH,
+			 "trip_point_%d_hyst", indx);
+
+		sysfs_attr_init(&tz->trip_hyst_attrs[indx].attr.attr);
+		tz->trip_hyst_attrs[indx].attr.attr.name =
+					tz->trip_hyst_attrs[indx].name;
+		tz->trip_hyst_attrs[indx].attr.attr.mode = S_IRUGO;
+		tz->trip_hyst_attrs[indx].attr.show = trip_point_hyst_show;
+		if (tz->ops->set_trip_hyst) {
+			tz->trip_hyst_attrs[indx].attr.attr.mode |= S_IWUSR;
+			tz->trip_hyst_attrs[indx].attr.store =
+					trip_point_hyst_store;
+		}
+
+		device_create_file(&tz->device,
+				   &tz->trip_hyst_attrs[indx].attr);
 	}
 	return 0;
 }
@@ -1149,9 +1223,13 @@ static void remove_trip_attrs(struct thermal_zone_device *tz)
 				   &tz->trip_type_attrs[indx].attr);
 		device_remove_file(&tz->device,
 				   &tz->trip_temp_attrs[indx].attr);
+		if (tz->ops->get_trip_hyst)
+			device_remove_file(&tz->device,
+				  &tz->trip_hyst_attrs[indx].attr);
 	}
 	kfree(tz->trip_type_attrs);
 	kfree(tz->trip_temp_attrs);
+	kfree(tz->trip_hyst_attrs);
 }
 
 /**
diff --git a/include/linux/thermal.h b/include/linux/thermal.h
index 6eaf914..cfc8d90 100644
--- a/include/linux/thermal.h
+++ b/include/linux/thermal.h
@@ -60,6 +60,10 @@ struct thermal_zone_device_ops {
 			      unsigned long *);
 	int (*set_trip_temp) (struct thermal_zone_device *, int,
 			      unsigned long);
+	int (*get_trip_hyst) (struct thermal_zone_device *, int,
+			      unsigned long *);
+	int (*set_trip_hyst) (struct thermal_zone_device *, int,
+			      unsigned long);
 	int (*get_crit_temp) (struct thermal_zone_device *, unsigned long *);
 	int (*notify) (struct thermal_zone_device *, int,
 		       enum thermal_trip_type);
@@ -98,6 +102,7 @@ struct thermal_zone_device {
 	struct device device;
 	struct thermal_attr *trip_temp_attrs;
 	struct thermal_attr *trip_type_attrs;
+	struct thermal_attr *trip_hyst_attrs;
 	void *devdata;
 	int trips;
 	int tc1;
-- 
1.7.9.5


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

* [PATCH RESEND 03/16] Thermal: Documentation update
  2012-07-25  2:10 [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement Zhang Rui
  2012-07-25  2:10 ` [PATCH RESEND 01/16] Thermal: Make Thermal trip points writeable Zhang Rui
  2012-07-25  2:10 ` [PATCH RESEND 02/16] Thermal: Add Hysteresis attributes Zhang Rui
@ 2012-07-25  2:11 ` Zhang Rui
  2012-07-25  2:11 ` [PATCH RESEND 04/16] Thermal: Introduce multiple cooling states support Zhang Rui
                   ` (12 subsequent siblings)
  15 siblings, 0 replies; 41+ messages in thread
From: Zhang Rui @ 2012-07-25  2:11 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

With commit 6503e5df08008b9a47022b5e9ebba658c8fa69af,
the value of /sys/class/thermal/thermal_zoneX/mode has been changed
from user/kernel to enabled/disabled.
Update the documentation so that users won't be confused.

Signed-off-by: Zhang Rui <rui.zhang@intel.com>
---
 Documentation/thermal/sysfs-api.txt |   20 ++++++++++----------
 drivers/acpi/thermal.c              |    6 ++----
 2 files changed, 12 insertions(+), 14 deletions(-)

diff --git a/Documentation/thermal/sysfs-api.txt b/Documentation/thermal/sysfs-api.txt
index 2ba4c9b..c087dbc 100644
--- a/Documentation/thermal/sysfs-api.txt
+++ b/Documentation/thermal/sysfs-api.txt
@@ -47,11 +47,11 @@ temperature) and throttle appropriate devices.
 	.bind: bind the thermal zone device with a thermal cooling device.
 	.unbind: unbind the thermal zone device with a thermal cooling device.
 	.get_temp: get the current temperature of the thermal zone.
-	.get_mode: get the current mode (user/kernel) of the thermal zone.
-	    - "kernel" means thermal management is done in kernel.
-	    - "user" will prevent kernel thermal driver actions upon trip points
+	.get_mode: get the current mode (enabled/disabled) of the thermal zone.
+	    - "enabled" means the kernel thermal management is enabled.
+	    - "disabled" will prevent kernel thermal driver action upon trip points
 	      so that user applications can take charge of thermal management.
-	.set_mode: set the mode (user/kernel) of the thermal zone.
+	.set_mode: set the mode (enabled/disabled) of the thermal zone.
 	.get_trip_type: get the type of certain trip point.
 	.get_trip_temp: get the temperature above which the certain trip point
 			will be fired.
@@ -170,14 +170,14 @@ temp
 	RO, Required
 
 mode
-	One of the predefined values in [kernel, user].
+	One of the predefined values in [enabled, disabled].
 	This file gives information about the algorithm that is currently
 	managing the thermal zone. It can be either default kernel based
 	algorithm or user space application.
-	kernel	= Thermal management in kernel thermal zone driver.
-	user	= Preventing kernel thermal zone driver actions upon
-		  trip points so that user application can take full
-		  charge of the thermal management.
+	enabled		= enable Kernel Thermal management.
+	disabled	= Preventing kernel thermal zone driver actions upon
+			  trip points so that user application can take full
+			  charge of the thermal management.
 	RW, Optional
 
 trip_point_[0-*]_temp
@@ -256,7 +256,7 @@ If the processor is listed in _PSL method, and the fan is listed in _AL0
 |thermal_zone1:
     |---type:			acpitz
     |---temp:			37000
-    |---mode:			kernel
+    |---mode:			enabled
     |---trip_point_0_temp:	100000
     |---trip_point_0_type:	critical
     |---trip_point_1_temp:	80000
diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 2107d1b..8275e7b 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -550,8 +550,6 @@ static int thermal_get_temp(struct thermal_zone_device *thermal,
 	return 0;
 }
 
-static const char enabled[] = "kernel";
-static const char disabled[] = "user";
 static int thermal_get_mode(struct thermal_zone_device *thermal,
 				enum thermal_device_mode *mode)
 {
@@ -588,8 +586,8 @@ static int thermal_set_mode(struct thermal_zone_device *thermal,
 	if (enable != tz->tz_enabled) {
 		tz->tz_enabled = enable;
 		ACPI_DEBUG_PRINT((ACPI_DB_INFO,
-			"%s ACPI thermal control\n",
-			tz->tz_enabled ? enabled : disabled));
+			"%s kernel ACPI thermal control\n",
+			tz->tz_enabled ? "Enable" : "Disable"));
 		acpi_thermal_check(tz);
 	}
 	return 0;
-- 
1.7.9.5


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

* [PATCH RESEND 04/16] Thermal: Introduce multiple cooling states support
  2012-07-25  2:10 [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (2 preceding siblings ...)
  2012-07-25  2:11 ` [PATCH RESEND 03/16] Thermal: Documentation update Zhang Rui
@ 2012-07-25  2:11 ` Zhang Rui
  2012-07-25 20:06   ` Rafael J. Wysocki
  2012-07-25  2:11 ` [PATCH RESEND 05/16] Thermal: Introduce cooling states range support Zhang Rui
                   ` (11 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Zhang Rui @ 2012-07-25  2:11 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.

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] 41+ messages in thread

* [PATCH RESEND 05/16] Thermal: Introduce cooling states range support
  2012-07-25  2:10 [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (3 preceding siblings ...)
  2012-07-25  2:11 ` [PATCH RESEND 04/16] Thermal: Introduce multiple cooling states support Zhang Rui
@ 2012-07-25  2:11 ` Zhang Rui
  2012-07-25 20:08   ` Rafael J. Wysocki
  2012-08-08 12:07   ` Valentin, Eduardo
  2012-07-25  2:11 ` [PATCH RESEND 06/16] Thermal: set upper and lower limits Zhang Rui
                   ` (10 subsequent siblings)
  15 siblings, 2 replies; 41+ messages in thread
From: Zhang Rui @ 2012-07-25  2:11 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.

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] 41+ messages in thread

* [PATCH RESEND 06/16] Thermal: set upper and lower limits
  2012-07-25  2:10 [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (4 preceding siblings ...)
  2012-07-25  2:11 ` [PATCH RESEND 05/16] Thermal: Introduce cooling states range support Zhang Rui
@ 2012-07-25  2:11 ` Zhang Rui
  2012-07-25 20:14   ` Rafael J. Wysocki
  2012-08-08 12:50   ` Valentin, Eduardo
  2012-07-25  2:11 ` [PATCH RESEND 07/16] Thermal: Introduce .get_trend() callback Zhang Rui
                   ` (9 subsequent siblings)
  15 siblings, 2 replies; 41+ messages in thread
From: Zhang Rui @ 2012-07-25  2:11 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.

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..0154eac 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, 1);
 }
 
 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, 0);
 }
 
 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] 41+ messages in thread

* [PATCH RESEND 07/16] Thermal: Introduce .get_trend() callback.
  2012-07-25  2:10 [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (5 preceding siblings ...)
  2012-07-25  2:11 ` [PATCH RESEND 06/16] Thermal: set upper and lower limits Zhang Rui
@ 2012-07-25  2:11 ` Zhang Rui
  2012-07-25 20:19   ` Rafael J. Wysocki
  2012-07-25  2:11 ` [PATCH RESEND 08/16] Thermal: Remove tc1/tc2 in generic thermal layer Zhang Rui
                   ` (8 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Zhang Rui @ 2012-07-25  2:11 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

tc1 and tc2 are used by OSPM to anticipate the temperature trends.
But they are ACPI platform specific concepts.

Introduce .get_trend() as a more general solution.

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

diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 0154eac..01c92fd 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..d406524 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -699,6 +699,21 @@ thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
 }
 #endif
 
+static void thermal_get_trend(struct thermal_zone_device *tz,
+		int trip, enum thermal_trend *trend)
+{
+	if (tz->ops->get_trend && !tz->ops->get_trend(tz, trip, trend))
+			return;
+
+	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;
+	return;
+}
+
 static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
 					    int delay)
 {
@@ -733,6 +748,8 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
 	if (temp >= trip_temp) {
 		tz->passive = true;
 
+		thermal_get_trend(tz, trip, (enum thermal_trend *)&trend);
+
 		trend = (tz->tc1 * (temp - tz->last_temperature)) +
 			(tz->tc2 * (temp - trip_temp));
 
@@ -1091,6 +1108,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 +1170,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] 41+ messages in thread

* [PATCH RESEND 08/16] Thermal: Remove tc1/tc2 in generic thermal layer.
  2012-07-25  2:10 [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (6 preceding siblings ...)
  2012-07-25  2:11 ` [PATCH RESEND 07/16] Thermal: Introduce .get_trend() callback Zhang Rui
@ 2012-07-25  2:11 ` Zhang Rui
  2012-07-25 20:24   ` Rafael J. Wysocki
  2012-07-25  2:11 ` [PATCH RESEND 09/16] Thermal: Introduce thermal_zone_trip_update() Zhang Rui
                   ` (7 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Zhang Rui @ 2012-07-25  2:11 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

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            |   23 ++++++-----------------
 include/linux/thermal.h                  |    5 +----
 6 files changed, 11 insertions(+), 28 deletions(-)

diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 01c92fd..5417362 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 d406524..727aa74 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);
@@ -733,7 +730,7 @@ 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;
@@ -748,13 +745,10 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
 	if (temp >= trip_temp) {
 		tz->passive = true;
 
-		thermal_get_trend(tz, trip, (enum thermal_trend *)&trend);
-
-		trend = (tz->tc1 * (temp - tz->last_temperature)) +
-			(tz->tc2 * (temp - trip_temp));
+		thermal_get_trend(tz, trip, &trend);
 
 		/* Heating up? */
-		if (trend > 0) {
+		if (trend == THERMAL_TREND_RAISING) {
 			list_for_each_entry(instance, &tz->cooling_devices,
 					    node) {
 				if (instance->trip != trip)
@@ -765,7 +759,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)
@@ -1291,8 +1285,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
@@ -1300,13 +1292,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;
@@ -1342,8 +1333,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] 41+ messages in thread

* [PATCH RESEND 09/16] Thermal: Introduce thermal_zone_trip_update()
  2012-07-25  2:10 [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (7 preceding siblings ...)
  2012-07-25  2:11 ` [PATCH RESEND 08/16] Thermal: Remove tc1/tc2 in generic thermal layer Zhang Rui
@ 2012-07-25  2:11 ` Zhang Rui
  2012-07-25 20:31   ` Rafael J. Wysocki
  2012-07-25  2:11 ` [PATCH RESEND 10/16] Thermal: rename structure thermal_cooling_device_instance to thermal_instance Zhang Rui
                   ` (6 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Zhang Rui @ 2012-07-25  2:11 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        |    7 +++-
 drivers/thermal/thermal_sys.c |   91 +++++++++++++++++++++++++++++------------
 2 files changed, 71 insertions(+), 27 deletions(-)

diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
index 5417362..8f8e695 100644
--- a/drivers/acpi/thermal.c
+++ b/drivers/acpi/thermal.c
@@ -714,7 +714,12 @@ 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_ACTIVE) {
+		/* aggressive active cooling */
+		*trend = THERMAL_TREND_RAISING;
+		return 0;
+	}
+
 	if (type != THERMAL_TRIP_PASSIVE)
 		return -EINVAL;
 
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index 727aa74..cc1b192 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -1080,6 +1080,70 @@ 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 (temp >= trip_temp) {
+		thermal_get_trend(tz, trip, &trend);
+
+		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
@@ -1090,9 +1154,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);
 
@@ -1128,29 +1189,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] 41+ messages in thread

* [PATCH RESEND 10/16] Thermal: rename structure thermal_cooling_device_instance to thermal_instance
  2012-07-25  2:10 [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (8 preceding siblings ...)
  2012-07-25  2:11 ` [PATCH RESEND 09/16] Thermal: Introduce thermal_zone_trip_update() Zhang Rui
@ 2012-07-25  2:11 ` Zhang Rui
  2012-07-25 20:32   ` Rafael J. Wysocki
  2012-07-25  2:11 ` [PATCH RESEND 11/16] Thermal: Rename thermal_zone_device.cooling_devices Zhang Rui
                   ` (5 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Zhang Rui @ 2012-07-25  2:11 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.

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 cc1b192..6f245c8 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");
@@ -731,7 +731,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;
 
@@ -816,8 +816,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;
@@ -848,7 +848,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;
@@ -913,7 +913,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) {
@@ -1099,7 +1099,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] 41+ messages in thread

* [PATCH RESEND 11/16] Thermal: Rename thermal_zone_device.cooling_devices
  2012-07-25  2:10 [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (9 preceding siblings ...)
  2012-07-25  2:11 ` [PATCH RESEND 10/16] Thermal: rename structure thermal_cooling_device_instance to thermal_instance Zhang Rui
@ 2012-07-25  2:11 ` Zhang Rui
  2012-07-25 20:33   ` Rafael J. Wysocki
  2012-07-25  2:11 ` [PATCH RESEND 12/16] Thermal: Rename thermal_instance.node to thermal_instance.tz_node Zhang Rui
                   ` (4 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Zhang Rui @ 2012-07-25  2:11 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.

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 6f245c8..5f362e1 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -749,7 +749,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;
@@ -760,7 +760,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;
@@ -781,7 +781,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;
@@ -877,13 +877,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)
@@ -916,7 +916,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);
@@ -1110,7 +1110,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
 	if (temp >= trip_temp) {
 		thermal_get_trend(tz, trip, &trend);
 
-		list_for_each_entry(instance, &tz->cooling_devices, node) {
+		list_for_each_entry(instance, &tz->thermal_instances, node) {
 			if (instance->trip != trip)
 				continue;
 
@@ -1129,7 +1129,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;
 
@@ -1358,7 +1358,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] 41+ messages in thread

* [PATCH RESEND 12/16] Thermal: Rename thermal_instance.node to thermal_instance.tz_node.
  2012-07-25  2:10 [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (10 preceding siblings ...)
  2012-07-25  2:11 ` [PATCH RESEND 11/16] Thermal: Rename thermal_zone_device.cooling_devices Zhang Rui
@ 2012-07-25  2:11 ` Zhang Rui
  2012-07-25 20:34   ` Rafael J. Wysocki
  2012-07-25  2:11 ` [PATCH RESEND 13/16] Thermal: List thermal_instance in thermal_cooling_device Zhang Rui
                   ` (3 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Zhang Rui @ 2012-07-25  2:11 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.

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 5f362e1..b76e55f 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);
@@ -750,7 +750,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;
@@ -761,7 +761,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;
@@ -781,7 +781,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;
@@ -877,13 +877,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)
@@ -916,9 +916,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;
 		}
@@ -1110,7 +1110,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
 	if (temp >= trip_temp) {
 		thermal_get_trend(tz, trip, &trend);
 
-		list_for_each_entry(instance, &tz->thermal_instances, node) {
+		list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
 			if (instance->trip != trip)
 				continue;
 
@@ -1129,7 +1129,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] 41+ messages in thread

* [PATCH RESEND 13/16] Thermal: List thermal_instance in thermal_cooling_device.
  2012-07-25  2:10 [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (11 preceding siblings ...)
  2012-07-25  2:11 ` [PATCH RESEND 12/16] Thermal: Rename thermal_instance.node to thermal_instance.tz_node Zhang Rui
@ 2012-07-25  2:11 ` Zhang Rui
  2012-07-25 20:35   ` Rafael J. Wysocki
  2012-07-25  2:11 ` [PATCH RESEND 14/16] Thermal: Introduce simple arbitrator for setting device cooling state Zhang Rui
                   ` (2 subsequent siblings)
  15 siblings, 1 reply; 41+ messages in thread
From: Zhang Rui @ 2012-07-25  2:11 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.

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 b76e55f..0a06ea4 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);
@@ -882,8 +883,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)
@@ -919,6 +922,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;
 		}
@@ -988,6 +992,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] 41+ messages in thread

* [PATCH RESEND 14/16] Thermal: Introduce simple arbitrator for setting device cooling state
  2012-07-25  2:10 [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (12 preceding siblings ...)
  2012-07-25  2:11 ` [PATCH RESEND 13/16] Thermal: List thermal_instance in thermal_cooling_device Zhang Rui
@ 2012-07-25  2:11 ` Zhang Rui
  2012-07-25 20:38   ` Rafael J. Wysocki
  2012-07-25  2:11 ` [PATCH RESEND 15/16] Thermal: Unify the code for both active and passive cooling Zhang Rui
  2012-07-25  2:11 ` [PATCH RESEND 16/16] Thermal: Introduce locking for cdev.thermal_instances list Zhang Rui
  15 siblings, 1 reply; 41+ messages in thread
From: Zhang Rui @ 2012-07-25  2:11 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.

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 0a06ea4..ee10df5 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 */
@@ -857,6 +859,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)
@@ -994,6 +997,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);
@@ -1085,6 +1089,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
  *
@@ -1131,19 +1163,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 deacitve 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 */
 		}
 	}
 
@@ -1204,6 +1241,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] 41+ messages in thread

* [PATCH RESEND 15/16] Thermal: Unify the code for both active and passive cooling
  2012-07-25  2:10 [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (13 preceding siblings ...)
  2012-07-25  2:11 ` [PATCH RESEND 14/16] Thermal: Introduce simple arbitrator for setting device cooling state Zhang Rui
@ 2012-07-25  2:11 ` Zhang Rui
  2012-07-25 20:41   ` Rafael J. Wysocki
  2012-08-09  8:26   ` Valentin, Eduardo
  2012-07-25  2:11 ` [PATCH RESEND 16/16] Thermal: Introduce locking for cdev.thermal_instances list Zhang Rui
  15 siblings, 2 replies; 41+ messages in thread
From: Zhang Rui @ 2012-07-25  2:11 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.

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

diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index ee10df5..23a5c86 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -730,73 +730,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;
-
-	/*
-	 * 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;
-
-		thermal_get_trend(tz, trip, &trend);
-
-		/* 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
@@ -1118,7 +1051,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
@@ -1140,9 +1073,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 (temp >= trip_temp) {
 		thermal_get_trend(tz, trip, &trend);
@@ -1163,6 +1103,12 @@ 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 &&
+			    instance->target == THERMAL_NO_TARGET)
+				tz->passive++;
+
 			instance->target = cur_state;
 			cdev->updated = false; /* cooling device needs update */
 		}
@@ -1179,6 +1125,11 @@ 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 &&
+			    cur_state == THERMAL_NO_TARGET)
+				tz->passive--;
 			instance->target = cur_state;
 			cdev->updated = false; /* cooling device needs update */
 		}
@@ -1235,16 +1186,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] 41+ messages in thread

* [PATCH RESEND 16/16] Thermal: Introduce locking for cdev.thermal_instances list.
  2012-07-25  2:10 [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement Zhang Rui
                   ` (14 preceding siblings ...)
  2012-07-25  2:11 ` [PATCH RESEND 15/16] Thermal: Unify the code for both active and passive cooling Zhang Rui
@ 2012-07-25  2:11 ` Zhang Rui
  2012-07-25 18:54   ` Rafael J. Wysocki
  15 siblings, 1 reply; 41+ messages in thread
From: Zhang Rui @ 2012-07-25  2:11 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

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 23a5c86..531480a 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -814,6 +814,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;
@@ -823,6 +824,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)
@@ -855,14 +857,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;
@@ -928,6 +933,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;
@@ -1031,6 +1037,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)
@@ -1038,6 +1045,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] 41+ messages in thread

* Re: [PATCH RESEND 01/16] Thermal: Make Thermal trip points writeable
  2012-07-25  2:10 ` [PATCH RESEND 01/16] Thermal: Make Thermal trip points writeable Zhang Rui
@ 2012-07-25  3:18   ` Len Brown
  0 siblings, 0 replies; 41+ messages in thread
From: Len Brown @ 2012-07-25  3:18 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

Applied.

Thanks for the refresh,
Len Brown, Intel Open Source Technology Center


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

* Re: [PATCH RESEND 02/16] Thermal: Add Hysteresis attributes
  2012-07-25  2:10 ` [PATCH RESEND 02/16] Thermal: Add Hysteresis attributes Zhang Rui
@ 2012-07-25  3:19   ` Len Brown
  0 siblings, 0 replies; 41+ messages in thread
From: Len Brown @ 2012-07-25  3:19 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, R Durgadoss,
	Eduardo Valentin, Amit Kachhap, Wei Ni, linux-acpi, linux-pm

Applied.

Thanks for the refresh.

-Len Brown, Intel Open Source Technology Center

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

* Re: [PATCH RESEND 16/16] Thermal: Introduce locking for cdev.thermal_instances list.
  2012-07-25  2:11 ` [PATCH RESEND 16/16] Thermal: Introduce locking for cdev.thermal_instances list Zhang Rui
@ 2012-07-25 18:54   ` Rafael J. Wysocki
  2012-07-26  2:32     ` Zhang Rui
  0 siblings, 1 reply; 41+ messages in thread
From: Rafael J. Wysocki @ 2012-07-25 18:54 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Matthew Garrett, Len Brown, R Durgadoss, Eduardo Valentin,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Wednesday, July 25, 2012, Zhang Rui wrote:

Can you please say something about the motivation in the changelog?

Thanks,
Rafael


> 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 23a5c86..531480a 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -814,6 +814,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;
> @@ -823,6 +824,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)
> @@ -855,14 +857,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;
> @@ -928,6 +933,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;
> @@ -1031,6 +1037,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)
> @@ -1038,6 +1045,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] 41+ messages in thread

* Re: [PATCH RESEND 04/16] Thermal: Introduce multiple cooling states support
  2012-07-25  2:11 ` [PATCH RESEND 04/16] Thermal: Introduce multiple cooling states support Zhang Rui
@ 2012-07-25 20:06   ` Rafael J. Wysocki
  2012-07-26  2:33     ` Zhang Rui
  0 siblings, 1 reply; 41+ messages in thread
From: Rafael J. Wysocki @ 2012-07-25 20:06 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Matthew Garrett, Len Brown, R Durgadoss, Eduardo Valentin,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Wednesday, July 25, 2012, Zhang Rui wrote:
> This is because general active cooling devices, like fans,
> may have multiple speeds, which can be mapped to different cooling states.
> 
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

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

> ---
>  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:
> 


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

* Re: [PATCH RESEND 05/16] Thermal: Introduce cooling states range support
  2012-07-25  2:11 ` [PATCH RESEND 05/16] Thermal: Introduce cooling states range support Zhang Rui
@ 2012-07-25 20:08   ` Rafael J. Wysocki
  2012-08-08 12:07   ` Valentin, Eduardo
  1 sibling, 0 replies; 41+ messages in thread
From: Rafael J. Wysocki @ 2012-07-25 20:08 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Matthew Garrett, Len Brown, R Durgadoss, Eduardo Valentin,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Wednesday, July 25, 2012, 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.
> 
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

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

> ---
>  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);
>  			}
> 


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

* Re: [PATCH RESEND 06/16] Thermal: set upper and lower limits
  2012-07-25  2:11 ` [PATCH RESEND 06/16] Thermal: set upper and lower limits Zhang Rui
@ 2012-07-25 20:14   ` Rafael J. Wysocki
  2012-08-08 12:50   ` Valentin, Eduardo
  1 sibling, 0 replies; 41+ messages in thread
From: Rafael J. Wysocki @ 2012-07-25 20:14 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Matthew Garrett, Len Brown, R Durgadoss, Eduardo Valentin,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Wednesday, July 25, 2012, Zhang Rui wrote:
> set upper and lower limits when binding
> a thermal cooling device to a thermal zone device.
> 
> 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..0154eac 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, 1);

That should be

+	return acpi_thermal_cooling_device_cb(thermal, cdev, true);

I suppose.

>  }
>  
>  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, 0);

And that should be

+	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 *);
> 

Looks good apart from the above nits (arguably minor).

Thanks,
Rafael

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

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

On Wednesday, July 25, 2012, Zhang Rui wrote:
> tc1 and tc2 are used by OSPM to anticipate the temperature trends.
> But they are ACPI platform specific concepts.
> 
> Introduce .get_trend() as a more general solution.
> 
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> ---
>  drivers/acpi/thermal.c        |   33 +++++++++++++++++++++++++++++++++
>  drivers/thermal/thermal_sys.c |   22 ++++++++++++++++++++--
>  include/linux/thermal.h       |    9 +++++++++
>  3 files changed, 62 insertions(+), 2 deletions(-)
> 
> diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> index 0154eac..01c92fd 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..d406524 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -699,6 +699,21 @@ thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
>  }
>  #endif
>  
> +static void thermal_get_trend(struct thermal_zone_device *tz,
> +		int trip, enum thermal_trend *trend)
> +{
> +	if (tz->ops->get_trend && !tz->ops->get_trend(tz, trip, trend))
> +			return;
> +
> +	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;
> +	return;
> +}
> +

As I said in the review of the previous version of this patch series, I think
that the code from the function above should go directly into
thermal_zone_device_passive().  The ugly pointer manipulations would be
avoidable in that case and the code would be cleaner overall in my opinion.

>  static void thermal_zone_device_set_polling(struct thermal_zone_device *tz,
>  					    int delay)
>  {
> @@ -733,6 +748,8 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>  	if (temp >= trip_temp) {
>  		tz->passive = true;
>  
> +		thermal_get_trend(tz, trip, (enum thermal_trend *)&trend);
> +
>  		trend = (tz->tc1 * (temp - tz->last_temperature)) +
>  			(tz->tc2 * (temp - trip_temp));
>  
> @@ -1091,6 +1108,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 +1170,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;
> 

Thanks,
Rafael

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

* Re: [PATCH RESEND 08/16] Thermal: Remove tc1/tc2 in generic thermal layer.
  2012-07-25  2:11 ` [PATCH RESEND 08/16] Thermal: Remove tc1/tc2 in generic thermal layer Zhang Rui
@ 2012-07-25 20:24   ` Rafael J. Wysocki
  2012-07-26  2:23     ` Zhang Rui
  0 siblings, 1 reply; 41+ messages in thread
From: Rafael J. Wysocki @ 2012-07-25 20:24 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Matthew Garrett, Len Brown, R Durgadoss, Eduardo Valentin,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

First, it would be good to write something about the motivation here.

Second, I suppose that there are no users of the code in question who
rely on the current behavior except for ACPI.  If that is the case, it
should be state in the changelog too, because that's an important piece
of information for whoever wants to understand what's going on.  If
that is not the case, however, you should describe how your changes will
affect the users in question, so that it's clear enough that no regressions
will result from this change.

Thanks,
Rafael


On Wednesday, July 25, 2012, Zhang Rui wrote:
> 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            |   23 ++++++-----------------
>  include/linux/thermal.h                  |    5 +----
>  6 files changed, 11 insertions(+), 28 deletions(-)
> 
> diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> index 01c92fd..5417362 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 d406524..727aa74 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);
> @@ -733,7 +730,7 @@ 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;
> @@ -748,13 +745,10 @@ static void thermal_zone_device_passive(struct thermal_zone_device *tz,
>  	if (temp >= trip_temp) {
>  		tz->passive = true;
>  
> -		thermal_get_trend(tz, trip, (enum thermal_trend *)&trend);
> -
> -		trend = (tz->tc1 * (temp - tz->last_temperature)) +
> -			(tz->tc2 * (temp - trip_temp));
> +		thermal_get_trend(tz, trip, &trend);
>  
>  		/* Heating up? */
> -		if (trend > 0) {
> +		if (trend == THERMAL_TREND_RAISING) {
>  			list_for_each_entry(instance, &tz->cooling_devices,
>  					    node) {
>  				if (instance->trip != trip)
> @@ -765,7 +759,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)
> @@ -1291,8 +1285,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
> @@ -1300,13 +1292,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;
> @@ -1342,8 +1333,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] 41+ messages in thread

* Re: [PATCH RESEND 09/16] Thermal: Introduce thermal_zone_trip_update()
  2012-07-25  2:11 ` [PATCH RESEND 09/16] Thermal: Introduce thermal_zone_trip_update() Zhang Rui
@ 2012-07-25 20:31   ` Rafael J. Wysocki
  2012-07-26  2:25     ` Zhang Rui
  0 siblings, 1 reply; 41+ messages in thread
From: Rafael J. Wysocki @ 2012-07-25 20:31 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Matthew Garrett, Len Brown, R Durgadoss, Eduardo Valentin,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Wednesday, July 25, 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>
> ---
>  drivers/acpi/thermal.c        |    7 +++-
>  drivers/thermal/thermal_sys.c |   91 +++++++++++++++++++++++++++++------------
>  2 files changed, 71 insertions(+), 27 deletions(-)
> 
> diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> index 5417362..8f8e695 100644
> --- a/drivers/acpi/thermal.c
> +++ b/drivers/acpi/thermal.c
> @@ -714,7 +714,12 @@ 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_ACTIVE) {
> +		/* aggressive active cooling */
> +		*trend = THERMAL_TREND_RAISING;
> +		return 0;
> +	}
> +

Do we still need the check below?

>  	if (type != THERMAL_TRIP_PASSIVE)
>  		return -EINVAL;
>  
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index 727aa74..cc1b192 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -1080,6 +1080,70 @@ 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 (temp >= trip_temp) {
> +		thermal_get_trend(tz, trip, &trend);

I see that you need thermal_get_trend() here.

BTW, why don't you make it return the trend instead of passing the poiter to it?

> +
> +		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 */

But wouldn't it be good to check the trend here too?  So that we don't
go to the lower state if the trend is rising, for example?

> +		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
> @@ -1090,9 +1154,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);
>  
> @@ -1128,29 +1189,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)
> 

Thanks,
Rafael

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

* Re: [PATCH RESEND 10/16] Thermal: rename structure thermal_cooling_device_instance to thermal_instance
  2012-07-25  2:11 ` [PATCH RESEND 10/16] Thermal: rename structure thermal_cooling_device_instance to thermal_instance Zhang Rui
@ 2012-07-25 20:32   ` Rafael J. Wysocki
  0 siblings, 0 replies; 41+ messages in thread
From: Rafael J. Wysocki @ 2012-07-25 20:32 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Matthew Garrett, Len Brown, R Durgadoss, Eduardo Valentin,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Wednesday, July 25, 2012, 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.
> 
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

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

> ---
>  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 cc1b192..6f245c8 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");
> @@ -731,7 +731,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;
>  
> @@ -816,8 +816,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;
> @@ -848,7 +848,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;
> @@ -913,7 +913,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) {
> @@ -1099,7 +1099,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;
> 


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

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

On Wednesday, July 25, 2012, 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.
> 
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

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

> ---
>  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 6f245c8..5f362e1 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -749,7 +749,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;
> @@ -760,7 +760,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;
> @@ -781,7 +781,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;
> @@ -877,13 +877,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)
> @@ -916,7 +916,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);
> @@ -1110,7 +1110,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
>  	if (temp >= trip_temp) {
>  		thermal_get_trend(tz, trip, &trend);
>  
> -		list_for_each_entry(instance, &tz->cooling_devices, node) {
> +		list_for_each_entry(instance, &tz->thermal_instances, node) {
>  			if (instance->trip != trip)
>  				continue;
>  
> @@ -1129,7 +1129,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;
>  
> @@ -1358,7 +1358,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;
>  };
> 


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

* Re: [PATCH RESEND 12/16] Thermal: Rename thermal_instance.node to thermal_instance.tz_node.
  2012-07-25  2:11 ` [PATCH RESEND 12/16] Thermal: Rename thermal_instance.node to thermal_instance.tz_node Zhang Rui
@ 2012-07-25 20:34   ` Rafael J. Wysocki
  0 siblings, 0 replies; 41+ messages in thread
From: Rafael J. Wysocki @ 2012-07-25 20:34 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Matthew Garrett, Len Brown, R Durgadoss, Eduardo Valentin,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Wednesday, July 25, 2012, 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.
> 
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

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

> ---
>  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 5f362e1..b76e55f 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);
> @@ -750,7 +750,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;
> @@ -761,7 +761,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;
> @@ -781,7 +781,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;
> @@ -877,13 +877,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)
> @@ -916,9 +916,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;
>  		}
> @@ -1110,7 +1110,7 @@ static void thermal_zone_trip_update(struct thermal_zone_device *tz,
>  	if (temp >= trip_temp) {
>  		thermal_get_trend(tz, trip, &trend);
>  
> -		list_for_each_entry(instance, &tz->thermal_instances, node) {
> +		list_for_each_entry(instance, &tz->thermal_instances, tz_node) {
>  			if (instance->trip != trip)
>  				continue;
>  
> @@ -1129,7 +1129,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;
>  
> 


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

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

On Wednesday, July 25, 2012, 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.
> 
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

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

> ---
>  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 b76e55f..0a06ea4 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);
> @@ -882,8 +883,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)
> @@ -919,6 +922,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;
>  		}
> @@ -988,6 +992,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;
>  };
>  
> 


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

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

On Wednesday, July 25, 2012, 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.
> 
> 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 0a06ea4..ee10df5 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 */
> @@ -857,6 +859,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)
> @@ -994,6 +997,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);
> @@ -1085,6 +1089,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
>   *
> @@ -1131,19 +1163,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 deacitve thermal instance */

s/deactive/inactive/

Apart from this looks good.

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

> +			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 */
>  		}
>  	}
>  
> @@ -1204,6 +1241,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;
>  };
> 

Thanks,
Rafael

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

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

On Wednesday, July 25, 2012, 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.
> 
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>

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

> ---
>  drivers/thermal/thermal_sys.c |   97 ++++++++++-------------------------------
>  include/linux/thermal.h       |    2 +-
>  2 files changed, 24 insertions(+), 75 deletions(-)
> 
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index ee10df5..23a5c86 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -730,73 +730,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;
> -
> -	/*
> -	 * 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;
> -
> -		thermal_get_trend(tz, trip, &trend);
> -
> -		/* 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
> @@ -1118,7 +1051,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
> @@ -1140,9 +1073,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 (temp >= trip_temp) {
>  		thermal_get_trend(tz, trip, &trend);
> @@ -1163,6 +1103,12 @@ 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 &&
> +			    instance->target == THERMAL_NO_TARGET)
> +				tz->passive++;
> +
>  			instance->target = cur_state;
>  			cdev->updated = false; /* cooling device needs update */
>  		}
> @@ -1179,6 +1125,11 @@ 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 &&
> +			    cur_state == THERMAL_NO_TARGET)
> +				tz->passive--;
>  			instance->target = cur_state;
>  			cdev->updated = false; /* cooling device needs update */
>  		}
> @@ -1235,16 +1186,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;
> 


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

* Re: [PATCH RESEND 07/16] Thermal: Introduce .get_trend() callback.
  2012-07-25 20:19   ` Rafael J. Wysocki
@ 2012-07-26  2:21     ` Zhang Rui
  0 siblings, 0 replies; 41+ messages in thread
From: Zhang Rui @ 2012-07-26  2:21 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-25 at 22:19 +0200, Rafael J. Wysocki wrote:
> On Wednesday, July 25, 2012, Zhang Rui wrote:
> > tc1 and tc2 are used by OSPM to anticipate the temperature trends.
> > But they are ACPI platform specific concepts.
> > 
> > Introduce .get_trend() as a more general solution.
> > 
> > Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> > ---
> >  drivers/acpi/thermal.c        |   33 +++++++++++++++++++++++++++++++++
> >  drivers/thermal/thermal_sys.c |   22 ++++++++++++++++++++--
> >  include/linux/thermal.h       |    9 +++++++++
> >  3 files changed, 62 insertions(+), 2 deletions(-)
> > 
> > diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> > index 0154eac..01c92fd 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..d406524 100644
> > --- a/drivers/thermal/thermal_sys.c
> > +++ b/drivers/thermal/thermal_sys.c
> > @@ -699,6 +699,21 @@ thermal_remove_hwmon_sysfs(struct thermal_zone_device *tz)
> >  }
> >  #endif
> >  
> > +static void thermal_get_trend(struct thermal_zone_device *tz,
> > +		int trip, enum thermal_trend *trend)
> > +{
> > +	if (tz->ops->get_trend && !tz->ops->get_trend(tz, trip, trend))
> > +			return;
> > +
> > +	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;
> > +	return;
> > +}
> > +
> 
> As I said in the review of the previous version of this patch series, I think
> that the code from the function above should go directly into
> thermal_zone_device_passive().  The ugly pointer manipulations would be
> avoidable in that case and the code would be cleaner overall in my opinion.
> 
agreed.

thanks,
rui

--
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] 41+ messages in thread

* Re: [PATCH RESEND 08/16] Thermal: Remove tc1/tc2 in generic thermal layer.
  2012-07-25 20:24   ` Rafael J. Wysocki
@ 2012-07-26  2:23     ` Zhang Rui
  0 siblings, 0 replies; 41+ messages in thread
From: Zhang Rui @ 2012-07-26  2:23 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-25 at 22:24 +0200, Rafael J. Wysocki wrote:
> First, it would be good to write something about the motivation here.
> 
> Second, I suppose that there are no users of the code in question who
> rely on the current behavior except for ACPI.  If that is the case, it
> should be state in the changelog too, because that's an important piece
> of information for whoever wants to understand what's going on.  If
> that is not the case, however, you should describe how your changes will
> affect the users in question, so that it's clear enough that no regressions
> will result from this change.
> 
yep, but I think I should state this in the previous patch, when
introducing .get_trend() callback.
This patch just does some cleanups.

thanks,
rui

--
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] 41+ messages in thread

* Re: [PATCH RESEND 09/16] Thermal: Introduce thermal_zone_trip_update()
  2012-07-25 20:31   ` Rafael J. Wysocki
@ 2012-07-26  2:25     ` Zhang Rui
  0 siblings, 0 replies; 41+ messages in thread
From: Zhang Rui @ 2012-07-26  2:25 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-25 at 22:31 +0200, Rafael J. Wysocki wrote:
> On Wednesday, July 25, 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>
> > ---
> >  drivers/acpi/thermal.c        |    7 +++-
> >  drivers/thermal/thermal_sys.c |   91 +++++++++++++++++++++++++++++------------
> >  2 files changed, 71 insertions(+), 27 deletions(-)
> > 
> > diff --git a/drivers/acpi/thermal.c b/drivers/acpi/thermal.c
> > index 5417362..8f8e695 100644
> > --- a/drivers/acpi/thermal.c
> > +++ b/drivers/acpi/thermal.c
> > @@ -714,7 +714,12 @@ 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_ACTIVE) {
> > +		/* aggressive active cooling */
> > +		*trend = THERMAL_TREND_RAISING;
> > +		return 0;
> > +	}
> > +
> 
> Do we still need the check below?
> 
No.
Although there are other trip types like HOT/CRIT, but only updating
PASSIVE/ACTIVE points will invoke this thermal_get_trend callback.

> >  	if (type != THERMAL_TRIP_PASSIVE)
> >  		return -EINVAL;
> >  

thanks,
rui

--
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] 41+ messages in thread

* Re: [PATCH RESEND 16/16] Thermal: Introduce locking for cdev.thermal_instances list.
  2012-07-25 18:54   ` Rafael J. Wysocki
@ 2012-07-26  2:32     ` Zhang Rui
  0 siblings, 0 replies; 41+ messages in thread
From: Zhang Rui @ 2012-07-26  2:32 UTC (permalink / raw)
  To: Rafael J. Wysocki
  Cc: Matthew Garrett, Len Brown, R Durgadoss, Eduardo Valentin,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

Hi, Rafael,

On 三, 2012-07-25 at 20:54 +0200, Rafael J. Wysocki wrote:
> On Wednesday, July 25, 2012, Zhang Rui wrote:
> 
> Can you please say something about the motivation in the changelog?
> 
sure.
I just thought that the subject is enough illustrating the problem.
will fix it.

thanks for your comments on this!

-rui
> 


--
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] 41+ messages in thread

* Re: [PATCH RESEND 04/16] Thermal: Introduce multiple cooling states support
  2012-07-25 20:06   ` Rafael J. Wysocki
@ 2012-07-26  2:33     ` Zhang Rui
  0 siblings, 0 replies; 41+ messages in thread
From: Zhang Rui @ 2012-07-26  2:33 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-25 at 22:06 +0200, Rafael J. Wysocki wrote:
> On Wednesday, July 25, 2012, Zhang Rui wrote:
> > This is because general active cooling devices, like fans,
> > may have multiple speeds, which can be mapped to different cooling states.
> > 
> > Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> 
> Reviewed-by: Rafael J. Wysocki <rjw@sisk.pl>
> 
again, thanks for reviewing this patch set, Rafael!

-rui

--
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] 41+ messages in thread

* Re: [PATCH RESEND 05/16] Thermal: Introduce cooling states range support
  2012-07-25  2:11 ` [PATCH RESEND 05/16] Thermal: Introduce cooling states range support Zhang Rui
  2012-07-25 20:08   ` Rafael J. Wysocki
@ 2012-08-08 12:07   ` Valentin, Eduardo
  1 sibling, 0 replies; 41+ messages in thread
From: Valentin, Eduardo @ 2012-08-08 12:07 UTC (permalink / raw)
  To: Zhang Rui
  Cc: Rafael J. Wysocki, Matthew Garrett, Len Brown, R Durgadoss,
	Amit Kachhap, Wei Ni, linux-acpi, linux-pm

On Wed, Jul 25, 2012 at 5:11 AM, Zhang Rui <rui.zhang@intel.com> 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.
>
> 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
>



-- 

Eduardo Valentin

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

* Re: [PATCH RESEND 06/16] Thermal: set upper and lower limits
  2012-07-25  2:11 ` [PATCH RESEND 06/16] Thermal: set upper and lower limits Zhang Rui
  2012-07-25 20:14   ` Rafael J. Wysocki
@ 2012-08-08 12:50   ` Valentin, Eduardo
  1 sibling, 0 replies; 41+ messages in thread
From: Valentin, Eduardo @ 2012-08-08 12:50 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 Wed, Jul 25, 2012 at 5:11 AM, Zhang Rui <rui.zhang@intel.com> wrote:
> set upper and lower limits when binding
> a thermal cooling device to a thermal zone device.
>
> 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 +++-

Could you please update omap-thermal-common.c
(drivers/staging/omap-thermal/omap-thermal-common.c) as well?
otherwise I will get a compilation problem:

drivers/staging/omap-thermal/omap-thermal-common.c: In function
'omap_thermal_bind':
drivers/staging/omap-thermal/omap-thermal-common.c:123: error: too few
arguments to function 'thermal_zone_bind_cooling_device'
make[3]: *** [drivers/staging/omap-thermal/omap-thermal-common.o] Error 1
make[3]: *** Waiting for unfinished jobs....

FYR:

--- 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 */


Cheers,


>  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..0154eac 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, 1);
>  }
>
>  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, 0);
>  }
>
>  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
>



-- 

Eduardo Valentin

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

* Re: [PATCH RESEND 15/16] Thermal: Unify the code for both active and passive cooling
  2012-07-25  2:11 ` [PATCH RESEND 15/16] Thermal: Unify the code for both active and passive cooling Zhang Rui
  2012-07-25 20:41   ` Rafael J. Wysocki
@ 2012-08-09  8:26   ` Valentin, Eduardo
  2012-08-09  8:32     ` Zhang Rui
  1 sibling, 1 reply; 41+ messages in thread
From: Valentin, Eduardo @ 2012-08-09  8:26 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 Wed, Jul 25, 2012 at 5:11 AM, Zhang Rui <rui.zhang@intel.com> wrote:
> Remove thermal_zone_device_passive(). And use
> thermal_zone_trip_update() and thermal_zone_do_update()
> for both active and passive cooling.

I believe you need to refresh this patch on top of your new changes on
this series. It is not applying cleanly due to changes done in
previous patches.

>
> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> ---
>  drivers/thermal/thermal_sys.c |   97 ++++++++++-------------------------------
>  include/linux/thermal.h       |    2 +-
>  2 files changed, 24 insertions(+), 75 deletions(-)
>
> diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> index ee10df5..23a5c86 100644
> --- a/drivers/thermal/thermal_sys.c
> +++ b/drivers/thermal/thermal_sys.c
> @@ -730,73 +730,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;
> -
> -       /*
> -        * 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;
> -
> -               thermal_get_trend(tz, trip, &trend);
> -
> -               /* 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
> @@ -1118,7 +1051,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
> @@ -1140,9 +1073,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 (temp >= trip_temp) {
>                 thermal_get_trend(tz, trip, &trend);
> @@ -1163,6 +1103,12 @@ 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 &&
> +                           instance->target == THERMAL_NO_TARGET)
> +                               tz->passive++;
> +
>                         instance->target = cur_state;
>                         cdev->updated = false; /* cooling device needs update */
>                 }
> @@ -1179,6 +1125,11 @@ 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 &&
> +                           cur_state == THERMAL_NO_TARGET)
> +                               tz->passive--;
>                         instance->target = cur_state;
>                         cdev->updated = false; /* cooling device needs update */
>                 }
> @@ -1235,16 +1186,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
>



-- 

Eduardo Valentin

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

* Re: [PATCH RESEND 15/16] Thermal: Unify the code for both active and passive cooling
  2012-08-09  8:26   ` Valentin, Eduardo
@ 2012-08-09  8:32     ` Zhang Rui
  0 siblings, 0 replies; 41+ messages in thread
From: Zhang Rui @ 2012-08-09  8:32 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-09 at 11:26 +0300, Valentin, Eduardo wrote:
> Hello,
> 
> 
> 
> On Wed, Jul 25, 2012 at 5:11 AM, Zhang Rui <rui.zhang@intel.com> wrote:
> > Remove thermal_zone_device_passive(). And use
> > thermal_zone_trip_update() and thermal_zone_do_update()
> > for both active and passive cooling.
> 
> I believe you need to refresh this patch on top of your new changes on
> this series. It is not applying cleanly due to changes done in
> previous patches.
> 
hmm,

probably you are testing patches from different version.
does the problem still exist in Patch set V4?

thanks,
rui

> >
> > Signed-off-by: Zhang Rui <rui.zhang@intel.com>
> > ---
> >  drivers/thermal/thermal_sys.c |   97 ++++++++++-------------------------------
> >  include/linux/thermal.h       |    2 +-
> >  2 files changed, 24 insertions(+), 75 deletions(-)
> >
> > diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
> > index ee10df5..23a5c86 100644
> > --- a/drivers/thermal/thermal_sys.c
> > +++ b/drivers/thermal/thermal_sys.c
> > @@ -730,73 +730,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;
> > -
> > -       /*
> > -        * 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;
> > -
> > -               thermal_get_trend(tz, trip, &trend);
> > -
> > -               /* 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
> > @@ -1118,7 +1051,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
> > @@ -1140,9 +1073,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 (temp >= trip_temp) {
> >                 thermal_get_trend(tz, trip, &trend);
> > @@ -1163,6 +1103,12 @@ 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 &&
> > +                           instance->target == THERMAL_NO_TARGET)
> > +                               tz->passive++;
> > +
> >                         instance->target = cur_state;
> >                         cdev->updated = false; /* cooling device needs update */
> >                 }
> > @@ -1179,6 +1125,11 @@ 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 &&
> > +                           cur_state == THERMAL_NO_TARGET)
> > +                               tz->passive--;
> >                         instance->target = cur_state;
> >                         cdev->updated = false; /* cooling device needs update */
> >                 }
> > @@ -1235,16 +1186,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
> >
> 
> 
> 


--
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] 41+ messages in thread

end of thread, other threads:[~2012-08-09  8:31 UTC | newest]

Thread overview: 41+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2012-07-25  2:10 [PATCH RESEND 00/16] Thermal: generic thermal layer enhancement Zhang Rui
2012-07-25  2:10 ` [PATCH RESEND 01/16] Thermal: Make Thermal trip points writeable Zhang Rui
2012-07-25  3:18   ` Len Brown
2012-07-25  2:10 ` [PATCH RESEND 02/16] Thermal: Add Hysteresis attributes Zhang Rui
2012-07-25  3:19   ` Len Brown
2012-07-25  2:11 ` [PATCH RESEND 03/16] Thermal: Documentation update Zhang Rui
2012-07-25  2:11 ` [PATCH RESEND 04/16] Thermal: Introduce multiple cooling states support Zhang Rui
2012-07-25 20:06   ` Rafael J. Wysocki
2012-07-26  2:33     ` Zhang Rui
2012-07-25  2:11 ` [PATCH RESEND 05/16] Thermal: Introduce cooling states range support Zhang Rui
2012-07-25 20:08   ` Rafael J. Wysocki
2012-08-08 12:07   ` Valentin, Eduardo
2012-07-25  2:11 ` [PATCH RESEND 06/16] Thermal: set upper and lower limits Zhang Rui
2012-07-25 20:14   ` Rafael J. Wysocki
2012-08-08 12:50   ` Valentin, Eduardo
2012-07-25  2:11 ` [PATCH RESEND 07/16] Thermal: Introduce .get_trend() callback Zhang Rui
2012-07-25 20:19   ` Rafael J. Wysocki
2012-07-26  2:21     ` Zhang Rui
2012-07-25  2:11 ` [PATCH RESEND 08/16] Thermal: Remove tc1/tc2 in generic thermal layer Zhang Rui
2012-07-25 20:24   ` Rafael J. Wysocki
2012-07-26  2:23     ` Zhang Rui
2012-07-25  2:11 ` [PATCH RESEND 09/16] Thermal: Introduce thermal_zone_trip_update() Zhang Rui
2012-07-25 20:31   ` Rafael J. Wysocki
2012-07-26  2:25     ` Zhang Rui
2012-07-25  2:11 ` [PATCH RESEND 10/16] Thermal: rename structure thermal_cooling_device_instance to thermal_instance Zhang Rui
2012-07-25 20:32   ` Rafael J. Wysocki
2012-07-25  2:11 ` [PATCH RESEND 11/16] Thermal: Rename thermal_zone_device.cooling_devices Zhang Rui
2012-07-25 20:33   ` Rafael J. Wysocki
2012-07-25  2:11 ` [PATCH RESEND 12/16] Thermal: Rename thermal_instance.node to thermal_instance.tz_node Zhang Rui
2012-07-25 20:34   ` Rafael J. Wysocki
2012-07-25  2:11 ` [PATCH RESEND 13/16] Thermal: List thermal_instance in thermal_cooling_device Zhang Rui
2012-07-25 20:35   ` Rafael J. Wysocki
2012-07-25  2:11 ` [PATCH RESEND 14/16] Thermal: Introduce simple arbitrator for setting device cooling state Zhang Rui
2012-07-25 20:38   ` Rafael J. Wysocki
2012-07-25  2:11 ` [PATCH RESEND 15/16] Thermal: Unify the code for both active and passive cooling Zhang Rui
2012-07-25 20:41   ` Rafael J. Wysocki
2012-08-09  8:26   ` Valentin, Eduardo
2012-08-09  8:32     ` Zhang Rui
2012-07-25  2:11 ` [PATCH RESEND 16/16] Thermal: Introduce locking for cdev.thermal_instances list Zhang Rui
2012-07-25 18:54   ` Rafael J. Wysocki
2012-07-26  2:32     ` Zhang Rui

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.