diff options
author | Eduardo Valentin <eduardo.valentin@ti.com> | 2013-07-16 14:54:55 -0400 |
---|---|---|
committer | Eduardo Valentin <eduardo.valentin@ti.com> | 2013-12-04 08:34:24 -0500 |
commit | 22e731838b0e337fed5f16c67aa0b954028dfe93 (patch) | |
tree | 1078bfdd1249fd0f5c3c7c49238ff749626fd8fa /drivers | |
parent | 77cff5926a14e80d4545be5841d5938b87b654a4 (diff) |
hwmon: lm75: expose to thermal fw via DT nodes
This patch adds to lm75 temperature sensor the possibility
to expose itself as thermal zone device, registered on the
thermal framework.
The thermal zone is built only if a device tree node
describing a thermal zone for this sensor is present
inside the lm75 DT node. Otherwise, the driver behavior
will be the same.
Note: This patch has also been reviewed by Jean D. He has
requested to perform a wider inspection of possible
users of thermal and hwmon interaction API. On the other
hand, the change on this patch is acceptable on first
step of overall code change.
Cc: Jean Delvare <khali@linux-fr.org>
Cc: lm-sensors@lm-sensors.org
Cc: linux-kernel@vger.kernel.org
Acked-by: Guenter Roeck <linux@roeck-us.net>
Signed-off-by: Eduardo Valentin <eduardo.valentin@ti.com>
Diffstat (limited to 'drivers')
-rw-r--r-- | drivers/hwmon/lm75.c | 35 |
1 files changed, 30 insertions, 5 deletions
diff --git a/drivers/hwmon/lm75.c b/drivers/hwmon/lm75.c index 7e3ef134f1d2..84a55eacd903 100644 --- a/drivers/hwmon/lm75.c +++ b/drivers/hwmon/lm75.c | |||
@@ -27,6 +27,8 @@ | |||
27 | #include <linux/hwmon-sysfs.h> | 27 | #include <linux/hwmon-sysfs.h> |
28 | #include <linux/err.h> | 28 | #include <linux/err.h> |
29 | #include <linux/mutex.h> | 29 | #include <linux/mutex.h> |
30 | #include <linux/of.h> | ||
31 | #include <linux/thermal.h> | ||
30 | #include "lm75.h" | 32 | #include "lm75.h" |
31 | 33 | ||
32 | 34 | ||
@@ -71,6 +73,7 @@ static const u8 LM75_REG_TEMP[3] = { | |||
71 | /* Each client has this additional data */ | 73 | /* Each client has this additional data */ |
72 | struct lm75_data { | 74 | struct lm75_data { |
73 | struct device *hwmon_dev; | 75 | struct device *hwmon_dev; |
76 | struct thermal_zone_device *tz; | ||
74 | struct mutex update_lock; | 77 | struct mutex update_lock; |
75 | u8 orig_conf; | 78 | u8 orig_conf; |
76 | u8 resolution; /* In bits, between 9 and 12 */ | 79 | u8 resolution; /* In bits, between 9 and 12 */ |
@@ -91,22 +94,36 @@ static struct lm75_data *lm75_update_device(struct device *dev); | |||
91 | 94 | ||
92 | /*-----------------------------------------------------------------------*/ | 95 | /*-----------------------------------------------------------------------*/ |
93 | 96 | ||
97 | static inline long lm75_reg_to_mc(s16 temp, u8 resolution) | ||
98 | { | ||
99 | return ((temp >> (16 - resolution)) * 1000) >> (resolution - 8); | ||
100 | } | ||
101 | |||
94 | /* sysfs attributes for hwmon */ | 102 | /* sysfs attributes for hwmon */ |
95 | 103 | ||
104 | static int lm75_read_temp(void *dev, long *temp) | ||
105 | { | ||
106 | struct lm75_data *data = lm75_update_device(dev); | ||
107 | |||
108 | if (IS_ERR(data)) | ||
109 | return PTR_ERR(data); | ||
110 | |||
111 | *temp = lm75_reg_to_mc(data->temp[0], data->resolution); | ||
112 | |||
113 | return 0; | ||
114 | } | ||
115 | |||
96 | static ssize_t show_temp(struct device *dev, struct device_attribute *da, | 116 | static ssize_t show_temp(struct device *dev, struct device_attribute *da, |
97 | char *buf) | 117 | char *buf) |
98 | { | 118 | { |
99 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); | 119 | struct sensor_device_attribute *attr = to_sensor_dev_attr(da); |
100 | struct lm75_data *data = lm75_update_device(dev); | 120 | struct lm75_data *data = lm75_update_device(dev); |
101 | long temp; | ||
102 | 121 | ||
103 | if (IS_ERR(data)) | 122 | if (IS_ERR(data)) |
104 | return PTR_ERR(data); | 123 | return PTR_ERR(data); |
105 | 124 | ||
106 | temp = ((data->temp[attr->index] >> (16 - data->resolution)) * 1000) | 125 | return sprintf(buf, "%ld\n", lm75_reg_to_mc(data->temp[attr->index], |
107 | >> (data->resolution - 8); | 126 | data->resolution)); |
108 | |||
109 | return sprintf(buf, "%ld\n", temp); | ||
110 | } | 127 | } |
111 | 128 | ||
112 | static ssize_t set_temp(struct device *dev, struct device_attribute *da, | 129 | static ssize_t set_temp(struct device *dev, struct device_attribute *da, |
@@ -273,6 +290,13 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id) | |||
273 | goto exit_remove; | 290 | goto exit_remove; |
274 | } | 291 | } |
275 | 292 | ||
293 | data->tz = thermal_zone_of_sensor_register(&client->dev, | ||
294 | 0, | ||
295 | &client->dev, | ||
296 | lm75_read_temp, NULL); | ||
297 | if (IS_ERR(data->tz)) | ||
298 | data->tz = NULL; | ||
299 | |||
276 | dev_info(&client->dev, "%s: sensor '%s'\n", | 300 | dev_info(&client->dev, "%s: sensor '%s'\n", |
277 | dev_name(data->hwmon_dev), client->name); | 301 | dev_name(data->hwmon_dev), client->name); |
278 | 302 | ||
@@ -287,6 +311,7 @@ static int lm75_remove(struct i2c_client *client) | |||
287 | { | 311 | { |
288 | struct lm75_data *data = i2c_get_clientdata(client); | 312 | struct lm75_data *data = i2c_get_clientdata(client); |
289 | 313 | ||
314 | thermal_zone_of_sensor_unregister(&client->dev, data->tz); | ||
290 | hwmon_device_unregister(data->hwmon_dev); | 315 | hwmon_device_unregister(data->hwmon_dev); |
291 | sysfs_remove_group(&client->dev.kobj, &lm75_group); | 316 | sysfs_remove_group(&client->dev.kobj, &lm75_group); |
292 | lm75_write_value(client, LM75_REG_CONF, data->orig_conf); | 317 | lm75_write_value(client, LM75_REG_CONF, data->orig_conf); |