aboutsummaryrefslogtreecommitdiffstats
path: root/drivers
diff options
context:
space:
mode:
authorEduardo Valentin <eduardo.valentin@ti.com>2013-07-16 14:54:55 -0400
committerEduardo Valentin <eduardo.valentin@ti.com>2013-12-04 08:34:24 -0500
commit22e731838b0e337fed5f16c67aa0b954028dfe93 (patch)
tree1078bfdd1249fd0f5c3c7c49238ff749626fd8fa /drivers
parent77cff5926a14e80d4545be5841d5938b87b654a4 (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.c35
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 */
72struct lm75_data { 74struct 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
97static 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
104static 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
96static ssize_t show_temp(struct device *dev, struct device_attribute *da, 116static 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
112static ssize_t set_temp(struct device *dev, struct device_attribute *da, 129static 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);