diff options
Diffstat (limited to 'drivers/thermal/thermal_sys.c')
-rw-r--r-- | drivers/thermal/thermal_sys.c | 79 |
1 files changed, 68 insertions, 11 deletions
diff --git a/drivers/thermal/thermal_sys.c b/drivers/thermal/thermal_sys.c index 0a1bf6b032ea..0675687c6de8 100644 --- a/drivers/thermal/thermal_sys.c +++ b/drivers/thermal/thermal_sys.c | |||
@@ -378,24 +378,54 @@ static void handle_thermal_trip(struct thermal_zone_device *tz, int trip) | |||
378 | monitor_thermal_zone(tz); | 378 | monitor_thermal_zone(tz); |
379 | } | 379 | } |
380 | 380 | ||
381 | static int thermal_zone_get_temp(struct thermal_zone_device *tz, | ||
382 | unsigned long *temp) | ||
383 | { | ||
384 | int ret = 0, count; | ||
385 | unsigned long crit_temp = -1UL; | ||
386 | enum thermal_trip_type type; | ||
387 | |||
388 | mutex_lock(&tz->lock); | ||
389 | |||
390 | ret = tz->ops->get_temp(tz, temp); | ||
391 | #ifdef CONFIG_THERMAL_EMULATION | ||
392 | if (!tz->emul_temperature) | ||
393 | goto skip_emul; | ||
394 | |||
395 | for (count = 0; count < tz->trips; count++) { | ||
396 | ret = tz->ops->get_trip_type(tz, count, &type); | ||
397 | if (!ret && type == THERMAL_TRIP_CRITICAL) { | ||
398 | ret = tz->ops->get_trip_temp(tz, count, &crit_temp); | ||
399 | break; | ||
400 | } | ||
401 | } | ||
402 | |||
403 | if (ret) | ||
404 | goto skip_emul; | ||
405 | |||
406 | if (*temp < crit_temp) | ||
407 | *temp = tz->emul_temperature; | ||
408 | skip_emul: | ||
409 | #endif | ||
410 | mutex_unlock(&tz->lock); | ||
411 | return ret; | ||
412 | } | ||
413 | |||
381 | static void update_temperature(struct thermal_zone_device *tz) | 414 | static void update_temperature(struct thermal_zone_device *tz) |
382 | { | 415 | { |
383 | long temp; | 416 | long temp; |
384 | int ret; | 417 | int ret; |
385 | 418 | ||
386 | mutex_lock(&tz->lock); | 419 | ret = thermal_zone_get_temp(tz, &temp); |
387 | |||
388 | ret = tz->ops->get_temp(tz, &temp); | ||
389 | if (ret) { | 420 | if (ret) { |
390 | dev_warn(&tz->device, "failed to read out thermal zone %d\n", | 421 | dev_warn(&tz->device, "failed to read out thermal zone %d\n", |
391 | tz->id); | 422 | tz->id); |
392 | goto exit; | 423 | return; |
393 | } | 424 | } |
394 | 425 | ||
426 | mutex_lock(&tz->lock); | ||
395 | tz->last_temperature = tz->temperature; | 427 | tz->last_temperature = tz->temperature; |
396 | tz->temperature = temp; | 428 | tz->temperature = temp; |
397 | |||
398 | exit: | ||
399 | mutex_unlock(&tz->lock); | 429 | mutex_unlock(&tz->lock); |
400 | } | 430 | } |
401 | 431 | ||
@@ -438,10 +468,7 @@ temp_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
438 | long temperature; | 468 | long temperature; |
439 | int ret; | 469 | int ret; |
440 | 470 | ||
441 | if (!tz->ops->get_temp) | 471 | ret = thermal_zone_get_temp(tz, &temperature); |
442 | return -EPERM; | ||
443 | |||
444 | ret = tz->ops->get_temp(tz, &temperature); | ||
445 | 472 | ||
446 | if (ret) | 473 | if (ret) |
447 | return ret; | 474 | return ret; |
@@ -701,6 +728,31 @@ policy_show(struct device *dev, struct device_attribute *devattr, char *buf) | |||
701 | return sprintf(buf, "%s\n", tz->governor->name); | 728 | return sprintf(buf, "%s\n", tz->governor->name); |
702 | } | 729 | } |
703 | 730 | ||
731 | #ifdef CONFIG_THERMAL_EMULATION | ||
732 | static ssize_t | ||
733 | emul_temp_store(struct device *dev, struct device_attribute *attr, | ||
734 | const char *buf, size_t count) | ||
735 | { | ||
736 | struct thermal_zone_device *tz = to_thermal_zone(dev); | ||
737 | int ret = 0; | ||
738 | unsigned long temperature; | ||
739 | |||
740 | if (kstrtoul(buf, 10, &temperature)) | ||
741 | return -EINVAL; | ||
742 | |||
743 | if (!tz->ops->set_emul_temp) { | ||
744 | mutex_lock(&tz->lock); | ||
745 | tz->emul_temperature = temperature; | ||
746 | mutex_unlock(&tz->lock); | ||
747 | } else { | ||
748 | ret = tz->ops->set_emul_temp(tz, temperature); | ||
749 | } | ||
750 | |||
751 | return ret ? ret : count; | ||
752 | } | ||
753 | static DEVICE_ATTR(emul_temp, S_IWUSR, NULL, emul_temp_store); | ||
754 | #endif/*CONFIG_THERMAL_EMULATION*/ | ||
755 | |||
704 | static DEVICE_ATTR(type, 0444, type_show, NULL); | 756 | static DEVICE_ATTR(type, 0444, type_show, NULL); |
705 | static DEVICE_ATTR(temp, 0444, temp_show, NULL); | 757 | static DEVICE_ATTR(temp, 0444, temp_show, NULL); |
706 | static DEVICE_ATTR(mode, 0644, mode_show, mode_store); | 758 | static DEVICE_ATTR(mode, 0644, mode_show, mode_store); |
@@ -843,7 +895,7 @@ temp_input_show(struct device *dev, struct device_attribute *attr, char *buf) | |||
843 | temp_input); | 895 | temp_input); |
844 | struct thermal_zone_device *tz = temp->tz; | 896 | struct thermal_zone_device *tz = temp->tz; |
845 | 897 | ||
846 | ret = tz->ops->get_temp(tz, &temperature); | 898 | ret = thermal_zone_get_temp(tz, &temperature); |
847 | 899 | ||
848 | if (ret) | 900 | if (ret) |
849 | return ret; | 901 | return ret; |
@@ -1596,6 +1648,11 @@ struct thermal_zone_device *thermal_zone_device_register(const char *type, | |||
1596 | goto unregister; | 1648 | goto unregister; |
1597 | } | 1649 | } |
1598 | 1650 | ||
1651 | #ifdef CONFIG_THERMAL_EMULATION | ||
1652 | result = device_create_file(&tz->device, &dev_attr_emul_temp); | ||
1653 | if (result) | ||
1654 | goto unregister; | ||
1655 | #endif | ||
1599 | /* Create policy attribute */ | 1656 | /* Create policy attribute */ |
1600 | result = device_create_file(&tz->device, &dev_attr_policy); | 1657 | result = device_create_file(&tz->device, &dev_attr_policy); |
1601 | if (result) | 1658 | if (result) |