浏览代码

thermal: thermal_core: allow binding with limits on bind_params

When registering a thermal zone device using platform information
via bind_params, the thermal framework will always perform the
cdev binding using the lowest and highest limits (THERMAL_NO_LIMIT).

This patch changes the data structures so that it is possible
to inform what are the desired limits for each trip point
inside a bind_param. The way the binding is performed is also
changed so that it uses the new data structure.

Cc: Zhang Rui <rui.zhang@intel.com>
Cc: linux-pm@vger.kernel.org
Cc: linux-kernel@vger.kernel.org
Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Eduardo Valentin 12 年之前
父节点
当前提交
a8892d8389
共有 3 个文件被更改,包括 32 次插入4 次删除
  1. 7 0
      Documentation/thermal/sysfs-api.txt
  2. 15 4
      drivers/thermal/thermal_core.c
  3. 10 0
      include/linux/thermal.h

+ 7 - 0
Documentation/thermal/sysfs-api.txt

@@ -134,6 +134,13 @@ temperature) and throttle appropriate devices.
                this thermal zone and cdev, for a particular trip point.
                this thermal zone and cdev, for a particular trip point.
                If nth bit is set, then the cdev and thermal zone are bound
                If nth bit is set, then the cdev and thermal zone are bound
                for trip point n.
                for trip point n.
+    .limits: This is an array of cooling state limits. Must have exactly
+         2 * thermal_zone.number_of_trip_points. It is an array consisting
+         of tuples <lower-state upper-state> of state limits. Each trip
+         will be associated with one state limit tuple when binding.
+         A NULL pointer means <THERMAL_NO_LIMITS THERMAL_NO_LIMITS>
+         on all trips. These limits are used when binding a cdev to a
+         trip point.
     .match: This call back returns success(0) if the 'tz and cdev' need to
     .match: This call back returns success(0) if the 'tz and cdev' need to
 	    be bound, as per platform data.
 	    be bound, as per platform data.
 1.4.2 struct thermal_zone_params
 1.4.2 struct thermal_zone_params

+ 15 - 4
drivers/thermal/thermal_core.c

@@ -202,14 +202,23 @@ static void print_bind_err_msg(struct thermal_zone_device *tz,
 }
 }
 
 
 static void __bind(struct thermal_zone_device *tz, int mask,
 static void __bind(struct thermal_zone_device *tz, int mask,
-			struct thermal_cooling_device *cdev)
+			struct thermal_cooling_device *cdev,
+			unsigned long *limits)
 {
 {
 	int i, ret;
 	int i, ret;
 
 
 	for (i = 0; i < tz->trips; i++) {
 	for (i = 0; i < tz->trips; i++) {
 		if (mask & (1 << i)) {
 		if (mask & (1 << i)) {
+			unsigned long upper, lower;
+
+			upper = THERMAL_NO_LIMIT;
+			lower = THERMAL_NO_LIMIT;
+			if (limits) {
+				lower = limits[i * 2];
+				upper = limits[i * 2 + 1];
+			}
 			ret = thermal_zone_bind_cooling_device(tz, i, cdev,
 			ret = thermal_zone_bind_cooling_device(tz, i, cdev,
-					THERMAL_NO_LIMIT, THERMAL_NO_LIMIT);
+							       upper, lower);
 			if (ret)
 			if (ret)
 				print_bind_err_msg(tz, cdev, ret);
 				print_bind_err_msg(tz, cdev, ret);
 		}
 		}
@@ -254,7 +263,8 @@ static void bind_cdev(struct thermal_cooling_device *cdev)
 			if (tzp->tbp[i].match(pos, cdev))
 			if (tzp->tbp[i].match(pos, cdev))
 				continue;
 				continue;
 			tzp->tbp[i].cdev = cdev;
 			tzp->tbp[i].cdev = cdev;
-			__bind(pos, tzp->tbp[i].trip_mask, cdev);
+			__bind(pos, tzp->tbp[i].trip_mask, cdev,
+			       tzp->tbp[i].binding_limits);
 		}
 		}
 	}
 	}
 
 
@@ -292,7 +302,8 @@ static void bind_tz(struct thermal_zone_device *tz)
 			if (tzp->tbp[i].match(tz, pos))
 			if (tzp->tbp[i].match(tz, pos))
 				continue;
 				continue;
 			tzp->tbp[i].cdev = pos;
 			tzp->tbp[i].cdev = pos;
-			__bind(tz, tzp->tbp[i].trip_mask, pos);
+			__bind(tz, tzp->tbp[i].trip_mask, pos,
+			       tzp->tbp[i].binding_limits);
 		}
 		}
 	}
 	}
 exit:
 exit:

+ 10 - 0
include/linux/thermal.h

@@ -207,6 +207,16 @@ struct thermal_bind_params {
 	 * See Documentation/thermal/sysfs-api.txt for more information.
 	 * See Documentation/thermal/sysfs-api.txt for more information.
 	 */
 	 */
 	int trip_mask;
 	int trip_mask;
+
+	/*
+	 * This is an array of cooling state limits. Must have exactly
+	 * 2 * thermal_zone.number_of_trip_points. It is an array consisting
+	 * of tuples <lower-state upper-state> of state limits. Each trip
+	 * will be associated with one state limit tuple when binding.
+	 * A NULL pointer means <THERMAL_NO_LIMITS THERMAL_NO_LIMITS>
+	 * on all trips.
+	 */
+	unsigned long *binding_limits;
 	int (*match) (struct thermal_zone_device *tz,
 	int (*match) (struct thermal_zone_device *tz,
 			struct thermal_cooling_device *cdev);
 			struct thermal_cooling_device *cdev);
 };
 };