From: Wei Ni Subject: hwmon: lm90: expose to thermal fw via DT nodes This patch adds to lm90 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 lm90 DT node. Otherwise, the driver behavior will be the same. Discussed in: http://www.gossamer-threads.com/lists/linux/kernel/1992853 BUG=chrome-os-partner:30834 TEST=Verified. Build and boot up system. Signed-off-by: Wei Ni Reviewed-on: https://chromium-review.googlesource.com/181447 Reviewed-by: Dylan Reid Tested-by: Dylan Reid Commit-Queue: Dylan Reid Change-Id: Id356b94d7e8f4b49ec15e46b17a1fa2ff0cbf8cf Reviewed-on: https://chromium-review.googlesource.com/212414 Tested-by: Wei Ni Reviewed-by: Olof Johansson Commit-Queue: Olof Johansson --- diff --git a/drivers/hwmon/lm90.c b/drivers/hwmon/lm90.c index fb9e224..c54d3c8 100644 --- a/drivers/hwmon/lm90.c +++ b/drivers/hwmon/lm90.c @@ -96,6 +96,8 @@ #include #include #include +#include +#include /* * Addresses to scan @@ -118,6 +120,13 @@ enum chips { lm90, adm1032, lm99, lm86, max6657, max6659, adt7461, max6680, max6646, w83l771, max6696, sa56004, g781, tmp451 }; + +enum sensor_id { + LOCAL = 0, + REMOTE, + REMOTE2, + SENSOR_ID_END, +}; /* * The LM90 registers @@ -368,6 +377,7 @@ struct i2c_client *client; struct device *hwmon_dev; const struct attribute_group *groups[6]; + struct thermal_zone_device *tz[SENSOR_ID_END]; struct mutex update_lock; struct regulator *regulator; char valid; /* zero until following fields are valid */ @@ -878,6 +888,24 @@ struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr); return sprintf(buf, "%d\n", read_temp11(dev, attr->index)); +} + +static int lm90_read_local_temp(void *dev, int *temp) +{ + *temp = read_temp11(dev, 4); + return 0; +} + +static int lm90_read_remote_temp(void *dev, int *temp) +{ + *temp = read_temp11(dev, 0); + return 0; +} + +static int lm90_read_remote2_temp(void *dev, int *temp) +{ + *temp = read_temp11(dev, 5); + return 0; } static int write_temp11(struct device *dev, int nr, int index, long val) @@ -1150,6 +1238,18 @@ .attrs = lm90_temp3_attributes, }; +static const struct thermal_zone_of_device_ops local_temp_sensor = { + .get_temp = lm90_read_local_temp, +}; + +static const struct thermal_zone_of_device_ops remote_temp_sensor = { + .get_temp = lm90_read_remote_temp, +}; + +static const struct thermal_zone_of_device_ops remote2_temp_sensor = { + .get_temp = lm90_read_remote2_temp, +}; + /* pec used for ADM1032 only */ static ssize_t show_pec(struct device *dev, struct device_attribute *dummy, char *buf) @@ -1599,6 +1699,30 @@ } } + data->tz[LOCAL] = thermal_zone_of_sensor_register(&client->dev, + LOCAL, + &client->dev, + &local_temp_sensor); + if (IS_ERR(data->tz[LOCAL])) + data->tz[LOCAL] = NULL; + + data->tz[REMOTE] = thermal_zone_of_sensor_register(&client->dev, + REMOTE, + &client->dev, + &remote_temp_sensor); + if (IS_ERR(data->tz[REMOTE])) + data->tz[REMOTE] = NULL; + + if (data->flags & LM90_HAVE_TEMP3) { + data->tz[REMOTE2] = thermal_zone_of_sensor_register( + &client->dev, + REMOTE2, + &client->dev, + &remote2_temp_sensor); + if (IS_ERR(data->tz[REMOTE2])) + data->tz[REMOTE2] = NULL; + } + return 0; exit_unregister: @@ -1674,8 +1726,11 @@ static int lm90_remove(struct i2c_client *client) { + int i; struct lm90_data *data = i2c_get_clientdata(client); + for (i = 0; i < SENSOR_ID_END; i++) + thermal_zone_of_sensor_unregister(&client->dev, data->tz[i]); hwmon_device_unregister(data->hwmon_dev); device_remove_file(&client->dev, &dev_attr_pec); lm90_restore_conf(client, data);