Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

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>

+32 -4
+7
Documentation/thermal/sysfs-api.txt
··· 134 134 this thermal zone and cdev, for a particular trip point. 135 135 If nth bit is set, then the cdev and thermal zone are bound 136 136 for trip point n. 137 + .limits: This is an array of cooling state limits. Must have exactly 138 + 2 * thermal_zone.number_of_trip_points. It is an array consisting 139 + of tuples <lower-state upper-state> of state limits. Each trip 140 + will be associated with one state limit tuple when binding. 141 + A NULL pointer means <THERMAL_NO_LIMITS THERMAL_NO_LIMITS> 142 + on all trips. These limits are used when binding a cdev to a 143 + trip point. 137 144 .match: This call back returns success(0) if the 'tz and cdev' need to 138 145 be bound, as per platform data. 139 146 1.4.2 struct thermal_zone_params
+15 -4
drivers/thermal/thermal_core.c
··· 202 202 } 203 203 204 204 static void __bind(struct thermal_zone_device *tz, int mask, 205 - struct thermal_cooling_device *cdev) 205 + struct thermal_cooling_device *cdev, 206 + unsigned long *limits) 206 207 { 207 208 int i, ret; 208 209 209 210 for (i = 0; i < tz->trips; i++) { 210 211 if (mask & (1 << i)) { 212 + unsigned long upper, lower; 213 + 214 + upper = THERMAL_NO_LIMIT; 215 + lower = THERMAL_NO_LIMIT; 216 + if (limits) { 217 + lower = limits[i * 2]; 218 + upper = limits[i * 2 + 1]; 219 + } 211 220 ret = thermal_zone_bind_cooling_device(tz, i, cdev, 212 - THERMAL_NO_LIMIT, THERMAL_NO_LIMIT); 221 + upper, lower); 213 222 if (ret) 214 223 print_bind_err_msg(tz, cdev, ret); 215 224 } ··· 263 254 if (tzp->tbp[i].match(pos, cdev)) 264 255 continue; 265 256 tzp->tbp[i].cdev = cdev; 266 - __bind(pos, tzp->tbp[i].trip_mask, cdev); 257 + __bind(pos, tzp->tbp[i].trip_mask, cdev, 258 + tzp->tbp[i].binding_limits); 267 259 } 268 260 } 269 261 ··· 302 292 if (tzp->tbp[i].match(tz, pos)) 303 293 continue; 304 294 tzp->tbp[i].cdev = pos; 305 - __bind(tz, tzp->tbp[i].trip_mask, pos); 295 + __bind(tz, tzp->tbp[i].trip_mask, pos, 296 + tzp->tbp[i].binding_limits); 306 297 } 307 298 } 308 299 exit:
+10
include/linux/thermal.h
··· 207 207 * See Documentation/thermal/sysfs-api.txt for more information. 208 208 */ 209 209 int trip_mask; 210 + 211 + /* 212 + * This is an array of cooling state limits. Must have exactly 213 + * 2 * thermal_zone.number_of_trip_points. It is an array consisting 214 + * of tuples <lower-state upper-state> of state limits. Each trip 215 + * will be associated with one state limit tuple when binding. 216 + * A NULL pointer means <THERMAL_NO_LIMITS THERMAL_NO_LIMITS> 217 + * on all trips. 218 + */ 219 + unsigned long *binding_limits; 210 220 int (*match) (struct thermal_zone_device *tz, 211 221 struct thermal_cooling_device *cdev); 212 222 };