1 // SPDX-License-Identifier: GPL-2.0-only
3 * hwmon.c - part of lm_sensors, Linux kernel modules for hardware monitoring
5 * This file defines the sysfs class "hwmon", for use by sensors drivers.
7 * Copyright (C) 2005 Mark M. Hoffman <mhoffman@lightlink.com>
10 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
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/i2c.h>
18 #include <linux/idr.h>
19 #include <linux/kstrtox.h>
20 #include <linux/list.h>
21 #include <linux/module.h>
22 #include <linux/pci.h>
23 #include <linux/property.h>
24 #include <linux/slab.h>
25 #include <linux/string.h>
26 #include <linux/thermal.h>
28 #define CREATE_TRACE_POINTS
29 #include <trace/events/hwmon.h>
31 #define HWMON_ID_PREFIX "hwmon"
32 #define HWMON_ID_FORMAT HWMON_ID_PREFIX "%d"
38 const struct hwmon_chip_info
*chip
;
39 struct list_head tzdata
;
40 struct attribute_group group
;
41 const struct attribute_group
**groups
;
44 #define to_hwmon_device(d) container_of(d, struct hwmon_device, dev)
46 #define MAX_SYSFS_ATTR_NAME_LENGTH 32
48 struct hwmon_device_attribute
{
49 struct device_attribute dev_attr
;
50 const struct hwmon_ops
*ops
;
51 enum hwmon_sensor_types type
;
54 char name
[MAX_SYSFS_ATTR_NAME_LENGTH
];
57 #define to_hwmon_attr(d) \
58 container_of(d, struct hwmon_device_attribute, dev_attr)
59 #define to_dev_attr(a) container_of(a, struct device_attribute, attr)
62 * Thermal zone information
64 struct hwmon_thermal_data
{
65 struct list_head node
; /* hwmon tzdata list entry */
66 struct device
*dev
; /* Reference to hwmon device */
67 int index
; /* sensor index */
68 struct thermal_zone_device
*tzd
;/* thermal zone device */
72 name_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
74 return sprintf(buf
, "%s\n", to_hwmon_device(dev
)->name
);
76 static DEVICE_ATTR_RO(name
);
79 label_show(struct device
*dev
, struct device_attribute
*attr
, char *buf
)
81 return sysfs_emit(buf
, "%s\n", to_hwmon_device(dev
)->label
);
83 static DEVICE_ATTR_RO(label
);
85 static struct attribute
*hwmon_dev_attrs
[] = {
91 static umode_t
hwmon_dev_attr_is_visible(struct kobject
*kobj
,
92 struct attribute
*attr
, int n
)
94 struct device
*dev
= kobj_to_dev(kobj
);
95 struct hwmon_device
*hdev
= to_hwmon_device(dev
);
97 if (attr
== &dev_attr_name
.attr
&& hdev
->name
== NULL
)
100 if (attr
== &dev_attr_label
.attr
&& hdev
->label
== NULL
)
106 static const struct attribute_group hwmon_dev_attr_group
= {
107 .attrs
= hwmon_dev_attrs
,
108 .is_visible
= hwmon_dev_attr_is_visible
,
111 static const struct attribute_group
*hwmon_dev_attr_groups
[] = {
112 &hwmon_dev_attr_group
,
116 static void hwmon_free_attrs(struct attribute
**attrs
)
120 for (i
= 0; attrs
[i
]; i
++) {
121 struct device_attribute
*dattr
= to_dev_attr(attrs
[i
]);
122 struct hwmon_device_attribute
*hattr
= to_hwmon_attr(dattr
);
129 static void hwmon_dev_release(struct device
*dev
)
131 struct hwmon_device
*hwdev
= to_hwmon_device(dev
);
133 if (hwdev
->group
.attrs
)
134 hwmon_free_attrs(hwdev
->group
.attrs
);
135 kfree(hwdev
->groups
);
140 static const struct class hwmon_class
= {
142 .dev_groups
= hwmon_dev_attr_groups
,
143 .dev_release
= hwmon_dev_release
,
146 static DEFINE_IDA(hwmon_ida
);
148 static umode_t
hwmon_is_visible(const struct hwmon_ops
*ops
,
150 enum hwmon_sensor_types type
,
151 u32 attr
, int channel
)
156 return ops
->is_visible(drvdata
, type
, attr
, channel
);
159 /* Thermal zone handling */
162 * The complex conditional is necessary to avoid a cyclic dependency
163 * between hwmon and thermal_sys modules.
165 #ifdef CONFIG_THERMAL_OF
166 static int hwmon_thermal_get_temp(struct thermal_zone_device
*tz
, int *temp
)
168 struct hwmon_thermal_data
*tdata
= thermal_zone_device_priv(tz
);
169 struct hwmon_device
*hwdev
= to_hwmon_device(tdata
->dev
);
173 ret
= hwdev
->chip
->ops
->read(tdata
->dev
, hwmon_temp
, hwmon_temp_input
,
183 static int hwmon_thermal_set_trips(struct thermal_zone_device
*tz
, int low
, int high
)
185 struct hwmon_thermal_data
*tdata
= thermal_zone_device_priv(tz
);
186 struct hwmon_device
*hwdev
= to_hwmon_device(tdata
->dev
);
187 const struct hwmon_chip_info
*chip
= hwdev
->chip
;
188 const struct hwmon_channel_info
* const *info
= chip
->info
;
192 if (!chip
->ops
->write
)
195 for (i
= 0; info
[i
] && info
[i
]->type
!= hwmon_temp
; i
++)
201 if (info
[i
]->config
[tdata
->index
] & HWMON_T_MIN
) {
202 err
= chip
->ops
->write(tdata
->dev
, hwmon_temp
,
203 hwmon_temp_min
, tdata
->index
, low
);
204 if (err
&& err
!= -EOPNOTSUPP
)
208 if (info
[i
]->config
[tdata
->index
] & HWMON_T_MAX
) {
209 err
= chip
->ops
->write(tdata
->dev
, hwmon_temp
,
210 hwmon_temp_max
, tdata
->index
, high
);
211 if (err
&& err
!= -EOPNOTSUPP
)
218 static const struct thermal_zone_device_ops hwmon_thermal_ops
= {
219 .get_temp
= hwmon_thermal_get_temp
,
220 .set_trips
= hwmon_thermal_set_trips
,
223 static void hwmon_thermal_remove_sensor(void *data
)
228 static int hwmon_thermal_add_sensor(struct device
*dev
, int index
)
230 struct hwmon_device
*hwdev
= to_hwmon_device(dev
);
231 struct hwmon_thermal_data
*tdata
;
232 struct thermal_zone_device
*tzd
;
235 tdata
= devm_kzalloc(dev
, sizeof(*tdata
), GFP_KERNEL
);
240 tdata
->index
= index
;
242 tzd
= devm_thermal_of_zone_register(dev
, index
, tdata
,
245 if (PTR_ERR(tzd
) != -ENODEV
)
247 dev_info(dev
, "temp%d_input not attached to any thermal zone\n",
249 devm_kfree(dev
, tdata
);
253 err
= devm_add_action(dev
, hwmon_thermal_remove_sensor
, &tdata
->node
);
258 list_add(&tdata
->node
, &hwdev
->tzdata
);
263 static int hwmon_thermal_register_sensors(struct device
*dev
)
265 struct hwmon_device
*hwdev
= to_hwmon_device(dev
);
266 const struct hwmon_chip_info
*chip
= hwdev
->chip
;
267 const struct hwmon_channel_info
* const *info
= chip
->info
;
268 void *drvdata
= dev_get_drvdata(dev
);
271 for (i
= 1; info
[i
]; i
++) {
274 if (info
[i
]->type
!= hwmon_temp
)
277 for (j
= 0; info
[i
]->config
[j
]; j
++) {
280 if (!(info
[i
]->config
[j
] & HWMON_T_INPUT
) ||
281 !hwmon_is_visible(chip
->ops
, drvdata
, hwmon_temp
,
282 hwmon_temp_input
, j
))
285 err
= hwmon_thermal_add_sensor(dev
, j
);
294 static void hwmon_thermal_notify(struct device
*dev
, int index
)
296 struct hwmon_device
*hwdev
= to_hwmon_device(dev
);
297 struct hwmon_thermal_data
*tzdata
;
299 list_for_each_entry(tzdata
, &hwdev
->tzdata
, node
) {
300 if (tzdata
->index
== index
) {
301 thermal_zone_device_update(tzdata
->tzd
,
302 THERMAL_EVENT_UNSPECIFIED
);
308 static int hwmon_thermal_register_sensors(struct device
*dev
)
313 static void hwmon_thermal_notify(struct device
*dev
, int index
) { }
315 #endif /* IS_REACHABLE(CONFIG_THERMAL) && ... */
317 static int hwmon_attr_base(enum hwmon_sensor_types type
)
319 if (type
== hwmon_in
|| type
== hwmon_intrusion
)
324 #if IS_REACHABLE(CONFIG_I2C)
329 * The 'pec' attribute is attached to I2C client devices. It is only provided
330 * if the i2c controller supports PEC.
332 * The mutex ensures that PEC configuration between i2c device and the hardware
333 * is consistent. Use a single mutex because attribute writes are supposed to be
334 * rare, and maintaining a separate mutex for each hardware monitoring device
335 * would add substantial complexity to the driver for little if any gain.
337 * The hardware monitoring device is identified as child of the i2c client
338 * device. This assumes that only a single hardware monitoring device is
339 * attached to an i2c client device.
342 static DEFINE_MUTEX(hwmon_pec_mutex
);
344 static int hwmon_match_device(struct device
*dev
, void *data
)
346 return dev
->class == &hwmon_class
;
349 static ssize_t
pec_show(struct device
*dev
, struct device_attribute
*dummy
,
352 struct i2c_client
*client
= to_i2c_client(dev
);
354 return sysfs_emit(buf
, "%d\n", !!(client
->flags
& I2C_CLIENT_PEC
));
357 static ssize_t
pec_store(struct device
*dev
, struct device_attribute
*devattr
,
358 const char *buf
, size_t count
)
360 struct i2c_client
*client
= to_i2c_client(dev
);
361 struct hwmon_device
*hwdev
;
366 err
= kstrtobool(buf
, &val
);
370 hdev
= device_find_child(dev
, NULL
, hwmon_match_device
);
374 mutex_lock(&hwmon_pec_mutex
);
377 * If there is no write function, we assume that chip specific
378 * handling is not required.
380 hwdev
= to_hwmon_device(hdev
);
381 if (hwdev
->chip
->ops
->write
) {
382 err
= hwdev
->chip
->ops
->write(hdev
, hwmon_chip
, hwmon_chip_pec
, 0, val
);
383 if (err
&& err
!= -EOPNOTSUPP
)
388 client
->flags
&= ~I2C_CLIENT_PEC
;
390 client
->flags
|= I2C_CLIENT_PEC
;
394 mutex_unlock(&hwmon_pec_mutex
);
400 static DEVICE_ATTR_RW(pec
);
402 static void hwmon_remove_pec(void *dev
)
404 device_remove_file(dev
, &dev_attr_pec
);
407 static int hwmon_pec_register(struct device
*hdev
)
409 struct i2c_client
*client
= i2c_verify_client(hdev
->parent
);
415 if (!i2c_check_functionality(client
->adapter
, I2C_FUNC_SMBUS_PEC
))
418 err
= device_create_file(&client
->dev
, &dev_attr_pec
);
422 return devm_add_action_or_reset(hdev
, hwmon_remove_pec
, &client
->dev
);
425 #else /* CONFIG_I2C */
426 static int hwmon_pec_register(struct device
*hdev
)
430 #endif /* CONFIG_I2C */
432 /* sysfs attribute management */
434 static ssize_t
hwmon_attr_show(struct device
*dev
,
435 struct device_attribute
*devattr
, char *buf
)
437 struct hwmon_device_attribute
*hattr
= to_hwmon_attr(devattr
);
441 ret
= hattr
->ops
->read(dev
, hattr
->type
, hattr
->attr
, hattr
->index
,
446 trace_hwmon_attr_show(hattr
->index
+ hwmon_attr_base(hattr
->type
),
449 return sprintf(buf
, "%ld\n", val
);
452 static ssize_t
hwmon_attr_show_string(struct device
*dev
,
453 struct device_attribute
*devattr
,
456 struct hwmon_device_attribute
*hattr
= to_hwmon_attr(devattr
);
457 enum hwmon_sensor_types type
= hattr
->type
;
461 ret
= hattr
->ops
->read_string(dev
, hattr
->type
, hattr
->attr
,
466 trace_hwmon_attr_show_string(hattr
->index
+ hwmon_attr_base(type
),
469 return sprintf(buf
, "%s\n", s
);
472 static ssize_t
hwmon_attr_store(struct device
*dev
,
473 struct device_attribute
*devattr
,
474 const char *buf
, size_t count
)
476 struct hwmon_device_attribute
*hattr
= to_hwmon_attr(devattr
);
480 ret
= kstrtol(buf
, 10, &val
);
484 ret
= hattr
->ops
->write(dev
, hattr
->type
, hattr
->attr
, hattr
->index
,
489 trace_hwmon_attr_store(hattr
->index
+ hwmon_attr_base(hattr
->type
),
495 static bool is_string_attr(enum hwmon_sensor_types type
, u32 attr
)
497 return (type
== hwmon_temp
&& attr
== hwmon_temp_label
) ||
498 (type
== hwmon_in
&& attr
== hwmon_in_label
) ||
499 (type
== hwmon_curr
&& attr
== hwmon_curr_label
) ||
500 (type
== hwmon_power
&& attr
== hwmon_power_label
) ||
501 (type
== hwmon_energy
&& attr
== hwmon_energy_label
) ||
502 (type
== hwmon_humidity
&& attr
== hwmon_humidity_label
) ||
503 (type
== hwmon_fan
&& attr
== hwmon_fan_label
);
506 static struct attribute
*hwmon_genattr(const void *drvdata
,
507 enum hwmon_sensor_types type
,
510 const char *template,
511 const struct hwmon_ops
*ops
)
513 struct hwmon_device_attribute
*hattr
;
514 struct device_attribute
*dattr
;
518 bool is_string
= is_string_attr(type
, attr
);
520 mode
= hwmon_is_visible(ops
, drvdata
, type
, attr
, index
);
522 return ERR_PTR(-ENOENT
);
524 if ((mode
& 0444) && ((is_string
&& !ops
->read_string
) ||
525 (!is_string
&& !ops
->read
)))
526 return ERR_PTR(-EINVAL
);
527 if ((mode
& 0222) && !ops
->write
)
528 return ERR_PTR(-EINVAL
);
530 hattr
= kzalloc(sizeof(*hattr
), GFP_KERNEL
);
532 return ERR_PTR(-ENOMEM
);
534 if (type
== hwmon_chip
) {
537 scnprintf(hattr
->name
, sizeof(hattr
->name
), template,
538 index
+ hwmon_attr_base(type
));
544 hattr
->index
= index
;
547 dattr
= &hattr
->dev_attr
;
548 dattr
->show
= is_string
? hwmon_attr_show_string
: hwmon_attr_show
;
549 dattr
->store
= hwmon_attr_store
;
560 * Chip attributes are not attribute templates but actual sysfs attributes.
561 * See hwmon_genattr() for special handling.
563 static const char * const hwmon_chip_attrs
[] = {
564 [hwmon_chip_temp_reset_history
] = "temp_reset_history",
565 [hwmon_chip_in_reset_history
] = "in_reset_history",
566 [hwmon_chip_curr_reset_history
] = "curr_reset_history",
567 [hwmon_chip_power_reset_history
] = "power_reset_history",
568 [hwmon_chip_update_interval
] = "update_interval",
569 [hwmon_chip_alarms
] = "alarms",
570 [hwmon_chip_samples
] = "samples",
571 [hwmon_chip_curr_samples
] = "curr_samples",
572 [hwmon_chip_in_samples
] = "in_samples",
573 [hwmon_chip_power_samples
] = "power_samples",
574 [hwmon_chip_temp_samples
] = "temp_samples",
575 [hwmon_chip_beep_enable
] = "beep_enable",
578 static const char * const hwmon_temp_attr_templates
[] = {
579 [hwmon_temp_enable
] = "temp%d_enable",
580 [hwmon_temp_input
] = "temp%d_input",
581 [hwmon_temp_type
] = "temp%d_type",
582 [hwmon_temp_lcrit
] = "temp%d_lcrit",
583 [hwmon_temp_lcrit_hyst
] = "temp%d_lcrit_hyst",
584 [hwmon_temp_min
] = "temp%d_min",
585 [hwmon_temp_min_hyst
] = "temp%d_min_hyst",
586 [hwmon_temp_max
] = "temp%d_max",
587 [hwmon_temp_max_hyst
] = "temp%d_max_hyst",
588 [hwmon_temp_crit
] = "temp%d_crit",
589 [hwmon_temp_crit_hyst
] = "temp%d_crit_hyst",
590 [hwmon_temp_emergency
] = "temp%d_emergency",
591 [hwmon_temp_emergency_hyst
] = "temp%d_emergency_hyst",
592 [hwmon_temp_alarm
] = "temp%d_alarm",
593 [hwmon_temp_lcrit_alarm
] = "temp%d_lcrit_alarm",
594 [hwmon_temp_min_alarm
] = "temp%d_min_alarm",
595 [hwmon_temp_max_alarm
] = "temp%d_max_alarm",
596 [hwmon_temp_crit_alarm
] = "temp%d_crit_alarm",
597 [hwmon_temp_emergency_alarm
] = "temp%d_emergency_alarm",
598 [hwmon_temp_fault
] = "temp%d_fault",
599 [hwmon_temp_offset
] = "temp%d_offset",
600 [hwmon_temp_label
] = "temp%d_label",
601 [hwmon_temp_lowest
] = "temp%d_lowest",
602 [hwmon_temp_highest
] = "temp%d_highest",
603 [hwmon_temp_reset_history
] = "temp%d_reset_history",
604 [hwmon_temp_rated_min
] = "temp%d_rated_min",
605 [hwmon_temp_rated_max
] = "temp%d_rated_max",
606 [hwmon_temp_beep
] = "temp%d_beep",
609 static const char * const hwmon_in_attr_templates
[] = {
610 [hwmon_in_enable
] = "in%d_enable",
611 [hwmon_in_input
] = "in%d_input",
612 [hwmon_in_min
] = "in%d_min",
613 [hwmon_in_max
] = "in%d_max",
614 [hwmon_in_lcrit
] = "in%d_lcrit",
615 [hwmon_in_crit
] = "in%d_crit",
616 [hwmon_in_average
] = "in%d_average",
617 [hwmon_in_lowest
] = "in%d_lowest",
618 [hwmon_in_highest
] = "in%d_highest",
619 [hwmon_in_reset_history
] = "in%d_reset_history",
620 [hwmon_in_label
] = "in%d_label",
621 [hwmon_in_alarm
] = "in%d_alarm",
622 [hwmon_in_min_alarm
] = "in%d_min_alarm",
623 [hwmon_in_max_alarm
] = "in%d_max_alarm",
624 [hwmon_in_lcrit_alarm
] = "in%d_lcrit_alarm",
625 [hwmon_in_crit_alarm
] = "in%d_crit_alarm",
626 [hwmon_in_rated_min
] = "in%d_rated_min",
627 [hwmon_in_rated_max
] = "in%d_rated_max",
628 [hwmon_in_beep
] = "in%d_beep",
629 [hwmon_in_fault
] = "in%d_fault",
632 static const char * const hwmon_curr_attr_templates
[] = {
633 [hwmon_curr_enable
] = "curr%d_enable",
634 [hwmon_curr_input
] = "curr%d_input",
635 [hwmon_curr_min
] = "curr%d_min",
636 [hwmon_curr_max
] = "curr%d_max",
637 [hwmon_curr_lcrit
] = "curr%d_lcrit",
638 [hwmon_curr_crit
] = "curr%d_crit",
639 [hwmon_curr_average
] = "curr%d_average",
640 [hwmon_curr_lowest
] = "curr%d_lowest",
641 [hwmon_curr_highest
] = "curr%d_highest",
642 [hwmon_curr_reset_history
] = "curr%d_reset_history",
643 [hwmon_curr_label
] = "curr%d_label",
644 [hwmon_curr_alarm
] = "curr%d_alarm",
645 [hwmon_curr_min_alarm
] = "curr%d_min_alarm",
646 [hwmon_curr_max_alarm
] = "curr%d_max_alarm",
647 [hwmon_curr_lcrit_alarm
] = "curr%d_lcrit_alarm",
648 [hwmon_curr_crit_alarm
] = "curr%d_crit_alarm",
649 [hwmon_curr_rated_min
] = "curr%d_rated_min",
650 [hwmon_curr_rated_max
] = "curr%d_rated_max",
651 [hwmon_curr_beep
] = "curr%d_beep",
654 static const char * const hwmon_power_attr_templates
[] = {
655 [hwmon_power_enable
] = "power%d_enable",
656 [hwmon_power_average
] = "power%d_average",
657 [hwmon_power_average_interval
] = "power%d_average_interval",
658 [hwmon_power_average_interval_max
] = "power%d_interval_max",
659 [hwmon_power_average_interval_min
] = "power%d_interval_min",
660 [hwmon_power_average_highest
] = "power%d_average_highest",
661 [hwmon_power_average_lowest
] = "power%d_average_lowest",
662 [hwmon_power_average_max
] = "power%d_average_max",
663 [hwmon_power_average_min
] = "power%d_average_min",
664 [hwmon_power_input
] = "power%d_input",
665 [hwmon_power_input_highest
] = "power%d_input_highest",
666 [hwmon_power_input_lowest
] = "power%d_input_lowest",
667 [hwmon_power_reset_history
] = "power%d_reset_history",
668 [hwmon_power_accuracy
] = "power%d_accuracy",
669 [hwmon_power_cap
] = "power%d_cap",
670 [hwmon_power_cap_hyst
] = "power%d_cap_hyst",
671 [hwmon_power_cap_max
] = "power%d_cap_max",
672 [hwmon_power_cap_min
] = "power%d_cap_min",
673 [hwmon_power_min
] = "power%d_min",
674 [hwmon_power_max
] = "power%d_max",
675 [hwmon_power_lcrit
] = "power%d_lcrit",
676 [hwmon_power_crit
] = "power%d_crit",
677 [hwmon_power_label
] = "power%d_label",
678 [hwmon_power_alarm
] = "power%d_alarm",
679 [hwmon_power_cap_alarm
] = "power%d_cap_alarm",
680 [hwmon_power_min_alarm
] = "power%d_min_alarm",
681 [hwmon_power_max_alarm
] = "power%d_max_alarm",
682 [hwmon_power_lcrit_alarm
] = "power%d_lcrit_alarm",
683 [hwmon_power_crit_alarm
] = "power%d_crit_alarm",
684 [hwmon_power_rated_min
] = "power%d_rated_min",
685 [hwmon_power_rated_max
] = "power%d_rated_max",
688 static const char * const hwmon_energy_attr_templates
[] = {
689 [hwmon_energy_enable
] = "energy%d_enable",
690 [hwmon_energy_input
] = "energy%d_input",
691 [hwmon_energy_label
] = "energy%d_label",
694 static const char * const hwmon_humidity_attr_templates
[] = {
695 [hwmon_humidity_enable
] = "humidity%d_enable",
696 [hwmon_humidity_input
] = "humidity%d_input",
697 [hwmon_humidity_label
] = "humidity%d_label",
698 [hwmon_humidity_min
] = "humidity%d_min",
699 [hwmon_humidity_min_hyst
] = "humidity%d_min_hyst",
700 [hwmon_humidity_max
] = "humidity%d_max",
701 [hwmon_humidity_max_hyst
] = "humidity%d_max_hyst",
702 [hwmon_humidity_alarm
] = "humidity%d_alarm",
703 [hwmon_humidity_fault
] = "humidity%d_fault",
704 [hwmon_humidity_rated_min
] = "humidity%d_rated_min",
705 [hwmon_humidity_rated_max
] = "humidity%d_rated_max",
706 [hwmon_humidity_min_alarm
] = "humidity%d_min_alarm",
707 [hwmon_humidity_max_alarm
] = "humidity%d_max_alarm",
710 static const char * const hwmon_fan_attr_templates
[] = {
711 [hwmon_fan_enable
] = "fan%d_enable",
712 [hwmon_fan_input
] = "fan%d_input",
713 [hwmon_fan_label
] = "fan%d_label",
714 [hwmon_fan_min
] = "fan%d_min",
715 [hwmon_fan_max
] = "fan%d_max",
716 [hwmon_fan_div
] = "fan%d_div",
717 [hwmon_fan_pulses
] = "fan%d_pulses",
718 [hwmon_fan_target
] = "fan%d_target",
719 [hwmon_fan_alarm
] = "fan%d_alarm",
720 [hwmon_fan_min_alarm
] = "fan%d_min_alarm",
721 [hwmon_fan_max_alarm
] = "fan%d_max_alarm",
722 [hwmon_fan_fault
] = "fan%d_fault",
723 [hwmon_fan_beep
] = "fan%d_beep",
726 static const char * const hwmon_pwm_attr_templates
[] = {
727 [hwmon_pwm_input
] = "pwm%d",
728 [hwmon_pwm_enable
] = "pwm%d_enable",
729 [hwmon_pwm_mode
] = "pwm%d_mode",
730 [hwmon_pwm_freq
] = "pwm%d_freq",
731 [hwmon_pwm_auto_channels_temp
] = "pwm%d_auto_channels_temp",
734 static const char * const hwmon_intrusion_attr_templates
[] = {
735 [hwmon_intrusion_alarm
] = "intrusion%d_alarm",
736 [hwmon_intrusion_beep
] = "intrusion%d_beep",
739 static const char * const *__templates
[] = {
740 [hwmon_chip
] = hwmon_chip_attrs
,
741 [hwmon_temp
] = hwmon_temp_attr_templates
,
742 [hwmon_in
] = hwmon_in_attr_templates
,
743 [hwmon_curr
] = hwmon_curr_attr_templates
,
744 [hwmon_power
] = hwmon_power_attr_templates
,
745 [hwmon_energy
] = hwmon_energy_attr_templates
,
746 [hwmon_humidity
] = hwmon_humidity_attr_templates
,
747 [hwmon_fan
] = hwmon_fan_attr_templates
,
748 [hwmon_pwm
] = hwmon_pwm_attr_templates
,
749 [hwmon_intrusion
] = hwmon_intrusion_attr_templates
,
752 static const int __templates_size
[] = {
753 [hwmon_chip
] = ARRAY_SIZE(hwmon_chip_attrs
),
754 [hwmon_temp
] = ARRAY_SIZE(hwmon_temp_attr_templates
),
755 [hwmon_in
] = ARRAY_SIZE(hwmon_in_attr_templates
),
756 [hwmon_curr
] = ARRAY_SIZE(hwmon_curr_attr_templates
),
757 [hwmon_power
] = ARRAY_SIZE(hwmon_power_attr_templates
),
758 [hwmon_energy
] = ARRAY_SIZE(hwmon_energy_attr_templates
),
759 [hwmon_humidity
] = ARRAY_SIZE(hwmon_humidity_attr_templates
),
760 [hwmon_fan
] = ARRAY_SIZE(hwmon_fan_attr_templates
),
761 [hwmon_pwm
] = ARRAY_SIZE(hwmon_pwm_attr_templates
),
762 [hwmon_intrusion
] = ARRAY_SIZE(hwmon_intrusion_attr_templates
),
765 int hwmon_notify_event(struct device
*dev
, enum hwmon_sensor_types type
,
766 u32 attr
, int channel
)
768 char event
[MAX_SYSFS_ATTR_NAME_LENGTH
+ 5];
769 char sattr
[MAX_SYSFS_ATTR_NAME_LENGTH
];
770 char *envp
[] = { event
, NULL
};
771 const char * const *templates
;
772 const char *template;
775 if (type
>= ARRAY_SIZE(__templates
))
777 if (attr
>= __templates_size
[type
])
780 templates
= __templates
[type
];
781 template = templates
[attr
];
783 base
= hwmon_attr_base(type
);
785 scnprintf(sattr
, MAX_SYSFS_ATTR_NAME_LENGTH
, template, base
+ channel
);
786 scnprintf(event
, sizeof(event
), "NAME=%s", sattr
);
787 sysfs_notify(&dev
->kobj
, NULL
, sattr
);
788 kobject_uevent_env(&dev
->kobj
, KOBJ_CHANGE
, envp
);
790 if (type
== hwmon_temp
)
791 hwmon_thermal_notify(dev
, channel
);
795 EXPORT_SYMBOL_GPL(hwmon_notify_event
);
797 static int hwmon_num_channel_attrs(const struct hwmon_channel_info
*info
)
801 for (i
= n
= 0; info
->config
[i
]; i
++)
802 n
+= hweight32(info
->config
[i
]);
807 static int hwmon_genattrs(const void *drvdata
,
808 struct attribute
**attrs
,
809 const struct hwmon_ops
*ops
,
810 const struct hwmon_channel_info
*info
)
812 const char * const *templates
;
816 if (info
->type
>= ARRAY_SIZE(__templates
))
819 templates
= __templates
[info
->type
];
820 template_size
= __templates_size
[info
->type
];
822 for (i
= 0; info
->config
[i
]; i
++) {
823 u32 attr_mask
= info
->config
[i
];
829 attr
= __ffs(attr_mask
);
830 attr_mask
&= ~BIT(attr
);
831 if (attr
>= template_size
|| !templates
[attr
])
832 continue; /* attribute is invisible */
833 a
= hwmon_genattr(drvdata
, info
->type
, attr
, i
,
834 templates
[attr
], ops
);
836 if (PTR_ERR(a
) != -ENOENT
)
846 static struct attribute
**
847 __hwmon_create_attrs(const void *drvdata
, const struct hwmon_chip_info
*chip
)
849 int ret
, i
, aindex
= 0, nattrs
= 0;
850 struct attribute
**attrs
;
852 for (i
= 0; chip
->info
[i
]; i
++)
853 nattrs
+= hwmon_num_channel_attrs(chip
->info
[i
]);
856 return ERR_PTR(-EINVAL
);
858 attrs
= kcalloc(nattrs
+ 1, sizeof(*attrs
), GFP_KERNEL
);
860 return ERR_PTR(-ENOMEM
);
862 for (i
= 0; chip
->info
[i
]; i
++) {
863 ret
= hwmon_genattrs(drvdata
, &attrs
[aindex
], chip
->ops
,
866 hwmon_free_attrs(attrs
);
875 static struct device
*
876 __hwmon_device_register(struct device
*dev
, const char *name
, void *drvdata
,
877 const struct hwmon_chip_info
*chip
,
878 const struct attribute_group
**groups
)
880 struct hwmon_device
*hwdev
;
883 struct device
*tdev
= dev
;
886 /* Complain about invalid characters in hwmon name attribute */
887 if (name
&& (!strlen(name
) || strpbrk(name
, "-* \t\n")))
889 "hwmon: '%s' is not a valid name attribute, please fix\n",
892 id
= ida_alloc(&hwmon_ida
, GFP_KERNEL
);
896 hwdev
= kzalloc(sizeof(*hwdev
), GFP_KERNEL
);
905 struct attribute
**attrs
;
906 int ngroups
= 2; /* terminating NULL plus &hwdev->groups */
909 for (i
= 0; groups
[i
]; i
++)
912 hwdev
->groups
= kcalloc(ngroups
, sizeof(*groups
), GFP_KERNEL
);
913 if (!hwdev
->groups
) {
918 attrs
= __hwmon_create_attrs(drvdata
, chip
);
920 err
= PTR_ERR(attrs
);
924 hwdev
->group
.attrs
= attrs
;
926 hwdev
->groups
[ngroups
++] = &hwdev
->group
;
929 for (i
= 0; groups
[i
]; i
++)
930 hwdev
->groups
[ngroups
++] = groups
[i
];
933 hdev
->groups
= hwdev
->groups
;
935 hdev
->groups
= groups
;
938 if (dev
&& device_property_present(dev
, "label")) {
939 err
= device_property_read_string(dev
, "label", &label
);
943 hwdev
->label
= kstrdup(label
, GFP_KERNEL
);
944 if (hwdev
->label
== NULL
) {
951 hdev
->class = &hwmon_class
;
953 while (tdev
&& !tdev
->of_node
)
955 hdev
->of_node
= tdev
? tdev
->of_node
: NULL
;
957 dev_set_drvdata(hdev
, drvdata
);
958 dev_set_name(hdev
, HWMON_ID_FORMAT
, id
);
959 err
= device_register(hdev
);
965 INIT_LIST_HEAD(&hwdev
->tzdata
);
967 if (hdev
->of_node
&& chip
&& chip
->ops
->read
&&
968 chip
->info
[0]->type
== hwmon_chip
) {
969 u32 config
= chip
->info
[0]->config
[0];
971 if (config
& HWMON_C_REGISTER_TZ
) {
972 err
= hwmon_thermal_register_sensors(hdev
);
974 device_unregister(hdev
);
976 * Don't worry about hwdev; hwmon_dev_release(),
977 * called from device_unregister(), will free it.
982 if (config
& HWMON_C_PEC
) {
983 err
= hwmon_pec_register(hdev
);
985 device_unregister(hdev
);
994 hwmon_dev_release(hdev
);
996 ida_free(&hwmon_ida
, id
);
1001 * hwmon_device_register_with_groups - register w/ hwmon
1002 * @dev: the parent device
1003 * @name: hwmon name attribute
1004 * @drvdata: driver data to attach to created device
1005 * @groups: List of attribute groups to create
1007 * hwmon_device_unregister() must be called when the device is no
1010 * Returns the pointer to the new device.
1013 hwmon_device_register_with_groups(struct device
*dev
, const char *name
,
1015 const struct attribute_group
**groups
)
1018 return ERR_PTR(-EINVAL
);
1020 return __hwmon_device_register(dev
, name
, drvdata
, NULL
, groups
);
1022 EXPORT_SYMBOL_GPL(hwmon_device_register_with_groups
);
1025 * hwmon_device_register_with_info - register w/ hwmon
1026 * @dev: the parent device (mandatory)
1027 * @name: hwmon name attribute (mandatory)
1028 * @drvdata: driver data to attach to created device (optional)
1029 * @chip: pointer to hwmon chip information (mandatory)
1030 * @extra_groups: pointer to list of additional non-standard attribute groups
1033 * hwmon_device_unregister() must be called when the device is no
1036 * Returns the pointer to the new device.
1039 hwmon_device_register_with_info(struct device
*dev
, const char *name
,
1041 const struct hwmon_chip_info
*chip
,
1042 const struct attribute_group
**extra_groups
)
1044 if (!dev
|| !name
|| !chip
)
1045 return ERR_PTR(-EINVAL
);
1047 if (!chip
->ops
|| !(chip
->ops
->visible
|| chip
->ops
->is_visible
) || !chip
->info
)
1048 return ERR_PTR(-EINVAL
);
1050 return __hwmon_device_register(dev
, name
, drvdata
, chip
, extra_groups
);
1052 EXPORT_SYMBOL_GPL(hwmon_device_register_with_info
);
1055 * hwmon_device_register_for_thermal - register hwmon device for thermal subsystem
1056 * @dev: the parent device
1057 * @name: hwmon name attribute
1058 * @drvdata: driver data to attach to created device
1060 * The use of this function is restricted. It is provided for legacy reasons
1061 * and must only be called from the thermal subsystem.
1063 * hwmon_device_unregister() must be called when the device is no
1066 * Returns the pointer to the new device.
1069 hwmon_device_register_for_thermal(struct device
*dev
, const char *name
,
1073 return ERR_PTR(-EINVAL
);
1075 return __hwmon_device_register(dev
, name
, drvdata
, NULL
, NULL
);
1077 EXPORT_SYMBOL_NS_GPL(hwmon_device_register_for_thermal
, HWMON_THERMAL
);
1080 * hwmon_device_register - register w/ hwmon
1081 * @dev: the device to register
1083 * hwmon_device_unregister() must be called when the device is no
1086 * Returns the pointer to the new device.
1088 struct device
*hwmon_device_register(struct device
*dev
)
1091 "hwmon_device_register() is deprecated. Please convert the driver to use hwmon_device_register_with_info().\n");
1093 return __hwmon_device_register(dev
, NULL
, NULL
, NULL
, NULL
);
1095 EXPORT_SYMBOL_GPL(hwmon_device_register
);
1098 * hwmon_device_unregister - removes the previously registered class device
1100 * @dev: the class device to destroy
1102 void hwmon_device_unregister(struct device
*dev
)
1106 if (likely(sscanf(dev_name(dev
), HWMON_ID_FORMAT
, &id
) == 1)) {
1107 device_unregister(dev
);
1108 ida_free(&hwmon_ida
, id
);
1110 dev_dbg(dev
->parent
,
1111 "hwmon_device_unregister() failed: bad class ID!\n");
1113 EXPORT_SYMBOL_GPL(hwmon_device_unregister
);
1115 static void devm_hwmon_release(struct device
*dev
, void *res
)
1117 struct device
*hwdev
= *(struct device
**)res
;
1119 hwmon_device_unregister(hwdev
);
1123 * devm_hwmon_device_register_with_groups - register w/ hwmon
1124 * @dev: the parent device
1125 * @name: hwmon name attribute
1126 * @drvdata: driver data to attach to created device
1127 * @groups: List of attribute groups to create
1129 * Returns the pointer to the new device. The new device is automatically
1130 * unregistered with the parent device.
1133 devm_hwmon_device_register_with_groups(struct device
*dev
, const char *name
,
1135 const struct attribute_group
**groups
)
1137 struct device
**ptr
, *hwdev
;
1140 return ERR_PTR(-EINVAL
);
1142 ptr
= devres_alloc(devm_hwmon_release
, sizeof(*ptr
), GFP_KERNEL
);
1144 return ERR_PTR(-ENOMEM
);
1146 hwdev
= hwmon_device_register_with_groups(dev
, name
, drvdata
, groups
);
1151 devres_add(dev
, ptr
);
1158 EXPORT_SYMBOL_GPL(devm_hwmon_device_register_with_groups
);
1161 * devm_hwmon_device_register_with_info - register w/ hwmon
1162 * @dev: the parent device
1163 * @name: hwmon name attribute
1164 * @drvdata: driver data to attach to created device
1165 * @chip: pointer to hwmon chip information
1166 * @extra_groups: pointer to list of driver specific attribute groups
1168 * Returns the pointer to the new device. The new device is automatically
1169 * unregistered with the parent device.
1172 devm_hwmon_device_register_with_info(struct device
*dev
, const char *name
,
1174 const struct hwmon_chip_info
*chip
,
1175 const struct attribute_group
**extra_groups
)
1177 struct device
**ptr
, *hwdev
;
1180 return ERR_PTR(-EINVAL
);
1182 ptr
= devres_alloc(devm_hwmon_release
, sizeof(*ptr
), GFP_KERNEL
);
1184 return ERR_PTR(-ENOMEM
);
1186 hwdev
= hwmon_device_register_with_info(dev
, name
, drvdata
, chip
,
1192 devres_add(dev
, ptr
);
1200 EXPORT_SYMBOL_GPL(devm_hwmon_device_register_with_info
);
1202 static char *__hwmon_sanitize_name(struct device
*dev
, const char *old_name
)
1207 name
= devm_kstrdup(dev
, old_name
, GFP_KERNEL
);
1209 name
= kstrdup(old_name
, GFP_KERNEL
);
1211 return ERR_PTR(-ENOMEM
);
1213 for (p
= name
; *p
; p
++)
1214 if (hwmon_is_bad_char(*p
))
1221 * hwmon_sanitize_name - Replaces invalid characters in a hwmon name
1222 * @name: NUL-terminated name
1224 * Allocates a new string where any invalid characters will be replaced
1225 * by an underscore. It is the responsibility of the caller to release
1228 * Returns newly allocated name, or ERR_PTR on error.
1230 char *hwmon_sanitize_name(const char *name
)
1232 return __hwmon_sanitize_name(NULL
, name
);
1234 EXPORT_SYMBOL_GPL(hwmon_sanitize_name
);
1237 * devm_hwmon_sanitize_name - resource managed hwmon_sanitize_name()
1238 * @dev: device to allocate memory for
1239 * @name: NUL-terminated name
1241 * Allocates a new string where any invalid characters will be replaced
1244 * Returns newly allocated name, or ERR_PTR on error.
1246 char *devm_hwmon_sanitize_name(struct device
*dev
, const char *name
)
1249 return ERR_PTR(-EINVAL
);
1251 return __hwmon_sanitize_name(dev
, name
);
1253 EXPORT_SYMBOL_GPL(devm_hwmon_sanitize_name
);
1255 static void __init
hwmon_pci_quirks(void)
1257 #if defined CONFIG_X86 && defined CONFIG_PCI
1262 /* Open access to 0x295-0x296 on MSI MS-7031 */
1263 sb
= pci_get_device(PCI_VENDOR_ID_ATI
, 0x436c, NULL
);
1265 if (sb
->subsystem_vendor
== 0x1462 && /* MSI */
1266 sb
->subsystem_device
== 0x0031) { /* MS-7031 */
1267 pci_read_config_byte(sb
, 0x48, &enable
);
1268 pci_read_config_word(sb
, 0x64, &base
);
1270 if (base
== 0 && !(enable
& BIT(2))) {
1272 "Opening wide generic port at 0x295\n");
1273 pci_write_config_word(sb
, 0x64, 0x295);
1274 pci_write_config_byte(sb
, 0x48,
1283 static int __init
hwmon_init(void)
1289 err
= class_register(&hwmon_class
);
1291 pr_err("couldn't register hwmon sysfs class\n");
1297 static void __exit
hwmon_exit(void)
1299 class_unregister(&hwmon_class
);
1302 subsys_initcall(hwmon_init
);
1303 module_exit(hwmon_exit
);
1305 MODULE_AUTHOR("Mark M. Hoffman <mhoffman@lightlink.com>");
1306 MODULE_DESCRIPTION("hardware monitoring sysfs/class support");
1307 MODULE_LICENSE("GPL");