aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/thermal
diff options
context:
space:
mode:
authorAmit Daniel Kachhap <amit.daniel@samsung.com>2013-02-03 19:30:15 -0500
committerZhang Rui <rui.zhang@intel.com>2013-02-06 00:45:42 -0500
commite6e238c38bd4d42d5e2cddb2165e1a46e0fb1200 (patch)
treef09a49a963463468a39a62908583d5b0484c9d99 /drivers/thermal
parentc8165dc0ea75855b0bff6e5edbe4957b8a63d021 (diff)
thermal: sysfs: Add a new sysfs node emul_temp for thermal emulation
This patch adds support to set the emulated temperature method in thermal zone (sensor). After setting this feature thermal zone may report this temperature and not the actual temperature. The emulation implementation may be based on sensor capability through platform specific handler or pure software emulation if no platform handler defined. This is useful in debugging different temperature threshold and its associated cooling action. Critical threshold's cannot be emulated. Writing 0 on this node should disable emulation. Signed-off-by: Amit Daniel Kachhap <amit.daniel@samsung.com> Acked-by: Kukjin Kim <kgene.kim@samsung.com> Signed-off-by: Zhang Rui <rui.zhang@intel.com>
Diffstat (limited to 'drivers/thermal')
-rw-r--r--drivers/thermal/Kconfig8
-rw-r--r--drivers/thermal/thermal_sys.c79
2 files changed, 76 insertions, 11 deletions
diff --git a/drivers/thermal/Kconfig b/drivers/thermal/Kconfig
index faf38c522fa8..e4cf7fbc3a59 100644
--- a/drivers/thermal/Kconfig
+++ b/drivers/thermal/Kconfig
@@ -78,6 +78,14 @@ config CPU_THERMAL
78 and not the ACPI interface. 78 and not the ACPI interface.
79 If you want this support, you should say Y here. 79 If you want this support, you should say Y here.
80 80
81config THERMAL_EMULATION
82 bool "Thermal emulation mode support"
83 help
84 Enable this option to make a emul_temp sysfs node in thermal zone
85 directory to support temperature emulation. With emulation sysfs node,
86 user can manually input temperature and test the different trip
87 threshold behaviour for simulation purpose.
88
81config SPEAR_THERMAL 89config SPEAR_THERMAL
82 bool "SPEAr thermal sensor driver" 90 bool "SPEAr thermal sensor driver"
83 depends on PLAT_SPEAR 91 depends on PLAT_SPEAR
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
381static 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;
408skip_emul:
409#endif
410 mutex_unlock(&tz->lock);
411 return ret;
412}
413
381static void update_temperature(struct thermal_zone_device *tz) 414static 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
398exit:
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
732static ssize_t
733emul_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}
753static DEVICE_ATTR(emul_temp, S_IWUSR, NULL, emul_temp_store);
754#endif/*CONFIG_THERMAL_EMULATION*/
755
704static DEVICE_ATTR(type, 0444, type_show, NULL); 756static DEVICE_ATTR(type, 0444, type_show, NULL);
705static DEVICE_ATTR(temp, 0444, temp_show, NULL); 757static DEVICE_ATTR(temp, 0444, temp_show, NULL);
706static DEVICE_ATTR(mode, 0644, mode_show, mode_store); 758static 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)