hwmon.c (0898782247ae533d1f4e47a06bc5d4870931b284) hwmon.c (3bf8bdcf3bada771eb12b57f2a30caee69e8ab8d)
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 */

--- 37 unchanged lines hidden (view full) ---

46 enum hwmon_sensor_types type;
47 u32 attr;
48 int index;
49 char name[MAX_SYSFS_ATTR_NAME_LENGTH];
50};
51
52#define to_hwmon_attr(d) \
53 container_of(d, struct hwmon_device_attribute, dev_attr)
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 */

--- 37 unchanged lines hidden (view full) ---

46 enum hwmon_sensor_types type;
47 u32 attr;
48 int index;
49 char name[MAX_SYSFS_ATTR_NAME_LENGTH];
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)
54
55/*
56 * Thermal zone information
57 * In addition to the reference to the hwmon device,
58 * also provides the sensor index.
59 */
60struct hwmon_thermal_data {
55
56/*
57 * Thermal zone information
58 * In addition to the reference to the hwmon device,
59 * also provides the sensor index.
60 */
61struct hwmon_thermal_data {
61 struct hwmon_device *hwdev; /* Reference to hwmon device */
62 struct device *dev; /* Reference to hwmon device */
62 int index; /* sensor index */
63};
64
65static ssize_t
66name_show(struct device *dev, struct device_attribute *attr, char *buf)
67{
68 return sprintf(buf, "%s\n", to_hwmon_device(dev)->name);
69}

--- 20 unchanged lines hidden (view full) ---

90 .is_visible = hwmon_dev_name_is_visible,
91};
92
93static const struct attribute_group *hwmon_dev_attr_groups[] = {
94 &hwmon_dev_attr_group,
95 NULL
96};
97
63 int index; /* sensor index */
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}

--- 20 unchanged lines hidden (view full) ---

91 .is_visible = hwmon_dev_name_is_visible,
92};
93
94static const struct attribute_group *hwmon_dev_attr_groups[] = {
95 &hwmon_dev_attr_group,
96 NULL
97};
98
99static void hwmon_free_attrs(struct attribute **attrs)
100{
101 int i;
102
103 for (i = 0; attrs[i]; i++) {
104 struct device_attribute *dattr = to_dev_attr(attrs[i]);
105 struct hwmon_device_attribute *hattr = to_hwmon_attr(dattr);
106
107 kfree(hattr);
108 }
109 kfree(attrs);
110}
111
98static void hwmon_dev_release(struct device *dev)
99{
112static void hwmon_dev_release(struct device *dev)
113{
100 kfree(to_hwmon_device(dev));
114 struct hwmon_device *hwdev = to_hwmon_device(dev);
115
116 if (hwdev->group.attrs)
117 hwmon_free_attrs(hwdev->group.attrs);
118 kfree(hwdev->groups);
119 kfree(hwdev);
101}
102
103static struct class hwmon_class = {
104 .name = "hwmon",
105 .owner = THIS_MODULE,
106 .dev_groups = hwmon_dev_attr_groups,
107 .dev_release = hwmon_dev_release,
108};

--- 5 unchanged lines hidden (view full) ---

114/*
115 * The complex conditional is necessary to avoid a cyclic dependency
116 * between hwmon and thermal_sys modules.
117 */
118#ifdef CONFIG_THERMAL_OF
119static int hwmon_thermal_get_temp(void *data, int *temp)
120{
121 struct hwmon_thermal_data *tdata = data;
120}
121
122static struct class hwmon_class = {
123 .name = "hwmon",
124 .owner = THIS_MODULE,
125 .dev_groups = hwmon_dev_attr_groups,
126 .dev_release = hwmon_dev_release,
127};

--- 5 unchanged lines hidden (view full) ---

133/*
134 * The complex conditional is necessary to avoid a cyclic dependency
135 * between hwmon and thermal_sys modules.
136 */
137#ifdef CONFIG_THERMAL_OF
138static int hwmon_thermal_get_temp(void *data, int *temp)
139{
140 struct hwmon_thermal_data *tdata = data;
122 struct hwmon_device *hwdev = tdata->hwdev;
141 struct hwmon_device *hwdev = to_hwmon_device(tdata->dev);
123 int ret;
124 long t;
125
142 int ret;
143 long t;
144
126 ret = hwdev->chip->ops->read(&hwdev->dev, hwmon_temp, hwmon_temp_input,
145 ret = hwdev->chip->ops->read(tdata->dev, hwmon_temp, hwmon_temp_input,
127 tdata->index, &t);
128 if (ret < 0)
129 return ret;
130
131 *temp = t;
132
133 return 0;
134}
135
136static const struct thermal_zone_of_device_ops hwmon_thermal_ops = {
137 .get_temp = hwmon_thermal_get_temp,
138};
139
146 tdata->index, &t);
147 if (ret < 0)
148 return ret;
149
150 *temp = t;
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
140static int hwmon_thermal_add_sensor(struct device *dev,
141 struct hwmon_device *hwdev, int index)
159static int hwmon_thermal_add_sensor(struct device *dev, int index)
142{
143 struct hwmon_thermal_data *tdata;
144 struct thermal_zone_device *tzd;
145
146 tdata = devm_kzalloc(dev, sizeof(*tdata), GFP_KERNEL);
147 if (!tdata)
148 return -ENOMEM;
149
160{
161 struct hwmon_thermal_data *tdata;
162 struct thermal_zone_device *tzd;
163
164 tdata = devm_kzalloc(dev, sizeof(*tdata), GFP_KERNEL);
165 if (!tdata)
166 return -ENOMEM;
167
150 tdata->hwdev = hwdev;
168 tdata->dev = dev;
151 tdata->index = index;
152
169 tdata->index = index;
170
153 tzd = devm_thermal_zone_of_sensor_register(&hwdev->dev, index, tdata,
171 tzd = devm_thermal_zone_of_sensor_register(dev, index, tdata,
154 &hwmon_thermal_ops);
155 /*
156 * If CONFIG_THERMAL_OF is disabled, this returns -ENODEV,
157 * so ignore that error but forward any other error.
158 */
159 if (IS_ERR(tzd) && (PTR_ERR(tzd) != -ENODEV))
160 return PTR_ERR(tzd);
161
162 return 0;
163}
164#else
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
180 return 0;
181}
182#else
165static int hwmon_thermal_add_sensor(struct device *dev,
166 struct hwmon_device *hwdev, int index)
183static int hwmon_thermal_add_sensor(struct device *dev, int index)
167{
168 return 0;
169}
170#endif /* IS_REACHABLE(CONFIG_THERMAL) && ... */
171
172static int hwmon_attr_base(enum hwmon_sensor_types type)
173{
174 if (type == hwmon_in)

--- 70 unchanged lines hidden (view full) ---

245 (type == hwmon_in && attr == hwmon_in_label) ||
246 (type == hwmon_curr && attr == hwmon_curr_label) ||
247 (type == hwmon_power && attr == hwmon_power_label) ||
248 (type == hwmon_energy && attr == hwmon_energy_label) ||
249 (type == hwmon_humidity && attr == hwmon_humidity_label) ||
250 (type == hwmon_fan && attr == hwmon_fan_label);
251}
252
184{
185 return 0;
186}
187#endif /* IS_REACHABLE(CONFIG_THERMAL) && ... */
188
189static int hwmon_attr_base(enum hwmon_sensor_types type)
190{
191 if (type == hwmon_in)

--- 70 unchanged lines hidden (view full) ---

262 (type == hwmon_in && attr == hwmon_in_label) ||
263 (type == hwmon_curr && attr == hwmon_curr_label) ||
264 (type == hwmon_power && attr == hwmon_power_label) ||
265 (type == hwmon_energy && attr == hwmon_energy_label) ||
266 (type == hwmon_humidity && attr == hwmon_humidity_label) ||
267 (type == hwmon_fan && attr == hwmon_fan_label);
268}
269
253static struct attribute *hwmon_genattr(struct device *dev,
254 const void *drvdata,
270static struct attribute *hwmon_genattr(const void *drvdata,
255 enum hwmon_sensor_types type,
256 u32 attr,
257 int index,
258 const char *template,
259 const struct hwmon_ops *ops)
260{
261 struct hwmon_device_attribute *hattr;
262 struct device_attribute *dattr;

--- 11 unchanged lines hidden (view full) ---

274 return ERR_PTR(-ENOENT);
275
276 if ((mode & 0444) && ((is_string && !ops->read_string) ||
277 (!is_string && !ops->read)))
278 return ERR_PTR(-EINVAL);
279 if ((mode & 0222) && !ops->write)
280 return ERR_PTR(-EINVAL);
281
271 enum hwmon_sensor_types type,
272 u32 attr,
273 int index,
274 const char *template,
275 const struct hwmon_ops *ops)
276{
277 struct hwmon_device_attribute *hattr;
278 struct device_attribute *dattr;

--- 11 unchanged lines hidden (view full) ---

290 return ERR_PTR(-ENOENT);
291
292 if ((mode & 0444) && ((is_string && !ops->read_string) ||
293 (!is_string && !ops->read)))
294 return ERR_PTR(-EINVAL);
295 if ((mode & 0222) && !ops->write)
296 return ERR_PTR(-EINVAL);
297
282 hattr = devm_kzalloc(dev, sizeof(*hattr), GFP_KERNEL);
298 hattr = kzalloc(sizeof(*hattr), GFP_KERNEL);
283 if (!hattr)
284 return ERR_PTR(-ENOMEM);
285
286 if (type == hwmon_chip) {
287 name = template;
288 } else {
289 scnprintf(hattr->name, sizeof(hattr->name), template,
290 index + hwmon_attr_base(type));

--- 196 unchanged lines hidden (view full) ---

487 int i, n;
488
489 for (i = n = 0; info->config[i]; i++)
490 n += hweight32(info->config[i]);
491
492 return n;
493}
494
299 if (!hattr)
300 return ERR_PTR(-ENOMEM);
301
302 if (type == hwmon_chip) {
303 name = template;
304 } else {
305 scnprintf(hattr->name, sizeof(hattr->name), template,
306 index + hwmon_attr_base(type));

--- 196 unchanged lines hidden (view full) ---

503 int i, n;
504
505 for (i = n = 0; info->config[i]; i++)
506 n += hweight32(info->config[i]);
507
508 return n;
509}
510
495static int hwmon_genattrs(struct device *dev,
496 const void *drvdata,
511static int hwmon_genattrs(const void *drvdata,
497 struct attribute **attrs,
498 const struct hwmon_ops *ops,
499 const struct hwmon_channel_info *info)
500{
501 const char * const *templates;
502 int template_size;
503 int i, aindex = 0;
504

--- 9 unchanged lines hidden (view full) ---

514
515 while (attr_mask) {
516 struct attribute *a;
517
518 attr = __ffs(attr_mask);
519 attr_mask &= ~BIT(attr);
520 if (attr >= template_size)
521 return -EINVAL;
512 struct attribute **attrs,
513 const struct hwmon_ops *ops,
514 const struct hwmon_channel_info *info)
515{
516 const char * const *templates;
517 int template_size;
518 int i, aindex = 0;
519

--- 9 unchanged lines hidden (view full) ---

529
530 while (attr_mask) {
531 struct attribute *a;
532
533 attr = __ffs(attr_mask);
534 attr_mask &= ~BIT(attr);
535 if (attr >= template_size)
536 return -EINVAL;
522 a = hwmon_genattr(dev, drvdata, info->type, attr, i,
537 a = hwmon_genattr(drvdata, info->type, attr, i,
523 templates[attr], ops);
524 if (IS_ERR(a)) {
525 if (PTR_ERR(a) != -ENOENT)
526 return PTR_ERR(a);
527 continue;
528 }
529 attrs[aindex++] = a;
530 }
531 }
532 return aindex;
533}
534
535static struct attribute **
538 templates[attr], ops);
539 if (IS_ERR(a)) {
540 if (PTR_ERR(a) != -ENOENT)
541 return PTR_ERR(a);
542 continue;
543 }
544 attrs[aindex++] = a;
545 }
546 }
547 return aindex;
548}
549
550static struct attribute **
536__hwmon_create_attrs(struct device *dev, const void *drvdata,
537 const struct hwmon_chip_info *chip)
551__hwmon_create_attrs(const void *drvdata, const struct hwmon_chip_info *chip)
538{
539 int ret, i, aindex = 0, nattrs = 0;
540 struct attribute **attrs;
541
542 for (i = 0; chip->info[i]; i++)
543 nattrs += hwmon_num_channel_attrs(chip->info[i]);
544
545 if (nattrs == 0)
546 return ERR_PTR(-EINVAL);
547
552{
553 int ret, i, aindex = 0, nattrs = 0;
554 struct attribute **attrs;
555
556 for (i = 0; chip->info[i]; i++)
557 nattrs += hwmon_num_channel_attrs(chip->info[i]);
558
559 if (nattrs == 0)
560 return ERR_PTR(-EINVAL);
561
548 attrs = devm_kcalloc(dev, nattrs + 1, sizeof(*attrs), GFP_KERNEL);
562 attrs = kcalloc(nattrs + 1, sizeof(*attrs), GFP_KERNEL);
549 if (!attrs)
550 return ERR_PTR(-ENOMEM);
551
552 for (i = 0; chip->info[i]; i++) {
563 if (!attrs)
564 return ERR_PTR(-ENOMEM);
565
566 for (i = 0; chip->info[i]; i++) {
553 ret = hwmon_genattrs(dev, drvdata, &attrs[aindex], chip->ops,
567 ret = hwmon_genattrs(drvdata, &attrs[aindex], chip->ops,
554 chip->info[i]);
568 chip->info[i]);
555 if (ret < 0)
569 if (ret < 0) {
570 hwmon_free_attrs(attrs);
556 return ERR_PTR(ret);
571 return ERR_PTR(ret);
572 }
557 aindex += ret;
558 }
559
560 return attrs;
561}
562
563static struct device *
564__hwmon_device_register(struct device *dev, const char *name, void *drvdata,

--- 25 unchanged lines hidden (view full) ---

590 if (chip) {
591 struct attribute **attrs;
592 int ngroups = 2; /* terminating NULL plus &hwdev->groups */
593
594 if (groups)
595 for (i = 0; groups[i]; i++)
596 ngroups++;
597
573 aindex += ret;
574 }
575
576 return attrs;
577}
578
579static struct device *
580__hwmon_device_register(struct device *dev, const char *name, void *drvdata,

--- 25 unchanged lines hidden (view full) ---

606 if (chip) {
607 struct attribute **attrs;
608 int ngroups = 2; /* terminating NULL plus &hwdev->groups */
609
610 if (groups)
611 for (i = 0; groups[i]; i++)
612 ngroups++;
613
598 hwdev->groups = devm_kcalloc(dev, ngroups, sizeof(*groups),
599 GFP_KERNEL);
614 hwdev->groups = kcalloc(ngroups, sizeof(*groups), GFP_KERNEL);
600 if (!hwdev->groups) {
601 err = -ENOMEM;
602 goto free_hwmon;
603 }
604
615 if (!hwdev->groups) {
616 err = -ENOMEM;
617 goto free_hwmon;
618 }
619
605 attrs = __hwmon_create_attrs(dev, drvdata, chip);
620 attrs = __hwmon_create_attrs(drvdata, chip);
606 if (IS_ERR(attrs)) {
607 err = PTR_ERR(attrs);
608 goto free_hwmon;
609 }
610
611 hwdev->group.attrs = attrs;
612 ngroups = 0;
613 hwdev->groups[ngroups++] = &hwdev->group;

--- 28 unchanged lines hidden (view full) ---

642 if (info[i]->type != hwmon_temp)
643 continue;
644
645 for (j = 0; info[i]->config[j]; j++) {
646 if (!chip->ops->is_visible(drvdata, hwmon_temp,
647 hwmon_temp_input, j))
648 continue;
649 if (info[i]->config[j] & HWMON_T_INPUT) {
621 if (IS_ERR(attrs)) {
622 err = PTR_ERR(attrs);
623 goto free_hwmon;
624 }
625
626 hwdev->group.attrs = attrs;
627 ngroups = 0;
628 hwdev->groups[ngroups++] = &hwdev->group;

--- 28 unchanged lines hidden (view full) ---

657 if (info[i]->type != hwmon_temp)
658 continue;
659
660 for (j = 0; info[i]->config[j]; j++) {
661 if (!chip->ops->is_visible(drvdata, hwmon_temp,
662 hwmon_temp_input, j))
663 continue;
664 if (info[i]->config[j] & HWMON_T_INPUT) {
650 err = hwmon_thermal_add_sensor(dev,
651 hwdev, j);
665 err = hwmon_thermal_add_sensor(hdev, j);
652 if (err) {
653 device_unregister(hdev);
654 /*
655 * Don't worry about hwdev;
656 * hwmon_dev_release(), called
657 * from device_unregister(),
658 * will free it.
659 */
660 goto ida_remove;
661 }
662 }
663 }
664 }
665 }
666
667 return hdev;
668
669free_hwmon:
666 if (err) {
667 device_unregister(hdev);
668 /*
669 * Don't worry about hwdev;
670 * hwmon_dev_release(), called
671 * from device_unregister(),
672 * will free it.
673 */
674 goto ida_remove;
675 }
676 }
677 }
678 }
679 }
680
681 return hdev;
682
683free_hwmon:
670 kfree(hwdev);
684 hwmon_dev_release(hdev);
671ida_remove:
672 ida_simple_remove(&hwmon_ida, id);
673 return ERR_PTR(err);
674}
675
676/**
677 * hwmon_device_register_with_groups - register w/ hwmon
678 * @dev: the parent device

--- 248 unchanged lines hidden ---
685ida_remove:
686 ida_simple_remove(&hwmon_ida, id);
687 return ERR_PTR(err);
688}
689
690/**
691 * hwmon_device_register_with_groups - register w/ hwmon
692 * @dev: the parent device

--- 248 unchanged lines hidden ---