Add hwmon sys I/F for the generic thermal device. Signed-off-by: Zhang Rui <rui.zhang at intel.com> --- Documentation/thermal/sysfs-api.txt | 22 +++++---- drivers/thermal/Kconfig | 1 drivers/thermal/thermal.c | 86 ++++++++++++++++++++++++++++++++---- include/linux/thermal.h | 1 4 files changed, 92 insertions(+), 18 deletions(-) Index: linux-2.6.25-rc2/Documentation/thermal/sysfs-api.txt =================================================================== --- linux-2.6.25-rc2.orig/Documentation/thermal/sysfs-api.txt 2008-02-25 22:43:29.000000000 -0500 +++ linux-2.6.25-rc2/Documentation/thermal/sysfs-api.txt 2008-02-25 22:43:38.000000000 -0500 @@ -141,12 +141,14 @@ type Strings which represent the thermal zone type. This is given by thermal zone driver as part of registration. + In order to keep the compatibility with hwmon, + it should not contain any spaces or dashes. Eg: "ACPI thermal zone" indicates it's a ACPI thermal device RO - Optional + Required temp Current temperature as reported by thermal zone (sensor) - Unit: degree Celsius + Unit: millidegree Celsius RO Required @@ -163,7 +165,7 @@ charge of the thermal management. trip_point_[0-*]_temp The temperature above which trip point will be fired - Unit: degree Celsius + Unit: millidegree Celsius RO Optional @@ -219,16 +221,16 @@ |thermal_zone1: |-----type: ACPI thermal zone - |-----temp: 37 + |-----temp: 37000 |-----mode: kernel - |-----trip_point_0_temp: 100 + |-----trip_point_0_temp: 100000 |-----trip_point_0_type: critical - |-----trip_point_1_temp: 80 + |-----trip_point_1_temp: 80000 |-----trip_point_1_type: passive - |-----trip_point_2_temp: 70 - |-----trip_point_2_type: active[0] - |-----trip_point_3_temp: 60 - |-----trip_point_3_type: active[1] + |-----trip_point_2_temp: 70000 + |-----trip_point_2_type: active0 + |-----trip_point_3_temp: 60000 + |-----trip_point_3_type: active1 |-----cdev0: --->/sys/class/thermal/cooling_device0 |-----cdev0_trip_point: 1 /* cdev0 can be used for passive */ |-----cdev1: --->/sys/class/thermal/cooling_device3 Index: linux-2.6.25-rc2/drivers/thermal/Kconfig =================================================================== --- linux-2.6.25-rc2.orig/drivers/thermal/Kconfig 2008-02-25 22:43:29.000000000 -0500 +++ linux-2.6.25-rc2/drivers/thermal/Kconfig 2008-02-25 22:43:38.000000000 -0500 @@ -4,6 +4,7 @@ menuconfig THERMAL bool "Generic Thermal sysfs driver" + select HWMON default y help Generic Thermal Sysfs driver offers a generic mechanism for Index: linux-2.6.25-rc2/drivers/thermal/thermal.c =================================================================== --- linux-2.6.25-rc2.orig/drivers/thermal/thermal.c 2008-02-25 22:43:29.000000000 -0500 +++ linux-2.6.25-rc2/drivers/thermal/thermal.c 2008-02-26 00:37:57.000000000 -0500 @@ -30,8 +30,9 @@ #include <linux/idr.h> #include <linux/thermal.h> #include <linux/spinlock.h> +#include <linux/hwmon.h> -MODULE_AUTHOR("Zhang Rui") +MODULE_AUTHOR("Zhang Rui"); MODULE_DESCRIPTION("Generic thermal management sysfs support"); MODULE_LICENSE("GPL"); @@ -171,6 +172,47 @@ return tz->ops->get_trip_temp(tz, trip, buf); } +static ssize_t +hwmon_type_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct device *device = dev->parent; + return type_show(device, attr, buf); +} + +static ssize_t +hwmon_temp_show(struct device *dev, struct device_attribute *attr, char *buf) +{ + struct device *device = dev->parent; + return temp_show(device, attr, buf); +} + +static ssize_t +crit_trip_temp_show(struct device *dev, struct device_attribute *attr, + char *buf) +{ + struct device *device = dev->parent; + struct thermal_zone_device *tz = to_thermal_zone(device); + int result; + + if (!tz->ops->get_trip_temp ) + return -EPERM; + + /* assume trip 0 to be the critical trip point by default */ + if (tz->ops->get_trip_type) { + result = tz->ops->get_trip_type(tz, 0, buf); + if (result < 0) + return result; + if (strcmp(buf, "critical\n")) + return -ENODEV; + } + + return tz->ops->get_trip_temp(tz, 0, buf); +} + +static DEVICE_ATTR(name, 0444, hwmon_type_show, NULL); +static DEVICE_ATTR(temp1_input, 0444, hwmon_temp_show, NULL); +static DEVICE_ATTR(temp1_crit, 0444, crit_trip_temp_show, NULL); + static DEVICE_ATTR(type, 0444, type_show, NULL); static DEVICE_ATTR(temp, 0444, temp_show, NULL); static DEVICE_ATTR(mode, 0644, mode_show, mode_store); @@ -569,6 +611,9 @@ int result; int count; + if (!type) + return ERR_PTR(-EINVAL); + if (strlen(type) >= THERMAL_NAME_LENGTH) return NULL; @@ -604,13 +649,33 @@ return NULL; } - /* sys I/F */ - if (type) { - result = device_create_file(&tz->device, &dev_attr_type); - if (result) - goto unregister; + /* hwmon sys I/F */ + tz->hwmon = hwmon_device_register(&tz->device); + if (IS_ERR(tz->hwmon)) { + result = PTR_ERR(tz->hwmon); + tz->hwmon = NULL; + printk(KERN_ERR PREFIX + "unable to register hwmon device\n"); + goto unregister; } + result = device_create_file(tz->hwmon, &dev_attr_name); + if (result) + goto unregister; + + result = device_create_file(tz->hwmon, &dev_attr_temp1_input); + if (result) + goto unregister; + + result = device_create_file(tz->hwmon, &dev_attr_temp1_crit); + if (result) + goto unregister; + + /* sys I/F */ + result = device_create_file(&tz->device, &dev_attr_type); + if (result) + goto unregister; + result = device_create_file(&tz->device, &dev_attr_temp); if (result) goto unregister; @@ -676,8 +741,13 @@ tz->ops->unbind(tz, cdev); mutex_unlock(&thermal_list_lock); - if (tz->type[0]) - device_remove_file(&tz->device, &dev_attr_type); + device_remove_file(&tz->device, &dev_attr_name); + device_remove_file(&tz->device, &dev_attr_temp1_input); + device_remove_file(&tz->device, &dev_attr_temp1_crit); + hwmon_device_unregister(tz->hwmon); + tz->hwmon = NULL; + + device_remove_file(&tz->device, &dev_attr_type); device_remove_file(&tz->device, &dev_attr_temp); if (tz->ops->get_mode) device_remove_file(&tz->device, &dev_attr_mode); Index: linux-2.6.25-rc2/include/linux/thermal.h =================================================================== --- linux-2.6.25-rc2.orig/include/linux/thermal.h 2008-02-25 22:43:29.000000000 -0500 +++ linux-2.6.25-rc2/include/linux/thermal.h 2008-02-25 22:43:38.000000000 -0500 @@ -69,6 +69,7 @@ int id; char type[THERMAL_NAME_LENGTH]; struct device device; + struct device *hwmon; void *devdata; int trips; struct thermal_zone_device_ops *ops;