aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal/thermal_sys.c
diff options
context:
space:
mode:
authorDurgadoss R <durgadoss.r@intel.com>2012-09-18 01:34:59 -0400
committerZhang Rui <rui.zhang@intel.com>2012-11-05 01:00:06 -0500
commit7e8ee1e9d7561fe640ae8df6c28f10a6a3239592 (patch)
tree62424e9e873cf857727d6ce9803f2dc73647a561 /drivers/thermal/thermal_sys.c
parent5a2c090b3327353a78232182f2c7fcd69a46eff0 (diff)
Thermal: Update binding logic based on platform data
This patch updates the binding logic in thermal_sys.c It uses the platform layer data to bind a thermal zone to a cdev for a particular trip point. * If we do not have platform data and do not have .bind defined, do not bind. * If we do not have platform data but .bind is defined, then use tz->ops->bind. * If we have platform data, use it to create binding. The same logic sequence is followed for unbind also. Signed-off-by: Durgadoss R <durgadoss.r@intel.com> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Diffstat (limited to 'drivers/thermal/thermal_sys.c')
-rw-r--r--drivers/thermal/thermal_sys.c183
1 files changed, 157 insertions, 26 deletions
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c
index a6933dad3bab..a32803224e3c 100644
--- a/drivers/thermal/thermal_sys.c
+++ b/drivers/thermal/thermal_sys.c
@@ -201,6 +201,111 @@ struct thermal_instance *get_thermal_instance(struct thermal_zone_device *tz,
201} 201}
202EXPORT_SYMBOL(get_thermal_instance); 202EXPORT_SYMBOL(get_thermal_instance);
203 203
204static void print_bind_err_msg(struct thermal_zone_device *tz,
205 struct thermal_cooling_device *cdev, int ret)
206{
207 dev_err(&tz->device, "binding zone %s with cdev %s failed:%d\n",
208 tz->type, cdev->type, ret);
209}
210
211static void __bind(struct thermal_zone_device *tz, int mask,
212 struct thermal_cooling_device *cdev)
213{
214 int i, ret;
215
216 for (i = 0; i < tz->trips; i++) {
217 if (mask & (1 << i)) {
218 ret = thermal_zone_bind_cooling_device(tz, i, cdev,
219 THERMAL_NO_LIMIT, THERMAL_NO_LIMIT);
220 if (ret)
221 print_bind_err_msg(tz, cdev, ret);
222 }
223 }
224}
225
226static void __unbind(struct thermal_zone_device *tz, int mask,
227 struct thermal_cooling_device *cdev)
228{
229 int i;
230
231 for (i = 0; i < tz->trips; i++)
232 if (mask & (1 << i))
233 thermal_zone_unbind_cooling_device(tz, i, cdev);
234}
235
236static void bind_cdev(struct thermal_cooling_device *cdev)
237{
238 int i, ret;
239 const struct thermal_zone_params *tzp;
240 struct thermal_zone_device *pos = NULL;
241
242 mutex_lock(&thermal_list_lock);
243
244 list_for_each_entry(pos, &thermal_tz_list, node) {
245 if (!pos->tzp && !pos->ops->bind)
246 continue;
247
248 if (!pos->tzp && pos->ops->bind) {
249 ret = pos->ops->bind(pos, cdev);
250 if (ret)
251 print_bind_err_msg(pos, cdev, ret);
252 }
253
254 tzp = pos->tzp;
255 if (!tzp->tbp)
256 return;
257
258 for (i = 0; i < tzp->num_tbps; i++) {
259 if (tzp->tbp[i].cdev || !tzp->tbp[i].match)
260 continue;
261 if (tzp->tbp[i].match(pos, cdev))
262 continue;
263 tzp->tbp[i].cdev = cdev;
264 __bind(pos, tzp->tbp[i].trip_mask, cdev);
265 }
266 }
267
268 mutex_unlock(&thermal_list_lock);
269}
270
271static void bind_tz(struct thermal_zone_device *tz)
272{
273 int i, ret;
274 struct thermal_cooling_device *pos = NULL;
275 const struct thermal_zone_params *tzp = tz->tzp;
276
277 if (!tzp && !tz->ops->bind)
278 return;
279
280 mutex_lock(&thermal_list_lock);
281
282 /* If there is no platform data, try to use ops->bind */
283 if (!tzp && tz->ops->bind) {
284 list_for_each_entry(pos, &thermal_cdev_list, node) {
285 ret = tz->ops->bind(tz, pos);
286 if (ret)
287 print_bind_err_msg(tz, pos, ret);
288 }
289 goto exit;
290 }
291
292 if (!tzp->tbp)
293 goto exit;
294
295 list_for_each_entry(pos, &thermal_cdev_list, node) {
296 for (i = 0; i < tzp->num_tbps; i++) {
297 if (tzp->tbp[i].cdev || !tzp->tbp[i].match)
298 continue;
299 if (tzp->tbp[i].match(tz, pos))
300 continue;
301 tzp->tbp[i].cdev = pos;
302 __bind(tz, tzp->tbp[i].trip_mask, pos);
303 }
304 }
305exit:
306 mutex_unlock(&thermal_list_lock);
307}
308
204/* sys I/F for thermal zone */ 309/* sys I/F for thermal zone */
205 310
206#define to_thermal_zone(_dev) \ 311#define to_thermal_zone(_dev) \
@@ -1026,7 +1131,6 @@ thermal_cooling_device_register(char *type, void *devdata,
1026 const struct thermal_cooling_device_ops *ops) 1131 const struct thermal_cooling_device_ops *ops)
1027{ 1132{
1028 struct thermal_cooling_device *cdev; 1133 struct thermal_cooling_device *cdev;
1029 struct thermal_zone_device *pos;
1030 int result; 1134 int result;
1031 1135
1032 if (type && strlen(type) >= THERMAL_NAME_LENGTH) 1136 if (type && strlen(type) >= THERMAL_NAME_LENGTH)
@@ -1076,20 +1180,15 @@ thermal_cooling_device_register(char *type, void *devdata,
1076 if (result) 1180 if (result)
1077 goto unregister; 1181 goto unregister;
1078 1182
1183 /* Add 'this' new cdev to the global cdev list */
1079 mutex_lock(&thermal_list_lock); 1184 mutex_lock(&thermal_list_lock);
1080 list_add(&cdev->node, &thermal_cdev_list); 1185 list_add(&cdev->node, &thermal_cdev_list);
1081 list_for_each_entry(pos, &thermal_tz_list, node) {
1082 if (!pos->ops->bind)
1083 continue;
1084 result = pos->ops->bind(pos, cdev);
1085 if (result)
1086 break;
1087
1088 }
1089 mutex_unlock(&thermal_list_lock); 1186 mutex_unlock(&thermal_list_lock);
1090 1187
1091 if (!result) 1188 /* Update binding information for 'this' new cdev */
1092 return cdev; 1189 bind_cdev(cdev);
1190
1191 return cdev;
1093 1192
1094unregister: 1193unregister:
1095 release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id); 1194 release_idr(&thermal_cdev_idr, &thermal_idr_lock, cdev->id);
@@ -1105,10 +1204,10 @@ EXPORT_SYMBOL(thermal_cooling_device_register);
1105 * thermal_cooling_device_unregister() must be called when the device is no 1204 * thermal_cooling_device_unregister() must be called when the device is no
1106 * longer needed. 1205 * longer needed.
1107 */ 1206 */
1108void thermal_cooling_device_unregister(struct 1207void thermal_cooling_device_unregister(struct thermal_cooling_device *cdev)
1109 thermal_cooling_device
1110 *cdev)
1111{ 1208{
1209 int i;
1210 const struct thermal_zone_params *tzp;
1112 struct thermal_zone_device *tz; 1211 struct thermal_zone_device *tz;
1113 struct thermal_cooling_device *pos = NULL; 1212 struct thermal_cooling_device *pos = NULL;
1114 1213
@@ -1125,12 +1224,28 @@ void thermal_cooling_device_unregister(struct
1125 return; 1224 return;
1126 } 1225 }
1127 list_del(&cdev->node); 1226 list_del(&cdev->node);
1227
1228 /* Unbind all thermal zones associated with 'this' cdev */
1128 list_for_each_entry(tz, &thermal_tz_list, node) { 1229 list_for_each_entry(tz, &thermal_tz_list, node) {
1129 if (!tz->ops->unbind) 1230 if (tz->ops->unbind) {
1231 tz->ops->unbind(tz, cdev);
1232 continue;
1233 }
1234
1235 if (!tz->tzp || !tz->tzp->tbp)
1130 continue; 1236 continue;
1131 tz->ops->unbind(tz, cdev); 1237
1238 tzp = tz->tzp;
1239 for (i = 0; i < tzp->num_tbps; i++) {
1240 if (tzp->tbp[i].cdev == cdev) {
1241 __unbind(tz, tzp->tbp[i].trip_mask, cdev);
1242 tzp->tbp[i].cdev = NULL;
1243 }
1244 }
1132 } 1245 }
1246
1133 mutex_unlock(&thermal_list_lock); 1247 mutex_unlock(&thermal_list_lock);
1248
1134 if (cdev->type[0]) 1249 if (cdev->type[0])
1135 device_remove_file(&cdev->device, &dev_attr_cdev_type); 1250 device_remove_file(&cdev->device, &dev_attr_cdev_type);
1136 device_remove_file(&cdev->device, &dev_attr_max_state); 1251 device_remove_file(&cdev->device, &dev_attr_max_state);
@@ -1468,7 +1583,6 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
1468 int passive_delay, int polling_delay) 1583 int passive_delay, int polling_delay)
1469{ 1584{
1470 struct thermal_zone_device *tz; 1585 struct thermal_zone_device *tz;
1471 struct thermal_cooling_device *pos;
1472 enum thermal_trip_type trip_type; 1586 enum thermal_trip_type trip_type;
1473 int result; 1587 int result;
1474 int count; 1588 int count;
@@ -1567,14 +1681,11 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type,
1567 1681
1568 mutex_lock(&thermal_list_lock); 1682 mutex_lock(&thermal_list_lock);
1569 list_add_tail(&tz->node, &thermal_tz_list); 1683 list_add_tail(&tz->node, &thermal_tz_list);
1570 if (ops->bind)
1571 list_for_each_entry(pos, &thermal_cdev_list, node) {
1572 result = ops->bind(tz, pos);
1573 if (result)
1574 break;
1575 }
1576 mutex_unlock(&thermal_list_lock); 1684 mutex_unlock(&thermal_list_lock);
1577 1685
1686 /* Bind cooling devices for this zone */
1687 bind_tz(tz);
1688
1578 INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check); 1689 INIT_DELAYED_WORK(&(tz->poll_queue), thermal_zone_device_check);
1579 1690
1580 thermal_zone_device_update(tz); 1691 thermal_zone_device_update(tz);
@@ -1595,12 +1706,16 @@ EXPORT_SYMBOL(thermal_zone_device_register);
1595 */ 1706 */
1596void thermal_zone_device_unregister(struct thermal_zone_device *tz) 1707void thermal_zone_device_unregister(struct thermal_zone_device *tz)
1597{ 1708{
1709 int i;
1710 const struct thermal_zone_params *tzp;
1598 struct thermal_cooling_device *cdev; 1711 struct thermal_cooling_device *cdev;
1599 struct thermal_zone_device *pos = NULL; 1712 struct thermal_zone_device *pos = NULL;
1600 1713
1601 if (!tz) 1714 if (!tz)
1602 return; 1715 return;
1603 1716
1717 tzp = tz->tzp;
1718
1604 mutex_lock(&thermal_list_lock); 1719 mutex_lock(&thermal_list_lock);
1605 list_for_each_entry(pos, &thermal_tz_list, node) 1720 list_for_each_entry(pos, &thermal_tz_list, node)
1606 if (pos == tz) 1721 if (pos == tz)
@@ -1611,9 +1726,25 @@ void thermal_zone_device_unregister(struct thermal_zone_device *tz)
1611 return; 1726 return;
1612 } 1727 }
1613 list_del(&tz->node); 1728 list_del(&tz->node);
1614 if (tz->ops->unbind) 1729
1615 list_for_each_entry(cdev, &thermal_cdev_list, node) 1730 /* Unbind all cdevs associated with 'this' thermal zone */
1616 tz->ops->unbind(tz, cdev); 1731 list_for_each_entry(cdev, &thermal_cdev_list, node) {
1732 if (tz->ops->unbind) {
1733 tz->ops->unbind(tz, cdev);
1734 continue;
1735 }
1736
1737 if (!tzp || !tzp->tbp)
1738 break;
1739
1740 for (i = 0; i < tzp->num_tbps; i++) {
1741 if (tzp->tbp[i].cdev == cdev) {
1742 __unbind(tz, tzp->tbp[i].trip_mask, cdev);
1743 tzp->tbp[i].cdev = NULL;
1744 }
1745 }
1746 }
1747
1617 mutex_unlock(&thermal_list_lock); 1748 mutex_unlock(&thermal_list_lock);
1618 1749
1619 thermal_zone_device_set_polling(tz, 0); 1750 thermal_zone_device_set_polling(tz, 0);