hwmon.c (44e3ad882bb268563766c45cd842a229dd3a4902) | hwmon.c (1597b374af22266266e1e20612208c4b11359ad4) |
---|---|
1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * hwmon.c - part of lm_sensors, Linux kernel modules for hardware monitoring 4 * 5 * This file defines the sysfs class "hwmon", for use by sensors drivers. 6 * 7 * Copyright (C) 2005 Mark M. Hoffman <mhoffman@lightlink.com> 8 */ 9 10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 11 12#include <linux/bitops.h> 13#include <linux/device.h> 14#include <linux/err.h> 15#include <linux/gfp.h> 16#include <linux/hwmon.h> 17#include <linux/idr.h> | 1// SPDX-License-Identifier: GPL-2.0-only 2/* 3 * hwmon.c - part of lm_sensors, Linux kernel modules for hardware monitoring 4 * 5 * This file defines the sysfs class "hwmon", for use by sensors drivers. 6 * 7 * Copyright (C) 2005 Mark M. Hoffman <mhoffman@lightlink.com> 8 */ 9 10#define pr_fmt(fmt) KBUILD_MODNAME ": " fmt 11 12#include <linux/bitops.h> 13#include <linux/device.h> 14#include <linux/err.h> 15#include <linux/gfp.h> 16#include <linux/hwmon.h> 17#include <linux/idr.h> |
18#include <linux/list.h> |
|
18#include <linux/module.h> 19#include <linux/pci.h> 20#include <linux/slab.h> 21#include <linux/string.h> 22#include <linux/thermal.h> 23 24#define CREATE_TRACE_POINTS 25#include <trace/events/hwmon.h> 26 27#define HWMON_ID_PREFIX "hwmon" 28#define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d" 29 30struct hwmon_device { 31 const char *name; 32 struct device dev; 33 const struct hwmon_chip_info *chip; | 19#include <linux/module.h> 20#include <linux/pci.h> 21#include <linux/slab.h> 22#include <linux/string.h> 23#include <linux/thermal.h> 24 25#define CREATE_TRACE_POINTS 26#include <trace/events/hwmon.h> 27 28#define HWMON_ID_PREFIX "hwmon" 29#define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d" 30 31struct hwmon_device { 32 const char *name; 33 struct device dev; 34 const struct hwmon_chip_info *chip; |
34 | 35 struct list_head tzdata; |
35 struct attribute_group group; 36 const struct attribute_group **groups; 37}; 38 39#define to_hwmon_device(d) container_of(d, struct hwmon_device, dev) 40 41#define MAX_SYSFS_ATTR_NAME_LENGTH 32 42 --- 7 unchanged lines hidden (view full) --- 50}; 51 52#define to_hwmon_attr(d) \ 53 container_of(d, struct hwmon_device_attribute, dev_attr) 54#define to_dev_attr(a) container_of(a, struct device_attribute, attr) 55 56/* 57 * Thermal zone information | 36 struct attribute_group group; 37 const struct attribute_group **groups; 38}; 39 40#define to_hwmon_device(d) container_of(d, struct hwmon_device, dev) 41 42#define MAX_SYSFS_ATTR_NAME_LENGTH 32 43 --- 7 unchanged lines hidden (view full) --- 51}; 52 53#define to_hwmon_attr(d) \ 54 container_of(d, struct hwmon_device_attribute, dev_attr) 55#define to_dev_attr(a) container_of(a, struct device_attribute, attr) 56 57/* 58 * Thermal zone information |
58 * In addition to the reference to the hwmon device, 59 * also provides the sensor index. | |
60 */ 61struct hwmon_thermal_data { | 59 */ 60struct hwmon_thermal_data { |
61 struct list_head node; /* hwmon tzdata list entry */ |
|
62 struct device *dev; /* Reference to hwmon device */ 63 int index; /* sensor index */ | 62 struct device *dev; /* Reference to hwmon device */ 63 int index; /* sensor index */ |
64 struct thermal_zone_device *tzd;/* thermal zone device */ |
|
64}; 65 66static ssize_t 67name_show(struct device *dev, struct device_attribute *attr, char *buf) 68{ 69 return sprintf(buf, "%s\n", to_hwmon_device(dev)->name); 70} 71static DEVICE_ATTR_RO(name); --- 79 unchanged lines hidden (view full) --- 151 152 return 0; 153} 154 155static const struct thermal_zone_of_device_ops hwmon_thermal_ops = { 156 .get_temp = hwmon_thermal_get_temp, 157}; 158 | 65}; 66 67static ssize_t 68name_show(struct device *dev, struct device_attribute *attr, char *buf) 69{ 70 return sprintf(buf, "%s\n", to_hwmon_device(dev)->name); 71} 72static DEVICE_ATTR_RO(name); --- 79 unchanged lines hidden (view full) --- 152 153 return 0; 154} 155 156static const struct thermal_zone_of_device_ops hwmon_thermal_ops = { 157 .get_temp = hwmon_thermal_get_temp, 158}; 159 |
160static void hwmon_thermal_remove_sensor(void *data) 161{ 162 list_del(data); 163} 164 |
|
159static int hwmon_thermal_add_sensor(struct device *dev, int index) 160{ | 165static int hwmon_thermal_add_sensor(struct device *dev, int index) 166{ |
167 struct hwmon_device *hwdev = to_hwmon_device(dev); |
|
161 struct hwmon_thermal_data *tdata; 162 struct thermal_zone_device *tzd; | 168 struct hwmon_thermal_data *tdata; 169 struct thermal_zone_device *tzd; |
170 int err; |
|
163 164 tdata = devm_kzalloc(dev, sizeof(*tdata), GFP_KERNEL); 165 if (!tdata) 166 return -ENOMEM; 167 168 tdata->dev = dev; 169 tdata->index = index; 170 171 tzd = devm_thermal_zone_of_sensor_register(dev, index, tdata, 172 &hwmon_thermal_ops); 173 /* 174 * If CONFIG_THERMAL_OF is disabled, this returns -ENODEV, 175 * so ignore that error but forward any other error. 176 */ 177 if (IS_ERR(tzd) && (PTR_ERR(tzd) != -ENODEV)) 178 return PTR_ERR(tzd); 179 | 171 172 tdata = devm_kzalloc(dev, sizeof(*tdata), GFP_KERNEL); 173 if (!tdata) 174 return -ENOMEM; 175 176 tdata->dev = dev; 177 tdata->index = index; 178 179 tzd = devm_thermal_zone_of_sensor_register(dev, index, tdata, 180 &hwmon_thermal_ops); 181 /* 182 * If CONFIG_THERMAL_OF is disabled, this returns -ENODEV, 183 * so ignore that error but forward any other error. 184 */ 185 if (IS_ERR(tzd) && (PTR_ERR(tzd) != -ENODEV)) 186 return PTR_ERR(tzd); 187 |
188 err = devm_add_action(dev, hwmon_thermal_remove_sensor, &tdata->node); 189 if (err) 190 return err; 191 192 tdata->tzd = tzd; 193 list_add(&tdata->node, &hwdev->tzdata); 194 |
|
180 return 0; 181} 182 183static int hwmon_thermal_register_sensors(struct device *dev) 184{ 185 struct hwmon_device *hwdev = to_hwmon_device(dev); 186 const struct hwmon_chip_info *chip = hwdev->chip; 187 const struct hwmon_channel_info **info = chip->info; --- 18 unchanged lines hidden (view full) --- 206 if (err) 207 return err; 208 } 209 } 210 211 return 0; 212} 213 | 195 return 0; 196} 197 198static int hwmon_thermal_register_sensors(struct device *dev) 199{ 200 struct hwmon_device *hwdev = to_hwmon_device(dev); 201 const struct hwmon_chip_info *chip = hwdev->chip; 202 const struct hwmon_channel_info **info = chip->info; --- 18 unchanged lines hidden (view full) --- 221 if (err) 222 return err; 223 } 224 } 225 226 return 0; 227} 228 |
229static void hwmon_thermal_notify(struct device *dev, int index) 230{ 231 struct hwmon_device *hwdev = to_hwmon_device(dev); 232 struct hwmon_thermal_data *tzdata; 233 234 list_for_each_entry(tzdata, &hwdev->tzdata, node) { 235 if (tzdata->index == index) { 236 thermal_zone_device_update(tzdata->tzd, 237 THERMAL_EVENT_UNSPECIFIED); 238 } 239 } 240} 241 |
|
214#else 215static int hwmon_thermal_register_sensors(struct device *dev) 216{ 217 return 0; 218} | 242#else 243static int hwmon_thermal_register_sensors(struct device *dev) 244{ 245 return 0; 246} |
247 248static void hwmon_thermal_notify(struct device *dev, int index) { } 249 |
|
219#endif /* IS_REACHABLE(CONFIG_THERMAL) && ... */ 220 221static int hwmon_attr_base(enum hwmon_sensor_types type) 222{ 223 if (type == hwmon_in || type == hwmon_intrusion) 224 return 0; 225 return 1; 226} --- 311 unchanged lines hidden (view full) --- 538 [hwmon_power] = ARRAY_SIZE(hwmon_power_attr_templates), 539 [hwmon_energy] = ARRAY_SIZE(hwmon_energy_attr_templates), 540 [hwmon_humidity] = ARRAY_SIZE(hwmon_humidity_attr_templates), 541 [hwmon_fan] = ARRAY_SIZE(hwmon_fan_attr_templates), 542 [hwmon_pwm] = ARRAY_SIZE(hwmon_pwm_attr_templates), 543 [hwmon_intrusion] = ARRAY_SIZE(hwmon_intrusion_attr_templates), 544}; 545 | 250#endif /* IS_REACHABLE(CONFIG_THERMAL) && ... */ 251 252static int hwmon_attr_base(enum hwmon_sensor_types type) 253{ 254 if (type == hwmon_in || type == hwmon_intrusion) 255 return 0; 256 return 1; 257} --- 311 unchanged lines hidden (view full) --- 569 [hwmon_power] = ARRAY_SIZE(hwmon_power_attr_templates), 570 [hwmon_energy] = ARRAY_SIZE(hwmon_energy_attr_templates), 571 [hwmon_humidity] = ARRAY_SIZE(hwmon_humidity_attr_templates), 572 [hwmon_fan] = ARRAY_SIZE(hwmon_fan_attr_templates), 573 [hwmon_pwm] = ARRAY_SIZE(hwmon_pwm_attr_templates), 574 [hwmon_intrusion] = ARRAY_SIZE(hwmon_intrusion_attr_templates), 575}; 576 |
577int hwmon_notify_event(struct device *dev, enum hwmon_sensor_types type, 578 u32 attr, int channel) 579{ 580 char sattr[MAX_SYSFS_ATTR_NAME_LENGTH]; 581 const char * const *templates; 582 const char *template; 583 int base; 584 585 if (type >= ARRAY_SIZE(__templates)) 586 return -EINVAL; 587 if (attr >= __templates_size[type]) 588 return -EINVAL; 589 590 templates = __templates[type]; 591 template = templates[attr]; 592 593 base = hwmon_attr_base(type); 594 595 scnprintf(sattr, MAX_SYSFS_ATTR_NAME_LENGTH, template, base + channel); 596 sysfs_notify(&dev->kobj, NULL, sattr); 597 kobject_uevent(&dev->kobj, KOBJ_CHANGE); 598 599 if (type == hwmon_temp) 600 hwmon_thermal_notify(dev, channel); 601 602 return 0; 603} 604EXPORT_SYMBOL_GPL(hwmon_notify_event); 605 |
|
546static int hwmon_num_channel_attrs(const struct hwmon_channel_info *info) 547{ 548 int i, n; 549 550 for (i = n = 0; info->config[i]; i++) 551 n += hweight32(info->config[i]); 552 553 return n; --- 134 unchanged lines hidden (view full) --- 688 hdev->of_node = dev ? dev->of_node : NULL; 689 hwdev->chip = chip; 690 dev_set_drvdata(hdev, drvdata); 691 dev_set_name(hdev, HWMON_ID_FORMAT, id); 692 err = device_register(hdev); 693 if (err) 694 goto free_hwmon; 695 | 606static int hwmon_num_channel_attrs(const struct hwmon_channel_info *info) 607{ 608 int i, n; 609 610 for (i = n = 0; info->config[i]; i++) 611 n += hweight32(info->config[i]); 612 613 return n; --- 134 unchanged lines hidden (view full) --- 748 hdev->of_node = dev ? dev->of_node : NULL; 749 hwdev->chip = chip; 750 dev_set_drvdata(hdev, drvdata); 751 dev_set_name(hdev, HWMON_ID_FORMAT, id); 752 err = device_register(hdev); 753 if (err) 754 goto free_hwmon; 755 |
756 INIT_LIST_HEAD(&hwdev->tzdata); 757 |
|
696 if (dev && dev->of_node && chip && chip->ops->read && 697 chip->info[0]->type == hwmon_chip && 698 (chip->info[0]->config[0] & HWMON_C_REGISTER_TZ)) { 699 err = hwmon_thermal_register_sensors(hdev); 700 if (err) { 701 device_unregister(hdev); 702 /* 703 * Don't worry about hwdev; hwmon_dev_release(), called --- 266 unchanged lines hidden --- | 758 if (dev && dev->of_node && chip && chip->ops->read && 759 chip->info[0]->type == hwmon_chip && 760 (chip->info[0]->config[0] & HWMON_C_REGISTER_TZ)) { 761 err = hwmon_thermal_register_sensors(hdev); 762 if (err) { 763 device_unregister(hdev); 764 /* 765 * Don't worry about hwdev; hwmon_dev_release(), called --- 266 unchanged lines hidden --- |