Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

Merge tag 'hwmon-for-v6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging

Pull hwmon updates from Guenter Roeck:
"New drivers:

- Driver for HTU31

- Congatec Board Controller monitoring driver

- Driver for TI INA233 Current and Power Monitor

Support for additional chips or boards in existing drivers:

- pmbus/ltc2978: Add support for LT717x and LTM4673

- asus-ec-sensors: Add PRIME X670E-PRO WIFI

- k10temp: Add support for cyan skillfish

- nct6683: Add customer ID for AMD BC-250

- lm90: Add support for NCT7716, NCT7717 and NCT7718

Other notable improvements in existing drivers:

- emc2305: Add devicetree support, and use
devm_thermal_of_cooling_device_register

- acpi_power_meter: Convert to with_info API

- dell-smm: Increase the number of fans

- pmbus/core: Optimize debugfs support and use i2c_client
debugfs directory

- hwmon core: Fix the missing of 'average' word in
hwmon_power_attr_templates

- Various drivers: Use per-client debugfs entry provided by
I2C subsystem"

* tag 'hwmon-for-v6.15' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (49 commits)
hwmon: emc2305: Use devm_thermal_of_cooling_device_register
hwmon: emc2305: Add OF support
dt-bindings: hwmon: Add Microchip emc2305 support
dt-bindings: hwmon: Drop stray blank line in the header
hwmon: (acpi_power_meter) Replace the deprecated hwmon_device_register
hwmon: add driver for HTU31
dt-bindings: hwmon: Add description for sensor HTU31
hwmon: Add driver for TI INA233 Current and Power Monitor
dt-bindings: hwmon: ti,ina2xx: Add INA233 device
hwmon: Add Congatec Board Controller monitoring driver
hwmon: (pmbus/ltc2978) add support for lt717x
dt-bindings: hwmon: ltc2978: add support for LT717x
hwmon: (pmbus/ltc2978) Add support for LT717x - docs
hwmon: (dell-smm) Increment the number of fans
hwmon: (ntc_thermistor) return error instead of clipping on OOB
hwmon: (pt5161l) Use per-client debugfs entry
hwmon: Fix the missing of 'average' word in hwmon_power_attr_templates
hwmon: (acpi_power_meter) Fix the fake power alarm reporting
hwmon: (gpio-fan) Add missing mutex locks
dt-bindings: hwmon: gpio-fan: Add optional regulator support
...

+2151 -992
-1
Documentation/devicetree/bindings/hwmon/adi,ad741x.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - 5 4 $id: http://devicetree.org/schemas/hwmon/adi,ad741x.yaml# 6 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 7 6
-1
Documentation/devicetree/bindings/hwmon/adi,adm1275.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - 5 4 $id: http://devicetree.org/schemas/hwmon/adi,adm1275.yaml# 6 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 7 6
-1
Documentation/devicetree/bindings/hwmon/adi,ltc2991.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - 5 4 $id: http://devicetree.org/schemas/hwmon/adi,ltc2991.yaml# 6 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 7 6
+3
Documentation/devicetree/bindings/hwmon/gpio-fan.yaml
··· 23 23 alarm-gpios: 24 24 maxItems: 1 25 25 26 + fan-supply: 27 + description: Power supply for fan 28 + 26 29 gpio-fan,speed-map: 27 30 $ref: /schemas/types.yaml#/definitions/uint32-matrix 28 31 minItems: 2
+5
Documentation/devicetree/bindings/hwmon/lltc,ltc2978.yaml
··· 12 12 properties: 13 13 compatible: 14 14 enum: 15 + - lltc,lt7170 16 + - lltc,lt7171 15 17 - lltc,ltc2972 16 18 - lltc,ltc2974 17 19 - lltc,ltc2975 ··· 32 30 - lltc,ltc7880 33 31 - lltc,ltm2987 34 32 - lltc,ltm4664 33 + - lltc,ltm4673 35 34 - lltc,ltm4675 36 35 - lltc,ltm4676 37 36 - lltc,ltm4677 ··· 49 46 description: | 50 47 list of regulators provided by this controller. 51 48 Valid names of regulators depend on number of supplies supported per device: 49 + * lt7170, lt7171 : vout0 52 50 * ltc2972 vout0 - vout1 53 51 * ltc2974, ltc2975 : vout0 - vout3 54 52 * ltc2977, ltc2979, ltc2980, ltm2987 : vout0 - vout7 ··· 59 55 * ltc7880 : vout0 - vout1 60 56 * ltc3883 : vout0 61 57 * ltm4664 : vout0 - vout1 58 + * ltm4673 : vout0 - vout3 62 59 * ltm4675, ltm4676, ltm4677, ltm4678 : vout0 - vout1 63 60 * ltm4680, ltm4686 : vout0 - vout1 64 61 * ltm4700 : vout0 - vout1
-1
Documentation/devicetree/bindings/hwmon/maxim,max20730.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - 5 4 $id: http://devicetree.org/schemas/hwmon/maxim,max20730.yaml# 6 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 7 6
-1
Documentation/devicetree/bindings/hwmon/maxim,max6639.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - 5 4 $id: http://devicetree.org/schemas/hwmon/maxim,max6639.yaml# 6 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 7 6
-1
Documentation/devicetree/bindings/hwmon/maxim,max6650.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - 5 4 $id: http://devicetree.org/schemas/hwmon/maxim,max6650.yaml# 6 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 7 6
+111
Documentation/devicetree/bindings/hwmon/microchip,emc2305.yaml
··· 1 + # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 + %YAML 1.2 3 + --- 4 + $id: http://devicetree.org/schemas/hwmon/microchip,emc2305.yaml# 5 + $schema: http://devicetree.org/meta-schemas/core.yaml# 6 + 7 + title: Microchip EMC2305 SMBus compliant PWM fan controller 8 + 9 + maintainers: 10 + - Michael Shych <michaelsh@nvidia.com> 11 + 12 + description: 13 + Microchip EMC2301/2/3/5 pwm controller which supports up to five programmable 14 + fan control circuits. 15 + 16 + properties: 17 + compatible: 18 + oneOf: 19 + - enum: 20 + - microchip,emc2305 21 + - items: 22 + - enum: 23 + - microchip,emc2303 24 + - microchip,emc2302 25 + - microchip,emc2301 26 + - const: microchip,emc2305 27 + 28 + reg: 29 + maxItems: 1 30 + 31 + '#address-cells': 32 + const: 1 33 + 34 + '#size-cells': 35 + const: 0 36 + 37 + '#pwm-cells': 38 + const: 3 39 + description: | 40 + Number of cells in a PWM specifier. 41 + - cell 0: The PWM frequency 42 + - cell 1: The PWM polarity: 0 or PWM_POLARITY_INVERTED 43 + - cell 2: The PWM output config: 44 + - 0 (Open-Drain) 45 + - 1 (Push-Pull) 46 + 47 + patternProperties: 48 + '^fan@[0-4]$': 49 + $ref: fan-common.yaml# 50 + unevaluatedProperties: false 51 + properties: 52 + reg: 53 + description: 54 + The fan number used to determine the associated PWM channel. 55 + maxItems: 1 56 + 57 + required: 58 + - reg 59 + 60 + required: 61 + - compatible 62 + - reg 63 + 64 + additionalProperties: false 65 + 66 + examples: 67 + - | 68 + #include <dt-bindings/pwm/pwm.h> 69 + i2c { 70 + #address-cells = <1>; 71 + #size-cells = <0>; 72 + 73 + fan_controller: fan-controller@2f { 74 + compatible = "microchip,emc2305"; 75 + reg = <0x2f>; 76 + #address-cells = <1>; 77 + #size-cells = <0>; 78 + #pwm-cells = <3>; 79 + 80 + fan@0 { 81 + reg = <0x0>; 82 + pwms = <&fan_controller 26000 PWM_POLARITY_INVERTED 1>; 83 + #cooling-cells = <2>; 84 + }; 85 + 86 + fan@1 { 87 + reg = <0x1>; 88 + pwms = <&fan_controller 26000 0 1>; 89 + #cooling-cells = <2>; 90 + }; 91 + 92 + fan@2 { 93 + reg = <0x2>; 94 + pwms = <&fan_controller 26000 0 1>; 95 + #cooling-cells = <2>; 96 + }; 97 + 98 + fan@3 { 99 + reg = <0x3>; 100 + pwms = <&fan_controller 26000 0 1>; 101 + #cooling-cells = <2>; 102 + }; 103 + 104 + fan@4 { 105 + reg = <0x4>; 106 + pwms = <&fan_controller 26000 0 1>; 107 + #cooling-cells = <2>; 108 + }; 109 + }; 110 + }; 111 + ...
+6
Documentation/devicetree/bindings/hwmon/national,lm90.yaml
··· 32 32 - national,lm89 33 33 - national,lm90 34 34 - national,lm99 35 + - nuvoton,nct7716 36 + - nuvoton,nct7717 37 + - nuvoton,nct7718 35 38 - nxp,sa56004 36 39 - onnn,nct1008 37 40 - ti,tmp451 ··· 123 120 - dallas,max6659 124 121 - dallas,max6695 125 122 - dallas,max6696 123 + - nuvoton,nct7716 124 + - nuvoton,nct7717 126 125 then: 127 126 patternProperties: 128 127 "^channel@([0-2])$": ··· 160 155 - national,lm89 161 156 - national,lm90 162 157 - national,lm99 158 + - nuvoton,nct7718 163 159 - nxp,sa56004 164 160 - winbond,w83l771 165 161 then:
+1 -1
Documentation/devicetree/bindings/hwmon/ntc-thermistor.yaml
··· 76 76 - const: murata,ncp03wf104 77 77 - const: murata,ncp15xh103 78 78 - const: samsung,1404-001221 79 - # Deprecated "ntp," compatible strings 79 + # Deprecated "ntc," compatible strings 80 80 - const: ntc,ncp15wb473 81 81 deprecated: true 82 82 - const: ntc,ncp18wb473
-1
Documentation/devicetree/bindings/hwmon/nuvoton,nct6775.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0-only OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - 5 4 $id: http://devicetree.org/schemas/hwmon/nuvoton,nct6775.yaml# 6 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 7 6
-1
Documentation/devicetree/bindings/hwmon/nuvoton,nct7363.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - 5 4 $id: http://devicetree.org/schemas/hwmon/nuvoton,nct7363.yaml# 6 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 7 6
-1
Documentation/devicetree/bindings/hwmon/nuvoton,nct7802.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - 5 4 $id: http://devicetree.org/schemas/hwmon/nuvoton,nct7802.yaml# 6 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 7 6
+9
Documentation/devicetree/bindings/hwmon/pmbus/ti,ucd90320.yaml
··· 28 28 reg: 29 29 maxItems: 1 30 30 31 + gpio-controller: true 32 + 33 + gpio-line-names: 34 + minItems: 84 35 + maxItems: 84 36 + 37 + '#gpio-cells': 38 + const: 1 39 + 31 40 required: 32 41 - compatible 33 42 - reg
-1
Documentation/devicetree/bindings/hwmon/ti,adc128d818.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - 5 4 $id: http://devicetree.org/schemas/hwmon/ti,adc128d818.yaml# 6 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 7 6
-1
Documentation/devicetree/bindings/hwmon/ti,ads7828.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - 5 4 $id: http://devicetree.org/schemas/hwmon/ti,ads7828.yaml# 6 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 7 6
+30 -1
Documentation/devicetree/bindings/hwmon/ti,ina2xx.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - 5 4 $id: http://devicetree.org/schemas/hwmon/ti,ina2xx.yaml# 6 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 7 6 ··· 26 27 - ti,ina226 27 28 - ti,ina230 28 29 - ti,ina231 30 + - ti,ina233 29 31 - ti,ina237 30 32 - ti,ina238 31 33 - ti,ina260 ··· 75 75 the alert polarity to active-high. 76 76 $ref: /schemas/types.yaml#/definitions/flag 77 77 78 + ti,maximum-expected-current-microamp: 79 + description: | 80 + This value indicates the maximum current in microamps that you can 81 + expect to measure with ina233 in your circuit. 82 + 83 + This value will be used to calculate the Current_LSB and current/power 84 + coefficient for the pmbus and to calibrate the IC. 85 + minimum: 32768 86 + maximum: 4294967295 87 + default: 32768000 88 + 78 89 required: 79 90 - compatible 80 91 - reg 81 92 82 93 allOf: 83 94 - $ref: hwmon-common.yaml# 95 + - if: 96 + properties: 97 + compatible: 98 + contains: 99 + enum: 100 + - silergy,sy24655 101 + - ti,ina209 102 + - ti,ina219 103 + - ti,ina220 104 + - ti,ina226 105 + - ti,ina230 106 + - ti,ina231 107 + - ti,ina237 108 + - ti,ina238 109 + - ti,ina260 110 + then: 111 + properties: 112 + ti,maximum-expected-current-microamp: false 84 113 85 114 unevaluatedProperties: false 86 115
-1
Documentation/devicetree/bindings/hwmon/ti,lm87.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - 5 4 $id: http://devicetree.org/schemas/hwmon/ti,lm87.yaml# 6 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 7 6
-1
Documentation/devicetree/bindings/hwmon/ti,tmp513.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - 5 4 $id: http://devicetree.org/schemas/hwmon/ti,tmp513.yaml# 6 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 7 6
-1
Documentation/devicetree/bindings/hwmon/ti,tps23861.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - 5 4 $id: http://devicetree.org/schemas/hwmon/ti,tps23861.yaml# 6 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 7 6
-1
Documentation/devicetree/bindings/hwmon/winbond,w83781d.yaml
··· 1 1 # SPDX-License-Identifier: (GPL-2.0 OR BSD-2-Clause) 2 2 %YAML 1.2 3 3 --- 4 - 5 4 $id: http://devicetree.org/schemas/hwmon/winbond,w83781d.yaml# 6 5 $schema: http://devicetree.org/meta-schemas/core.yaml# 7 6
+2
Documentation/devicetree/bindings/trivial-devices.yaml
··· 189 189 - mcube,mc3230 190 190 # Measurement Specialities I2C temperature and humidity sensor 191 191 - meas,htu21 192 + # Measurement Specialities I2C temperature and humidity sensor 193 + - meas,htu31 192 194 # Measurement Specialities I2C pressure and temperature sensor 193 195 - meas,ms5637 194 196 # Measurement Specialities I2C pressure and temperature sensor
+4 -4
Documentation/hwmon/abituguru-datasheet.rst
··· 6 6 datasheet from Abit. The data I have got on uGuru have I assembled through 7 7 my weak knowledge in "backwards engineering". 8 8 And just for the record, you may have noticed uGuru isn't a chip developed by 9 - Abit, as they claim it to be. It's really just an microprocessor (uC) created by 9 + Abit, as they claim it to be. It's really just a microprocessor (uC) created by 10 10 Winbond (W83L950D). And no, reading the manual for this specific uC or 11 - mailing Windbond for help won't give any useful data about uGuru, as it is 11 + mailing Winbond for help won't give any useful data about uGuru, as it is 12 12 the program inside the uC that is responding to calls. 13 13 14 14 Olle Sandberg <ollebull@gmail.com>, 2005-05-25 ··· 35 35 ports are holding for detection. We will refer to 0xE0 as CMD (command-port) 36 36 and 0xE4 as DATA because Abit refers to them with these names. 37 37 38 - If DATA holds 0x00 or 0x08 and CMD holds 0x00 or 0xAC an uGuru could be 38 + If DATA holds 0x00 or 0x08 and CMD holds 0x00 or 0xAC a uGuru could be 39 39 present. We have to check for two different values at data-port, because 40 40 after a reboot uGuru will hold 0x00 here, but if the driver is removed and 41 41 later on attached again data-port will hold 0x08, more about this later. ··· 46 46 hold 0x09 and will only hold 0x08 after reading CMD first, so CMD must be read 47 47 first! 48 48 49 - To be really sure an uGuru is present a test read of one or more register 49 + To be really sure a uGuru is present a test read of one or more register 50 50 sets should be done. 51 51 52 52
+1 -1
Documentation/hwmon/abituguru.rst
··· 40 40 41 41 .. [2] There is a separate abituguru3 driver for these motherboards, 42 42 the abituguru (without the 3 !) driver will not work on these 43 - motherboards (and visa versa)! 43 + motherboards (and vice versa)! 44 44 45 45 Authors: 46 46 - Hans de Goede <j.w.r.degoede@hhs.nl>,
+1
Documentation/hwmon/asus_ec_sensors.rst
··· 6 6 Supported boards: 7 7 * PRIME X470-PRO 8 8 * PRIME X570-PRO 9 + * PRIME X670E-PRO WIFI 9 10 * Pro WS X570-ACE 10 11 * ProArt X570-CREATOR WIFI 11 12 * ProArt X670E-CREATOR WIFI
+63
Documentation/hwmon/cgbc-hwmon.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + Kernel driver cgbc-hwmon 4 + ======================== 5 + 6 + Supported chips: 7 + 8 + * Congatec Board Controller. 9 + 10 + Prefix: 'cgbc-hwmon' 11 + 12 + Author: Thomas Richard <thomas.richard@bootlin.com> 13 + 14 + Description 15 + ----------- 16 + 17 + This driver enables monitoring support for the Congatec Board Controller. 18 + This controller is embedded on the x86 SoMs of Congatec. 19 + 20 + Sysfs entries 21 + ------------- 22 + 23 + The following sysfs entries list contains all sensors defined in the Board 24 + Controller. The available sensors in sysfs depend on the SoM and the 25 + system. 26 + 27 + ============= ====================== 28 + Name Description 29 + ============= ====================== 30 + temp1_input CPU temperature 31 + temp2_input Box temperature 32 + temp3_input Ambient temperature 33 + temp4_input Board temperature 34 + temp5_input Carrier temperature 35 + temp6_input Chipset temperature 36 + temp7_input Video temperature 37 + temp8_input Other temperature 38 + temp9_input TOPDIM temperature 39 + temp10_input BOTTOMDIM temperature 40 + in0_input CPU voltage 41 + in1_input DC Runtime voltage 42 + in2_input DC Standby voltage 43 + in3_input CMOS Battery voltage 44 + in4_input Battery voltage 45 + in5_input AC voltage 46 + in6_input Other voltage 47 + in7_input 5V voltage 48 + in8_input 5V Standby voltage 49 + in9_input 3V3 voltage 50 + in10_input 3V3 Standby voltage 51 + in11_input VCore A voltage 52 + in12_input VCore B voltage 53 + in13_input 12V voltage 54 + curr1_input DC current 55 + curr2_input 5V current 56 + curr3_input 12V current 57 + fan1_input CPU fan 58 + fan2_input Box fan 59 + fan3_input Ambient fan 60 + fan4_input Chiptset fan 61 + fan5_input Video fan 62 + fan6_input Other fan 63 + ============= ======================
+7 -7
Documentation/hwmon/dell-smm-hwmon.rst
··· 32 32 =============================== ======= ======================================= 33 33 Name Perm Description 34 34 =============================== ======= ======================================= 35 - fan[1-3]_input RO Fan speed in RPM. 36 - fan[1-3]_label RO Fan label. 37 - fan[1-3]_min RO Minimal Fan speed in RPM 38 - fan[1-3]_max RO Maximal Fan speed in RPM 39 - fan[1-3]_target RO Expected Fan speed in RPM 40 - pwm[1-3] RW Control the fan PWM duty-cycle. 35 + fan[1-4]_input RO Fan speed in RPM. 36 + fan[1-4]_label RO Fan label. 37 + fan[1-4]_min RO Minimal Fan speed in RPM 38 + fan[1-4]_max RO Maximal Fan speed in RPM 39 + fan[1-4]_target RO Expected Fan speed in RPM 40 + pwm[1-4] RW Control the fan PWM duty-cycle. 41 41 pwm1_enable WO Enable or disable automatic BIOS fan 42 42 control (not supported on all laptops, 43 43 see below for details). ··· 93 93 --------------------------- 94 94 95 95 The driver also exports the fans as thermal cooling devices with 96 - ``type`` set to ``dell-smm-fan[1-3]``. This allows for easy fan control 96 + ``type`` set to ``dell-smm-fan[1-4]``. This allows for easy fan control 97 97 using one of the thermal governors. 98 98 99 99 Module parameters
+37
Documentation/hwmon/htu31.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0-or-later 2 + 3 + Kernel driver HTU31 4 + ==================== 5 + 6 + Supported chips: 7 + 8 + * Measurement Specialties HTU31 9 + 10 + Prefix: 'htu31' 11 + 12 + Addresses scanned: - 13 + 14 + Datasheet: Publicly available from https://www.te.com/en/product-CAT-HSC0007.html 15 + 16 + Author: 17 + 18 + - Andrei Lalaev <andrey.lalaev@gmail.com> 19 + 20 + Description 21 + ----------- 22 + 23 + HTU31 is a humidity and temperature sensor. 24 + 25 + Supported temperature range is from -40 to 125 degrees Celsius. 26 + 27 + Communication with the device is performed via I2C protocol. Sensor's default address 28 + is 0x40. 29 + 30 + sysfs-Interface 31 + --------------- 32 + 33 + =================== ================= 34 + temp1_input: temperature input 35 + humidity1_input: humidity input 36 + heater_enable: heater control 37 + =================== =================
+75
Documentation/hwmon/ina233.rst
··· 1 + .. SPDX-License-Identifier: GPL-2.0 2 + 3 + Kernel driver ina233 4 + ==================== 5 + 6 + Supported chips: 7 + 8 + * TI INA233 9 + 10 + Prefix: 'ina233' 11 + 12 + * Datasheet 13 + 14 + Publicly available at the TI website : https://www.ti.com/lit/ds/symlink/ina233.pdf 15 + 16 + Author: Leo Yang <leo.yang.sy0@gmail.com> 17 + 18 + Usage Notes 19 + ----------- 20 + 21 + The shunt resistor value can be configured by a device tree property; 22 + see Documentation/devicetree/bindings/hwmon/ti,ina2xx.yaml for details. 23 + 24 + 25 + Description 26 + ----------- 27 + 28 + This driver supports hardware monitoring for TI INA233. 29 + 30 + The driver is a client driver to the core PMBus driver. Please see 31 + Documentation/hwmon/pmbus.rst for details on PMBus client drivers. 32 + 33 + The driver provides the following attributes for input voltage: 34 + 35 + **in1_input** 36 + 37 + **in1_label** 38 + 39 + **in1_max** 40 + 41 + **in1_max_alarm** 42 + 43 + **in1_min** 44 + 45 + **in1_min_alarm** 46 + 47 + The driver provides the following attributes for shunt voltage: 48 + 49 + **in2_input** 50 + 51 + **in2_label** 52 + 53 + The driver provides the following attributes for output voltage: 54 + 55 + **in3_input** 56 + 57 + **in3_label** 58 + 59 + **in3_alarm** 60 + 61 + The driver provides the following attributes for output current: 62 + 63 + **curr1_input** 64 + 65 + **curr1_label** 66 + 67 + **curr1_max** 68 + 69 + **curr1_max_alarm** 70 + 71 + The driver provides the following attributes for input power: 72 + 73 + **power1_input** 74 + 75 + **power1_label**
+3
Documentation/hwmon/index.rst
··· 53 53 bel-pfe 54 54 bpa-rs600 55 55 bt1-pvt 56 + cgbc-hwmon 56 57 chipcap2 57 58 coretemp 58 59 corsair-cpro ··· 86 85 hih6130 87 86 hp-wmi-sensors 88 87 hs3001 88 + htu31 89 89 ibmaem 90 90 ibm-cffps 91 91 ibmpowernv 92 92 ina209 93 93 ina2xx 94 + ina233 94 95 ina238 95 96 ina3221 96 97 inspur-ipsps1
+43
Documentation/hwmon/lm90.rst
··· 365 365 366 366 Datasheet: Not publicly available, can be requested from Nuvoton 367 367 368 + * Nuvoton NCT7716 369 + 370 + Prefix: 'nct7716' 371 + 372 + Addresses scanned: I2C 0x48, 0x49 373 + 374 + Datasheet: Not publicly available, can be requested from Nuvoton 375 + 376 + * Nuvoton NCT7717 377 + 378 + Prefix: 'nct7717' 379 + 380 + Addresses scanned: I2C 0x48 381 + 382 + Datasheet: Publicly available at Nuvoton website 383 + 384 + https://www.nuvoton.com/resource-files/Nuvoton_NCT7717U_Datasheet_V111.pdf 385 + 386 + * Nuvoton NCT7718 387 + 388 + Prefix: 'nct7718' 389 + 390 + Addresses scanned: I2C 0x4c 391 + 392 + Datasheet: Publicly available at Nuvoton website 393 + 394 + https://www.nuvoton.com/resource-files/Nuvoton_NCT7718W_Datasheet_V11.pdf 395 + 368 396 * Philips/NXP SA56004X 369 397 370 398 Prefix: 'sa56004' ··· 600 572 * Successor of the W83L771W/G, same features. 601 573 * The AWG and ASG variants only differ in package format. 602 574 * Diode ideality factor configuration (remote sensor) at 0xE3 575 + 576 + NCT7716: 577 + * 8 bit sensor resolution 578 + * Selectable address 579 + * Configurable conversion rate 580 + 581 + NCT7717: 582 + * 8 bit sensor resolution 583 + * Configurable conversion rate 584 + 585 + NCT7718: 586 + * Temperature offset register for remote temperature sensor 587 + * 11 bit resolution for remote temperature sensor 588 + * Low temperature limits 589 + * Configurable conversion rate 603 590 604 591 SA56004X: 605 592 * Better local resolution
+33 -3
Documentation/hwmon/ltc2978.rst
··· 5 5 6 6 Supported chips: 7 7 8 + * Analog Devices LT7170 9 + 10 + Prefix: 'lt7170' 11 + 12 + Addresses scanned: - 13 + 14 + Datasheet: https://www.analog.com/en/products/lt7170.html 15 + 16 + * Analog Devices LT7171 17 + 18 + Prefix: 'lt7171' 19 + 20 + Addresses scanned: - 21 + 22 + Datasheet: https://www.analog.com/en/products/lt7171.html 23 + 8 24 * Linear Technology LTC2972 9 25 10 26 Prefix: 'ltc2972' ··· 167 151 168 152 Datasheet: https://www.analog.com/en/products/ltm4644 169 153 154 + * Linear Technology LTM4673 155 + 156 + Prefix: 'ltm4673' 157 + 158 + Addresses scanned: - 159 + 160 + Datasheet: https://www.analog.com/en/products/ltm4673 161 + 170 162 * Linear Technology LTM4675 171 163 172 164 Prefix: 'ltm4675' ··· 239 215 Description 240 216 ----------- 241 217 218 + - LT7170 and LT7171 are 20 A, 16 V, single- or dual-phase Silent Switcher 219 + - step-down regulators with Digital Power System Management. 242 220 - LTC2974 and LTC2975 are quad digital power supply managers. 243 221 - LTC2978 is an octal power supply monitor. 244 222 - LTC2977 is a pin compatible replacement for LTC2978. ··· 318 292 319 293 in[N]_label "vout[1-8]". 320 294 295 + - LT7170, LT7171: N=2 321 296 - LTC2972: N=2-3 322 297 - LTC2974, LTC2975: N=2-5 323 298 - LTC2977, LTC2979, LTC2980, LTM2987: N=2-9 ··· 357 330 358 331 temp[N]_input Measured temperature. 359 332 333 + - On LT7170 and LT7171, temp1 reports the chip 334 + temperature. 360 335 - On LTC2972, temp[1-2] report external temperatures, 361 336 and temp 3 reports the chip temperature. 362 337 - On LTC2974 and LTC2975, temp[1-4] report external ··· 432 403 433 404 curr1_label "iin". 434 405 435 - LTC3880, LTC3883, LTC3884, LTC3886, LTC3887, LTC3889, 436 - LTM4644, LTM4675, LTM4676, LTM4677, LTM4678, LTM4680, 437 - and LTM4700 only. 406 + LT7170, LT7171, LTC3880, LTC3883, LTC3884, LTC3886, 407 + LTC3887, LTC3889, LTM4644, LTM4675, LTM4676, LTM4677, 408 + LTM4678, LTM4680, and LTM4700 only. 438 409 439 410 curr1_input Measured input current. 440 411 ··· 452 423 453 424 curr[N]_label "iout[1-4]". 454 425 426 + - LT7170, LT7171: N=1 455 427 - LTC2972: N-1-2 456 428 - LTC2974, LTC2975: N=1-4 457 429 - LTC2977, LTC2979, LTC2980, LTM2987: not supported
+2 -1
Documentation/hwmon/nct6683.rst
··· 3 3 4 4 Supported chips: 5 5 6 - * Nuvoton NCT6683D/NCT6687D 6 + * Nuvoton NCT6683D/NCT6686D/NCT6687D 7 7 8 8 Prefix: 'nct6683' 9 9 ··· 61 61 Intel DH87RL NCT6683D EC firmware version 1.0 build 04/03/13 62 62 Intel DH87MC NCT6683D EC firmware version 1.0 build 04/03/13 63 63 Intel DB85FL NCT6683D EC firmware version 1.0 build 04/03/13 64 + AMD BC-250 NCT6686D EC firmware version 1.0 build 07/28/21 64 65 ASRock X570 NCT6683D EC firmware version 1.0 build 06/28/19 65 66 ASRock X670E NCT6686D EC firmware version 1.0 build 05/19/22 66 67 ASRock B650 Steel Legend WiFi NCT6686D EC firmware version 1.0 build 11/09/23
+14
MAINTAINERS
··· 5878 5878 M: Thomas Richard <thomas.richard@bootlin.com> 5879 5879 S: Maintained 5880 5880 F: drivers/gpio/gpio-cgbc.c 5881 + F: drivers/hwmon/cgbc-hwmon.c 5881 5882 F: drivers/i2c/busses/i2c-cgbc.c 5882 5883 F: drivers/mfd/cgbc-core.c 5883 5884 F: drivers/watchdog/cgbc_wdt.c ··· 10730 10729 F: Documentation/devicetree/bindings/iio/humidity/st,hts221.yaml 10731 10730 F: drivers/iio/humidity/hts221* 10732 10731 10732 + HTU31 Hardware Temperature and Humidity Sensor 10733 + M: Andrei Lalaev <andrey.lalaev@gmail.com> 10734 + L: linux-hwmon@vger.kernel.org 10735 + S: Maintained 10736 + F: drivers/hwmon/htu31.c 10737 + 10733 10738 HUAWEI ETHERNET DRIVER 10734 10739 M: Cai Huoqing <cai.huoqing@linux.dev> 10735 10740 L: netdev@vger.kernel.org ··· 11376 11369 L: linux-fbdev@vger.kernel.org 11377 11370 S: Orphan 11378 11371 F: drivers/video/fbdev/imsttfb.c 11372 + 11373 + INA233 HARDWARE MONITOR DRIVERS 11374 + M: Leo Yang <leo.yang.sy0@gmail.com> 11375 + L: linux-hwmon@vger.kernel.org 11376 + S: Maintained 11377 + F: Documentation/hwmon/ina233.rst 11378 + F: drivers/hwmon/pmbus/ina233.c 11379 11379 11380 11380 INDEX OF FURTHER KERNEL DOCUMENTATION 11381 11381 M: Carlos Bilbao <carlos.bilbao@kernel.org>
+23 -2
drivers/hwmon/Kconfig
··· 463 463 the data conversion will be periodically performed and the data will be 464 464 saved in the internal driver cache. 465 465 466 + config SENSORS_CGBC 467 + tristate "Congatec Board Controller Sensors" 468 + depends on MFD_CGBC 469 + help 470 + Enable sensors support for the Congatec Board Controller. It has 471 + temperature, voltage, current and fan sensors. 472 + 473 + This driver can also be built as a module. If so, the module will be 474 + called cgbc-hwmon. 475 + 466 476 config SENSORS_CHIPCAP2 467 477 tristate "Amphenol ChipCap 2 relative humidity and temperature sensor" 468 478 depends on I2C ··· 798 788 799 789 This driver can also be built as a module. If so, the module 800 790 will be called hs3001. 791 + 792 + config SENSORS_HTU31 793 + tristate "Measurement Specialties HTU31 humidity and temperature sensor" 794 + depends on I2C 795 + select CRC8 796 + help 797 + If you say yes here you get support for the HTU31 humidity 798 + and temperature sensors. 799 + 800 + This driver can also be built as a module. If so, the module 801 + will be called htu31. 801 802 802 803 config SENSORS_IBMAEM 803 804 tristate "IBM Active Energy Manager temperature/power sensors and control" ··· 1540 1519 MAX6657, MAX6658, MAX6659, MAX6680, MAX6681, MAX6692, MAX6695, 1541 1520 MAX6696, 1542 1521 ON Semiconductor NCT1008, NCT210, NCT72, NCT214, NCT218, 1543 - Winbond/Nuvoton W83L771W/G/AWG/ASG, 1522 + Winbond/Nuvoton W83L771W/G/AWG/ASG, NCT7716, NCT7717 and NCT7718, 1544 1523 Philips NE1618, SA56004, GMT G781, Texas Instruments TMP451 and TMP461 1545 1524 sensor chips. 1546 1525 ··· 1646 1625 B57891S0103 from EPCOS. 1647 1626 1648 1627 This driver can also be built as a module. If so, the module 1649 - will be called ntc-thermistor. 1628 + will be called ntc_thermistor. 1650 1629 1651 1630 config SENSORS_NCT6683 1652 1631 tristate "Nuvoton NCT6683D"
+2
drivers/hwmon/Makefile
··· 59 59 obj-$(CONFIG_SENSORS_ATXP1) += atxp1.o 60 60 obj-$(CONFIG_SENSORS_AXI_FAN_CONTROL) += axi-fan-control.o 61 61 obj-$(CONFIG_SENSORS_BT1_PVT) += bt1-pvt.o 62 + obj-$(CONFIG_SENSORS_CGBC) += cgbc-hwmon.o 62 63 obj-$(CONFIG_SENSORS_CHIPCAP2) += chipcap2.o 63 64 obj-$(CONFIG_SENSORS_CORETEMP) += coretemp.o 64 65 obj-$(CONFIG_SENSORS_CORSAIR_CPRO) += corsair-cpro.o ··· 92 91 obj-$(CONFIG_SENSORS_GXP_FAN_CTRL) += gxp-fan-ctrl.o 93 92 obj-$(CONFIG_SENSORS_HIH6130) += hih6130.o 94 93 obj-$(CONFIG_SENSORS_HS3001) += hs3001.o 94 + obj-$(CONFIG_SENSORS_HTU31) += htu31.o 95 95 obj-$(CONFIG_SENSORS_ULTRA45) += ultra45_env.o 96 96 obj-$(CONFIG_SENSORS_I5500) += i5500_temp.o 97 97 obj-$(CONFIG_SENSORS_I5K_AMB) += i5k_amb.o
+429 -435
drivers/hwmon/acpi_power_meter.c
··· 87 87 bool power_alarm; 88 88 int sensors_valid; 89 89 unsigned long sensors_last_updated; 90 - struct sensor_device_attribute sensors[NUM_SENSORS]; 91 - int num_sensors; 90 + #define POWER_METER_TRIP_AVERAGE_MIN_IDX 0 91 + #define POWER_METER_TRIP_AVERAGE_MAX_IDX 1 92 92 s64 trip[2]; 93 93 int num_domain_devices; 94 94 struct acpi_device **domain_devices; 95 95 struct kobject *holders_dir; 96 - }; 97 - 98 - struct sensor_template { 99 - char *label; 100 - ssize_t (*show)(struct device *dev, 101 - struct device_attribute *devattr, 102 - char *buf); 103 - ssize_t (*set)(struct device *dev, 104 - struct device_attribute *devattr, 105 - const char *buf, size_t count); 106 - int index; 107 96 }; 108 97 109 98 /* Averaging interval */ ··· 113 124 return 0; 114 125 } 115 126 116 - static ssize_t show_avg_interval(struct device *dev, 117 - struct device_attribute *devattr, 118 - char *buf) 119 - { 120 - struct acpi_device *acpi_dev = to_acpi_device(dev); 121 - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 122 - 123 - mutex_lock(&resource->lock); 124 - update_avg_interval(resource); 125 - mutex_unlock(&resource->lock); 126 - 127 - return sprintf(buf, "%llu\n", resource->avg_interval); 128 - } 129 - 130 - static ssize_t set_avg_interval(struct device *dev, 131 - struct device_attribute *devattr, 132 - const char *buf, size_t count) 133 - { 134 - struct acpi_device *acpi_dev = to_acpi_device(dev); 135 - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 136 - union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 137 - struct acpi_object_list args = { 1, &arg0 }; 138 - int res; 139 - unsigned long temp; 140 - unsigned long long data; 141 - acpi_status status; 142 - 143 - res = kstrtoul(buf, 10, &temp); 144 - if (res) 145 - return res; 146 - 147 - if (temp > resource->caps.max_avg_interval || 148 - temp < resource->caps.min_avg_interval) 149 - return -EINVAL; 150 - arg0.integer.value = temp; 151 - 152 - mutex_lock(&resource->lock); 153 - status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PAI", 154 - &args, &data); 155 - if (ACPI_SUCCESS(status)) 156 - resource->avg_interval = temp; 157 - mutex_unlock(&resource->lock); 158 - 159 - if (ACPI_FAILURE(status)) { 160 - acpi_evaluation_failure_warn(resource->acpi_dev->handle, "_PAI", 161 - status); 162 - return -EINVAL; 163 - } 164 - 165 - /* _PAI returns 0 on success, nonzero otherwise */ 166 - if (data) 167 - return -EINVAL; 168 - 169 - return count; 170 - } 171 - 172 127 /* Cap functions */ 173 128 static int update_cap(struct acpi_power_meter_resource *resource) 174 129 { ··· 129 196 130 197 resource->cap = data; 131 198 return 0; 132 - } 133 - 134 - static ssize_t show_cap(struct device *dev, 135 - struct device_attribute *devattr, 136 - char *buf) 137 - { 138 - struct acpi_device *acpi_dev = to_acpi_device(dev); 139 - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 140 - 141 - mutex_lock(&resource->lock); 142 - update_cap(resource); 143 - mutex_unlock(&resource->lock); 144 - 145 - return sprintf(buf, "%llu\n", resource->cap * 1000); 146 - } 147 - 148 - static ssize_t set_cap(struct device *dev, struct device_attribute *devattr, 149 - const char *buf, size_t count) 150 - { 151 - struct acpi_device *acpi_dev = to_acpi_device(dev); 152 - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 153 - union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 154 - struct acpi_object_list args = { 1, &arg0 }; 155 - int res; 156 - unsigned long temp; 157 - unsigned long long data; 158 - acpi_status status; 159 - 160 - res = kstrtoul(buf, 10, &temp); 161 - if (res) 162 - return res; 163 - 164 - temp = DIV_ROUND_CLOSEST(temp, 1000); 165 - if (temp > resource->caps.max_cap || temp < resource->caps.min_cap) 166 - return -EINVAL; 167 - arg0.integer.value = temp; 168 - 169 - mutex_lock(&resource->lock); 170 - status = acpi_evaluate_integer(resource->acpi_dev->handle, "_SHL", 171 - &args, &data); 172 - if (ACPI_SUCCESS(status)) 173 - resource->cap = temp; 174 - mutex_unlock(&resource->lock); 175 - 176 - if (ACPI_FAILURE(status)) { 177 - acpi_evaluation_failure_warn(resource->acpi_dev->handle, "_SHL", 178 - status); 179 - return -EINVAL; 180 - } 181 - 182 - /* _SHL returns 0 on success, nonzero otherwise */ 183 - if (data) 184 - return -EINVAL; 185 - 186 - return count; 187 199 } 188 200 189 201 /* Power meter trip points */ ··· 165 287 return 0; 166 288 } 167 289 168 - static ssize_t set_trip(struct device *dev, struct device_attribute *devattr, 169 - const char *buf, size_t count) 170 - { 171 - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 172 - struct acpi_device *acpi_dev = to_acpi_device(dev); 173 - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 174 - unsigned long temp, trip_bk; 175 - int res; 176 - 177 - res = kstrtoul(buf, 10, &temp); 178 - if (res) 179 - return res; 180 - 181 - temp = DIV_ROUND_CLOSEST(temp, 1000); 182 - 183 - guard(mutex)(&resource->lock); 184 - 185 - trip_bk = resource->trip[attr->index - 7]; 186 - resource->trip[attr->index - 7] = temp; 187 - res = set_acpi_trip(resource); 188 - if (res) { 189 - resource->trip[attr->index - 7] = trip_bk; 190 - return res; 191 - } 192 - 193 - return count; 194 - } 195 - 196 290 /* Power meter */ 197 291 static int update_meter(struct acpi_power_meter_resource *resource) 198 292 { ··· 190 340 resource->sensors_last_updated = jiffies; 191 341 return 0; 192 342 } 193 - 194 - static ssize_t show_power(struct device *dev, 195 - struct device_attribute *devattr, 196 - char *buf) 197 - { 198 - struct acpi_device *acpi_dev = to_acpi_device(dev); 199 - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 200 - 201 - mutex_lock(&resource->lock); 202 - update_meter(resource); 203 - mutex_unlock(&resource->lock); 204 - 205 - if (resource->power == UNKNOWN_POWER) 206 - return -ENODATA; 207 - 208 - return sprintf(buf, "%llu\n", resource->power * 1000); 209 - } 210 - 211 - /* Miscellaneous */ 212 - static ssize_t show_str(struct device *dev, 213 - struct device_attribute *devattr, 214 - char *buf) 215 - { 216 - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 217 - struct acpi_device *acpi_dev = to_acpi_device(dev); 218 - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 219 - acpi_string val; 220 - int ret; 221 - 222 - mutex_lock(&resource->lock); 223 - switch (attr->index) { 224 - case 0: 225 - val = resource->model_number; 226 - break; 227 - case 1: 228 - val = resource->serial_number; 229 - break; 230 - case 2: 231 - val = resource->oem_info; 232 - break; 233 - default: 234 - WARN(1, "Implementation error: unexpected attribute index %d\n", 235 - attr->index); 236 - val = ""; 237 - break; 238 - } 239 - ret = sprintf(buf, "%s\n", val); 240 - mutex_unlock(&resource->lock); 241 - return ret; 242 - } 243 - 244 - static ssize_t show_val(struct device *dev, 245 - struct device_attribute *devattr, 246 - char *buf) 247 - { 248 - struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr); 249 - struct acpi_device *acpi_dev = to_acpi_device(dev); 250 - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 251 - u64 val = 0; 252 - int ret; 253 - 254 - guard(mutex)(&resource->lock); 255 - 256 - switch (attr->index) { 257 - case 0: 258 - val = resource->caps.min_avg_interval; 259 - break; 260 - case 1: 261 - val = resource->caps.max_avg_interval; 262 - break; 263 - case 2: 264 - val = resource->caps.min_cap * 1000; 265 - break; 266 - case 3: 267 - val = resource->caps.max_cap * 1000; 268 - break; 269 - case 4: 270 - if (resource->caps.hysteresis == UNKNOWN_HYSTERESIS) 271 - return sprintf(buf, "unknown\n"); 272 - 273 - val = resource->caps.hysteresis * 1000; 274 - break; 275 - case 5: 276 - if (resource->caps.flags & POWER_METER_IS_BATTERY) 277 - val = 1; 278 - else 279 - val = 0; 280 - break; 281 - case 6: 282 - ret = update_meter(resource); 283 - if (ret) 284 - return ret; 285 - /* need to update cap if not to support the notification. */ 286 - if (!(resource->caps.flags & POWER_METER_CAN_NOTIFY)) { 287 - ret = update_cap(resource); 288 - if (ret) 289 - return ret; 290 - } 291 - val = resource->power_alarm || resource->power > resource->cap; 292 - resource->power_alarm = resource->power > resource->cap; 293 - break; 294 - case 7: 295 - case 8: 296 - if (resource->trip[attr->index - 7] < 0) 297 - return sprintf(buf, "unknown\n"); 298 - 299 - val = resource->trip[attr->index - 7] * 1000; 300 - break; 301 - default: 302 - WARN(1, "Implementation error: unexpected attribute index %d\n", 303 - attr->index); 304 - break; 305 - } 306 - 307 - return sprintf(buf, "%llu\n", val); 308 - } 309 - 310 - static ssize_t show_accuracy(struct device *dev, 311 - struct device_attribute *devattr, 312 - char *buf) 313 - { 314 - struct acpi_device *acpi_dev = to_acpi_device(dev); 315 - struct acpi_power_meter_resource *resource = acpi_dev->driver_data; 316 - unsigned int acc = resource->caps.accuracy; 317 - 318 - return sprintf(buf, "%u.%u%%\n", acc / 1000, acc % 1000); 319 - } 320 - 321 - static ssize_t show_name(struct device *dev, 322 - struct device_attribute *devattr, 323 - char *buf) 324 - { 325 - return sprintf(buf, "%s\n", ACPI_POWER_METER_NAME); 326 - } 327 - 328 - #define RO_SENSOR_TEMPLATE(_label, _show, _index) \ 329 - { \ 330 - .label = _label, \ 331 - .show = _show, \ 332 - .index = _index, \ 333 - } 334 - 335 - #define RW_SENSOR_TEMPLATE(_label, _show, _set, _index) \ 336 - { \ 337 - .label = _label, \ 338 - .show = _show, \ 339 - .set = _set, \ 340 - .index = _index, \ 341 - } 342 - 343 - /* Sensor descriptions. If you add a sensor, update NUM_SENSORS above! */ 344 - static struct sensor_template meter_attrs[] = { 345 - RO_SENSOR_TEMPLATE(POWER_AVERAGE_NAME, show_power, 0), 346 - RO_SENSOR_TEMPLATE("power1_accuracy", show_accuracy, 0), 347 - RO_SENSOR_TEMPLATE("power1_average_interval_min", show_val, 0), 348 - RO_SENSOR_TEMPLATE("power1_average_interval_max", show_val, 1), 349 - RO_SENSOR_TEMPLATE("power1_is_battery", show_val, 5), 350 - RW_SENSOR_TEMPLATE(POWER_AVG_INTERVAL_NAME, show_avg_interval, 351 - set_avg_interval, 0), 352 - {}, 353 - }; 354 - 355 - static struct sensor_template misc_cap_attrs[] = { 356 - RO_SENSOR_TEMPLATE("power1_cap_min", show_val, 2), 357 - RO_SENSOR_TEMPLATE("power1_cap_max", show_val, 3), 358 - RO_SENSOR_TEMPLATE("power1_cap_hyst", show_val, 4), 359 - RO_SENSOR_TEMPLATE(POWER_ALARM_NAME, show_val, 6), 360 - {}, 361 - }; 362 - 363 - static struct sensor_template ro_cap_attrs[] = { 364 - RO_SENSOR_TEMPLATE(POWER_CAP_NAME, show_cap, 0), 365 - {}, 366 - }; 367 - 368 - static struct sensor_template rw_cap_attrs[] = { 369 - RW_SENSOR_TEMPLATE(POWER_CAP_NAME, show_cap, set_cap, 0), 370 - {}, 371 - }; 372 - 373 - static struct sensor_template trip_attrs[] = { 374 - RW_SENSOR_TEMPLATE("power1_average_min", show_val, set_trip, 7), 375 - RW_SENSOR_TEMPLATE("power1_average_max", show_val, set_trip, 8), 376 - {}, 377 - }; 378 - 379 - static struct sensor_template misc_attrs[] = { 380 - RO_SENSOR_TEMPLATE("name", show_name, 0), 381 - RO_SENSOR_TEMPLATE("power1_model_number", show_str, 0), 382 - RO_SENSOR_TEMPLATE("power1_oem_info", show_str, 2), 383 - RO_SENSOR_TEMPLATE("power1_serial_number", show_str, 1), 384 - {}, 385 - }; 386 - 387 - #undef RO_SENSOR_TEMPLATE 388 - #undef RW_SENSOR_TEMPLATE 389 343 390 344 /* Read power domain data */ 391 345 static void remove_domain_devices(struct acpi_power_meter_resource *resource) ··· 292 638 return res; 293 639 } 294 640 295 - /* Registration and deregistration */ 296 - static int register_attrs(struct acpi_power_meter_resource *resource, 297 - struct sensor_template *attrs) 641 + static int set_trip(struct acpi_power_meter_resource *resource, u16 trip_idx, 642 + unsigned long trip) 298 643 { 299 - struct device *dev = &resource->acpi_dev->dev; 300 - struct sensor_device_attribute *sensors = 301 - &resource->sensors[resource->num_sensors]; 302 - int res = 0; 644 + unsigned long trip_bk; 645 + int ret; 303 646 304 - while (attrs->label) { 305 - sensors->dev_attr.attr.name = attrs->label; 306 - sensors->dev_attr.attr.mode = 0444; 307 - sensors->dev_attr.show = attrs->show; 308 - sensors->index = attrs->index; 647 + trip = DIV_ROUND_CLOSEST(trip, 1000); 648 + trip_bk = resource->trip[trip_idx]; 309 649 310 - if (attrs->set) { 311 - sensors->dev_attr.attr.mode |= 0200; 312 - sensors->dev_attr.store = attrs->set; 313 - } 314 - 315 - sysfs_attr_init(&sensors->dev_attr.attr); 316 - res = device_create_file(dev, &sensors->dev_attr); 317 - if (res) { 318 - sensors->dev_attr.attr.name = NULL; 319 - goto error; 320 - } 321 - sensors++; 322 - resource->num_sensors++; 323 - attrs++; 650 + resource->trip[trip_idx] = trip; 651 + ret = set_acpi_trip(resource); 652 + if (ret) { 653 + dev_err(&resource->acpi_dev->dev, "set %s failed.\n", 654 + (trip_idx == POWER_METER_TRIP_AVERAGE_MIN_IDX) ? 655 + "power1_average_min" : "power1_average_max"); 656 + resource->trip[trip_idx] = trip_bk; 324 657 } 325 658 326 - error: 327 - return res; 659 + return ret; 328 660 } 329 661 330 - static void remove_attrs(struct acpi_power_meter_resource *resource) 662 + static int set_cap(struct acpi_power_meter_resource *resource, 663 + unsigned long cap) 331 664 { 332 - int i; 665 + union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 666 + struct acpi_object_list args = { 1, &arg0 }; 667 + unsigned long long data; 668 + acpi_status status; 333 669 334 - for (i = 0; i < resource->num_sensors; i++) { 335 - if (!resource->sensors[i].dev_attr.attr.name) 336 - continue; 337 - device_remove_file(&resource->acpi_dev->dev, 338 - &resource->sensors[i].dev_attr); 670 + cap = DIV_ROUND_CLOSEST(cap, 1000); 671 + if (cap > resource->caps.max_cap || cap < resource->caps.min_cap) 672 + return -EINVAL; 673 + 674 + arg0.integer.value = cap; 675 + status = acpi_evaluate_integer(resource->acpi_dev->handle, "_SHL", 676 + &args, &data); 677 + if (ACPI_FAILURE(status)) { 678 + acpi_evaluation_failure_warn(resource->acpi_dev->handle, "_SHL", 679 + status); 680 + return -EINVAL; 339 681 } 682 + resource->cap = cap; 340 683 341 - remove_domain_devices(resource); 684 + /* _SHL returns 0 on success, nonzero otherwise */ 685 + if (data) 686 + return -EINVAL; 342 687 343 - resource->num_sensors = 0; 688 + return 0; 344 689 } 345 690 346 - static int setup_attrs(struct acpi_power_meter_resource *resource) 691 + static int set_avg_interval(struct acpi_power_meter_resource *resource, 692 + unsigned long val) 347 693 { 348 - int res = 0; 694 + union acpi_object arg0 = { ACPI_TYPE_INTEGER }; 695 + struct acpi_object_list args = { 1, &arg0 }; 696 + unsigned long long data; 697 + acpi_status status; 349 698 350 - /* _PMD method is optional. */ 351 - res = read_domain_devices(resource); 352 - if (res && res != -ENODEV) 353 - return res; 699 + if (val > resource->caps.max_avg_interval || 700 + val < resource->caps.min_avg_interval) 701 + return -EINVAL; 354 702 355 - if (resource->caps.flags & POWER_METER_CAN_MEASURE) { 356 - res = register_attrs(resource, meter_attrs); 357 - if (res) 358 - goto error; 703 + arg0.integer.value = val; 704 + status = acpi_evaluate_integer(resource->acpi_dev->handle, "_PAI", 705 + &args, &data); 706 + if (ACPI_FAILURE(status)) { 707 + acpi_evaluation_failure_warn(resource->acpi_dev->handle, "_PAI", 708 + status); 709 + return -EINVAL; 710 + } 711 + resource->avg_interval = val; 712 + 713 + /* _PAI returns 0 on success, nonzero otherwise */ 714 + if (data) 715 + return -EINVAL; 716 + 717 + return 0; 718 + } 719 + 720 + static int get_power_alarm_state(struct acpi_power_meter_resource *resource, 721 + long *val) 722 + { 723 + int ret; 724 + 725 + ret = update_meter(resource); 726 + if (ret) 727 + return ret; 728 + 729 + /* need to update cap if not to support the notification. */ 730 + if (!(resource->caps.flags & POWER_METER_CAN_NOTIFY)) { 731 + ret = update_cap(resource); 732 + if (ret) 733 + return ret; 734 + resource->power_alarm = resource->power > resource->cap; 735 + *val = resource->power_alarm; 736 + } else { 737 + *val = resource->power_alarm || resource->power > resource->cap; 738 + resource->power_alarm = resource->power > resource->cap; 359 739 } 360 740 361 - if (resource->caps.flags & POWER_METER_CAN_CAP) { 362 - if (!can_cap_in_hardware()) { 363 - dev_warn(&resource->acpi_dev->dev, 741 + return 0; 742 + } 743 + 744 + static umode_t power_meter_is_visible(const void *data, 745 + enum hwmon_sensor_types type, 746 + u32 attr, int channel) 747 + { 748 + const struct acpi_power_meter_resource *res = data; 749 + 750 + if (type != hwmon_power) 751 + return 0; 752 + 753 + switch (attr) { 754 + case hwmon_power_average: 755 + case hwmon_power_average_interval_min: 756 + case hwmon_power_average_interval_max: 757 + if (res->caps.flags & POWER_METER_CAN_MEASURE) 758 + return 0444; 759 + break; 760 + case hwmon_power_average_interval: 761 + if (res->caps.flags & POWER_METER_CAN_MEASURE) 762 + return 0644; 763 + break; 764 + case hwmon_power_cap_min: 765 + case hwmon_power_cap_max: 766 + case hwmon_power_alarm: 767 + if (res->caps.flags & POWER_METER_CAN_CAP && can_cap_in_hardware()) 768 + return 0444; 769 + break; 770 + case hwmon_power_cap: 771 + if (res->caps.flags & POWER_METER_CAN_CAP && can_cap_in_hardware()) { 772 + if (res->caps.configurable_cap) 773 + return 0644; 774 + else 775 + return 0444; 776 + } 777 + break; 778 + default: 779 + break; 780 + } 781 + 782 + return 0; 783 + } 784 + 785 + static int power_meter_read(struct device *dev, enum hwmon_sensor_types type, 786 + u32 attr, int channel, long *val) 787 + { 788 + struct acpi_power_meter_resource *res = dev_get_drvdata(dev); 789 + int ret = 0; 790 + 791 + if (type != hwmon_power) 792 + return -EINVAL; 793 + 794 + guard(mutex)(&res->lock); 795 + 796 + switch (attr) { 797 + case hwmon_power_average: 798 + ret = update_meter(res); 799 + if (ret) 800 + return ret; 801 + if (res->power == UNKNOWN_POWER) 802 + return -ENODATA; 803 + *val = res->power * 1000; 804 + break; 805 + case hwmon_power_average_interval_min: 806 + *val = res->caps.min_avg_interval; 807 + break; 808 + case hwmon_power_average_interval_max: 809 + *val = res->caps.max_avg_interval; 810 + break; 811 + case hwmon_power_average_interval: 812 + ret = update_avg_interval(res); 813 + if (ret) 814 + return ret; 815 + *val = (res)->avg_interval; 816 + break; 817 + case hwmon_power_cap_min: 818 + *val = res->caps.min_cap * 1000; 819 + break; 820 + case hwmon_power_cap_max: 821 + *val = res->caps.max_cap * 1000; 822 + break; 823 + case hwmon_power_alarm: 824 + ret = get_power_alarm_state(res, val); 825 + if (ret) 826 + return ret; 827 + break; 828 + case hwmon_power_cap: 829 + ret = update_cap(res); 830 + if (ret) 831 + return ret; 832 + *val = res->cap * 1000; 833 + break; 834 + default: 835 + break; 836 + } 837 + 838 + return 0; 839 + } 840 + 841 + static int power_meter_write(struct device *dev, enum hwmon_sensor_types type, 842 + u32 attr, int channel, long val) 843 + { 844 + struct acpi_power_meter_resource *res = dev_get_drvdata(dev); 845 + int ret; 846 + 847 + if (type != hwmon_power) 848 + return -EINVAL; 849 + 850 + guard(mutex)(&res->lock); 851 + switch (attr) { 852 + case hwmon_power_cap: 853 + ret = set_cap(res, val); 854 + break; 855 + case hwmon_power_average_interval: 856 + ret = set_avg_interval(res, val); 857 + break; 858 + default: 859 + ret = -EOPNOTSUPP; 860 + } 861 + 862 + return ret; 863 + } 864 + 865 + static const struct hwmon_channel_info * const power_meter_info[] = { 866 + HWMON_CHANNEL_INFO(power, HWMON_P_AVERAGE | 867 + HWMON_P_AVERAGE_INTERVAL | HWMON_P_AVERAGE_INTERVAL_MIN | 868 + HWMON_P_AVERAGE_INTERVAL_MAX | HWMON_P_CAP | HWMON_P_CAP_MIN | 869 + HWMON_P_CAP_MAX | HWMON_P_ALARM), 870 + NULL 871 + }; 872 + 873 + static const struct hwmon_ops power_meter_ops = { 874 + .is_visible = power_meter_is_visible, 875 + .read = power_meter_read, 876 + .write = power_meter_write, 877 + }; 878 + 879 + static const struct hwmon_chip_info power_meter_chip_info = { 880 + .ops = &power_meter_ops, 881 + .info = power_meter_info, 882 + }; 883 + 884 + static ssize_t power1_average_max_store(struct device *dev, 885 + struct device_attribute *attr, 886 + const char *buf, size_t count) 887 + { 888 + struct acpi_power_meter_resource *res = dev_get_drvdata(dev); 889 + unsigned long trip; 890 + int ret; 891 + 892 + ret = kstrtoul(buf, 10, &trip); 893 + if (ret) 894 + return ret; 895 + 896 + mutex_lock(&res->lock); 897 + ret = set_trip(res, POWER_METER_TRIP_AVERAGE_MAX_IDX, trip); 898 + mutex_unlock(&res->lock); 899 + 900 + return ret == 0 ? count : ret; 901 + } 902 + 903 + static ssize_t power1_average_min_store(struct device *dev, 904 + struct device_attribute *attr, 905 + const char *buf, size_t count) 906 + { 907 + struct acpi_power_meter_resource *res = dev_get_drvdata(dev); 908 + unsigned long trip; 909 + int ret; 910 + 911 + ret = kstrtoul(buf, 10, &trip); 912 + if (ret) 913 + return ret; 914 + 915 + mutex_lock(&res->lock); 916 + ret = set_trip(res, POWER_METER_TRIP_AVERAGE_MIN_IDX, trip); 917 + mutex_unlock(&res->lock); 918 + 919 + return ret == 0 ? count : ret; 920 + } 921 + 922 + static ssize_t power1_average_min_show(struct device *dev, 923 + struct device_attribute *attr, char *buf) 924 + { 925 + struct acpi_power_meter_resource *res = dev_get_drvdata(dev); 926 + 927 + if (res->trip[POWER_METER_TRIP_AVERAGE_MIN_IDX] < 0) 928 + return sysfs_emit(buf, "unknown\n"); 929 + 930 + return sysfs_emit(buf, "%lld\n", 931 + res->trip[POWER_METER_TRIP_AVERAGE_MIN_IDX] * 1000); 932 + } 933 + 934 + static ssize_t power1_average_max_show(struct device *dev, 935 + struct device_attribute *attr, char *buf) 936 + { 937 + struct acpi_power_meter_resource *res = dev_get_drvdata(dev); 938 + 939 + if (res->trip[POWER_METER_TRIP_AVERAGE_MAX_IDX] < 0) 940 + return sysfs_emit(buf, "unknown\n"); 941 + 942 + return sysfs_emit(buf, "%lld\n", 943 + res->trip[POWER_METER_TRIP_AVERAGE_MAX_IDX] * 1000); 944 + } 945 + 946 + static ssize_t power1_cap_hyst_show(struct device *dev, 947 + struct device_attribute *attr, char *buf) 948 + { 949 + struct acpi_power_meter_resource *res = dev_get_drvdata(dev); 950 + 951 + if (res->caps.hysteresis == UNKNOWN_HYSTERESIS) 952 + return sysfs_emit(buf, "unknown\n"); 953 + 954 + return sysfs_emit(buf, "%llu\n", res->caps.hysteresis * 1000); 955 + } 956 + 957 + static ssize_t power1_accuracy_show(struct device *dev, 958 + struct device_attribute *attr, 959 + char *buf) 960 + { 961 + struct acpi_power_meter_resource *res = dev_get_drvdata(dev); 962 + unsigned int acc = res->caps.accuracy; 963 + 964 + return sysfs_emit(buf, "%u.%u%%\n", acc / 1000, acc % 1000); 965 + } 966 + 967 + static ssize_t power1_is_battery_show(struct device *dev, 968 + struct device_attribute *attr, 969 + char *buf) 970 + { 971 + struct acpi_power_meter_resource *res = dev_get_drvdata(dev); 972 + 973 + return sysfs_emit(buf, "%u\n", 974 + res->caps.flags & POWER_METER_IS_BATTERY ? 1 : 0); 975 + } 976 + 977 + static ssize_t power1_model_number_show(struct device *dev, 978 + struct device_attribute *attr, 979 + char *buf) 980 + { 981 + struct acpi_power_meter_resource *res = dev_get_drvdata(dev); 982 + 983 + return sysfs_emit(buf, "%s\n", res->model_number); 984 + } 985 + 986 + static ssize_t power1_oem_info_show(struct device *dev, 987 + struct device_attribute *attr, 988 + char *buf) 989 + { 990 + struct acpi_power_meter_resource *res = dev_get_drvdata(dev); 991 + 992 + return sysfs_emit(buf, "%s\n", res->oem_info); 993 + } 994 + 995 + static ssize_t power1_serial_number_show(struct device *dev, 996 + struct device_attribute *attr, 997 + char *buf) 998 + { 999 + struct acpi_power_meter_resource *res = dev_get_drvdata(dev); 1000 + 1001 + return sysfs_emit(buf, "%s\n", res->serial_number); 1002 + } 1003 + 1004 + /* depend on POWER_METER_CAN_TRIP */ 1005 + static DEVICE_ATTR_RW(power1_average_max); 1006 + static DEVICE_ATTR_RW(power1_average_min); 1007 + 1008 + /* depend on POWER_METER_CAN_CAP */ 1009 + static DEVICE_ATTR_RO(power1_cap_hyst); 1010 + 1011 + /* depend on POWER_METER_CAN_MEASURE */ 1012 + static DEVICE_ATTR_RO(power1_accuracy); 1013 + static DEVICE_ATTR_RO(power1_is_battery); 1014 + 1015 + static DEVICE_ATTR_RO(power1_model_number); 1016 + static DEVICE_ATTR_RO(power1_oem_info); 1017 + static DEVICE_ATTR_RO(power1_serial_number); 1018 + 1019 + static umode_t power_extra_is_visible(struct kobject *kobj, 1020 + struct attribute *attr, int idx) 1021 + { 1022 + struct device *dev = kobj_to_dev(kobj); 1023 + struct acpi_power_meter_resource *res = dev_get_drvdata(dev); 1024 + 1025 + if (attr == &dev_attr_power1_is_battery.attr || 1026 + attr == &dev_attr_power1_accuracy.attr) { 1027 + if ((res->caps.flags & POWER_METER_CAN_MEASURE) == 0) 1028 + return 0; 1029 + } 1030 + 1031 + if (attr == &dev_attr_power1_cap_hyst.attr) { 1032 + if ((res->caps.flags & POWER_METER_CAN_CAP) == 0) { 1033 + return 0; 1034 + } else if (!can_cap_in_hardware()) { 1035 + dev_warn(&res->acpi_dev->dev, 364 1036 "Ignoring unsafe software power cap!\n"); 365 - goto skip_unsafe_cap; 1037 + return 0; 366 1038 } 367 - 368 - if (resource->caps.configurable_cap) 369 - res = register_attrs(resource, rw_cap_attrs); 370 - else 371 - res = register_attrs(resource, ro_cap_attrs); 372 - 373 - if (res) 374 - goto error; 375 - 376 - res = register_attrs(resource, misc_cap_attrs); 377 - if (res) 378 - goto error; 379 1039 } 380 1040 381 - skip_unsafe_cap: 382 - if (resource->caps.flags & POWER_METER_CAN_TRIP) { 383 - res = register_attrs(resource, trip_attrs); 384 - if (res) 385 - goto error; 1041 + if (attr == &dev_attr_power1_average_max.attr || 1042 + attr == &dev_attr_power1_average_min.attr) { 1043 + if ((res->caps.flags & POWER_METER_CAN_TRIP) == 0) 1044 + return 0; 386 1045 } 387 1046 388 - res = register_attrs(resource, misc_attrs); 389 - if (res) 390 - goto error; 391 - 392 - return res; 393 - error: 394 - remove_attrs(resource); 395 - return res; 1047 + return attr->mode; 396 1048 } 1049 + 1050 + static struct attribute *power_extra_attrs[] = { 1051 + &dev_attr_power1_average_max.attr, 1052 + &dev_attr_power1_average_min.attr, 1053 + &dev_attr_power1_cap_hyst.attr, 1054 + &dev_attr_power1_accuracy.attr, 1055 + &dev_attr_power1_is_battery.attr, 1056 + &dev_attr_power1_model_number.attr, 1057 + &dev_attr_power1_oem_info.attr, 1058 + &dev_attr_power1_serial_number.attr, 1059 + NULL 1060 + }; 1061 + 1062 + static const struct attribute_group power_extra_group = { 1063 + .attrs = power_extra_attrs, 1064 + .is_visible = power_extra_is_visible, 1065 + }; 1066 + 1067 + __ATTRIBUTE_GROUPS(power_extra); 397 1068 398 1069 static void free_capabilities(struct acpi_power_meter_resource *resource) 399 1070 { ··· 827 848 case METER_NOTIFY_CONFIG: 828 849 mutex_lock(&resource->lock); 829 850 free_capabilities(resource); 851 + remove_domain_devices(resource); 852 + hwmon_device_unregister(resource->hwmon_dev); 830 853 res = read_capabilities(resource); 831 - mutex_unlock(&resource->lock); 832 854 if (res) 833 - break; 834 - 835 - remove_attrs(resource); 836 - setup_attrs(resource); 855 + dev_err_once(&device->dev, "read capabilities failed.\n"); 856 + res = read_domain_devices(resource); 857 + if (res && res != -ENODEV) 858 + dev_err_once(&device->dev, "read domain devices failed.\n"); 859 + resource->hwmon_dev = 860 + hwmon_device_register_with_info(&device->dev, 861 + ACPI_POWER_METER_NAME, 862 + resource, 863 + &power_meter_chip_info, 864 + power_extra_groups); 865 + if (IS_ERR(resource->hwmon_dev)) 866 + dev_err_once(&device->dev, "register hwmon device failed.\n"); 867 + mutex_unlock(&resource->lock); 837 868 break; 838 869 case METER_NOTIFY_TRIP: 839 870 sysfs_notify(&device->dev.kobj, NULL, POWER_AVERAGE_NAME); ··· 905 916 struct acpi_device *ipi_device = acpi_dev_get_first_match_dev("IPI0001", NULL, -1); 906 917 907 918 if (ipi_device && acpi_wait_for_acpi_ipmi()) 908 - dev_warn(&device->dev, "Waiting for ACPI IPMI timeout"); 919 + dev_warn(&device->dev, "Waiting for ACPI IPMI timeout"); 909 920 acpi_dev_put(ipi_device); 910 921 } 911 922 #endif ··· 917 928 resource->trip[0] = -1; 918 929 resource->trip[1] = -1; 919 930 920 - res = setup_attrs(resource); 921 - if (res) 931 + /* _PMD method is optional. */ 932 + res = read_domain_devices(resource); 933 + if (res && res != -ENODEV) 922 934 goto exit_free_capability; 923 935 924 - resource->hwmon_dev = hwmon_device_register(&device->dev); 936 + resource->hwmon_dev = 937 + hwmon_device_register_with_info(&device->dev, 938 + ACPI_POWER_METER_NAME, resource, 939 + &power_meter_chip_info, 940 + power_extra_groups); 925 941 if (IS_ERR(resource->hwmon_dev)) { 926 942 res = PTR_ERR(resource->hwmon_dev); 927 943 goto exit_remove; ··· 936 942 goto exit; 937 943 938 944 exit_remove: 939 - remove_attrs(resource); 945 + remove_domain_devices(resource); 940 946 exit_free_capability: 941 947 free_capabilities(resource); 942 948 exit_free: ··· 955 961 resource = acpi_driver_data(device); 956 962 hwmon_device_unregister(resource->hwmon_dev); 957 963 958 - remove_attrs(resource); 964 + remove_domain_devices(resource); 959 965 free_capabilities(resource); 960 966 961 967 kfree(resource);
+10
drivers/hwmon/asus-ec-sensors.c
··· 316 316 .family = family_amd_500_series, 317 317 }; 318 318 319 + static const struct ec_board_info board_info_prime_x670e_pro_wifi = { 320 + .sensors = SENSOR_TEMP_CPU | SENSOR_TEMP_CPU_PACKAGE | 321 + SENSOR_TEMP_MB | SENSOR_TEMP_VRM | 322 + SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT, 323 + .mutex_path = ACPI_GLOBAL_LOCK_PSEUDO_PATH, 324 + .family = family_amd_600_series, 325 + }; 326 + 319 327 static const struct ec_board_info board_info_pro_art_x570_creator_wifi = { 320 328 .sensors = SENSOR_SET_TEMP_CHIPSET_CPU_MB | SENSOR_TEMP_VRM | 321 329 SENSOR_TEMP_T_SENSOR | SENSOR_FAN_CPU_OPT | ··· 511 503 &board_info_prime_x470_pro), 512 504 DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X570-PRO", 513 505 &board_info_prime_x570_pro), 506 + DMI_EXACT_MATCH_ASUS_BOARD_NAME("PRIME X670E-PRO WIFI", 507 + &board_info_prime_x670e_pro_wifi), 514 508 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt X570-CREATOR WIFI", 515 509 &board_info_pro_art_x570_creator_wifi), 516 510 DMI_EXACT_MATCH_ASUS_BOARD_NAME("ProArt X670E-CREATOR WIFI",
+304
drivers/hwmon/cgbc-hwmon.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * cgbc-hwmon - Congatec Board Controller hardware monitoring driver 4 + * 5 + * Copyright (C) 2024 Thomas Richard <thomas.richard@bootlin.com> 6 + */ 7 + 8 + #include <linux/bitfield.h> 9 + #include <linux/device.h> 10 + #include <linux/hwmon.h> 11 + #include <linux/mfd/cgbc.h> 12 + #include <linux/module.h> 13 + #include <linux/platform_device.h> 14 + 15 + #define CGBC_HWMON_CMD_SENSOR 0x77 16 + #define CGBC_HWMON_CMD_SENSOR_DATA_SIZE 0x05 17 + 18 + #define CGBC_HWMON_TYPE_MASK GENMASK(6, 5) 19 + #define CGBC_HWMON_ID_MASK GENMASK(4, 0) 20 + #define CGBC_HWMON_ACTIVE_BIT BIT(7) 21 + 22 + struct cgbc_hwmon_sensor { 23 + enum hwmon_sensor_types type; 24 + bool active; 25 + unsigned int index; 26 + unsigned int channel; 27 + const char *label; 28 + }; 29 + 30 + struct cgbc_hwmon_data { 31 + struct cgbc_device_data *cgbc; 32 + unsigned int nb_sensors; 33 + struct cgbc_hwmon_sensor *sensors; 34 + }; 35 + 36 + enum cgbc_sensor_types { 37 + CGBC_HWMON_TYPE_TEMP = 1, 38 + CGBC_HWMON_TYPE_IN, 39 + CGBC_HWMON_TYPE_FAN 40 + }; 41 + 42 + static const char * const cgbc_hwmon_labels_temp[] = { 43 + "CPU Temperature", 44 + "Box Temperature", 45 + "Ambient Temperature", 46 + "Board Temperature", 47 + "Carrier Temperature", 48 + "Chipset Temperature", 49 + "Video Temperature", 50 + "Other Temperature", 51 + "TOPDIM Temperature", 52 + "BOTTOMDIM Temperature", 53 + }; 54 + 55 + static const struct { 56 + enum hwmon_sensor_types type; 57 + const char *label; 58 + } cgbc_hwmon_labels_in[] = { 59 + { hwmon_in, "CPU Voltage" }, 60 + { hwmon_in, "DC Runtime Voltage" }, 61 + { hwmon_in, "DC Standby Voltage" }, 62 + { hwmon_in, "CMOS Battery Voltage" }, 63 + { hwmon_in, "Battery Voltage" }, 64 + { hwmon_in, "AC Voltage" }, 65 + { hwmon_in, "Other Voltage" }, 66 + { hwmon_in, "5V Voltage" }, 67 + { hwmon_in, "5V Standby Voltage" }, 68 + { hwmon_in, "3V3 Voltage" }, 69 + { hwmon_in, "3V3 Standby Voltage" }, 70 + { hwmon_in, "VCore A Voltage" }, 71 + { hwmon_in, "VCore B Voltage" }, 72 + { hwmon_in, "12V Voltage" }, 73 + { hwmon_curr, "DC Current" }, 74 + { hwmon_curr, "5V Current" }, 75 + { hwmon_curr, "12V Current" }, 76 + }; 77 + 78 + #define CGBC_HWMON_NB_IN_SENSORS 14 79 + 80 + static const char * const cgbc_hwmon_labels_fan[] = { 81 + "CPU Fan", 82 + "Box Fan", 83 + "Ambient Fan", 84 + "Chipset Fan", 85 + "Video Fan", 86 + "Other Fan", 87 + }; 88 + 89 + static int cgbc_hwmon_cmd(struct cgbc_device_data *cgbc, u8 index, u8 *data) 90 + { 91 + u8 cmd[2] = {CGBC_HWMON_CMD_SENSOR, index}; 92 + 93 + return cgbc_command(cgbc, cmd, sizeof(cmd), data, CGBC_HWMON_CMD_SENSOR_DATA_SIZE, NULL); 94 + } 95 + 96 + static int cgbc_hwmon_probe_sensors(struct device *dev, struct cgbc_hwmon_data *hwmon) 97 + { 98 + struct cgbc_device_data *cgbc = hwmon->cgbc; 99 + struct cgbc_hwmon_sensor *sensor = hwmon->sensors; 100 + u8 data[CGBC_HWMON_CMD_SENSOR_DATA_SIZE], nb_sensors, i; 101 + int ret; 102 + 103 + ret = cgbc_hwmon_cmd(cgbc, 0, &data[0]); 104 + if (ret) 105 + return ret; 106 + 107 + nb_sensors = data[0]; 108 + 109 + hwmon->sensors = devm_kzalloc(dev, sizeof(*hwmon->sensors) * nb_sensors, GFP_KERNEL); 110 + sensor = hwmon->sensors; 111 + 112 + for (i = 0; i < nb_sensors; i++) { 113 + enum cgbc_sensor_types type; 114 + unsigned int channel; 115 + 116 + /* 117 + * No need to request data for the first sensor. 118 + * We got data for the first sensor when we ask the number of sensors to the Board 119 + * Controller. 120 + */ 121 + if (i) { 122 + ret = cgbc_hwmon_cmd(cgbc, i, &data[0]); 123 + if (ret) 124 + return ret; 125 + } 126 + 127 + type = FIELD_GET(CGBC_HWMON_TYPE_MASK, data[1]); 128 + channel = FIELD_GET(CGBC_HWMON_ID_MASK, data[1]) - 1; 129 + 130 + if (type == CGBC_HWMON_TYPE_TEMP && channel < ARRAY_SIZE(cgbc_hwmon_labels_temp)) { 131 + sensor->type = hwmon_temp; 132 + sensor->label = cgbc_hwmon_labels_temp[channel]; 133 + } else if (type == CGBC_HWMON_TYPE_IN && 134 + channel < ARRAY_SIZE(cgbc_hwmon_labels_in)) { 135 + /* 136 + * The Board Controller doesn't differentiate current and voltage sensors. 137 + * Get the sensor type from cgbc_hwmon_labels_in[channel].type instead. 138 + */ 139 + sensor->type = cgbc_hwmon_labels_in[channel].type; 140 + sensor->label = cgbc_hwmon_labels_in[channel].label; 141 + } else if (type == CGBC_HWMON_TYPE_FAN && 142 + channel < ARRAY_SIZE(cgbc_hwmon_labels_fan)) { 143 + sensor->type = hwmon_fan; 144 + sensor->label = cgbc_hwmon_labels_fan[channel]; 145 + } else { 146 + dev_warn(dev, "Board Controller returned an unknown sensor (type=%d, channel=%d), ignore it", 147 + type, channel); 148 + continue; 149 + } 150 + 151 + sensor->active = FIELD_GET(CGBC_HWMON_ACTIVE_BIT, data[1]); 152 + sensor->channel = channel; 153 + sensor->index = i; 154 + sensor++; 155 + hwmon->nb_sensors++; 156 + } 157 + 158 + return 0; 159 + } 160 + 161 + static struct cgbc_hwmon_sensor *cgbc_hwmon_find_sensor(struct cgbc_hwmon_data *hwmon, 162 + enum hwmon_sensor_types type, int channel) 163 + { 164 + struct cgbc_hwmon_sensor *sensor = NULL; 165 + int i; 166 + 167 + /* 168 + * The Board Controller doesn't differentiate current and voltage sensors. 169 + * The channel value (from the Board Controller point of view) shall be computed for current 170 + * sensors. 171 + */ 172 + if (type == hwmon_curr) 173 + channel += CGBC_HWMON_NB_IN_SENSORS; 174 + 175 + for (i = 0; i < hwmon->nb_sensors; i++) { 176 + if (hwmon->sensors[i].type == type && hwmon->sensors[i].channel == channel) { 177 + sensor = &hwmon->sensors[i]; 178 + break; 179 + } 180 + } 181 + 182 + return sensor; 183 + } 184 + 185 + static int cgbc_hwmon_read(struct device *dev, enum hwmon_sensor_types type, u32 attr, int channel, 186 + long *val) 187 + { 188 + struct cgbc_hwmon_data *hwmon = dev_get_drvdata(dev); 189 + struct cgbc_hwmon_sensor *sensor = cgbc_hwmon_find_sensor(hwmon, type, channel); 190 + struct cgbc_device_data *cgbc = hwmon->cgbc; 191 + u8 data[CGBC_HWMON_CMD_SENSOR_DATA_SIZE]; 192 + int ret; 193 + 194 + ret = cgbc_hwmon_cmd(cgbc, sensor->index, &data[0]); 195 + if (ret) 196 + return ret; 197 + 198 + *val = (data[3] << 8) | data[2]; 199 + 200 + /* 201 + * For the Board Controller 1lsb = 0.1 degree centigrade. 202 + * Other units are as expected. 203 + */ 204 + if (sensor->type == hwmon_temp) 205 + *val *= 100; 206 + 207 + return 0; 208 + } 209 + 210 + static umode_t cgbc_hwmon_is_visible(const void *_data, enum hwmon_sensor_types type, u32 attr, 211 + int channel) 212 + { 213 + struct cgbc_hwmon_data *data = (struct cgbc_hwmon_data *)_data; 214 + struct cgbc_hwmon_sensor *sensor; 215 + 216 + sensor = cgbc_hwmon_find_sensor(data, type, channel); 217 + if (!sensor) 218 + return 0; 219 + 220 + return sensor->active ? 0444 : 0; 221 + } 222 + 223 + static int cgbc_hwmon_read_string(struct device *dev, enum hwmon_sensor_types type, u32 attr, 224 + int channel, const char **str) 225 + { 226 + struct cgbc_hwmon_data *hwmon = dev_get_drvdata(dev); 227 + struct cgbc_hwmon_sensor *sensor = cgbc_hwmon_find_sensor(hwmon, type, channel); 228 + 229 + *str = sensor->label; 230 + 231 + return 0; 232 + } 233 + 234 + static const struct hwmon_channel_info * const cgbc_hwmon_info[] = { 235 + HWMON_CHANNEL_INFO(temp, 236 + HWMON_T_INPUT | HWMON_T_LABEL, HWMON_T_INPUT | HWMON_T_LABEL, 237 + HWMON_T_INPUT | HWMON_T_LABEL, HWMON_T_INPUT | HWMON_T_LABEL, 238 + HWMON_T_INPUT | HWMON_T_LABEL, HWMON_T_INPUT | HWMON_T_LABEL, 239 + HWMON_T_INPUT | HWMON_T_LABEL, HWMON_T_INPUT | HWMON_T_LABEL, 240 + HWMON_T_INPUT | HWMON_T_LABEL, HWMON_T_INPUT | HWMON_T_LABEL), 241 + HWMON_CHANNEL_INFO(in, 242 + HWMON_I_INPUT | HWMON_I_LABEL, HWMON_I_INPUT | HWMON_I_LABEL, 243 + HWMON_I_INPUT | HWMON_I_LABEL, HWMON_I_INPUT | HWMON_I_LABEL, 244 + HWMON_I_INPUT | HWMON_I_LABEL, HWMON_I_INPUT | HWMON_I_LABEL, 245 + HWMON_I_INPUT | HWMON_I_LABEL, HWMON_I_INPUT | HWMON_I_LABEL, 246 + HWMON_I_INPUT | HWMON_I_LABEL, HWMON_I_INPUT | HWMON_I_LABEL, 247 + HWMON_I_INPUT | HWMON_I_LABEL, HWMON_I_INPUT | HWMON_I_LABEL, 248 + HWMON_I_INPUT | HWMON_I_LABEL, HWMON_I_INPUT | HWMON_I_LABEL), 249 + HWMON_CHANNEL_INFO(curr, 250 + HWMON_C_INPUT | HWMON_C_LABEL, HWMON_C_INPUT | HWMON_C_LABEL, 251 + HWMON_C_INPUT | HWMON_C_LABEL), 252 + HWMON_CHANNEL_INFO(fan, 253 + HWMON_F_INPUT | HWMON_F_LABEL, HWMON_F_INPUT | HWMON_F_LABEL, 254 + HWMON_F_INPUT | HWMON_F_LABEL, HWMON_F_INPUT | HWMON_F_LABEL, 255 + HWMON_F_INPUT | HWMON_F_LABEL, HWMON_F_INPUT | HWMON_F_LABEL), 256 + NULL 257 + }; 258 + 259 + static const struct hwmon_ops cgbc_hwmon_ops = { 260 + .is_visible = cgbc_hwmon_is_visible, 261 + .read = cgbc_hwmon_read, 262 + .read_string = cgbc_hwmon_read_string, 263 + }; 264 + 265 + static const struct hwmon_chip_info cgbc_chip_info = { 266 + .ops = &cgbc_hwmon_ops, 267 + .info = cgbc_hwmon_info, 268 + }; 269 + 270 + static int cgbc_hwmon_probe(struct platform_device *pdev) 271 + { 272 + struct cgbc_device_data *cgbc = dev_get_drvdata(pdev->dev.parent); 273 + struct device *dev = &pdev->dev; 274 + struct cgbc_hwmon_data *data; 275 + struct device *hwmon_dev; 276 + int ret; 277 + 278 + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 279 + if (!data) 280 + return -ENOMEM; 281 + 282 + data->cgbc = cgbc; 283 + 284 + ret = cgbc_hwmon_probe_sensors(dev, data); 285 + if (ret) 286 + return dev_err_probe(dev, ret, "Failed to probe sensors"); 287 + 288 + hwmon_dev = devm_hwmon_device_register_with_info(dev, "cgbc_hwmon", data, &cgbc_chip_info, 289 + NULL); 290 + return PTR_ERR_OR_ZERO(hwmon_dev); 291 + } 292 + 293 + static struct platform_driver cgbc_hwmon_driver = { 294 + .driver = { 295 + .name = "cgbc-hwmon", 296 + }, 297 + .probe = cgbc_hwmon_probe, 298 + }; 299 + 300 + module_platform_driver(cgbc_hwmon_driver); 301 + 302 + MODULE_AUTHOR("Thomas Richard <thomas.richard@bootlin.com>"); 303 + MODULE_DESCRIPTION("Congatec Board Controller Hardware Monitoring Driver"); 304 + MODULE_LICENSE("GPL");
+4 -1
drivers/hwmon/dell-smm-hwmon.c
··· 73 73 #define DELL_SMM_LEGACY_EXECUTE 0x1 74 74 75 75 #define DELL_SMM_NO_TEMP 10 76 - #define DELL_SMM_NO_FANS 3 76 + #define DELL_SMM_NO_FANS 4 77 77 78 78 struct smm_regs { 79 79 unsigned int eax; ··· 1074 1074 HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_MIN | HWMON_F_MAX | 1075 1075 HWMON_F_TARGET, 1076 1076 HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_MIN | HWMON_F_MAX | 1077 + HWMON_F_TARGET, 1078 + HWMON_F_INPUT | HWMON_F_LABEL | HWMON_F_MIN | HWMON_F_MAX | 1077 1079 HWMON_F_TARGET 1078 1080 ), 1079 1081 HWMON_CHANNEL_INFO(pwm, 1080 1082 HWMON_PWM_INPUT | HWMON_PWM_ENABLE, 1083 + HWMON_PWM_INPUT, 1081 1084 HWMON_PWM_INPUT, 1082 1085 HWMON_PWM_INPUT 1083 1086 ),
+10 -28
drivers/hwmon/emc2305.c
··· 112 112 "emc2305_fan5", 113 113 }; 114 114 115 - static void emc2305_unset_tz(struct device *dev); 116 - 117 115 static int emc2305_get_max_channel(const struct emc2305_data *data) 118 116 { 119 117 return data->pwm_num; ··· 291 293 pwm = data->pwm_min[cdev_idx]; 292 294 293 295 data->cdev_data[cdev_idx].cdev = 294 - thermal_cooling_device_register(emc2305_fan_name[idx], data, 295 - &emc2305_cooling_ops); 296 + devm_thermal_of_cooling_device_register(dev, dev->of_node, 297 + emc2305_fan_name[idx], data, 298 + &emc2305_cooling_ops); 296 299 297 300 if (IS_ERR(data->cdev_data[cdev_idx].cdev)) { 298 301 dev_err(dev, "Failed to register cooling device %s\n", emc2305_fan_name[idx]); ··· 331 332 for (i = 0; i < data->pwm_num; i++) { 332 333 ret = emc2305_set_single_tz(dev, i + 1); 333 334 if (ret) 334 - goto thermal_cooling_device_register_fail; 335 + return ret; 335 336 } 336 337 return 0; 337 - 338 - thermal_cooling_device_register_fail: 339 - emc2305_unset_tz(dev); 340 - return ret; 341 - } 342 - 343 - static void emc2305_unset_tz(struct device *dev) 344 - { 345 - struct emc2305_data *data = dev_get_drvdata(dev); 346 - int i; 347 - 348 - /* Unregister cooling device. */ 349 - for (i = 0; i < EMC2305_PWM_MAX; i++) 350 - if (data->cdev_data[i].cdev) 351 - thermal_cooling_device_unregister(data->cdev_data[i].cdev); 352 338 } 353 339 354 340 static umode_t ··· 583 599 return 0; 584 600 } 585 601 586 - static void emc2305_remove(struct i2c_client *client) 587 - { 588 - struct device *dev = &client->dev; 589 - 590 - if (IS_REACHABLE(CONFIG_THERMAL)) 591 - emc2305_unset_tz(dev); 592 - } 602 + static const struct of_device_id of_emc2305_match_table[] = { 603 + { .compatible = "microchip,emc2305", }, 604 + {}, 605 + }; 606 + MODULE_DEVICE_TABLE(of, of_emc2305_match_table); 593 607 594 608 static struct i2c_driver emc2305_driver = { 595 609 .driver = { 596 610 .name = "emc2305", 611 + .of_match_table = of_emc2305_match_table, 597 612 }, 598 613 .probe = emc2305_probe, 599 - .remove = emc2305_remove, 600 614 .id_table = emc2305_ids, 601 615 }; 602 616
+15 -1
drivers/hwmon/gpio-fan.c
··· 393 393 if (state >= fan_data->num_speed) 394 394 return -EINVAL; 395 395 396 + mutex_lock(&fan_data->lock); 397 + 396 398 set_fan_speed(fan_data, state); 399 + 400 + mutex_unlock(&fan_data->lock); 401 + 397 402 return 0; 398 403 } 399 404 ··· 494 489 495 490 static void gpio_fan_stop(void *data) 496 491 { 492 + struct gpio_fan_data *fan_data = data; 493 + 494 + mutex_lock(&fan_data->lock); 497 495 set_fan_speed(data, 0); 496 + mutex_unlock(&fan_data->lock); 498 497 } 499 498 500 499 static int gpio_fan_probe(struct platform_device *pdev) ··· 571 562 572 563 if (fan_data->gpios) { 573 564 fan_data->resume_speed = fan_data->speed_index; 565 + mutex_lock(&fan_data->lock); 574 566 set_fan_speed(fan_data, 0); 567 + mutex_unlock(&fan_data->lock); 575 568 } 576 569 577 570 return 0; ··· 583 572 { 584 573 struct gpio_fan_data *fan_data = dev_get_drvdata(dev); 585 574 586 - if (fan_data->gpios) 575 + if (fan_data->gpios) { 576 + mutex_lock(&fan_data->lock); 587 577 set_fan_speed(fan_data, fan_data->resume_speed); 578 + mutex_unlock(&fan_data->lock); 579 + } 588 580 589 581 return 0; 590 582 }
-1
drivers/hwmon/gsc-hwmon.c
··· 47 47 static const struct regmap_config gsc_hwmon_regmap_config = { 48 48 .reg_bits = 8, 49 49 .val_bits = 8, 50 - .cache_type = REGCACHE_NONE, 51 50 }; 52 51 53 52 static ssize_t pwm_auto_point_temp_show(struct device *dev,
+350
drivers/hwmon/htu31.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * The driver for Measurement Specialties HTU31 Temperature and Humidity sensor. 4 + * 5 + * Copyright (C) 2025 6 + * Author: Andrei Lalaev <andrey.lalaev@gmail.com> 7 + */ 8 + 9 + #include <linux/array_size.h> 10 + #include <linux/cleanup.h> 11 + #include <linux/crc8.h> 12 + #include <linux/debugfs.h> 13 + #include <linux/delay.h> 14 + #include <linux/hwmon.h> 15 + #include <linux/hwmon-sysfs.h> 16 + #include <linux/i2c.h> 17 + #include <linux/init.h> 18 + #include <linux/module.h> 19 + 20 + #define HTU31_READ_TEMP_HUM_CMD 0x00 21 + #define HTU31_READ_SERIAL_CMD 0x0a 22 + #define HTU31_CONVERSION_CMD 0x5e 23 + #define HTU31_HEATER_OFF_CMD 0x02 24 + #define HTU31_HEATER_ON_CMD 0x04 25 + 26 + #define HTU31_TEMP_HUM_LEN 6 27 + 28 + /* Conversion time for the highest resolution */ 29 + #define HTU31_HUMIDITY_CONV_TIME 10000 /* us */ 30 + #define HTU31_TEMPERATURE_CONV_TIME 15000 /* us */ 31 + 32 + #define HTU31_SERIAL_NUMBER_LEN 3 33 + #define HTU31_SERIAL_NUMBER_CRC_LEN 1 34 + #define HTU31_SERIAL_NUMBER_CRC_OFFSET 3 35 + 36 + #define HTU31_CRC8_INIT_VAL 0 37 + #define HTU31_CRC8_POLYNOMIAL 0x31 38 + DECLARE_CRC8_TABLE(htu31_crc8_table); 39 + 40 + /** 41 + * struct htu31_data - all the data required to operate a HTU31 chip 42 + * @client: the i2c client associated with the HTU31 43 + * @lock: a mutex to prevent parallel access to the data 44 + * @wait_time: the time needed by sensor to convert values 45 + * @temperature: the latest temperature value in millidegrees 46 + * @humidity: the latest relative humidity value in millipercent 47 + * @serial_number: the serial number of the sensor 48 + * @heater_enable: the internal state of the heater 49 + */ 50 + struct htu31_data { 51 + struct i2c_client *client; 52 + struct mutex lock; /* Used to protect against parallel data updates */ 53 + long wait_time; 54 + long temperature; 55 + long humidity; 56 + u8 serial_number[HTU31_SERIAL_NUMBER_LEN]; 57 + bool heater_enable; 58 + }; 59 + 60 + static long htu31_temp_to_millicelsius(u16 val) 61 + { 62 + return -40000 + DIV_ROUND_CLOSEST_ULL(165000ULL * val, 65535); 63 + } 64 + 65 + static long htu31_relative_humidity(u16 val) 66 + { 67 + return DIV_ROUND_CLOSEST_ULL(100000ULL * val, 65535); 68 + } 69 + 70 + static int htu31_data_fetch_command(struct htu31_data *data) 71 + { 72 + struct i2c_client *client = data->client; 73 + u8 conversion_on = HTU31_CONVERSION_CMD; 74 + u8 read_data_cmd = HTU31_READ_TEMP_HUM_CMD; 75 + u8 t_h_buf[HTU31_TEMP_HUM_LEN] = {}; 76 + struct i2c_msg msgs[] = { 77 + { 78 + .addr = client->addr, 79 + .flags = 0, 80 + .len = 1, 81 + .buf = &read_data_cmd, 82 + }, 83 + { 84 + .addr = client->addr, 85 + .flags = I2C_M_RD, 86 + .len = sizeof(t_h_buf), 87 + .buf = t_h_buf, 88 + }, 89 + }; 90 + int ret; 91 + u8 crc; 92 + 93 + guard(mutex)(&data->lock); 94 + 95 + ret = i2c_master_send(client, &conversion_on, 1); 96 + if (ret != 1) { 97 + ret = ret < 0 ? ret : -EIO; 98 + dev_err(&client->dev, 99 + "Conversion command is failed. Error code: %d\n", ret); 100 + return ret; 101 + } 102 + 103 + fsleep(data->wait_time); 104 + 105 + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 106 + if (ret != ARRAY_SIZE(msgs)) { 107 + ret = ret < 0 ? ret : -EIO; 108 + dev_err(&client->dev, 109 + "T&H command is failed. Error code: %d\n", ret); 110 + return ret; 111 + } 112 + 113 + crc = crc8(htu31_crc8_table, &t_h_buf[0], 2, HTU31_CRC8_INIT_VAL); 114 + if (crc != t_h_buf[2]) { 115 + dev_err(&client->dev, "Temperature CRC mismatch\n"); 116 + return -EIO; 117 + } 118 + 119 + crc = crc8(htu31_crc8_table, &t_h_buf[3], 2, HTU31_CRC8_INIT_VAL); 120 + if (crc != t_h_buf[5]) { 121 + dev_err(&client->dev, "Humidity CRC mismatch\n"); 122 + return -EIO; 123 + } 124 + 125 + data->temperature = htu31_temp_to_millicelsius(be16_to_cpup((__be16 *)&t_h_buf[0])); 126 + data->humidity = htu31_relative_humidity(be16_to_cpup((__be16 *)&t_h_buf[3])); 127 + 128 + return 0; 129 + } 130 + 131 + static umode_t htu31_is_visible(const void *data, enum hwmon_sensor_types type, 132 + u32 attr, int channel) 133 + { 134 + switch (type) { 135 + case hwmon_temp: 136 + case hwmon_humidity: 137 + return 0444; 138 + default: 139 + return 0; 140 + } 141 + } 142 + 143 + static int htu31_read(struct device *dev, enum hwmon_sensor_types type, 144 + u32 attr, int channel, long *val) 145 + { 146 + struct htu31_data *data = dev_get_drvdata(dev); 147 + int ret; 148 + 149 + ret = htu31_data_fetch_command(data); 150 + if (ret < 0) 151 + return ret; 152 + 153 + switch (type) { 154 + case hwmon_temp: 155 + if (attr != hwmon_temp_input) 156 + return -EINVAL; 157 + 158 + *val = data->temperature; 159 + break; 160 + case hwmon_humidity: 161 + if (attr != hwmon_humidity_input) 162 + return -EINVAL; 163 + 164 + *val = data->humidity; 165 + break; 166 + default: 167 + return -EOPNOTSUPP; 168 + } 169 + 170 + return 0; 171 + } 172 + 173 + static int htu31_read_serial_number(struct htu31_data *data) 174 + { 175 + struct i2c_client *client = data->client; 176 + u8 read_sn_cmd = HTU31_READ_SERIAL_CMD; 177 + u8 sn_buf[HTU31_SERIAL_NUMBER_LEN + HTU31_SERIAL_NUMBER_CRC_LEN]; 178 + struct i2c_msg msgs[] = { 179 + { 180 + .addr = client->addr, 181 + .flags = 0, 182 + .len = 1, 183 + .buf = &read_sn_cmd, 184 + }, 185 + { 186 + .addr = client->addr, 187 + .flags = I2C_M_RD, 188 + .len = sizeof(sn_buf), 189 + .buf = sn_buf, 190 + }, 191 + }; 192 + int ret; 193 + u8 crc; 194 + 195 + ret = i2c_transfer(client->adapter, msgs, ARRAY_SIZE(msgs)); 196 + if (ret < 0) 197 + return ret; 198 + 199 + crc = crc8(htu31_crc8_table, sn_buf, HTU31_SERIAL_NUMBER_LEN, HTU31_CRC8_INIT_VAL); 200 + if (crc != sn_buf[HTU31_SERIAL_NUMBER_CRC_OFFSET]) { 201 + dev_err(&client->dev, "Serial number CRC mismatch\n"); 202 + return -EIO; 203 + } 204 + 205 + memcpy(data->serial_number, sn_buf, HTU31_SERIAL_NUMBER_LEN); 206 + 207 + return 0; 208 + } 209 + 210 + static ssize_t heater_enable_show(struct device *dev, 211 + struct device_attribute *attr, 212 + char *buf) 213 + { 214 + struct htu31_data *data = dev_get_drvdata(dev); 215 + 216 + return sysfs_emit(buf, "%d\n", data->heater_enable); 217 + } 218 + 219 + static ssize_t heater_enable_store(struct device *dev, 220 + struct device_attribute *attr, 221 + const char *buf, 222 + size_t count) 223 + { 224 + struct htu31_data *data = dev_get_drvdata(dev); 225 + u8 heater_cmd; 226 + bool status; 227 + int ret; 228 + 229 + ret = kstrtobool(buf, &status); 230 + if (ret) 231 + return ret; 232 + 233 + heater_cmd = status ? HTU31_HEATER_ON_CMD : HTU31_HEATER_OFF_CMD; 234 + 235 + guard(mutex)(&data->lock); 236 + 237 + ret = i2c_master_send(data->client, &heater_cmd, 1); 238 + if (ret < 0) 239 + return ret; 240 + 241 + data->heater_enable = status; 242 + 243 + return count; 244 + } 245 + 246 + static DEVICE_ATTR_RW(heater_enable); 247 + 248 + static int serial_number_show(struct seq_file *seq_file, 249 + void *unused) 250 + { 251 + struct htu31_data *data = seq_file->private; 252 + 253 + seq_printf(seq_file, "%X%X%X\n", data->serial_number[0], 254 + data->serial_number[1], data->serial_number[2]); 255 + return 0; 256 + } 257 + 258 + DEFINE_SHOW_ATTRIBUTE(serial_number); 259 + 260 + static struct attribute *htu31_attrs[] = { 261 + &dev_attr_heater_enable.attr, 262 + NULL 263 + }; 264 + 265 + ATTRIBUTE_GROUPS(htu31); 266 + 267 + static const struct hwmon_channel_info * const htu31_info[] = { 268 + HWMON_CHANNEL_INFO(temp, HWMON_T_INPUT), 269 + HWMON_CHANNEL_INFO(humidity, HWMON_H_INPUT), 270 + NULL 271 + }; 272 + 273 + static const struct hwmon_ops htu31_hwmon_ops = { 274 + .is_visible = htu31_is_visible, 275 + .read = htu31_read, 276 + }; 277 + 278 + static const struct hwmon_chip_info htu31_chip_info = { 279 + .info = htu31_info, 280 + .ops = &htu31_hwmon_ops, 281 + }; 282 + 283 + static int htu31_probe(struct i2c_client *client) 284 + { 285 + struct device *dev = &client->dev; 286 + struct device *hwmon_dev; 287 + struct htu31_data *data; 288 + int ret; 289 + 290 + data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL); 291 + if (!data) 292 + return -ENOMEM; 293 + 294 + data->client = client; 295 + data->wait_time = HTU31_TEMPERATURE_CONV_TIME + HTU31_HUMIDITY_CONV_TIME; 296 + 297 + ret = devm_mutex_init(dev, &data->lock); 298 + if (ret) 299 + return ret; 300 + 301 + crc8_populate_msb(htu31_crc8_table, HTU31_CRC8_POLYNOMIAL); 302 + 303 + ret = htu31_read_serial_number(data); 304 + if (ret) { 305 + dev_err(dev, "Failed to read serial number\n"); 306 + return ret; 307 + } 308 + 309 + debugfs_create_file("serial_number", 310 + 0444, 311 + client->debugfs, 312 + data, 313 + &serial_number_fops); 314 + 315 + hwmon_dev = devm_hwmon_device_register_with_info(dev, 316 + client->name, 317 + data, 318 + &htu31_chip_info, 319 + htu31_groups); 320 + 321 + return PTR_ERR_OR_ZERO(hwmon_dev); 322 + } 323 + 324 + static const struct i2c_device_id htu31_id[] = { 325 + { "htu31" }, 326 + { } 327 + }; 328 + MODULE_DEVICE_TABLE(i2c, htu31_id); 329 + 330 + #if IS_ENABLED(CONFIG_OF) 331 + static const struct of_device_id htu31_of_match[] = { 332 + { .compatible = "meas,htu31" }, 333 + { } 334 + }; 335 + MODULE_DEVICE_TABLE(of, htu31_of_match); 336 + #endif 337 + 338 + static struct i2c_driver htu31_driver = { 339 + .driver = { 340 + .name = "htu31", 341 + .of_match_table = of_match_ptr(htu31_of_match), 342 + }, 343 + .probe = htu31_probe, 344 + .id_table = htu31_id, 345 + }; 346 + module_i2c_driver(htu31_driver); 347 + 348 + MODULE_AUTHOR("Andrei Lalaev <andrey.lalaev@gmail.com>"); 349 + MODULE_DESCRIPTION("HTU31 Temperature and Humidity sensor driver"); 350 + MODULE_LICENSE("GPL");
+2 -2
drivers/hwmon/hwmon.c
··· 646 646 [hwmon_power_enable] = "power%d_enable", 647 647 [hwmon_power_average] = "power%d_average", 648 648 [hwmon_power_average_interval] = "power%d_average_interval", 649 - [hwmon_power_average_interval_max] = "power%d_interval_max", 650 - [hwmon_power_average_interval_min] = "power%d_interval_min", 649 + [hwmon_power_average_interval_max] = "power%d_average_interval_max", 650 + [hwmon_power_average_interval_min] = "power%d_average_interval_min", 651 651 [hwmon_power_average_highest] = "power%d_average_highest", 652 652 [hwmon_power_average_lowest] = "power%d_average_lowest", 653 653 [hwmon_power_average_max] = "power%d_average_max",
+1 -8
drivers/hwmon/ina3221.c
··· 116 116 * @fields: Register fields of the device 117 117 * @inputs: Array of channel input source specific structures 118 118 * @lock: mutex lock to serialize sysfs attribute accesses 119 - * @debugfs: Pointer to debugfs entry for device 120 119 * @reg_config: Register value of INA3221_CONFIG 121 120 * @summation_shunt_resistor: equivalent shunt resistor value for summation 122 121 * @summation_channel_control: Value written to SCC field in INA3221_MASK_ENABLE ··· 127 128 struct regmap_field *fields[F_MAX_FIELDS]; 128 129 struct ina3221_input inputs[INA3221_NUM_CHANNELS]; 129 130 struct mutex lock; 130 - struct dentry *debugfs; 131 131 u32 reg_config; 132 132 int summation_shunt_resistor; 133 133 u32 summation_channel_control; ··· 911 913 goto fail; 912 914 } 913 915 914 - scnprintf(name, sizeof(name), "%s-%s", INA3221_DRIVER_NAME, dev_name(dev)); 915 - ina->debugfs = debugfs_create_dir(name, NULL); 916 - 917 916 for (i = 0; i < INA3221_NUM_CHANNELS; i++) { 918 917 scnprintf(name, sizeof(name), "in%d_summation_disable", i); 919 - debugfs_create_bool(name, 0400, ina->debugfs, 918 + debugfs_create_bool(name, 0400, client->debugfs, 920 919 &ina->inputs[i].summation_disable); 921 920 } 922 921 ··· 934 939 { 935 940 struct ina3221_data *ina = dev_get_drvdata(&client->dev); 936 941 int i; 937 - 938 - debugfs_remove_recursive(ina->debugfs); 939 942 940 943 pm_runtime_disable(ina->pm_dev); 941 944 pm_runtime_set_suspended(ina->pm_dev);
+2 -42
drivers/hwmon/isl28022.c
··· 324 324 } 325 325 DEFINE_SHOW_ATTRIBUTE(shunt_voltage); 326 326 327 - static struct dentry *isl28022_debugfs_root; 328 - 329 - static void isl28022_debugfs_remove(void *res) 330 - { 331 - debugfs_remove_recursive(res); 332 - } 333 - 334 - static void isl28022_debugfs_init(struct i2c_client *client, struct isl28022_data *data) 335 - { 336 - char name[16]; 337 - struct dentry *debugfs; 338 - 339 - scnprintf(name, sizeof(name), "%d-%04hx", client->adapter->nr, client->addr); 340 - 341 - debugfs = debugfs_create_dir(name, isl28022_debugfs_root); 342 - debugfs_create_file("shunt_voltage", 0444, debugfs, data, &shunt_voltage_fops); 343 - 344 - devm_add_action_or_reset(&client->dev, isl28022_debugfs_remove, debugfs); 345 - } 346 - 347 327 /* 348 328 * read property values and make consistency checks. 349 329 * ··· 455 475 if (err) 456 476 return err; 457 477 458 - isl28022_debugfs_init(client, data); 478 + debugfs_create_file("shunt_voltage", 0444, client->debugfs, data, &shunt_voltage_fops); 459 479 460 480 hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, 461 481 data, &isl28022_chip_info, NULL); ··· 485 505 .probe = isl28022_probe, 486 506 .id_table = isl28022_ids, 487 507 }; 488 - 489 - static int __init isl28022_init(void) 490 - { 491 - int err; 492 - 493 - isl28022_debugfs_root = debugfs_create_dir("isl28022", NULL); 494 - err = i2c_add_driver(&isl28022_driver); 495 - if (!err) 496 - return 0; 497 - 498 - debugfs_remove_recursive(isl28022_debugfs_root); 499 - return err; 500 - } 501 - module_init(isl28022_init); 502 - 503 - static void __exit isl28022_exit(void) 504 - { 505 - i2c_del_driver(&isl28022_driver); 506 - debugfs_remove_recursive(isl28022_debugfs_root); 507 - } 508 - module_exit(isl28022_exit); 508 + module_i2c_driver(isl28022_driver); 509 509 510 510 MODULE_AUTHOR("Carsten Spieß <mail@carsten-spiess.de>"); 511 511 MODULE_DESCRIPTION("ISL28022 driver");
+2
drivers/hwmon/k10temp.c
··· 467 467 k10temp_get_ccd_support(data, 4); 468 468 break; 469 469 case 0x31: /* Zen2 Threadripper */ 470 + case 0x47: /* Cyan Skillfish */ 470 471 case 0x60: /* Renoir */ 471 472 case 0x68: /* Lucienne */ 472 473 case 0x71: /* Zen2 */ ··· 536 535 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_DF_F3) }, 537 536 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M10H_DF_F3) }, 538 537 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M30H_DF_F3) }, 538 + { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M40H_DF_F3) }, 539 539 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M60H_DF_F3) }, 540 540 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_M70H_DF_F3) }, 541 541 { PCI_VDEVICE(AMD, PCI_DEVICE_ID_AMD_17H_MA0H_DF_F3) },
+80 -2
drivers/hwmon/lm90.c
··· 90 90 * This driver also supports NE1618 from Philips. It is similar to NE1617 91 91 * but supports 11 bit external temperature values. 92 92 * 93 + * This driver also supports NCT7716, NCT7717 and NCT7718 from Nuvoton. 94 + * The NCT7716 is similar to NCT7717 but has one more address support. 95 + * 93 96 * Since the LM90 was the first chipset supported by this driver, most 94 97 * comments will refer to this chipset, but are actually general and 95 98 * concern all supported chipsets, unless mentioned otherwise. ··· 122 119 * Address is fully defined internally and cannot be changed except for 123 120 * MAX6659, MAX6680 and MAX6681. 124 121 * LM86, LM89, LM90, LM99, ADM1032, ADM1032-1, ADT7461, ADT7461A, MAX6649, 125 - * MAX6657, MAX6658, NCT1008 and W83L771 have address 0x4c. 122 + * MAX6657, MAX6658, NCT1008, NCT7718 and W83L771 have address 0x4c. 126 123 * ADM1032-2, ADT7461-2, ADT7461A-2, LM89-1, LM99-1, MAX6646, and NCT1008D 127 124 * have address 0x4d. 128 125 * MAX6647 has address 0x4e. 129 126 * MAX6659 can have address 0x4c, 0x4d or 0x4e. 130 127 * MAX6654, MAX6680, and MAX6681 can have address 0x18, 0x19, 0x1a, 0x29, 131 128 * 0x2a, 0x2b, 0x4c, 0x4d or 0x4e. 129 + * NCT7716 can have address 0x48 or 0x49. 130 + * NCT7717 has address 0x48. 132 131 * SA56004 can have address 0x48 through 0x4F. 133 132 */ 134 133 ··· 141 136 enum chips { adm1023, adm1032, adt7461, adt7461a, adt7481, 142 137 g781, lm84, lm90, lm99, 143 138 max1617, max6642, max6646, max6648, max6654, max6657, max6659, max6680, max6696, 144 - nct210, nct72, ne1618, sa56004, tmp451, tmp461, w83l771, 139 + nct210, nct72, nct7716, nct7717, nct7718, ne1618, sa56004, tmp451, tmp461, w83l771, 145 140 }; 146 141 147 142 /* ··· 195 190 196 191 #define ADT7481_REG_MAN_ID 0x3e 197 192 #define ADT7481_REG_CHIP_ID 0x3d 193 + 194 + /* NCT7716/7717/7718 registers */ 195 + #define NCT7716_REG_CHIP_ID 0xFD 198 196 199 197 /* Device features */ 200 198 #define LM90_HAVE_EXTENDED_TEMP BIT(0) /* extended temperature support */ ··· 283 275 { "nct214", nct72 }, 284 276 { "nct218", nct72 }, 285 277 { "nct72", nct72 }, 278 + { "nct7716", nct7716 }, 279 + { "nct7717", nct7717 }, 280 + { "nct7718", nct7718 }, 286 281 { "ne1618", ne1618 }, 287 282 { "w83l771", w83l771 }, 288 283 { "sa56004", sa56004 }, ··· 392 381 { 393 382 .compatible = "onnn,nct72", 394 383 .data = (void *)nct72 384 + }, 385 + { 386 + .compatible = "nuvoton,nct7716", 387 + .data = (void *)nct7716 388 + }, 389 + { 390 + .compatible = "nuvoton,nct7717", 391 + .data = (void *)nct7717 392 + }, 393 + { 394 + .compatible = "nuvoton,nct7718", 395 + .data = (void *)nct7718 395 396 }, 396 397 { 397 398 .compatible = "winbond,w83l771", ··· 623 600 .alert_alarms = 0x7c, 624 601 .resolution = 11, 625 602 .max_convrate = 7, 603 + }, 604 + [nct7716] = { 605 + .flags = LM90_HAVE_ALARMS | LM90_HAVE_CONVRATE, 606 + .alert_alarms = 0x40, 607 + .resolution = 8, 608 + .max_convrate = 8, 609 + }, 610 + [nct7717] = { 611 + .flags = LM90_HAVE_ALARMS | LM90_HAVE_CONVRATE, 612 + .alert_alarms = 0x40, 613 + .resolution = 8, 614 + .max_convrate = 8, 615 + }, 616 + [nct7718] = { 617 + .flags = LM90_HAVE_OFFSET | LM90_HAVE_REM_LIMIT_EXT | LM90_HAVE_CRIT 618 + | LM90_HAVE_ALARMS | LM90_HAVE_LOW | LM90_HAVE_CONVRATE 619 + | LM90_HAVE_REMOTE_EXT, 620 + .alert_alarms = 0x7c, 621 + .resolution = 11, 622 + .max_convrate = 8, 626 623 }, 627 624 [ne1618] = { 628 625 .flags = LM90_PAUSE_FOR_CONFIG | LM90_HAVE_BROKEN_ALERT ··· 2343 2300 return name; 2344 2301 } 2345 2302 2303 + static const char *lm90_detect_nuvoton_50(struct i2c_client *client, int chip_id, 2304 + int config1, int convrate) 2305 + { 2306 + int chip_id2 = i2c_smbus_read_byte_data(client, NCT7716_REG_CHIP_ID); 2307 + int config2 = i2c_smbus_read_byte_data(client, LM90_REG_CONFIG2); 2308 + int address = client->addr; 2309 + const char *name = NULL; 2310 + 2311 + if (chip_id2 < 0 || config2 < 0) 2312 + return NULL; 2313 + 2314 + if (chip_id2 != 0x50 || convrate > 0x08) 2315 + return NULL; 2316 + 2317 + switch (chip_id) { 2318 + case 0x90: 2319 + if (address == 0x48 && !(config1 & 0x3e) && !(config2 & 0xfe)) 2320 + name = "nct7717"; 2321 + break; 2322 + case 0x91: 2323 + if ((address == 0x48 || address == 0x49) && !(config1 & 0x3e) && 2324 + !(config2 & 0xfe)) 2325 + name = "nct7716"; 2326 + else if (address == 0x4c && !(config1 & 0x38) && !(config2 & 0xf8)) 2327 + name = "nct7718"; 2328 + break; 2329 + default: 2330 + break; 2331 + } 2332 + return name; 2333 + } 2334 + 2346 2335 static const char *lm90_detect_nxp(struct i2c_client *client, bool common_address, 2347 2336 int chip_id, int config1, int convrate) 2348 2337 { ··· 2558 2483 case 0x4d: /* Maxim Integrated */ 2559 2484 name = lm90_detect_maxim(client, common_address, chip_id, 2560 2485 config1, convrate); 2486 + break; 2487 + case 0x50: 2488 + name = lm90_detect_nuvoton_50(client, chip_id, config1, convrate); 2561 2489 break; 2562 2490 case 0x54: /* ON MC1066, Microchip TC1068, TCM1617 (originally TelCom) */ 2563 2491 if (common_address && !(config1 & 0x3f) && !(convrate & 0xf8))
+8 -36
drivers/hwmon/ltc4282.c
··· 1674 1674 DEFINE_DEBUGFS_ATTRIBUTE(ltc4282_power1_bad_fault_log, 1675 1675 ltc4282_show_power1_bad_fault_log, NULL, "%llu\n"); 1676 1676 1677 - static void ltc4282_debugfs_remove(void *dir) 1677 + static void ltc4282_debugfs_init(struct ltc4282_state *st, struct i2c_client *i2c) 1678 1678 { 1679 - debugfs_remove_recursive(dir); 1680 - } 1681 - 1682 - static void ltc4282_debugfs_init(struct ltc4282_state *st, 1683 - struct i2c_client *i2c, 1684 - const struct device *hwmon) 1685 - { 1686 - const char *debugfs_name; 1687 - struct dentry *dentry; 1688 - int ret; 1689 - 1690 - if (!IS_ENABLED(CONFIG_DEBUG_FS)) 1691 - return; 1692 - 1693 - debugfs_name = devm_kasprintf(&i2c->dev, GFP_KERNEL, "ltc4282-%s", 1694 - dev_name(hwmon)); 1695 - if (!debugfs_name) 1696 - return; 1697 - 1698 - dentry = debugfs_create_dir(debugfs_name, NULL); 1699 - if (IS_ERR(dentry)) 1700 - return; 1701 - 1702 - ret = devm_add_action_or_reset(&i2c->dev, ltc4282_debugfs_remove, 1703 - dentry); 1704 - if (ret) 1705 - return; 1706 - 1707 - debugfs_create_file_unsafe("power1_bad_fault_log", 0400, dentry, st, 1679 + debugfs_create_file_unsafe("power1_bad_fault_log", 0400, i2c->debugfs, st, 1708 1680 &ltc4282_power1_bad_fault_log); 1709 - debugfs_create_file_unsafe("in0_fet_short_fault_log", 0400, dentry, st, 1681 + debugfs_create_file_unsafe("in0_fet_short_fault_log", 0400, i2c->debugfs, st, 1710 1682 &ltc4282_fet_short_fault_log); 1711 - debugfs_create_file_unsafe("in0_fet_bad_fault_log", 0400, dentry, st, 1683 + debugfs_create_file_unsafe("in0_fet_bad_fault_log", 0400, i2c->debugfs, st, 1712 1684 &ltc4282_fet_bad_fault_log); 1713 - debugfs_create_file_unsafe("in1_crit_fault_log", 0400, dentry, st, 1685 + debugfs_create_file_unsafe("in1_crit_fault_log", 0400, i2c->debugfs, st, 1714 1686 &ltc4282_in1_crit_fault_log); 1715 - debugfs_create_file_unsafe("in1_lcrit_fault_log", 0400, dentry, st, 1687 + debugfs_create_file_unsafe("in1_lcrit_fault_log", 0400, i2c->debugfs, st, 1716 1688 &ltc4282_in1_lcrit_fault_log); 1717 - debugfs_create_file_unsafe("curr1_crit_fault_log", 0400, dentry, st, 1689 + debugfs_create_file_unsafe("curr1_crit_fault_log", 0400, i2c->debugfs, st, 1718 1690 &ltc4282_curr1_crit_fault_log); 1719 1691 } 1720 1692 ··· 1729 1757 if (IS_ERR(hwmon)) 1730 1758 return PTR_ERR(hwmon); 1731 1759 1732 - ltc4282_debugfs_init(st, i2c, hwmon); 1760 + ltc4282_debugfs_init(st, i2c); 1733 1761 1734 1762 return 0; 1735 1763 }
+3
drivers/hwmon/nct6683.c
··· 176 176 #define NCT6683_CUSTOMER_ID_MSI2 0x200 177 177 #define NCT6683_CUSTOMER_ID_MSI3 0x207 178 178 #define NCT6683_CUSTOMER_ID_MSI4 0x20d 179 + #define NCT6683_CUSTOMER_ID_AMD 0x162b 179 180 #define NCT6683_CUSTOMER_ID_ASROCK 0xe2c 180 181 #define NCT6683_CUSTOMER_ID_ASROCK2 0xe1b 181 182 #define NCT6683_CUSTOMER_ID_ASROCK3 0x1631 ··· 1231 1230 case NCT6683_CUSTOMER_ID_MSI3: 1232 1231 break; 1233 1232 case NCT6683_CUSTOMER_ID_MSI4: 1233 + break; 1234 + case NCT6683_CUSTOMER_ID_AMD: 1234 1235 break; 1235 1236 case NCT6683_CUSTOMER_ID_ASROCK: 1236 1237 break;
+7 -8
drivers/hwmon/ntc_thermistor.c
··· 387 387 puo = data->pullup_ohm; 388 388 pdo = data->pulldown_ohm; 389 389 390 - if (uv == 0) 391 - return (data->connect == NTC_CONNECTED_POSITIVE) ? 392 - INT_MAX : 0; 393 - if (uv >= puv) 394 - return (data->connect == NTC_CONNECTED_POSITIVE) ? 395 - 0 : INT_MAX; 390 + /* faulty adc value */ 391 + if (uv == 0 || uv >= puv) 392 + return -ENODATA; 396 393 397 394 if (data->connect == NTC_CONNECTED_POSITIVE && puo == 0) 398 395 n = div_u64(pdo * (puv - uv), uv); ··· 401 404 else 402 405 n = div64_u64_safe(pdo * puo * uv, pdo * (puv - uv) - puo * uv); 403 406 404 - if (n > INT_MAX) 405 - n = INT_MAX; 407 + /* sensor out of bounds */ 408 + if (n > data->comp[0].ohm || n < data->comp[data->n_comp - 1].ohm) 409 + return -ENODATA; 410 + 406 411 return n; 407 412 } 408 413
+12 -3
drivers/hwmon/pmbus/Kconfig
··· 133 133 This driver can also be built as a module. If so, the module will 134 134 be called dps920ab. 135 135 136 + config SENSORS_INA233 137 + tristate "Texas Instruments INA233 and compatibles" 138 + help 139 + If you say yes here you get hardware monitoring support for Texas 140 + Instruments INA233. 141 + 142 + This driver can also be built as a module. If so, the module will 143 + be called ina233. 144 + 136 145 config SENSORS_INSPUR_IPSPS 137 146 tristate "INSPUR Power System Power Supply" 138 147 help ··· 242 233 depends on SENSORS_LTC2978 && REGULATOR 243 234 help 244 235 If you say yes here you get regulator support for Linear Technology 245 - LTC3880, LTC3883, LTC3884, LTC3886, LTC3887, LTC3889, LTC7841, 246 - LTC7880, LTM4644, LTM4675, LTM4676, LTM4677, LTM4678, LTM4680, 247 - LTM4686, and LTM4700. 236 + LT7170, LT7171, LTC3880, LTC3883, LTC3884, LTC3886, LTC3887, LTC3889, 237 + LTC7841, LTC7880, LTM4644, LTM4673, LTM4675, LTM4676, LTM4677, 238 + LTM4678, LTM4680, LTM4686, and LTM4700. 248 239 249 240 config SENSORS_LTC3815 250 241 tristate "Linear Technologies LTC3815"
+1
drivers/hwmon/pmbus/Makefile
··· 15 15 obj-$(CONFIG_SENSORS_FSP_3Y) += fsp-3y.o 16 16 obj-$(CONFIG_SENSORS_IBM_CFFPS) += ibm-cffps.o 17 17 obj-$(CONFIG_SENSORS_DPS920AB) += dps920ab.o 18 + obj-$(CONFIG_SENSORS_INA233) += ina233.o 18 19 obj-$(CONFIG_SENSORS_INSPUR_IPSPS) += inspur-ipsps.o 19 20 obj-$(CONFIG_SENSORS_IR35221) += ir35221.o 20 21 obj-$(CONFIG_SENSORS_IR36021) += ir36021.o
+191
drivers/hwmon/pmbus/ina233.c
··· 1 + // SPDX-License-Identifier: GPL-2.0-or-later 2 + /* 3 + * Hardware monitoring driver for ina233 4 + * 5 + * Copyright (c) 2025 Leo Yang 6 + */ 7 + 8 + #include <linux/err.h> 9 + #include <linux/i2c.h> 10 + #include <linux/init.h> 11 + #include <linux/kernel.h> 12 + #include <linux/module.h> 13 + #include "pmbus.h" 14 + 15 + #define MFR_READ_VSHUNT 0xd1 16 + #define MFR_CALIBRATION 0xd4 17 + 18 + #define INA233_MAX_CURRENT_DEFAULT 32768000 /* uA */ 19 + #define INA233_RSHUNT_DEFAULT 2000 /* uOhm */ 20 + 21 + #define MAX_M_VAL 32767 22 + 23 + static void calculate_coef(int *m, int *R, u32 current_lsb, int power_coef) 24 + { 25 + u64 scaled_m; 26 + int scale_factor = 0; 27 + int scale_coef = 1; 28 + 29 + /* 30 + * 1000000 from Current_LSB A->uA . 31 + * scale_coef is for scaling up to minimize rounding errors, 32 + * If there is no decimal information, no need to scale. 33 + */ 34 + if (1000000 % current_lsb) { 35 + /* Scaling to keep integer precision */ 36 + scale_factor = -3; 37 + scale_coef = 1000; 38 + } 39 + 40 + /* 41 + * Unit Conversion (Current_LSB A->uA) and use scaling(scale_factor) 42 + * to keep integer precision. 43 + * Formulae referenced from spec. 44 + */ 45 + scaled_m = div64_u64(1000000 * scale_coef, (u64)current_lsb * power_coef); 46 + 47 + /* Maximize while keeping it bounded.*/ 48 + while (scaled_m > MAX_M_VAL) { 49 + scaled_m = div_u64(scaled_m, 10); 50 + scale_factor++; 51 + } 52 + /* Scale up only if fractional part exists. */ 53 + while (scaled_m * 10 < MAX_M_VAL && scale_coef != 1) { 54 + scaled_m *= 10; 55 + scale_factor--; 56 + } 57 + 58 + *m = scaled_m; 59 + *R = scale_factor; 60 + } 61 + 62 + static int ina233_read_word_data(struct i2c_client *client, int page, 63 + int phase, int reg) 64 + { 65 + int ret; 66 + 67 + switch (reg) { 68 + case PMBUS_VIRT_READ_VMON: 69 + ret = pmbus_read_word_data(client, 0, 0xff, MFR_READ_VSHUNT); 70 + 71 + /* Adjust returned value to match VIN coefficients */ 72 + /* VIN: 1.25 mV VSHUNT: 2.5 uV LSB */ 73 + ret = DIV_ROUND_CLOSEST(ret * 25, 12500); 74 + break; 75 + default: 76 + ret = -ENODATA; 77 + break; 78 + } 79 + return ret; 80 + } 81 + 82 + static int ina233_probe(struct i2c_client *client) 83 + { 84 + struct device *dev = &client->dev; 85 + int ret, m, R; 86 + u32 rshunt; 87 + u32 max_current; 88 + u32 current_lsb; 89 + u16 calibration; 90 + struct pmbus_driver_info *info; 91 + 92 + info = devm_kzalloc(dev, sizeof(struct pmbus_driver_info), 93 + GFP_KERNEL); 94 + if (!info) 95 + return -ENOMEM; 96 + 97 + info->pages = 1; 98 + info->format[PSC_VOLTAGE_IN] = direct; 99 + info->format[PSC_VOLTAGE_OUT] = direct; 100 + info->format[PSC_CURRENT_OUT] = direct; 101 + info->format[PSC_POWER] = direct; 102 + info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_INPUT 103 + | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT 104 + | PMBUS_HAVE_POUT 105 + | PMBUS_HAVE_VMON | PMBUS_HAVE_STATUS_VMON; 106 + info->m[PSC_VOLTAGE_IN] = 8; 107 + info->R[PSC_VOLTAGE_IN] = 2; 108 + info->m[PSC_VOLTAGE_OUT] = 8; 109 + info->R[PSC_VOLTAGE_OUT] = 2; 110 + info->read_word_data = ina233_read_word_data; 111 + 112 + /* If INA233 skips current/power, shunt-resistor and current-lsb aren't needed. */ 113 + /* read rshunt value (uOhm) */ 114 + ret = device_property_read_u32(dev, "shunt-resistor", &rshunt); 115 + if (ret) { 116 + if (ret != -EINVAL) 117 + return dev_err_probe(dev, ret, "Shunt resistor property read fail.\n"); 118 + rshunt = INA233_RSHUNT_DEFAULT; 119 + } 120 + if (!rshunt) 121 + return dev_err_probe(dev, -EINVAL, 122 + "Shunt resistor cannot be zero.\n"); 123 + 124 + /* read Maximum expected current value (uA) */ 125 + ret = device_property_read_u32(dev, "ti,maximum-expected-current-microamp", &max_current); 126 + if (ret) { 127 + if (ret != -EINVAL) 128 + return dev_err_probe(dev, ret, 129 + "Maximum expected current property read fail.\n"); 130 + max_current = INA233_MAX_CURRENT_DEFAULT; 131 + } 132 + if (max_current < 32768) 133 + return dev_err_probe(dev, -EINVAL, 134 + "Maximum expected current cannot less then 32768.\n"); 135 + 136 + /* Calculate Current_LSB according to the spec formula */ 137 + current_lsb = max_current / 32768; 138 + 139 + /* calculate current coefficient */ 140 + calculate_coef(&m, &R, current_lsb, 1); 141 + info->m[PSC_CURRENT_OUT] = m; 142 + info->R[PSC_CURRENT_OUT] = R; 143 + 144 + /* calculate power coefficient */ 145 + calculate_coef(&m, &R, current_lsb, 25); 146 + info->m[PSC_POWER] = m; 147 + info->R[PSC_POWER] = R; 148 + 149 + /* write MFR_CALIBRATION register, Apply formula from spec with unit scaling. */ 150 + calibration = div64_u64(5120000000ULL, (u64)rshunt * current_lsb); 151 + if (calibration > 0x7FFF) 152 + return dev_err_probe(dev, -EINVAL, 153 + "Product of Current_LSB %u and shunt resistor %u too small, MFR_CALIBRATION reg exceeds 0x7FFF.\n", 154 + current_lsb, rshunt); 155 + ret = i2c_smbus_write_word_data(client, MFR_CALIBRATION, calibration); 156 + if (ret < 0) 157 + return dev_err_probe(dev, ret, "Unable to write calibration.\n"); 158 + 159 + dev_dbg(dev, "power monitor %s (Rshunt = %u uOhm, Current_LSB = %u uA/bit)\n", 160 + client->name, rshunt, current_lsb); 161 + 162 + return pmbus_do_probe(client, info); 163 + } 164 + 165 + static const struct i2c_device_id ina233_id[] = { 166 + {"ina233", 0}, 167 + {} 168 + }; 169 + MODULE_DEVICE_TABLE(i2c, ina233_id); 170 + 171 + static const struct of_device_id __maybe_unused ina233_of_match[] = { 172 + { .compatible = "ti,ina233" }, 173 + {} 174 + }; 175 + MODULE_DEVICE_TABLE(of, ina233_of_match); 176 + 177 + static struct i2c_driver ina233_driver = { 178 + .driver = { 179 + .name = "ina233", 180 + .of_match_table = of_match_ptr(ina233_of_match), 181 + }, 182 + .probe = ina233_probe, 183 + .id_table = ina233_id, 184 + }; 185 + 186 + module_i2c_driver(ina233_driver); 187 + 188 + MODULE_AUTHOR("Leo Yang <leo.yang.sy0@gmail.com>"); 189 + MODULE_DESCRIPTION("PMBus driver for INA233 and compatible chips"); 190 + MODULE_LICENSE("GPL"); 191 + MODULE_IMPORT_NS("PMBUS");
+64 -5
drivers/hwmon/pmbus/ltc2978.c
··· 23 23 /* Managers */ 24 24 ltc2972, ltc2974, ltc2975, ltc2977, ltc2978, ltc2979, ltc2980, 25 25 /* Controllers */ 26 - ltc3880, ltc3882, ltc3883, ltc3884, ltc3886, ltc3887, ltc3889, ltc7132, 27 - ltc7841, ltc7880, 26 + lt7170, lt7171, ltc3880, ltc3882, ltc3883, ltc3884, ltc3886, ltc3887, 27 + ltc3889, ltc7132, ltc7841, ltc7880, 28 28 /* Modules */ 29 - ltm2987, ltm4664, ltm4675, ltm4676, ltm4677, ltm4678, ltm4680, ltm4686, 30 - ltm4700, 29 + ltm2987, ltm4664, ltm4673, ltm4675, ltm4676, ltm4677, ltm4678, ltm4680, 30 + ltm4686, ltm4700, 31 31 }; 32 32 33 33 /* Common for all chips */ ··· 62 62 63 63 #define LTC2978_ID_MASK 0xfff0 64 64 65 + #define LT7170_ID 0x1C10 65 66 #define LTC2972_ID 0x0310 66 67 #define LTC2974_ID 0x0210 67 68 #define LTC2975_ID 0x0220 ··· 87 86 #define LTM2987_ID_A 0x8010 /* A/B for two die IDs */ 88 87 #define LTM2987_ID_B 0x8020 89 88 #define LTM4664_ID 0x4120 89 + #define LTM4673_ID_REV1 0x0230 90 + #define LTM4673_ID 0x4480 90 91 #define LTM4675_ID 0x47a0 91 92 #define LTM4676_ID_REV1 0x4400 92 93 #define LTM4676_ID_REV2 0x4480 ··· 538 535 } 539 536 540 537 static const struct i2c_device_id ltc2978_id[] = { 538 + {"lt7170", lt7170}, 539 + {"lt7171", lt7171}, 541 540 {"ltc2972", ltc2972}, 542 541 {"ltc2974", ltc2974}, 543 542 {"ltc2975", ltc2975}, ··· 559 554 {"ltc7880", ltc7880}, 560 555 {"ltm2987", ltm2987}, 561 556 {"ltm4664", ltm4664}, 557 + {"ltm4673", ltm4673}, 562 558 {"ltm4675", ltm4675}, 563 559 {"ltm4676", ltm4676}, 564 560 {"ltm4677", ltm4677}, ··· 618 612 ret = i2c_smbus_read_block_data(client, PMBUS_MFR_ID, buf); 619 613 if (ret < 0) 620 614 return ret; 621 - if (ret < 3 || strncmp(buf, "LTC", 3)) 615 + if (ret < 3 || (strncmp(buf, "LTC", 3) && strncmp(buf, "ADI", 3))) 622 616 return -ENODEV; 623 617 624 618 ret = i2c_smbus_read_block_data(client, PMBUS_MFR_MODEL, buf); ··· 632 626 } 633 627 634 628 chip_id &= LTC2978_ID_MASK; 629 + 630 + if (chip_id == LT7170_ID) { 631 + u8 buf[I2C_SMBUS_BLOCK_MAX]; 632 + int ret; 633 + 634 + ret = i2c_smbus_read_i2c_block_data(client, PMBUS_IC_DEVICE_ID, 635 + sizeof(buf), buf); 636 + if (ret < 0) 637 + return ret; 638 + 639 + if (!strncmp(buf + 1, "LT7170", 6) || 640 + !strncmp(buf + 1, "LT7170-1", 8)) 641 + return lt7170; 642 + if (!strncmp(buf + 1, "LT7171", 6) || 643 + !strncmp(buf + 1, "LT7171-1", 8)) 644 + return lt7171; 645 + 646 + return -ENODEV; 647 + } 635 648 636 649 if (chip_id == LTC2972_ID) 637 650 return ltc2972; ··· 690 665 return ltm2987; 691 666 else if (chip_id == LTM4664_ID) 692 667 return ltm4664; 668 + else if (chip_id == LTM4673_ID || chip_id == LTM4673_ID_REV1) 669 + return ltm4673; 693 670 else if (chip_id == LTM4675_ID) 694 671 return ltm4675; 695 672 else if (chip_id == LTM4676_ID_REV1 || chip_id == LTM4676_ID_REV2 || ··· 763 736 data->temp2_max = 0x7c00; 764 737 765 738 switch (data->id) { 739 + case lt7170: 740 + case lt7171: 741 + data->features |= FEAT_CLEAR_PEAKS | FEAT_NEEDS_POLLING; 742 + info->read_word_data = ltc3883_read_word_data; 743 + info->pages = LTC3883_NUM_PAGES; 744 + info->format[PSC_VOLTAGE_IN] = ieee754; 745 + info->format[PSC_VOLTAGE_OUT] = ieee754; 746 + info->format[PSC_CURRENT_OUT] = ieee754; 747 + info->format[PSC_TEMPERATURE] = ieee754; 748 + info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT 749 + | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 750 + | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT 751 + | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; 752 + break; 766 753 case ltc2972: 767 754 info->read_word_data = ltc2975_read_word_data; 768 755 info->pages = LTC2972_NUM_PAGES; ··· 910 869 | PMBUS_HAVE_IOUT 911 870 | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; 912 871 break; 872 + case ltm4673: 873 + data->features |= FEAT_NEEDS_POLLING; 874 + info->read_word_data = ltc2975_read_word_data; 875 + info->pages = LTC2974_NUM_PAGES; 876 + info->func[0] = PMBUS_HAVE_VIN | PMBUS_HAVE_STATUS_INPUT 877 + | PMBUS_HAVE_TEMP2; 878 + for (i = 0; i < info->pages; i++) { 879 + info->func[i] |= PMBUS_HAVE_IIN 880 + | PMBUS_HAVE_VOUT | PMBUS_HAVE_STATUS_VOUT 881 + | PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT 882 + | PMBUS_HAVE_PIN 883 + | PMBUS_HAVE_POUT 884 + | PMBUS_HAVE_TEMP | PMBUS_HAVE_STATUS_TEMP; 885 + } 886 + break; 913 887 default: 914 888 return -ENODEV; 915 889 } ··· 963 907 964 908 #ifdef CONFIG_OF 965 909 static const struct of_device_id ltc2978_of_match[] = { 910 + { .compatible = "lltc,lt7170" }, 911 + { .compatible = "lltc,lt7171" }, 966 912 { .compatible = "lltc,ltc2972" }, 967 913 { .compatible = "lltc,ltc2974" }, 968 914 { .compatible = "lltc,ltc2975" }, ··· 984 926 { .compatible = "lltc,ltc7880" }, 985 927 { .compatible = "lltc,ltm2987" }, 986 928 { .compatible = "lltc,ltm4664" }, 929 + { .compatible = "lltc,ltm4673" }, 987 930 { .compatible = "lltc,ltm4675" }, 988 931 { .compatible = "lltc,ltm4676" }, 989 932 { .compatible = "lltc,ltm4677" },
+150 -227
drivers/hwmon/pmbus/pmbus_core.c
··· 8 8 9 9 #include <linux/debugfs.h> 10 10 #include <linux/delay.h> 11 + #include <linux/dcache.h> 11 12 #include <linux/kernel.h> 12 13 #include <linux/math64.h> 13 14 #include <linux/module.h> ··· 45 44 enum pmbus_sensor_classes class; /* sensor class */ 46 45 bool update; /* runtime sensor update needed */ 47 46 bool convert; /* Whether or not to apply linear/vid/direct */ 48 - int data; /* Sensor data. 49 - Negative if there was a read error */ 47 + int data; /* Sensor data; negative if there was a read error */ 50 48 }; 51 49 #define to_pmbus_sensor(_attr) \ 52 50 container_of(_attr, struct pmbus_sensor, attribute) ··· 100 100 int num_attributes; 101 101 struct attribute_group group; 102 102 const struct attribute_group **groups; 103 - struct dentry *debugfs; /* debugfs device directory */ 104 103 105 104 struct pmbus_sensor *sensors; 106 105 ··· 191 192 struct pmbus_data *data = i2c_get_clientdata(client); 192 193 const struct pmbus_driver_info *info = data->info; 193 194 194 - if (info->access_delay) { 195 + if (info->access_delay) 195 196 data->access_time = ktime_get(); 196 - } else if (info->write_delay && write_op) { 197 + else if (info->write_delay && write_op) 197 198 data->write_time = ktime_get(); 198 - } 199 199 } 200 200 201 201 int pmbus_set_page(struct i2c_client *client, int page, int phase) ··· 290 292 } 291 293 EXPORT_SYMBOL_NS_GPL(pmbus_write_word_data, "PMBUS"); 292 294 293 - 294 295 static int pmbus_write_virt_reg(struct i2c_client *client, int page, int reg, 295 296 u16 word) 296 297 { ··· 378 381 u8 to; 379 382 380 383 from = _pmbus_read_byte_data(client, page, 381 - pmbus_fan_config_registers[id]); 384 + pmbus_fan_config_registers[id]); 382 385 if (from < 0) 383 386 return from; 384 387 385 388 to = (from & ~mask) | (config & mask); 386 389 if (to != from) { 387 390 rv = _pmbus_write_byte_data(client, page, 388 - pmbus_fan_config_registers[id], to); 391 + pmbus_fan_config_registers[id], to); 389 392 if (rv < 0) 390 393 return rv; 391 394 } ··· 560 563 } 561 564 562 565 config = _pmbus_read_byte_data(client, page, 563 - pmbus_fan_config_registers[id]); 566 + pmbus_fan_config_registers[id]); 564 567 if (config < 0) 565 568 return config; 566 569 ··· 785 788 786 789 if (sensor->class == PSC_VOLTAGE_OUT) { /* LINEAR16 */ 787 790 exponent = data->exponent[sensor->page]; 788 - mantissa = (u16) sensor->data; 791 + mantissa = (u16)sensor->data; 789 792 } else { /* LINEAR11 */ 790 793 exponent = ((s16)sensor->data) >> 11; 791 794 mantissa = ((s16)((sensor->data & 0x7ff) << 5)) >> 5; ··· 1170 1173 } else { 1171 1174 pmbus_clear_fault_page(client, page); 1172 1175 } 1173 - 1174 1176 } 1175 1177 if (s1 && s2) { 1176 1178 s64 v1, v2; ··· 1466 1470 snprintf(label->name, sizeof(label->name), "%s%d_label", name, seq); 1467 1471 if (!index) { 1468 1472 if (phase == 0xff) 1469 - strncpy(label->label, lstring, 1470 - sizeof(label->label) - 1); 1473 + strscpy(label->label, lstring); 1471 1474 else 1472 1475 snprintf(label->label, sizeof(label->label), "%s.%d", 1473 1476 lstring, phase); ··· 1495 1500 u16 reg; /* Limit register */ 1496 1501 u16 sbit; /* Alarm attribute status bit */ 1497 1502 bool update; /* True if register needs updates */ 1498 - bool low; /* True if low limit; for limits with compare 1499 - functions only */ 1503 + bool low; /* True if low limit; for limits with compare functions only */ 1500 1504 const char *attr; /* Attribute name */ 1501 1505 const char *alarm; /* Alarm attribute name */ 1502 1506 }; ··· 2206 2212 2207 2213 /* Precondition: FAN_CONFIG_x_y and FAN_COMMAND_x must exist for the fan ID */ 2208 2214 static int pmbus_add_fan_ctrl(struct i2c_client *client, 2209 - struct pmbus_data *data, int index, int page, int id, 2210 - u8 config) 2215 + struct pmbus_data *data, int index, int page, 2216 + int id, u8 config) 2211 2217 { 2212 2218 struct pmbus_sensor *sensor; 2213 2219 ··· 2219 2225 return -ENOMEM; 2220 2226 2221 2227 if (!((data->info->func[page] & PMBUS_HAVE_PWM12) || 2222 - (data->info->func[page] & PMBUS_HAVE_PWM34))) 2228 + (data->info->func[page] & PMBUS_HAVE_PWM34))) 2223 2229 return 0; 2224 2230 2225 2231 sensor = pmbus_add_sensor(data, "pwm", NULL, index, page, ··· 2929 2935 } 2930 2936 2931 2937 static int _pmbus_get_flags(struct pmbus_data *data, u8 page, unsigned int *flags, 2932 - unsigned int *event, bool notify) 2938 + unsigned int *event, bool notify) 2933 2939 { 2934 2940 int i, status; 2935 2941 const struct pmbus_status_category *cat; ··· 2958 2964 2959 2965 if (notify && status) 2960 2966 pmbus_notify(data, page, cat->reg, status); 2961 - 2962 2967 } 2963 2968 2964 2969 /* ··· 3007 3014 *flags |= REGULATOR_ERROR_OVER_TEMP_WARN; 3008 3015 *event |= REGULATOR_EVENT_OVER_TEMP_WARN; 3009 3016 } 3010 - 3011 3017 3012 3018 return 0; 3013 3019 } ··· 3220 3228 } 3221 3229 3222 3230 static int pmbus_regulator_list_voltage(struct regulator_dev *rdev, 3223 - unsigned int selector) 3231 + unsigned int selector) 3224 3232 { 3225 3233 struct device *dev = rdev_get_dev(rdev); 3226 3234 struct i2c_client *client = to_i2c_client(dev->parent); ··· 3312 3320 return 0; 3313 3321 } 3314 3322 3315 - static int pmbus_regulator_notify(struct pmbus_data *data, int page, int event) 3323 + static void pmbus_regulator_notify(struct pmbus_data *data, int page, int event) 3316 3324 { 3317 - int j; 3325 + int j; 3318 3326 3319 - for (j = 0; j < data->info->num_regulators; j++) { 3320 - if (page == rdev_get_id(data->rdevs[j])) { 3321 - regulator_notifier_call_chain(data->rdevs[j], event, NULL); 3322 - break; 3323 - } 3327 + for (j = 0; j < data->info->num_regulators; j++) { 3328 + if (page == rdev_get_id(data->rdevs[j])) { 3329 + regulator_notifier_call_chain(data->rdevs[j], event, NULL); 3330 + break; 3324 3331 } 3325 - return 0; 3332 + } 3326 3333 } 3327 3334 #else 3328 3335 static int pmbus_regulator_register(struct pmbus_data *data) ··· 3329 3338 return 0; 3330 3339 } 3331 3340 3332 - static int pmbus_regulator_notify(struct pmbus_data *data, int page, int event) 3341 + static void pmbus_regulator_notify(struct pmbus_data *data, int page, int event) 3333 3342 { 3334 - return 0; 3335 3343 } 3336 3344 #endif 3337 3345 ··· 3353 3363 { 3354 3364 struct pmbus_data *data = pdata; 3355 3365 struct i2c_client *client = to_i2c_client(data->dev); 3356 - 3357 3366 int i, status, event; 3367 + 3358 3368 mutex_lock(&data->update_lock); 3359 3369 for (i = 0; i < data->info->pages; i++) { 3360 3370 _pmbus_get_flags(data, i, &status, &event, true); ··· 3418 3428 3419 3429 static struct dentry *pmbus_debugfs_dir; /* pmbus debugfs directory */ 3420 3430 3421 - #if IS_ENABLED(CONFIG_DEBUG_FS) 3422 3431 static int pmbus_debugfs_get(void *data, u64 *val) 3423 3432 { 3424 3433 int rc; ··· 3460 3471 DEFINE_DEBUGFS_ATTRIBUTE(pmbus_debugfs_ops_status, pmbus_debugfs_get_status, 3461 3472 NULL, "0x%04llx\n"); 3462 3473 3463 - static ssize_t pmbus_debugfs_mfr_read(struct file *file, char __user *buf, 3464 - size_t count, loff_t *ppos) 3474 + static ssize_t pmbus_debugfs_block_read(struct file *file, char __user *buf, 3475 + size_t count, loff_t *ppos) 3465 3476 { 3466 3477 int rc; 3467 3478 struct pmbus_debugfs_entry *entry = file->private_data; ··· 3486 3497 return simple_read_from_buffer(buf, count, ppos, data, rc); 3487 3498 } 3488 3499 3489 - static const struct file_operations pmbus_debugfs_ops_mfr = { 3500 + static const struct file_operations pmbus_debugfs_block_ops = { 3490 3501 .llseek = noop_llseek, 3491 - .read = pmbus_debugfs_mfr_read, 3502 + .read = pmbus_debugfs_block_read, 3492 3503 .write = NULL, 3493 3504 .open = simple_open, 3494 3505 }; 3495 3506 3496 - static void pmbus_remove_debugfs(void *data) 3507 + static void pmbus_remove_symlink(void *symlink) 3497 3508 { 3498 - struct dentry *entry = data; 3499 - 3500 - debugfs_remove_recursive(entry); 3509 + debugfs_remove(symlink); 3501 3510 } 3502 3511 3503 - static int pmbus_init_debugfs(struct i2c_client *client, 3504 - struct pmbus_data *data) 3505 - { 3506 - int i, idx = 0; 3507 - char name[PMBUS_NAME_SIZE]; 3508 - struct pmbus_debugfs_entry *entries; 3512 + struct pmbus_debugfs_data { 3513 + u8 reg; 3514 + u32 flag; 3515 + const char *name; 3516 + }; 3509 3517 3510 - if (!pmbus_debugfs_dir) 3511 - return -ENODEV; 3518 + static const struct pmbus_debugfs_data pmbus_debugfs_block_data[] = { 3519 + { .reg = PMBUS_MFR_ID, .name = "mfr_id" }, 3520 + { .reg = PMBUS_MFR_MODEL, .name = "mfr_model" }, 3521 + { .reg = PMBUS_MFR_REVISION, .name = "mfr_revision" }, 3522 + { .reg = PMBUS_MFR_LOCATION, .name = "mfr_location" }, 3523 + { .reg = PMBUS_MFR_DATE, .name = "mfr_date" }, 3524 + { .reg = PMBUS_MFR_SERIAL, .name = "mfr_serial" }, 3525 + }; 3526 + 3527 + static const struct pmbus_debugfs_data pmbus_debugfs_status_data[] = { 3528 + { .reg = PMBUS_STATUS_VOUT, .flag = PMBUS_HAVE_STATUS_VOUT, .name = "status%d_vout" }, 3529 + { .reg = PMBUS_STATUS_IOUT, .flag = PMBUS_HAVE_STATUS_IOUT, .name = "status%d_iout" }, 3530 + { .reg = PMBUS_STATUS_INPUT, .flag = PMBUS_HAVE_STATUS_INPUT, .name = "status%d_input" }, 3531 + { .reg = PMBUS_STATUS_TEMPERATURE, .flag = PMBUS_HAVE_STATUS_TEMP, 3532 + .name = "status%d_temp" }, 3533 + { .reg = PMBUS_STATUS_FAN_12, .flag = PMBUS_HAVE_STATUS_FAN12, .name = "status%d_fan12" }, 3534 + { .reg = PMBUS_STATUS_FAN_34, .flag = PMBUS_HAVE_STATUS_FAN34, .name = "status%d_fan34" }, 3535 + { .reg = PMBUS_STATUS_CML, .name = "status%d_cml" }, 3536 + { .reg = PMBUS_STATUS_OTHER, .name = "status%d_other" }, 3537 + { .reg = PMBUS_STATUS_MFR_SPECIFIC, .name = "status%d_mfr" }, 3538 + }; 3539 + 3540 + static void pmbus_init_debugfs(struct i2c_client *client, 3541 + struct pmbus_data *data) 3542 + { 3543 + struct dentry *symlink_d, *debugfs = client->debugfs; 3544 + struct pmbus_debugfs_entry *entries; 3545 + const char *pathname, *symlink; 3546 + char name[PMBUS_NAME_SIZE]; 3547 + int page, i, idx = 0; 3512 3548 3513 3549 /* 3514 - * Create the debugfs directory for this device. Use the hwmon device 3515 - * name to avoid conflicts (hwmon numbers are globally unique). 3550 + * client->debugfs may be NULL or an ERR_PTR(). dentry_path_raw() 3551 + * does not check if its parameters are valid, so validate 3552 + * client->debugfs before using it. 3516 3553 */ 3517 - data->debugfs = debugfs_create_dir(dev_name(data->hwmon_dev), 3518 - pmbus_debugfs_dir); 3519 - if (IS_ERR_OR_NULL(data->debugfs)) { 3520 - data->debugfs = NULL; 3521 - return -ENODEV; 3522 - } 3554 + if (!pmbus_debugfs_dir || IS_ERR_OR_NULL(debugfs)) 3555 + return; 3556 + 3557 + /* 3558 + * Backwards compatibility: Create symlink from /pmbus/<hwmon_device> 3559 + * to i2c debugfs directory. 3560 + */ 3561 + pathname = dentry_path_raw(debugfs, name, sizeof(name)); 3562 + if (IS_ERR(pathname)) 3563 + return; 3564 + 3565 + /* 3566 + * The path returned by dentry_path_raw() starts with '/'. Prepend it 3567 + * with ".." to get the symlink relative to the pmbus root directory. 3568 + */ 3569 + symlink = kasprintf(GFP_KERNEL, "..%s", pathname); 3570 + if (!symlink) 3571 + return; 3572 + 3573 + symlink_d = debugfs_create_symlink(dev_name(data->hwmon_dev), 3574 + pmbus_debugfs_dir, symlink); 3575 + kfree(symlink); 3576 + 3577 + devm_add_action_or_reset(data->dev, pmbus_remove_symlink, symlink_d); 3523 3578 3524 3579 /* 3525 3580 * Allocate the max possible entries we need. 3526 - * 7 entries device-specific 3527 - * 10 entries page-specific 3581 + * device specific: 3582 + * ARRAY_SIZE(pmbus_debugfs_block_data) + 2 3583 + * page specific: 3584 + * ARRAY_SIZE(pmbus_debugfs_status_data) + 1 3528 3585 */ 3529 3586 entries = devm_kcalloc(data->dev, 3530 - 7 + data->info->pages * 10, sizeof(*entries), 3531 - GFP_KERNEL); 3587 + ARRAY_SIZE(pmbus_debugfs_block_data) + 2 + 3588 + data->info->pages * (ARRAY_SIZE(pmbus_debugfs_status_data) + 1), 3589 + sizeof(*entries), GFP_KERNEL); 3532 3590 if (!entries) 3533 - return -ENOMEM; 3591 + return; 3534 3592 3535 3593 /* 3536 3594 * Add device-specific entries. ··· 3587 3551 * assume that values of the following registers are the same for all 3588 3552 * pages and report values only for page 0. 3589 3553 */ 3554 + if (!(data->flags & PMBUS_NO_CAPABILITY) && 3555 + pmbus_check_byte_register(client, 0, PMBUS_CAPABILITY)) { 3556 + entries[idx].client = client; 3557 + entries[idx].page = 0; 3558 + entries[idx].reg = PMBUS_CAPABILITY; 3559 + debugfs_create_file("capability", 0444, debugfs, 3560 + &entries[idx++], 3561 + &pmbus_debugfs_ops); 3562 + } 3590 3563 if (pmbus_check_byte_register(client, 0, PMBUS_REVISION)) { 3591 3564 entries[idx].client = client; 3592 3565 entries[idx].page = 0; 3593 3566 entries[idx].reg = PMBUS_REVISION; 3594 - debugfs_create_file("revision", 0444, data->debugfs, 3567 + debugfs_create_file("pmbus_revision", 0444, debugfs, 3595 3568 &entries[idx++], 3596 3569 &pmbus_debugfs_ops); 3597 3570 } 3598 3571 3599 - if (pmbus_check_block_register(client, 0, PMBUS_MFR_ID)) { 3600 - entries[idx].client = client; 3601 - entries[idx].page = 0; 3602 - entries[idx].reg = PMBUS_MFR_ID; 3603 - debugfs_create_file("mfr_id", 0444, data->debugfs, 3604 - &entries[idx++], 3605 - &pmbus_debugfs_ops_mfr); 3606 - } 3572 + for (i = 0; i < ARRAY_SIZE(pmbus_debugfs_block_data); i++) { 3573 + const struct pmbus_debugfs_data *d = &pmbus_debugfs_block_data[i]; 3607 3574 3608 - if (pmbus_check_block_register(client, 0, PMBUS_MFR_MODEL)) { 3609 - entries[idx].client = client; 3610 - entries[idx].page = 0; 3611 - entries[idx].reg = PMBUS_MFR_MODEL; 3612 - debugfs_create_file("mfr_model", 0444, data->debugfs, 3613 - &entries[idx++], 3614 - &pmbus_debugfs_ops_mfr); 3615 - } 3616 - 3617 - if (pmbus_check_block_register(client, 0, PMBUS_MFR_REVISION)) { 3618 - entries[idx].client = client; 3619 - entries[idx].page = 0; 3620 - entries[idx].reg = PMBUS_MFR_REVISION; 3621 - debugfs_create_file("mfr_revision", 0444, data->debugfs, 3622 - &entries[idx++], 3623 - &pmbus_debugfs_ops_mfr); 3624 - } 3625 - 3626 - if (pmbus_check_block_register(client, 0, PMBUS_MFR_LOCATION)) { 3627 - entries[idx].client = client; 3628 - entries[idx].page = 0; 3629 - entries[idx].reg = PMBUS_MFR_LOCATION; 3630 - debugfs_create_file("mfr_location", 0444, data->debugfs, 3631 - &entries[idx++], 3632 - &pmbus_debugfs_ops_mfr); 3633 - } 3634 - 3635 - if (pmbus_check_block_register(client, 0, PMBUS_MFR_DATE)) { 3636 - entries[idx].client = client; 3637 - entries[idx].page = 0; 3638 - entries[idx].reg = PMBUS_MFR_DATE; 3639 - debugfs_create_file("mfr_date", 0444, data->debugfs, 3640 - &entries[idx++], 3641 - &pmbus_debugfs_ops_mfr); 3642 - } 3643 - 3644 - if (pmbus_check_block_register(client, 0, PMBUS_MFR_SERIAL)) { 3645 - entries[idx].client = client; 3646 - entries[idx].page = 0; 3647 - entries[idx].reg = PMBUS_MFR_SERIAL; 3648 - debugfs_create_file("mfr_serial", 0444, data->debugfs, 3649 - &entries[idx++], 3650 - &pmbus_debugfs_ops_mfr); 3575 + if (pmbus_check_block_register(client, 0, d->reg)) { 3576 + entries[idx].client = client; 3577 + entries[idx].page = 0; 3578 + entries[idx].reg = d->reg; 3579 + debugfs_create_file(d->name, 0444, debugfs, 3580 + &entries[idx++], 3581 + &pmbus_debugfs_block_ops); 3582 + } 3651 3583 } 3652 3584 3653 3585 /* Add page specific entries */ 3654 - for (i = 0; i < data->info->pages; ++i) { 3586 + for (page = 0; page < data->info->pages; ++page) { 3655 3587 /* Check accessibility of status register if it's not page 0 */ 3656 - if (!i || pmbus_check_status_register(client, i)) { 3588 + if (!page || pmbus_check_status_register(client, page)) { 3657 3589 /* No need to set reg as we have special read op. */ 3658 3590 entries[idx].client = client; 3659 - entries[idx].page = i; 3660 - scnprintf(name, PMBUS_NAME_SIZE, "status%d", i); 3661 - debugfs_create_file(name, 0444, data->debugfs, 3591 + entries[idx].page = page; 3592 + scnprintf(name, PMBUS_NAME_SIZE, "status%d", page); 3593 + debugfs_create_file(name, 0444, debugfs, 3662 3594 &entries[idx++], 3663 3595 &pmbus_debugfs_ops_status); 3664 3596 } 3665 3597 3666 - if (data->info->func[i] & PMBUS_HAVE_STATUS_VOUT) { 3667 - entries[idx].client = client; 3668 - entries[idx].page = i; 3669 - entries[idx].reg = PMBUS_STATUS_VOUT; 3670 - scnprintf(name, PMBUS_NAME_SIZE, "status%d_vout", i); 3671 - debugfs_create_file(name, 0444, data->debugfs, 3672 - &entries[idx++], 3673 - &pmbus_debugfs_ops); 3674 - } 3598 + for (i = 0; i < ARRAY_SIZE(pmbus_debugfs_status_data); i++) { 3599 + const struct pmbus_debugfs_data *d = 3600 + &pmbus_debugfs_status_data[i]; 3675 3601 3676 - if (data->info->func[i] & PMBUS_HAVE_STATUS_IOUT) { 3677 - entries[idx].client = client; 3678 - entries[idx].page = i; 3679 - entries[idx].reg = PMBUS_STATUS_IOUT; 3680 - scnprintf(name, PMBUS_NAME_SIZE, "status%d_iout", i); 3681 - debugfs_create_file(name, 0444, data->debugfs, 3682 - &entries[idx++], 3683 - &pmbus_debugfs_ops); 3684 - } 3685 - 3686 - if (data->info->func[i] & PMBUS_HAVE_STATUS_INPUT) { 3687 - entries[idx].client = client; 3688 - entries[idx].page = i; 3689 - entries[idx].reg = PMBUS_STATUS_INPUT; 3690 - scnprintf(name, PMBUS_NAME_SIZE, "status%d_input", i); 3691 - debugfs_create_file(name, 0444, data->debugfs, 3692 - &entries[idx++], 3693 - &pmbus_debugfs_ops); 3694 - } 3695 - 3696 - if (data->info->func[i] & PMBUS_HAVE_STATUS_TEMP) { 3697 - entries[idx].client = client; 3698 - entries[idx].page = i; 3699 - entries[idx].reg = PMBUS_STATUS_TEMPERATURE; 3700 - scnprintf(name, PMBUS_NAME_SIZE, "status%d_temp", i); 3701 - debugfs_create_file(name, 0444, data->debugfs, 3702 - &entries[idx++], 3703 - &pmbus_debugfs_ops); 3704 - } 3705 - 3706 - if (pmbus_check_byte_register(client, i, PMBUS_STATUS_CML)) { 3707 - entries[idx].client = client; 3708 - entries[idx].page = i; 3709 - entries[idx].reg = PMBUS_STATUS_CML; 3710 - scnprintf(name, PMBUS_NAME_SIZE, "status%d_cml", i); 3711 - debugfs_create_file(name, 0444, data->debugfs, 3712 - &entries[idx++], 3713 - &pmbus_debugfs_ops); 3714 - } 3715 - 3716 - if (pmbus_check_byte_register(client, i, PMBUS_STATUS_OTHER)) { 3717 - entries[idx].client = client; 3718 - entries[idx].page = i; 3719 - entries[idx].reg = PMBUS_STATUS_OTHER; 3720 - scnprintf(name, PMBUS_NAME_SIZE, "status%d_other", i); 3721 - debugfs_create_file(name, 0444, data->debugfs, 3722 - &entries[idx++], 3723 - &pmbus_debugfs_ops); 3724 - } 3725 - 3726 - if (pmbus_check_byte_register(client, i, 3727 - PMBUS_STATUS_MFR_SPECIFIC)) { 3728 - entries[idx].client = client; 3729 - entries[idx].page = i; 3730 - entries[idx].reg = PMBUS_STATUS_MFR_SPECIFIC; 3731 - scnprintf(name, PMBUS_NAME_SIZE, "status%d_mfr", i); 3732 - debugfs_create_file(name, 0444, data->debugfs, 3733 - &entries[idx++], 3734 - &pmbus_debugfs_ops); 3735 - } 3736 - 3737 - if (data->info->func[i] & PMBUS_HAVE_STATUS_FAN12) { 3738 - entries[idx].client = client; 3739 - entries[idx].page = i; 3740 - entries[idx].reg = PMBUS_STATUS_FAN_12; 3741 - scnprintf(name, PMBUS_NAME_SIZE, "status%d_fan12", i); 3742 - debugfs_create_file(name, 0444, data->debugfs, 3743 - &entries[idx++], 3744 - &pmbus_debugfs_ops); 3745 - } 3746 - 3747 - if (data->info->func[i] & PMBUS_HAVE_STATUS_FAN34) { 3748 - entries[idx].client = client; 3749 - entries[idx].page = i; 3750 - entries[idx].reg = PMBUS_STATUS_FAN_34; 3751 - scnprintf(name, PMBUS_NAME_SIZE, "status%d_fan34", i); 3752 - debugfs_create_file(name, 0444, data->debugfs, 3753 - &entries[idx++], 3754 - &pmbus_debugfs_ops); 3602 + if ((data->info->func[page] & d->flag) || 3603 + (!d->flag && pmbus_check_byte_register(client, page, d->reg))) { 3604 + entries[idx].client = client; 3605 + entries[idx].page = page; 3606 + entries[idx].reg = d->reg; 3607 + scnprintf(name, PMBUS_NAME_SIZE, d->name, page); 3608 + debugfs_create_file(name, 0444, debugfs, 3609 + &entries[idx++], 3610 + &pmbus_debugfs_ops); 3611 + } 3755 3612 } 3756 3613 } 3757 - 3758 - return devm_add_action_or_reset(data->dev, 3759 - pmbus_remove_debugfs, data->debugfs); 3760 3614 } 3761 - #else 3762 - static int pmbus_init_debugfs(struct i2c_client *client, 3763 - struct pmbus_data *data) 3764 - { 3765 - return 0; 3766 - } 3767 - #endif /* IS_ENABLED(CONFIG_DEBUG_FS) */ 3768 3615 3769 3616 int pmbus_do_probe(struct i2c_client *client, struct pmbus_driver_info *info) 3770 3617 { ··· 3719 3800 3720 3801 data->groups[0] = &data->group; 3721 3802 memcpy(data->groups + 1, info->groups, sizeof(void *) * groups_num); 3722 - data->hwmon_dev = devm_hwmon_device_register_with_groups(dev, 3723 - name, data, data->groups); 3803 + data->hwmon_dev = devm_hwmon_device_register_with_groups(dev, name, 3804 + data, data->groups); 3724 3805 if (IS_ERR(data->hwmon_dev)) { 3725 3806 dev_err(dev, "Failed to register hwmon device\n"); 3726 3807 return PTR_ERR(data->hwmon_dev); ··· 3734 3815 if (ret) 3735 3816 return ret; 3736 3817 3737 - ret = pmbus_init_debugfs(client, data); 3738 - if (ret) 3739 - dev_warn(dev, "Failed to register debugfs\n"); 3818 + pmbus_init_debugfs(client, data); 3740 3819 3741 3820 return 0; 3742 3821 } ··· 3742 3825 3743 3826 struct dentry *pmbus_get_debugfs_dir(struct i2c_client *client) 3744 3827 { 3745 - struct pmbus_data *data = i2c_get_clientdata(client); 3746 - 3747 - return data->debugfs; 3828 + /* 3829 + * client->debugfs may be an ERR_PTR(). Returning that to 3830 + * the calling code would potentially require additional 3831 + * complexity in the calling code and otherwise add no 3832 + * value. Return NULL in that case. 3833 + */ 3834 + if (IS_ERR_OR_NULL(client->debugfs)) 3835 + return NULL; 3836 + return client->debugfs; 3748 3837 } 3749 3838 EXPORT_SYMBOL_NS_GPL(pmbus_get_debugfs_dir, "PMBUS"); 3750 3839
+9 -37
drivers/hwmon/pt5161l.c
··· 63 63 /* Each client has this additional data */ 64 64 struct pt5161l_data { 65 65 struct i2c_client *client; 66 - struct dentry *debugfs; 67 66 struct pt5161l_fw_ver fw_ver; 68 67 struct mutex lock; /* for atomic I2C transactions */ 69 68 bool init_done; ··· 70 71 bool mm_heartbeat_okay; /* indicate if Main Micro heartbeat is good */ 71 72 bool mm_wide_reg_access; /* MM assisted wide register access */ 72 73 }; 73 - 74 - static struct dentry *pt5161l_debugfs_dir; 75 74 76 75 /* 77 76 * Write multiple data bytes to Aries over I2C ··· 565 568 .open = simple_open, 566 569 }; 567 570 568 - static int pt5161l_init_debugfs(struct pt5161l_data *data) 571 + static void pt5161l_init_debugfs(struct i2c_client *client, struct pt5161l_data *data) 569 572 { 570 - data->debugfs = debugfs_create_dir(dev_name(&data->client->dev), 571 - pt5161l_debugfs_dir); 572 - 573 - debugfs_create_file("fw_ver", 0444, data->debugfs, data, 573 + debugfs_create_file("fw_ver", 0444, client->debugfs, data, 574 574 &pt5161l_debugfs_ops_fw_ver); 575 575 576 - debugfs_create_file("fw_load_status", 0444, data->debugfs, data, 576 + debugfs_create_file("fw_load_status", 0444, client->debugfs, data, 577 577 &pt5161l_debugfs_ops_fw_load_sts); 578 578 579 - debugfs_create_file("heartbeat_status", 0444, data->debugfs, data, 579 + debugfs_create_file("heartbeat_status", 0444, client->debugfs, data, 580 580 &pt5161l_debugfs_ops_hb_sts); 581 - 582 - return 0; 583 581 } 584 582 585 583 static int pt5161l_probe(struct i2c_client *client) ··· 596 604 data, 597 605 &pt5161l_chip_info, 598 606 NULL); 607 + if (IS_ERR(hwmon_dev)) 608 + return PTR_ERR(hwmon_dev); 599 609 600 - pt5161l_init_debugfs(data); 610 + pt5161l_init_debugfs(client, data); 601 611 602 - return PTR_ERR_OR_ZERO(hwmon_dev); 603 - } 604 - 605 - static void pt5161l_remove(struct i2c_client *client) 606 - { 607 - struct pt5161l_data *data = i2c_get_clientdata(client); 608 - 609 - debugfs_remove_recursive(data->debugfs); 612 + return 0; 610 613 } 611 614 612 615 static const struct of_device_id __maybe_unused pt5161l_of_match[] = { ··· 630 643 .acpi_match_table = ACPI_PTR(pt5161l_acpi_match), 631 644 }, 632 645 .probe = pt5161l_probe, 633 - .remove = pt5161l_remove, 634 646 .id_table = pt5161l_id, 635 647 }; 636 - 637 - static int __init pt5161l_init(void) 638 - { 639 - pt5161l_debugfs_dir = debugfs_create_dir("pt5161l", NULL); 640 - return i2c_add_driver(&pt5161l_driver); 641 - } 642 - 643 - static void __exit pt5161l_exit(void) 644 - { 645 - i2c_del_driver(&pt5161l_driver); 646 - debugfs_remove_recursive(pt5161l_debugfs_dir); 647 - } 648 - 649 - module_init(pt5161l_init); 650 - module_exit(pt5161l_exit); 648 + module_i2c_driver(pt5161l_driver); 651 649 652 650 MODULE_AUTHOR("Cosmo Chou <cosmo.chou@quantatw.com>"); 653 651 MODULE_DESCRIPTION("Hwmon driver for Astera Labs Aries PCIe retimer");
+7 -35
drivers/hwmon/sg2042-mcu.c
··· 50 50 51 51 struct sg2042_mcu_data { 52 52 struct i2c_client *client; 53 - struct dentry *debugfs; 54 53 struct mutex mutex; 55 54 }; 56 - 57 - static struct dentry *sgmcu_debugfs; 58 55 59 56 static ssize_t reset_count_show(struct device *dev, 60 57 struct device_attribute *attr, ··· 289 292 .info = sg2042_mcu_info, 290 293 }; 291 294 292 - static void sg2042_mcu_debugfs_init(struct sg2042_mcu_data *mcu, 293 - struct device *dev) 295 + static void sg2042_mcu_debugfs_init(struct sg2042_mcu_data *mcu) 294 296 { 295 - mcu->debugfs = debugfs_create_dir(dev_name(dev), sgmcu_debugfs); 296 - 297 - debugfs_create_file("firmware_version", 0444, mcu->debugfs, 297 + debugfs_create_file("firmware_version", 0444, mcu->client->debugfs, 298 298 mcu, &firmware_version_fops); 299 - debugfs_create_file("pcb_version", 0444, mcu->debugfs, mcu, 299 + debugfs_create_file("pcb_version", 0444, mcu->client->debugfs, mcu, 300 300 &pcb_version_fops); 301 - debugfs_create_file("mcu_type", 0444, mcu->debugfs, mcu, 301 + debugfs_create_file("mcu_type", 0444, mcu->client->debugfs, mcu, 302 302 &mcu_type_fops); 303 - debugfs_create_file("board_type", 0444, mcu->debugfs, mcu, 303 + debugfs_create_file("board_type", 0444, mcu->client->debugfs, mcu, 304 304 &board_type_fops); 305 305 } 306 306 ··· 327 333 if (IS_ERR(hwmon_dev)) 328 334 return PTR_ERR(hwmon_dev); 329 335 330 - sg2042_mcu_debugfs_init(mcu, dev); 336 + sg2042_mcu_debugfs_init(mcu); 331 337 332 338 return 0; 333 - } 334 - 335 - static void sg2042_mcu_i2c_remove(struct i2c_client *client) 336 - { 337 - struct sg2042_mcu_data *mcu = i2c_get_clientdata(client); 338 - 339 - debugfs_remove_recursive(mcu->debugfs); 340 339 } 341 340 342 341 static const struct i2c_device_id sg2042_mcu_id[] = { ··· 351 364 .dev_groups = sg2042_mcu_groups, 352 365 }, 353 366 .probe = sg2042_mcu_i2c_probe, 354 - .remove = sg2042_mcu_i2c_remove, 355 367 .id_table = sg2042_mcu_id, 356 368 }; 357 - 358 - static int __init sg2042_mcu_init(void) 359 - { 360 - sgmcu_debugfs = debugfs_create_dir("sg2042-mcu", NULL); 361 - return i2c_add_driver(&sg2042_mcu_driver); 362 - } 363 - 364 - static void __exit sg2042_mcu_exit(void) 365 - { 366 - debugfs_remove_recursive(sgmcu_debugfs); 367 - i2c_del_driver(&sg2042_mcu_driver); 368 - } 369 - 370 - module_init(sg2042_mcu_init); 371 - module_exit(sg2042_mcu_exit); 369 + module_i2c_driver(sg2042_mcu_driver); 372 370 373 371 MODULE_AUTHOR("Inochi Amaoto <inochiama@outlook.com>"); 374 372 MODULE_DESCRIPTION("MCU I2C driver for SG2042 soc platform");
+11 -56
drivers/hwmon/sht3x.c
··· 44 44 static const unsigned char sht3x_cmd_clear_status_reg[] = { 0x30, 0x41 }; 45 45 static const unsigned char sht3x_cmd_read_serial_number[] = { 0x37, 0x80 }; 46 46 47 - static struct dentry *debugfs; 48 - 49 47 /* delays for single-shot mode i2c commands, both in us */ 50 48 #define SHT3X_SINGLE_WAIT_TIME_HPM 15000 51 49 #define SHT3X_SINGLE_WAIT_TIME_MPM 6000 ··· 165 167 enum sht3x_chips chip_id; 166 168 struct mutex i2c_lock; /* lock for sending i2c commands */ 167 169 struct mutex data_lock; /* lock for updating driver data */ 168 - struct dentry *sensor_dir; 169 170 170 171 u8 mode; 171 172 const unsigned char *command; ··· 834 837 } 835 838 } 836 839 837 - static void sht3x_debugfs_init(struct sht3x_data *data) 838 - { 839 - char name[32]; 840 - 841 - snprintf(name, sizeof(name), "i2c%u-%02x", 842 - data->client->adapter->nr, data->client->addr); 843 - data->sensor_dir = debugfs_create_dir(name, debugfs); 844 - debugfs_create_u32("serial_number", 0444, 845 - data->sensor_dir, &data->serial_number); 846 - } 847 - 848 - static void sht3x_debugfs_remove(void *sensor_dir) 849 - { 850 - debugfs_remove_recursive(sensor_dir); 851 - } 852 - 853 - static int sht3x_serial_number_read(struct sht3x_data *data) 840 + static void sht3x_serial_number_read(struct sht3x_data *data) 854 841 { 855 842 int ret; 856 843 char buffer[SHT3X_RESPONSE_LENGTH]; ··· 845 864 buffer, 846 865 SHT3X_RESPONSE_LENGTH, 0); 847 866 if (ret) 848 - return ret; 867 + return; 849 868 850 869 data->serial_number = (buffer[0] << 24) | (buffer[1] << 16) | 851 870 (buffer[3] << 8) | buffer[4]; 852 - return ret; 871 + 872 + debugfs_create_u32("serial_number", 0444, client->debugfs, &data->serial_number); 853 873 } 854 874 855 875 static const struct hwmon_ops sht3x_ops = { ··· 912 930 if (ret) 913 931 return ret; 914 932 915 - ret = sht3x_serial_number_read(data); 916 - if (ret) { 917 - dev_dbg(dev, "unable to read serial number\n"); 918 - } else { 919 - sht3x_debugfs_init(data); 920 - ret = devm_add_action_or_reset(dev, 921 - sht3x_debugfs_remove, 922 - data->sensor_dir); 923 - if (ret) 924 - return ret; 925 - } 926 - 927 - hwmon_dev = devm_hwmon_device_register_with_info(dev, 928 - client->name, 929 - data, 930 - &sht3x_chip_info, 931 - sht3x_groups); 932 - 933 + hwmon_dev = devm_hwmon_device_register_with_info(dev, client->name, data, 934 + &sht3x_chip_info, sht3x_groups); 933 935 if (IS_ERR(hwmon_dev)) 934 - dev_dbg(dev, "unable to register hwmon device\n"); 936 + return PTR_ERR(hwmon_dev); 935 937 936 - return PTR_ERR_OR_ZERO(hwmon_dev); 938 + sht3x_serial_number_read(data); 939 + 940 + return 0; 937 941 } 938 942 939 943 /* device ID table */ ··· 936 968 .probe = sht3x_probe, 937 969 .id_table = sht3x_ids, 938 970 }; 939 - 940 - static int __init sht3x_init(void) 941 - { 942 - debugfs = debugfs_create_dir("sht3x", NULL); 943 - return i2c_add_driver(&sht3x_i2c_driver); 944 - } 945 - module_init(sht3x_init); 946 - 947 - static void __exit sht3x_cleanup(void) 948 - { 949 - debugfs_remove_recursive(debugfs); 950 - i2c_del_driver(&sht3x_i2c_driver); 951 - } 952 - module_exit(sht3x_cleanup); 971 + module_i2c_driver(sht3x_i2c_driver); 953 972 954 973 MODULE_AUTHOR("David Frey <david.frey@sensirion.com>"); 955 974 MODULE_AUTHOR("Pascal Sachs <pascal.sachs@sensirion.com>");
+2 -29
drivers/hwmon/tps23861.c
··· 114 114 struct regmap *regmap; 115 115 u32 shunt_resistor; 116 116 struct i2c_client *client; 117 - struct dentry *debugfs_dir; 118 117 }; 119 118 120 119 static const struct regmap_config tps23861_regmap_config = { ··· 502 503 503 504 DEFINE_SHOW_ATTRIBUTE(tps23861_port_status); 504 505 505 - static void tps23861_init_debugfs(struct tps23861_data *data, 506 - struct device *hwmon_dev) 507 - { 508 - const char *debugfs_name; 509 - 510 - debugfs_name = devm_kasprintf(&data->client->dev, GFP_KERNEL, "%s-%s", 511 - data->client->name, dev_name(hwmon_dev)); 512 - if (!debugfs_name) 513 - return; 514 - 515 - data->debugfs_dir = debugfs_create_dir(debugfs_name, NULL); 516 - 517 - debugfs_create_file("port_status", 518 - 0400, 519 - data->debugfs_dir, 520 - data, 521 - &tps23861_port_status_fops); 522 - } 523 - 524 506 static int tps23861_probe(struct i2c_client *client) 525 507 { 526 508 struct device *dev = &client->dev; ··· 542 562 if (IS_ERR(hwmon_dev)) 543 563 return PTR_ERR(hwmon_dev); 544 564 545 - tps23861_init_debugfs(data, hwmon_dev); 565 + debugfs_create_file("port_status", 0400, client->debugfs, data, 566 + &tps23861_port_status_fops); 546 567 547 568 return 0; 548 - } 549 - 550 - static void tps23861_remove(struct i2c_client *client) 551 - { 552 - struct tps23861_data *data = i2c_get_clientdata(client); 553 - 554 - debugfs_remove_recursive(data->debugfs_dir); 555 569 } 556 570 557 571 static const struct of_device_id __maybe_unused tps23861_of_match[] = { ··· 556 582 557 583 static struct i2c_driver tps23861_driver = { 558 584 .probe = tps23861_probe, 559 - .remove = tps23861_remove, 560 585 .driver = { 561 586 .name = "tps23861", 562 587 .of_match_table = of_match_ptr(tps23861_of_match),
+1 -1
drivers/hwmon/xgene-hwmon.c
··· 105 105 106 106 phys_addr_t comm_base_addr; 107 107 void *pcc_comm_addr; 108 - u64 usecs_lat; 108 + unsigned int usecs_lat; 109 109 }; 110 110 111 111 /*
+1
include/linux/pci_ids.h
··· 569 569 #define PCI_DEVICE_ID_AMD_17H_DF_F3 0x1463 570 570 #define PCI_DEVICE_ID_AMD_17H_M10H_DF_F3 0x15eb 571 571 #define PCI_DEVICE_ID_AMD_17H_M30H_DF_F3 0x1493 572 + #define PCI_DEVICE_ID_AMD_17H_M40H_DF_F3 0x13f3 572 573 #define PCI_DEVICE_ID_AMD_17H_M60H_DF_F3 0x144b 573 574 #define PCI_DEVICE_ID_AMD_17H_M70H_DF_F3 0x1443 574 575 #define PCI_DEVICE_ID_AMD_17H_MA0H_DF_F3 0x1727