Browse Source

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

Pull hwmon updates from Guenter Roeck:
 "Notable changes:

   - Heiko Schocher provided a driver for TI TMP103.
   - Kamil Debski provided a driver for pwm-controlled fans.
   - Neelesh Gupta provided a driver for power, fan rpm, voltage and
     temperature reporting on powerpc/powernv systems.
   - Scott Kanowitz provided a driver supporting Lattice's POWR1220
     power manager IC.
   - Richard Zhu provided a pmbus front-end driver for TPS40422.
   - Frans Klaver added support for TMP112 to the lm75 driver.
   - Johannes Pointner added support for EPCOS B57330V2103 to the
     ntc_thermistor driver.
   - Guenter Roeck added support for TMP441 and TMP442 to the tmp421
     driver.
   - Axel Lin converted several drivers to the new hwmon API (36 of
     them, if I counted correctly), and cleaned up many of the drivers
     along the way.

  There are also a number of patches fixing bugs discovered while
  testing Axel's changes"

* tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (88 commits)
  hwmon: (g762) Use of_property_read_u32 at appropriate place
  hwmon: (sis5595) Prevent overflow problem when writing large limits
  hwmon: (gpio-fan) Prevent overflow problem when writing large limits
  hwmon: (ibmpowernv) Use of_property_read_u32 at appropriate place
  hwmon: (lm85) Convert to devm_hwmon_device_register_with_groups
  hwmon: (lm85) Avoid forward declaration
  hwmon: (lm78) Convert to devm_hwmon_device_register_with_groups
  hwmon: (max6697) Use of_property_read_bool at appropriate places
  hwmon: (pwm-fan) Make SENSORS_PWM_FAN depend on OF
  hwmon: (pwm-fan) Remove duplicate dev_set_drvdata call
  hwmon: (nct6775) Remove num_attr_groups from struct nct6775_data
  hwmon: (nct6775) Update module description and Kconfig for NCT6106D and NCT6791D
  hwmon: (adt7411) Convert to devm_hwmon_device_register_with_groups
  hwmon: (g762) Convert to hwmon_device_register_with_groups
  hwmon: (emc2103) Convert to devm_hwmon_device_register_with_groups
  hwmon: (smsc47m1) Avoid forward declaration
  hwmon: (smsc47m192) Convert to devm_hwmon_device_register_with_groups
  hwmon: (smsc47m192) Avoid forward declaration
  hwmon: (max1668) Make max1668_addr_list array const
  hwmon: (max6639) Make normal_i2c array const
  ...
Linus Torvalds 11 years ago
parent
commit
161d2e0a19
81 changed files with 4258 additions and 3885 deletions
  1. 23 0
      Documentation/devicetree/bindings/hwmon/ibmpowernv.txt
  2. 1 0
      Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt
  3. 12 0
      Documentation/devicetree/bindings/hwmon/pwm-fan.txt
  4. 1 0
      Documentation/devicetree/bindings/i2c/trivial-devices.txt
  5. 1 0
      Documentation/devicetree/bindings/vendor-prefixes.txt
  6. 41 0
      Documentation/hwmon/ibmpowernv
  7. 3 2
      Documentation/hwmon/lm75
  8. 5 0
      Documentation/hwmon/ntc_thermistor
  9. 2 3
      Documentation/hwmon/pmbus
  10. 45 0
      Documentation/hwmon/powr1220
  11. 17 0
      Documentation/hwmon/pwm-fan
  12. 28 0
      Documentation/hwmon/tmp103
  13. 17 9
      Documentation/hwmon/tmp421
  14. 64 0
      Documentation/hwmon/tps40422
  15. 51 6
      drivers/hwmon/Kconfig
  16. 4 0
      drivers/hwmon/Makefile
  17. 16 41
      drivers/hwmon/ad7414.c
  18. 56 77
      drivers/hwmon/ad7418.c
  19. 83 92
      drivers/hwmon/adm1021.c
  20. 95 136
      drivers/hwmon/adm1025.c
  21. 272 316
      drivers/hwmon/adm1026.c
  22. 84 124
      drivers/hwmon/adm1029.c
  23. 157 192
      drivers/hwmon/adm1031.c
  24. 154 185
      drivers/hwmon/adm9240.c
  25. 1 1
      drivers/hwmon/ads1015.c
  26. 14 38
      drivers/hwmon/ads7828.c
  27. 20 39
      drivers/hwmon/adt7411.c
  28. 57 85
      drivers/hwmon/adt7462.c
  29. 72 91
      drivers/hwmon/adt7470.c
  30. 165 232
      drivers/hwmon/amc6821.c
  31. 7 7
      drivers/hwmon/asc7621.c
  32. 21 55
      drivers/hwmon/atxp1.c
  33. 17 43
      drivers/hwmon/ds620.c
  34. 1 1
      drivers/hwmon/emc1403.c
  35. 26 63
      drivers/hwmon/emc2103.c
  36. 19 45
      drivers/hwmon/emc6w201.c
  37. 9 45
      drivers/hwmon/fam15h_power.c
  38. 26 58
      drivers/hwmon/g760a.c
  39. 29 49
      drivers/hwmon/g762.c
  40. 141 178
      drivers/hwmon/gl518sm.c
  41. 155 198
      drivers/hwmon/gl520sm.c
  42. 5 14
      drivers/hwmon/gpio-fan.c
  43. 23 65
      drivers/hwmon/hih6130.c
  44. 22 47
      drivers/hwmon/htu21.c
  45. 363 0
      drivers/hwmon/ibmpowernv.c
  46. 19 47
      drivers/hwmon/lineage-pem.c
  47. 10 17
      drivers/hwmon/lm63.c
  48. 8 0
      drivers/hwmon/lm75.c
  49. 6 5
      drivers/hwmon/lm77.c
  50. 16 84
      drivers/hwmon/lm78.c
  51. 304 356
      drivers/hwmon/lm85.c
  52. 66 88
      drivers/hwmon/lm93.c
  53. 1 1
      drivers/hwmon/ltc2945.c
  54. 1 1
      drivers/hwmon/ltc4222.c
  55. 1 1
      drivers/hwmon/ltc4260.c
  56. 1 4
      drivers/hwmon/max16065.c
  57. 1 1
      drivers/hwmon/max1668.c
  58. 1 1
      drivers/hwmon/max6639.c
  59. 7 9
      drivers/hwmon/max6697.c
  60. 7 7
      drivers/hwmon/nct6775.c
  61. 49 1
      drivers/hwmon/ntc_thermistor.c
  62. 11 2
      drivers/hwmon/pmbus/Kconfig
  63. 1 0
      drivers/hwmon/pmbus/Makefile
  64. 0 1
      drivers/hwmon/pmbus/pmbus.c
  65. 64 0
      drivers/hwmon/pmbus/tps40422.c
  66. 391 0
      drivers/hwmon/powr1220.c
  67. 193 0
      drivers/hwmon/pwm-fan.c
  68. 22 60
      drivers/hwmon/sht21.c
  69. 1 1
      drivers/hwmon/sis5595.c
  70. 16 28
      drivers/hwmon/smm665.c
  71. 55 60
      drivers/hwmon/smsc47m1.c
  72. 99 133
      drivers/hwmon/smsc47m192.c
  73. 88 124
      drivers/hwmon/thmc50.c
  74. 206 0
      drivers/hwmon/tmp103.c
  75. 31 8
      drivers/hwmon/tmp421.c
  76. 6 32
      drivers/hwmon/twl4030-madc-hwmon.c
  77. 6 9
      drivers/hwmon/w83791d.c
  78. 126 163
      drivers/hwmon/w83l786ng.c
  79. 11 61
      drivers/hwmon/wm831x-hwmon.c
  80. 7 43
      drivers/hwmon/wm8350-hwmon.c
  81. 1 0
      include/linux/platform_data/ntc_thermistor.h

+ 23 - 0
Documentation/devicetree/bindings/hwmon/ibmpowernv.txt

@@ -0,0 +1,23 @@
+IBM POWERNV platform sensors
+----------------------------
+
+Required node properties:
+- compatible: must be one of
+		"ibm,opal-sensor-cooling-fan"
+		"ibm,opal-sensor-amb-temp"
+		"ibm,opal-sensor-power-supply"
+		"ibm,opal-sensor-power"
+- sensor-id: an opaque id provided by the firmware to the kernel, identifies a
+	     given sensor and its attribute data
+
+Example sensors node:
+
+cooling-fan#8-data {
+	sensor-id = <0x7052107>;
+	compatible = "ibm,opal-sensor-cooling-fan";
+};
+
+amb-temp#1-thrs {
+	sensor-id = <0x5096000>;
+	compatible = "ibm,opal-sensor-amb-temp";
+};

+ 1 - 0
Documentation/devicetree/bindings/hwmon/ntc_thermistor.txt

@@ -3,6 +3,7 @@ NTC Thermistor hwmon sensors
 
 
 Requires node properties:
 Requires node properties:
 - "compatible" value : one of
 - "compatible" value : one of
+	"epcos,b57330v2103"
 	"murata,ncp15wb473"
 	"murata,ncp15wb473"
 	"murata,ncp18wb473"
 	"murata,ncp18wb473"
 	"murata,ncp21wb473"
 	"murata,ncp21wb473"

+ 12 - 0
Documentation/devicetree/bindings/hwmon/pwm-fan.txt

@@ -0,0 +1,12 @@
+Bindings for a fan connected to the PWM lines
+
+Required properties:
+- compatible	: "pwm-fan"
+- pwms		: the PWM that is used to control the PWM fan
+
+Example:
+	pwm-fan {
+		compatible = "pwm-fan";
+		status = "okay";
+		pwms = <&pwm 0 10000 0>;
+	};

+ 1 - 0
Documentation/devicetree/bindings/i2c/trivial-devices.txt

@@ -84,5 +84,6 @@ stm,m41t80		M41T80 - SERIAL ACCESS RTC WITH ALARMS
 taos,tsl2550		Ambient Light Sensor with SMBUS/Two Wire Serial Interface
 taos,tsl2550		Ambient Light Sensor with SMBUS/Two Wire Serial Interface
 ti,tsc2003		I2C Touch-Screen Controller
 ti,tsc2003		I2C Touch-Screen Controller
 ti,tmp102		Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface
 ti,tmp102		Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface
+ti,tmp103		Low Power Digital Temperature Sensor with SMBUS/Two Wire Serial Interface
 ti,tmp275		Digital Temperature Sensor
 ti,tmp275		Digital Temperature Sensor
 winbond,wpct301		i2c trusted platform module (TPM)
 winbond,wpct301		i2c trusted platform module (TPM)

+ 1 - 0
Documentation/devicetree/bindings/vendor-prefixes.txt

@@ -42,6 +42,7 @@ dmo	Data Modul AG
 ebv	EBV Elektronik
 ebv	EBV Elektronik
 edt	Emerging Display Technologies
 edt	Emerging Display Technologies
 emmicro	EM Microelectronic
 emmicro	EM Microelectronic
+epcos	EPCOS AG
 epfl	Ecole Polytechnique Fédérale de Lausanne
 epfl	Ecole Polytechnique Fédérale de Lausanne
 epson	Seiko Epson Corp.
 epson	Seiko Epson Corp.
 est	ESTeem Wireless Modems
 est	ESTeem Wireless Modems

+ 41 - 0
Documentation/hwmon/ibmpowernv

@@ -0,0 +1,41 @@
+Kernel Driver IBMPOWERNV
+========================
+
+Supported systems:
+  * Any recent IBM P servers based on POWERNV platform
+
+Author: Neelesh Gupta
+
+Description
+-----------
+
+This driver implements reading the platform sensors data like temperature/fan/
+voltage/power for 'POWERNV' platform.
+
+The driver uses the platform device infrastructure. It probes the device tree
+for sensor devices during the __init phase and registers them with the 'hwmon'.
+'hwmon' populates the 'sysfs' tree having attribute files, each for a given
+sensor type and its attribute data.
+
+All the nodes in the DT appear under "/ibm,opal/sensors" and each valid node in
+the DT maps to an attribute file in 'sysfs'. The node exports unique 'sensor-id'
+which the driver uses to make an OPAL call to the firmware.
+
+Usage notes
+-----------
+The driver is built statically with the kernel by enabling the config
+CONFIG_SENSORS_IBMPOWERNV. It can also be built as module 'ibmpowernv'.
+
+Sysfs attributes
+----------------
+
+fanX_input		Measured RPM value.
+fanX_min		Threshold RPM for alert generation.
+fanX_fault		0: No fail condition
+			1: Failing fan
+tempX_input		Measured ambient temperature.
+tempX_max		Threshold ambient temperature for alert generation.
+inX_input		Measured power supply voltage
+inX_fault		0: No fail condition.
+			1: Failing power supply.
+power1_input		System power consumption (microWatt)

+ 3 - 2
Documentation/hwmon/lm75

@@ -42,13 +42,14 @@ Supported chips:
     Addresses scanned: none
     Addresses scanned: none
     Datasheet: Publicly available at the ST website
     Datasheet: Publicly available at the ST website
                http://www.st.com/internet/analog/product/121769.jsp
                http://www.st.com/internet/analog/product/121769.jsp
-  * Texas Instruments TMP100, TMP101, TMP105, TMP75, TMP175, TMP275
-    Prefixes: 'tmp100', 'tmp101', 'tmp105', 'tmp175', 'tmp75', 'tmp275'
+  * Texas Instruments TMP100, TMP101, TMP105, TMP112, TMP75, TMP175, TMP275
+    Prefixes: 'tmp100', 'tmp101', 'tmp105', 'tmp112', 'tmp175', 'tmp75', 'tmp275'
     Addresses scanned: none
     Addresses scanned: none
     Datasheet: Publicly available at the Texas Instruments website
     Datasheet: Publicly available at the Texas Instruments website
                http://www.ti.com/product/tmp100
                http://www.ti.com/product/tmp100
                http://www.ti.com/product/tmp101
                http://www.ti.com/product/tmp101
                http://www.ti.com/product/tmp105
                http://www.ti.com/product/tmp105
+               http://www.ti.com/product/tmp112
                http://www.ti.com/product/tmp75
                http://www.ti.com/product/tmp75
                http://www.ti.com/product/tmp175
                http://www.ti.com/product/tmp175
                http://www.ti.com/product/tmp275
                http://www.ti.com/product/tmp275

+ 5 - 0
Documentation/hwmon/ntc_thermistor

@@ -6,6 +6,11 @@ Supported thermistors from Murata:
   Prefixes: 'ncp15wb473', 'ncp18wb473', 'ncp21wb473', 'ncp03wb473', 'ncp15wl333'
   Prefixes: 'ncp15wb473', 'ncp18wb473', 'ncp21wb473', 'ncp03wb473', 'ncp15wl333'
   Datasheet: Publicly available at Murata
   Datasheet: Publicly available at Murata
 
 
+Supported thermistors from EPCOS:
+* EPCOS NTC Thermistors B57330V2103
+  Prefixes: b57330v2103
+  Datasheet: Publicly available at EPCOS
+
 Other NTC thermistors can be supported simply by adding compensation
 Other NTC thermistors can be supported simply by adding compensation
 tables; e.g., NCP15WL333 support is added by the table ncpXXwl333.
 tables; e.g., NCP15WL333 support is added by the table ncpXXwl333.
 
 

+ 2 - 3
Documentation/hwmon/pmbus

@@ -23,12 +23,11 @@ Supported chips:
 	http://www.lineagepower.com/oem/pdf/PDT012A0X.pdf
 	http://www.lineagepower.com/oem/pdf/PDT012A0X.pdf
 	http://www.lineagepower.com/oem/pdf/UDT020A0X.pdf
 	http://www.lineagepower.com/oem/pdf/UDT020A0X.pdf
 	http://www.lineagepower.com/oem/pdf/MDT040A0X.pdf
 	http://www.lineagepower.com/oem/pdf/MDT040A0X.pdf
-  * Texas Instruments TPS40400, TPS40422
-    Prefixes: 'tps40400', 'tps40422'
+  * Texas Instruments TPS40400
+    Prefixes: 'tps40400'
     Addresses scanned: -
     Addresses scanned: -
     Datasheets:
     Datasheets:
 	http://www.ti.com/lit/gpn/tps40400
 	http://www.ti.com/lit/gpn/tps40400
-	http://www.ti.com/lit/gpn/tps40422
   * Generic PMBus devices
   * Generic PMBus devices
     Prefix: 'pmbus'
     Prefix: 'pmbus'
     Addresses scanned: -
     Addresses scanned: -

+ 45 - 0
Documentation/hwmon/powr1220

@@ -0,0 +1,45 @@
+Kernel driver powr1220
+==================
+
+Supported chips:
+  * Lattice POWR1220AT8
+    Prefix: 'powr1220'
+    Addresses scanned: none
+    Datasheet: Publicly available at the Lattice website
+               http://www.latticesemi.com/
+
+Author: Scott Kanowitz <scott.kanowitz@gmail.com>
+
+Description
+-----------
+
+This driver supports the Lattice POWR1220AT8 chip. The POWR1220
+includes voltage monitoring for 14 inputs as well as trim settings
+for output voltages and GPIOs. This driver implements the voltage
+monitoring portion of the chip.
+
+Voltages are sampled by a 12-bit ADC with a step size of 2 mV.
+An in-line attenuator allows measurements from 0 to 6 V. The
+attenuator is enabled or disabled depending on the setting of the
+input's max value. The driver will enable the attenuator for any
+value over the low measurement range maximum of 2 V.
+
+The input naming convention is as follows:
+
+driver name    pin name
+in0            VMON1
+in1            VMON2
+in2            VMON3
+in2            VMON4
+in4            VMON5
+in5            VMON6
+in6            VMON7
+in7            VMON8
+in8            VMON9
+in9            VMON10
+in10           VMON11
+in11           VMON12
+in12           VCCA
+in13           VCCINP
+
+The ADC readings are updated on request with a minimum period of 1s.

+ 17 - 0
Documentation/hwmon/pwm-fan

@@ -0,0 +1,17 @@
+Kernel driver pwm-fan
+=====================
+
+This driver enables the use of a PWM module to drive a fan. It uses the
+generic PWM interface thus it is hardware independent. It can be used on
+many SoCs, as long as the SoC supplies a PWM line driver that exposes
+the generic PWM API.
+
+Author: Kamil Debski <k.debski@samsung.com>
+
+Description
+-----------
+
+The driver implements a simple interface for driving a fan connected to
+a PWM output. It uses the generic PWM interface, thus it can be used with
+a range of SoCs. The driver exposes the fan to the user space through
+the hwmon's sysfs interface.

+ 28 - 0
Documentation/hwmon/tmp103

@@ -0,0 +1,28 @@
+Kernel driver tmp103
+====================
+
+Supported chips:
+  * Texas Instruments TMP103
+    Prefix: 'tmp103'
+    Addresses scanned: none
+    Product info and datasheet: http://www.ti.com/product/tmp103
+
+Author:
+	Heiko Schocher <hs@denx.de>
+
+Description
+-----------
+
+The TMP103 is a digital output temperature sensor in a four-ball
+wafer chip-scale package (WCSP). The TMP103 is capable of reading
+temperatures to a resolution of 1°C. The TMP103 is specified for
+operation over a temperature range of –40°C to +125°C.
+
+Resolution: 8 Bits
+Accuracy: ±1°C Typ (–10°C to +100°C)
+
+The driver provides the common sysfs-interface for temperatures (see
+Documentation/hwmon/sysfs-interface under Temperatures).
+
+Please refer how to instantiate this driver:
+Documentation/i2c/instantiating-devices

+ 17 - 9
Documentation/hwmon/tmp421

@@ -8,12 +8,20 @@ Supported chips:
     Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
     Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
   * Texas Instruments TMP422
   * Texas Instruments TMP422
     Prefix: 'tmp422'
     Prefix: 'tmp422'
-    Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
+    Addresses scanned: I2C 0x4c, 0x4d, 0x4e and 0x4f
     Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
     Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
   * Texas Instruments TMP423
   * Texas Instruments TMP423
     Prefix: 'tmp423'
     Prefix: 'tmp423'
-    Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
+    Addresses scanned: I2C 0x4c and 0x4d
     Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
     Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
+  * Texas Instruments TMP441
+    Prefix: 'tmp441'
+    Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
+    Datasheet: http://www.ti.com/product/tmp441
+  * Texas Instruments TMP442
+    Prefix: 'tmp442'
+    Addresses scanned: I2C 0x4c and 0x4d
+    Datasheet: http://www.ti.com/product/tmp442
 
 
 Authors:
 Authors:
 	Andre Prendel <andre.prendel@gmx.de>
 	Andre Prendel <andre.prendel@gmx.de>
@@ -21,13 +29,13 @@ Authors:
 Description
 Description
 -----------
 -----------
 
 
-This driver implements support for Texas Instruments TMP421, TMP422
-and TMP423 temperature sensor chips. These chips implement one local
-and up to one (TMP421), up to two (TMP422) or up to three (TMP423)
-remote sensors. Temperature is measured in degrees Celsius. The chips
-are wired over I2C/SMBus and specified over a temperature range of -40
-to +125 degrees Celsius. Resolution for both the local and remote
-channels is 0.0625 degree C.
+This driver implements support for Texas Instruments TMP421, TMP422,
+TMP423, TMP441, and TMP442 temperature sensor chips. These chips
+implement one local and up to one (TMP421, TMP441), up to two (TMP422,
+TMP442) or up to three (TMP423) remote sensors. Temperature is measured
+in degrees Celsius. The chips are wired over I2C/SMBus and specified
+over a temperature range of -40 to +125 degrees Celsius. Resolution
+for both the local and remote channels is 0.0625 degree C.
 
 
 The chips support only temperature measurement. The driver exports
 The chips support only temperature measurement. The driver exports
 the temperature values via the following sysfs files:
 the temperature values via the following sysfs files:

+ 64 - 0
Documentation/hwmon/tps40422

@@ -0,0 +1,64 @@
+Kernel driver tps40422
+======================
+
+Supported chips:
+  * TI TPS40422
+    Prefix: 'tps40422'
+    Addresses scanned: -
+    Datasheet: http://www.ti.com/lit/gpn/tps40422
+
+Author: Zhu Laiwen <richard.zhu@nsn.com>
+
+
+Description
+-----------
+
+This driver supports TI TPS40422 Dual-Output or Two-Phase Synchronous Buck
+Controller with PMBus
+
+The driver is a client driver to the core PMBus driver.
+Please see Documentation/hwmon/pmbus for details on PMBus client drivers.
+
+
+Usage Notes
+-----------
+
+This driver does not auto-detect devices. You will have to instantiate the
+devices explicitly. Please see Documentation/i2c/instantiating-devices for
+details.
+
+
+Platform data support
+---------------------
+
+The driver supports standard PMBus driver platform data.
+
+
+Sysfs entries
+-------------
+
+The following attributes are supported.
+
+in[1-2]_label		"vout[1-2]"
+in[1-2]_input		Measured voltage. From READ_VOUT register.
+in[1-2]_alarm		voltage alarm.
+
+curr[1-2]_input		Measured current. From READ_IOUT register.
+curr[1-2]_label		"iout[1-2]"
+curr1_max		Maximum current. From IOUT_OC_WARN_LIMIT register.
+curr1_crit		Critical maximum current. From IOUT_OC_FAULT_LIMIT register.
+curr1_max_alarm		Current high alarm. From IOUT_OC_WARN_LIMIT status.
+curr1_crit_alarm	Current critical high alarm. From IOUT_OC_FAULT status.
+curr2_alarm		Current high alarm. From IOUT_OC_WARNING status.
+
+temp1_input		Measured temperature. From READ_TEMPERATURE_2 register on page 0.
+temp1_max		Maximum temperature. From OT_WARN_LIMIT register.
+temp1_crit		Critical high temperature. From OT_FAULT_LIMIT register.
+temp1_max_alarm		Chip temperature high alarm. Set by comparing
+			READ_TEMPERATURE_2 on page 0 with OT_WARN_LIMIT if TEMP_OT_WARNING
+			status is set.
+temp1_crit_alarm	Chip temperature critical high alarm. Set by comparing
+			READ_TEMPERATURE_2 on page 0 with OT_FAULT_LIMIT if TEMP_OT_FAULT
+			status is set.
+temp2_input		Measured temperature. From READ_TEMPERATURE_2 register on page 1.
+temp2_alarm		Chip temperature alarm on page 1.

+ 51 - 6
drivers/hwmon/Kconfig

@@ -554,6 +554,17 @@ config SENSORS_IBMPEX
 	  This driver can also be built as a module.  If so, the module
 	  This driver can also be built as a module.  If so, the module
 	  will be called ibmpex.
 	  will be called ibmpex.
 
 
+config SENSORS_IBMPOWERNV
+	tristate "IBM POWERNV platform sensors"
+	depends on PPC_POWERNV
+	default y
+	help
+	  If you say yes here you get support for the temperature/fan/power
+	  sensors on your PowerNV platform.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called ibmpowernv.
+
 config SENSORS_IIO_HWMON
 config SENSORS_IIO_HWMON
 	tristate "Hwmon driver that uses channels specified via iio maps"
 	tristate "Hwmon driver that uses channels specified via iio maps"
 	depends on IIO
 	depends on IIO
@@ -608,6 +619,18 @@ config SENSORS_JC42
 	  This driver can also be built as a module.  If so, the module
 	  This driver can also be built as a module.  If so, the module
 	  will be called jc42.
 	  will be called jc42.
 
 
+config SENSORS_POWR1220
+	tristate "Lattice POWR1220 Power Monitoring"
+	depends on I2C
+	default n
+	help
+	  If you say yes here you get access to the hardware monitoring
+	  functions of the Lattice POWR1220 isp Power Supply Monitoring,
+	  Sequencing and Margining Controller.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called powr1220.
+
 config SENSORS_LINEAGE
 config SENSORS_LINEAGE
 	tristate "Lineage Compact Power Line Power Entry Module"
 	tristate "Lineage Compact Power Line Power Entry Module"
 	depends on I2C
 	depends on I2C
@@ -882,8 +905,8 @@ config SENSORS_LM75
 		- NXP's LM75A
 		- NXP's LM75A
 		- ST Microelectronics STDS75
 		- ST Microelectronics STDS75
 		- TelCom (now Microchip) TCN75
 		- TelCom (now Microchip) TCN75
-		- Texas Instruments TMP100, TMP101, TMP105, TMP75, TMP175,
-		  TMP275
+		- Texas Instruments TMP100, TMP101, TMP105, TMP112, TMP75,
+		  TMP175, TMP275
 
 
 	  This driver supports driver model based binding through board
 	  This driver supports driver model based binding through board
 	  specific I2C device tables.
 	  specific I2C device tables.
@@ -1061,7 +1084,7 @@ config SENSORS_NTC_THERMISTOR
 
 
 	  Currently, this driver supports
 	  Currently, this driver supports
 	  NCP15WB473, NCP18WB473, NCP21WB473, NCP03WB473, and NCP15WL333
 	  NCP15WB473, NCP18WB473, NCP21WB473, NCP03WB473, and NCP15WL333
-	  from Murata.
+	  from Murata and B57330V2103 from EPCOS.
 
 
 	  This driver can also be built as a module.  If so, the module
 	  This driver can also be built as a module.  If so, the module
 	  will be called ntc-thermistor.
 	  will be called ntc-thermistor.
@@ -1082,8 +1105,8 @@ config SENSORS_NCT6775
 	select HWMON_VID
 	select HWMON_VID
 	help
 	help
 	  If you say yes here you get support for the hardware monitoring
 	  If you say yes here you get support for the hardware monitoring
-	  functionality of the Nuvoton NCT6775F, NCT6776F, NCT6779D
-	  and compatible Super-I/O chips. This driver replaces the
+	  functionality of the Nuvoton NCT6106D, NCT6775F, NCT6776F, NCT6779D,
+	  NCT6791D and compatible Super-I/O chips. This driver replaces the
 	  w83627ehf driver for NCT6775F and NCT6776F.
 	  w83627ehf driver for NCT6775F and NCT6776F.
 
 
 	  This driver can also be built as a module.  If so, the module
 	  This driver can also be built as a module.  If so, the module
@@ -1105,6 +1128,17 @@ config SENSORS_PCF8591
 
 
 source drivers/hwmon/pmbus/Kconfig
 source drivers/hwmon/pmbus/Kconfig
 
 
+config SENSORS_PWM_FAN
+	tristate "PWM fan"
+	depends on (PWM && OF) || COMPILE_TEST
+	help
+	  If you say yes here you get support for fans connected to PWM lines.
+	  The driver uses the generic PWM interface, thus it will work on a
+	  variety of SoCs.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called pwm-fan.
+
 config SENSORS_SHT15
 config SENSORS_SHT15
 	tristate "Sensiron humidity and temperature sensors. SHT15 and compat."
 	tristate "Sensiron humidity and temperature sensors. SHT15 and compat."
 	depends on GPIOLIB
 	depends on GPIOLIB
@@ -1393,6 +1427,17 @@ config SENSORS_TMP102
 	  This driver can also be built as a module.  If so, the module
 	  This driver can also be built as a module.  If so, the module
 	  will be called tmp102.
 	  will be called tmp102.
 
 
+config SENSORS_TMP103
+	tristate "Texas Instruments TMP103"
+	depends on I2C
+	select REGMAP_I2C
+	help
+	  If you say yes here you get support for Texas Instruments TMP103
+	  sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called tmp103.
+
 config SENSORS_TMP401
 config SENSORS_TMP401
 	tristate "Texas Instruments TMP401 and compatibles"
 	tristate "Texas Instruments TMP401 and compatibles"
 	depends on I2C
 	depends on I2C
@@ -1408,7 +1453,7 @@ config SENSORS_TMP421
 	depends on I2C
 	depends on I2C
 	help
 	help
 	  If you say yes here you get support for Texas Instruments TMP421,
 	  If you say yes here you get support for Texas Instruments TMP421,
-	  TMP422 and TMP423 temperature sensor chips.
+	  TMP422, TMP423, TMP441, and TMP442 temperature sensor chips.
 
 
 	  This driver can also be built as a module.  If so, the module
 	  This driver can also be built as a module.  If so, the module
 	  will be called tmp421.
 	  will be called tmp421.

+ 4 - 0
drivers/hwmon/Makefile

@@ -71,6 +71,7 @@ obj-$(CONFIG_SENSORS_ULTRA45)	+= ultra45_env.o
 obj-$(CONFIG_SENSORS_I5K_AMB)	+= i5k_amb.o
 obj-$(CONFIG_SENSORS_I5K_AMB)	+= i5k_amb.o
 obj-$(CONFIG_SENSORS_IBMAEM)	+= ibmaem.o
 obj-$(CONFIG_SENSORS_IBMAEM)	+= ibmaem.o
 obj-$(CONFIG_SENSORS_IBMPEX)	+= ibmpex.o
 obj-$(CONFIG_SENSORS_IBMPEX)	+= ibmpex.o
+obj-$(CONFIG_SENSORS_IBMPOWERNV)+= ibmpowernv.o
 obj-$(CONFIG_SENSORS_IIO_HWMON) += iio_hwmon.o
 obj-$(CONFIG_SENSORS_IIO_HWMON) += iio_hwmon.o
 obj-$(CONFIG_SENSORS_INA209)	+= ina209.o
 obj-$(CONFIG_SENSORS_INA209)	+= ina209.o
 obj-$(CONFIG_SENSORS_INA2XX)	+= ina2xx.o
 obj-$(CONFIG_SENSORS_INA2XX)	+= ina2xx.o
@@ -120,6 +121,8 @@ obj-$(CONFIG_SENSORS_NTC_THERMISTOR)	+= ntc_thermistor.o
 obj-$(CONFIG_SENSORS_PC87360)	+= pc87360.o
 obj-$(CONFIG_SENSORS_PC87360)	+= pc87360.o
 obj-$(CONFIG_SENSORS_PC87427)	+= pc87427.o
 obj-$(CONFIG_SENSORS_PC87427)	+= pc87427.o
 obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
 obj-$(CONFIG_SENSORS_PCF8591)	+= pcf8591.o
+obj-$(CONFIG_SENSORS_POWR1220)  += powr1220.o
+obj-$(CONFIG_SENSORS_PWM_FAN)	+= pwm-fan.o
 obj-$(CONFIG_SENSORS_S3C)	+= s3c-hwmon.o
 obj-$(CONFIG_SENSORS_S3C)	+= s3c-hwmon.o
 obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o
 obj-$(CONFIG_SENSORS_SCH56XX_COMMON)+= sch56xx-common.o
 obj-$(CONFIG_SENSORS_SCH5627)	+= sch5627.o
 obj-$(CONFIG_SENSORS_SCH5627)	+= sch5627.o
@@ -135,6 +138,7 @@ obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
 obj-$(CONFIG_SENSORS_AMC6821)	+= amc6821.o
 obj-$(CONFIG_SENSORS_AMC6821)	+= amc6821.o
 obj-$(CONFIG_SENSORS_THMC50)	+= thmc50.o
 obj-$(CONFIG_SENSORS_THMC50)	+= thmc50.o
 obj-$(CONFIG_SENSORS_TMP102)	+= tmp102.o
 obj-$(CONFIG_SENSORS_TMP102)	+= tmp102.o
+obj-$(CONFIG_SENSORS_TMP103)	+= tmp103.o
 obj-$(CONFIG_SENSORS_TMP401)	+= tmp401.o
 obj-$(CONFIG_SENSORS_TMP401)	+= tmp401.o
 obj-$(CONFIG_SENSORS_TMP421)	+= tmp421.o
 obj-$(CONFIG_SENSORS_TMP421)	+= tmp421.o
 obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o
 obj-$(CONFIG_SENSORS_TWL4030_MADC)+= twl4030-madc-hwmon.o

+ 16 - 41
drivers/hwmon/ad7414.c

@@ -39,7 +39,7 @@
 static u8 AD7414_REG_LIMIT[] = { AD7414_REG_T_HIGH, AD7414_REG_T_LOW };
 static u8 AD7414_REG_LIMIT[] = { AD7414_REG_T_HIGH, AD7414_REG_T_LOW };
 
 
 struct ad7414_data {
 struct ad7414_data {
-	struct device		*hwmon_dev;
+	struct i2c_client	*client;
 	struct mutex		lock;	/* atomic read data updates */
 	struct mutex		lock;	/* atomic read data updates */
 	char			valid;	/* !=0 if following fields are valid */
 	char			valid;	/* !=0 if following fields are valid */
 	unsigned long		next_update;	/* In jiffies */
 	unsigned long		next_update;	/* In jiffies */
@@ -72,8 +72,8 @@ static inline int ad7414_write(struct i2c_client *client, u8 reg, u8 value)
 
 
 static struct ad7414_data *ad7414_update_device(struct device *dev)
 static struct ad7414_data *ad7414_update_device(struct device *dev)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct ad7414_data *data = i2c_get_clientdata(client);
+	struct ad7414_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 
 
 	mutex_lock(&data->lock);
 	mutex_lock(&data->lock);
 
 
@@ -127,8 +127,8 @@ static ssize_t set_max_min(struct device *dev,
 			   struct device_attribute *attr,
 			   struct device_attribute *attr,
 			   const char *buf, size_t count)
 			   const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct ad7414_data *data = i2c_get_clientdata(client);
+	struct ad7414_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int index = to_sensor_dev_attr(attr)->index;
 	int index = to_sensor_dev_attr(attr)->index;
 	u8 reg = AD7414_REG_LIMIT[index];
 	u8 reg = AD7414_REG_LIMIT[index];
 	long temp;
 	long temp;
@@ -164,7 +164,7 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *attr,
 static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 3);
 static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL, 3);
 static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 4);
 static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL, 4);
 
 
-static struct attribute *ad7414_attributes[] = {
+static struct attribute *ad7414_attrs[] = {
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
 	&sensor_dev_attr_temp1_min.dev_attr.attr,
 	&sensor_dev_attr_temp1_min.dev_attr.attr,
@@ -173,27 +173,25 @@ static struct attribute *ad7414_attributes[] = {
 	NULL
 	NULL
 };
 };
 
 
-static const struct attribute_group ad7414_group = {
-	.attrs = ad7414_attributes,
-};
+ATTRIBUTE_GROUPS(ad7414);
 
 
 static int ad7414_probe(struct i2c_client *client,
 static int ad7414_probe(struct i2c_client *client,
 			const struct i2c_device_id *dev_id)
 			const struct i2c_device_id *dev_id)
 {
 {
+	struct device *dev = &client->dev;
 	struct ad7414_data *data;
 	struct ad7414_data *data;
+	struct device *hwmon_dev;
 	int conf;
 	int conf;
-	int err;
 
 
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
 				     I2C_FUNC_SMBUS_READ_WORD_DATA))
 				     I2C_FUNC_SMBUS_READ_WORD_DATA))
 		return -EOPNOTSUPP;
 		return -EOPNOTSUPP;
 
 
-	data = devm_kzalloc(&client->dev, sizeof(struct ad7414_data),
-			    GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(struct ad7414_data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	i2c_set_clientdata(client, data);
+	data->client = client;
 	mutex_init(&data->lock);
 	mutex_init(&data->lock);
 
 
 	dev_info(&client->dev, "chip found\n");
 	dev_info(&client->dev, "chip found\n");
@@ -201,38 +199,16 @@ static int ad7414_probe(struct i2c_client *client,
 	/* Make sure the chip is powered up. */
 	/* Make sure the chip is powered up. */
 	conf = i2c_smbus_read_byte_data(client, AD7414_REG_CONF);
 	conf = i2c_smbus_read_byte_data(client, AD7414_REG_CONF);
 	if (conf < 0)
 	if (conf < 0)
-		dev_warn(&client->dev,
-			 "ad7414_probe unable to read config register.\n");
+		dev_warn(dev, "ad7414_probe unable to read config register.\n");
 	else {
 	else {
 		conf &= ~(1 << 7);
 		conf &= ~(1 << 7);
 		i2c_smbus_write_byte_data(client, AD7414_REG_CONF, conf);
 		i2c_smbus_write_byte_data(client, AD7414_REG_CONF, conf);
 	}
 	}
 
 
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&client->dev.kobj, &ad7414_group);
-	if (err)
-		return err;
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove;
-	}
-
-	return 0;
-
-exit_remove:
-	sysfs_remove_group(&client->dev.kobj, &ad7414_group);
-	return err;
-}
-
-static int ad7414_remove(struct i2c_client *client)
-{
-	struct ad7414_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &ad7414_group);
-	return 0;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev,
+							   client->name,
+							   data, ad7414_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
 static const struct i2c_device_id ad7414_id[] = {
 static const struct i2c_device_id ad7414_id[] = {
@@ -246,7 +222,6 @@ static struct i2c_driver ad7414_driver = {
 		.name	= "ad7414",
 		.name	= "ad7414",
 	},
 	},
 	.probe	= ad7414_probe,
 	.probe	= ad7414_probe,
-	.remove	= ad7414_remove,
 	.id_table = ad7414_id,
 	.id_table = ad7414_id,
 };
 };
 
 

+ 56 - 77
drivers/hwmon/ad7418.c

@@ -44,8 +44,7 @@ static const u8 AD7418_REG_TEMP[] = { AD7418_REG_TEMP_IN,
 					AD7418_REG_TEMP_OS };
 					AD7418_REG_TEMP_OS };
 
 
 struct ad7418_data {
 struct ad7418_data {
-	struct device		*hwmon_dev;
-	struct attribute_group	attrs;
+	struct i2c_client	*client;
 	enum chips		type;
 	enum chips		type;
 	struct mutex		lock;
 	struct mutex		lock;
 	int			adc_max;	/* number of ADC channels */
 	int			adc_max;	/* number of ADC channels */
@@ -55,48 +54,10 @@ struct ad7418_data {
 	u16			in[4];
 	u16			in[4];
 };
 };
 
 
-static int ad7418_probe(struct i2c_client *client,
-			const struct i2c_device_id *id);
-static int ad7418_remove(struct i2c_client *client);
-
-static const struct i2c_device_id ad7418_id[] = {
-	{ "ad7416", ad7416 },
-	{ "ad7417", ad7417 },
-	{ "ad7418", ad7418 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, ad7418_id);
-
-static struct i2c_driver ad7418_driver = {
-	.driver = {
-		.name	= "ad7418",
-	},
-	.probe		= ad7418_probe,
-	.remove		= ad7418_remove,
-	.id_table	= ad7418_id,
-};
-
-static void ad7418_init_client(struct i2c_client *client)
-{
-	struct ad7418_data *data = i2c_get_clientdata(client);
-
-	int reg = i2c_smbus_read_byte_data(client, AD7418_REG_CONF);
-	if (reg < 0) {
-		dev_err(&client->dev, "cannot read configuration register\n");
-	} else {
-		dev_info(&client->dev, "configuring for mode 1\n");
-		i2c_smbus_write_byte_data(client, AD7418_REG_CONF, reg & 0xfe);
-
-		if (data->type == ad7417 || data->type == ad7418)
-			i2c_smbus_write_byte_data(client,
-						AD7418_REG_CONF2, 0x00);
-	}
-}
-
 static struct ad7418_data *ad7418_update_device(struct device *dev)
 static struct ad7418_data *ad7418_update_device(struct device *dev)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct ad7418_data *data = i2c_get_clientdata(client);
+	struct ad7418_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 
 
 	mutex_lock(&data->lock);
 	mutex_lock(&data->lock);
 
 
@@ -165,8 +126,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
 			const char *buf, size_t count)
 			const char *buf, size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct ad7418_data *data = i2c_get_clientdata(client);
+	struct ad7418_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 	int ret = kstrtol(buf, 10, &temp);
 	int ret = kstrtol(buf, 10, &temp);
 
 
@@ -193,14 +154,15 @@ static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, show_adc, NULL, 1);
 static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_adc, NULL, 2);
 static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, show_adc, NULL, 2);
 static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_adc, NULL, 3);
 static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, show_adc, NULL, 3);
 
 
-static struct attribute *ad7416_attributes[] = {
+static struct attribute *ad7416_attrs[] = {
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
 	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
 	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	NULL
 	NULL
 };
 };
+ATTRIBUTE_GROUPS(ad7416);
 
 
-static struct attribute *ad7417_attributes[] = {
+static struct attribute *ad7417_attrs[] = {
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
 	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
 	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
@@ -210,83 +172,100 @@ static struct attribute *ad7417_attributes[] = {
 	&sensor_dev_attr_in4_input.dev_attr.attr,
 	&sensor_dev_attr_in4_input.dev_attr.attr,
 	NULL
 	NULL
 };
 };
+ATTRIBUTE_GROUPS(ad7417);
 
 
-static struct attribute *ad7418_attributes[] = {
+static struct attribute *ad7418_attrs[] = {
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
 	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
 	&sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_in1_input.dev_attr.attr,
 	&sensor_dev_attr_in1_input.dev_attr.attr,
 	NULL
 	NULL
 };
 };
+ATTRIBUTE_GROUPS(ad7418);
+
+static void ad7418_init_client(struct i2c_client *client)
+{
+	struct ad7418_data *data = i2c_get_clientdata(client);
+
+	int reg = i2c_smbus_read_byte_data(client, AD7418_REG_CONF);
+	if (reg < 0) {
+		dev_err(&client->dev, "cannot read configuration register\n");
+	} else {
+		dev_info(&client->dev, "configuring for mode 1\n");
+		i2c_smbus_write_byte_data(client, AD7418_REG_CONF, reg & 0xfe);
+
+		if (data->type == ad7417 || data->type == ad7418)
+			i2c_smbus_write_byte_data(client,
+						AD7418_REG_CONF2, 0x00);
+	}
+}
 
 
 static int ad7418_probe(struct i2c_client *client,
 static int ad7418_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 			 const struct i2c_device_id *id)
 {
 {
+	struct device *dev = &client->dev;
 	struct i2c_adapter *adapter = client->adapter;
 	struct i2c_adapter *adapter = client->adapter;
 	struct ad7418_data *data;
 	struct ad7418_data *data;
-	int err;
+	struct device *hwmon_dev;
+	const struct attribute_group **attr_groups = NULL;
 
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
 					I2C_FUNC_SMBUS_WORD_DATA))
 					I2C_FUNC_SMBUS_WORD_DATA))
 		return -EOPNOTSUPP;
 		return -EOPNOTSUPP;
 
 
-	data = devm_kzalloc(&client->dev, sizeof(struct ad7418_data),
-			    GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(struct ad7418_data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	i2c_set_clientdata(client, data);
 	i2c_set_clientdata(client, data);
 
 
 	mutex_init(&data->lock);
 	mutex_init(&data->lock);
+	data->client = client;
 	data->type = id->driver_data;
 	data->type = id->driver_data;
 
 
 	switch (data->type) {
 	switch (data->type) {
 	case ad7416:
 	case ad7416:
 		data->adc_max = 0;
 		data->adc_max = 0;
-		data->attrs.attrs = ad7416_attributes;
+		attr_groups = ad7416_groups;
 		break;
 		break;
 
 
 	case ad7417:
 	case ad7417:
 		data->adc_max = 4;
 		data->adc_max = 4;
-		data->attrs.attrs = ad7417_attributes;
+		attr_groups = ad7417_groups;
 		break;
 		break;
 
 
 	case ad7418:
 	case ad7418:
 		data->adc_max = 1;
 		data->adc_max = 1;
-		data->attrs.attrs = ad7418_attributes;
+		attr_groups = ad7418_groups;
 		break;
 		break;
 	}
 	}
 
 
-	dev_info(&client->dev, "%s chip found\n", client->name);
+	dev_info(dev, "%s chip found\n", client->name);
 
 
 	/* Initialize the AD7418 chip */
 	/* Initialize the AD7418 chip */
 	ad7418_init_client(client);
 	ad7418_init_client(client);
 
 
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&client->dev.kobj, &data->attrs);
-	if (err)
-		return err;
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove;
-	}
-
-	return 0;
-
-exit_remove:
-	sysfs_remove_group(&client->dev.kobj, &data->attrs);
-	return err;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev,
+							   client->name,
+							   data, attr_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
-static int ad7418_remove(struct i2c_client *client)
-{
-	struct ad7418_data *data = i2c_get_clientdata(client);
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &data->attrs);
-	return 0;
-}
+static const struct i2c_device_id ad7418_id[] = {
+	{ "ad7416", ad7416 },
+	{ "ad7417", ad7417 },
+	{ "ad7418", ad7418 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, ad7418_id);
+
+static struct i2c_driver ad7418_driver = {
+	.driver = {
+		.name	= "ad7418",
+	},
+	.probe		= ad7418_probe,
+	.id_table	= ad7418_id,
+};
 
 
 module_i2c_driver(ad7418_driver);
 module_i2c_driver(ad7418_driver);
 
 

+ 83 - 92
drivers/hwmon/adm1021.c

@@ -98,41 +98,63 @@ struct adm1021_data {
 	u8 remote_temp_offset_prec;
 	u8 remote_temp_offset_prec;
 };
 };
 
 
-static int adm1021_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id);
-static int adm1021_detect(struct i2c_client *client,
-			  struct i2c_board_info *info);
-static void adm1021_init_client(struct i2c_client *client);
-static struct adm1021_data *adm1021_update_device(struct device *dev);
-
 /* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */
 /* (amalysh) read only mode, otherwise any limit's writing confuse BIOS */
 static bool read_only;
 static bool read_only;
 
 
+static struct adm1021_data *adm1021_update_device(struct device *dev)
+{
+	struct adm1021_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 
 
-static const struct i2c_device_id adm1021_id[] = {
-	{ "adm1021", adm1021 },
-	{ "adm1023", adm1023 },
-	{ "max1617", max1617 },
-	{ "max1617a", max1617a },
-	{ "thmc10", thmc10 },
-	{ "lm84", lm84 },
-	{ "gl523sm", gl523sm },
-	{ "mc1066", mc1066 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, adm1021_id);
+	mutex_lock(&data->update_lock);
 
 
-/* This is the driver that will be inserted */
-static struct i2c_driver adm1021_driver = {
-	.class		= I2C_CLASS_HWMON,
-	.driver = {
-		.name	= "adm1021",
-	},
-	.probe		= adm1021_probe,
-	.id_table	= adm1021_id,
-	.detect		= adm1021_detect,
-	.address_list	= normal_i2c,
-};
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+		int i;
+
+		dev_dbg(dev, "Starting adm1021 update\n");
+
+		for (i = 0; i < 2; i++) {
+			data->temp[i] = 1000 *
+				(s8) i2c_smbus_read_byte_data(
+					client, ADM1021_REG_TEMP(i));
+			data->temp_max[i] = 1000 *
+				(s8) i2c_smbus_read_byte_data(
+					client, ADM1021_REG_TOS_R(i));
+			if (data->type != lm84) {
+				data->temp_min[i] = 1000 *
+				  (s8) i2c_smbus_read_byte_data(client,
+							ADM1021_REG_THYST_R(i));
+			}
+		}
+		data->alarms = i2c_smbus_read_byte_data(client,
+						ADM1021_REG_STATUS) & 0x7c;
+		if (data->type == adm1023) {
+			/*
+			 * The ADM1023 provides 3 extra bits of precision for
+			 * the remote sensor in extra registers.
+			 */
+			data->temp[1] += 125 * (i2c_smbus_read_byte_data(
+				client, ADM1023_REG_REM_TEMP_PREC) >> 5);
+			data->temp_max[1] += 125 * (i2c_smbus_read_byte_data(
+				client, ADM1023_REG_REM_TOS_PREC) >> 5);
+			data->temp_min[1] += 125 * (i2c_smbus_read_byte_data(
+				client, ADM1023_REG_REM_THYST_PREC) >> 5);
+			data->remote_temp_offset =
+				i2c_smbus_read_byte_data(client,
+						ADM1023_REG_REM_OFFSET);
+			data->remote_temp_offset_prec =
+				i2c_smbus_read_byte_data(client,
+						ADM1023_REG_REM_OFFSET_PREC);
+		}
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
 
 
 static ssize_t show_temp(struct device *dev,
 static ssize_t show_temp(struct device *dev,
 			 struct device_attribute *devattr, char *buf)
 			 struct device_attribute *devattr, char *buf)
@@ -411,6 +433,15 @@ static int adm1021_detect(struct i2c_client *client,
 	return 0;
 	return 0;
 }
 }
 
 
+static void adm1021_init_client(struct i2c_client *client)
+{
+	/* Enable ADC and disable suspend mode */
+	i2c_smbus_write_byte_data(client, ADM1021_REG_CONFIG_W,
+		i2c_smbus_read_byte_data(client, ADM1021_REG_CONFIG_R) & 0xBF);
+	/* Set Conversion rate to 1/sec (this can be tinkered with) */
+	i2c_smbus_write_byte_data(client, ADM1021_REG_CONV_RATE_W, 0x04);
+}
+
 static int adm1021_probe(struct i2c_client *client,
 static int adm1021_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 			 const struct i2c_device_id *id)
 {
 {
@@ -440,69 +471,29 @@ static int adm1021_probe(struct i2c_client *client,
 	return PTR_ERR_OR_ZERO(hwmon_dev);
 	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
-static void adm1021_init_client(struct i2c_client *client)
-{
-	/* Enable ADC and disable suspend mode */
-	i2c_smbus_write_byte_data(client, ADM1021_REG_CONFIG_W,
-		i2c_smbus_read_byte_data(client, ADM1021_REG_CONFIG_R) & 0xBF);
-	/* Set Conversion rate to 1/sec (this can be tinkered with) */
-	i2c_smbus_write_byte_data(client, ADM1021_REG_CONV_RATE_W, 0x04);
-}
-
-static struct adm1021_data *adm1021_update_device(struct device *dev)
-{
-	struct adm1021_data *data = dev_get_drvdata(dev);
-	struct i2c_client *client = data->client;
-
-	mutex_lock(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
-		int i;
-
-		dev_dbg(dev, "Starting adm1021 update\n");
-
-		for (i = 0; i < 2; i++) {
-			data->temp[i] = 1000 *
-				(s8) i2c_smbus_read_byte_data(
-					client, ADM1021_REG_TEMP(i));
-			data->temp_max[i] = 1000 *
-				(s8) i2c_smbus_read_byte_data(
-					client, ADM1021_REG_TOS_R(i));
-			if (data->type != lm84) {
-				data->temp_min[i] = 1000 *
-				  (s8) i2c_smbus_read_byte_data(client,
-							ADM1021_REG_THYST_R(i));
-			}
-		}
-		data->alarms = i2c_smbus_read_byte_data(client,
-						ADM1021_REG_STATUS) & 0x7c;
-		if (data->type == adm1023) {
-			/*
-			 * The ADM1023 provides 3 extra bits of precision for
-			 * the remote sensor in extra registers.
-			 */
-			data->temp[1] += 125 * (i2c_smbus_read_byte_data(
-				client, ADM1023_REG_REM_TEMP_PREC) >> 5);
-			data->temp_max[1] += 125 * (i2c_smbus_read_byte_data(
-				client, ADM1023_REG_REM_TOS_PREC) >> 5);
-			data->temp_min[1] += 125 * (i2c_smbus_read_byte_data(
-				client, ADM1023_REG_REM_THYST_PREC) >> 5);
-			data->remote_temp_offset =
-				i2c_smbus_read_byte_data(client,
-						ADM1023_REG_REM_OFFSET);
-			data->remote_temp_offset_prec =
-				i2c_smbus_read_byte_data(client,
-						ADM1023_REG_REM_OFFSET_PREC);
-		}
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	mutex_unlock(&data->update_lock);
+static const struct i2c_device_id adm1021_id[] = {
+	{ "adm1021", adm1021 },
+	{ "adm1023", adm1023 },
+	{ "max1617", max1617 },
+	{ "max1617a", max1617a },
+	{ "thmc10", thmc10 },
+	{ "lm84", lm84 },
+	{ "gl523sm", gl523sm },
+	{ "mc1066", mc1066 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, adm1021_id);
 
 
-	return data;
-}
+static struct i2c_driver adm1021_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "adm1021",
+	},
+	.probe		= adm1021_probe,
+	.id_table	= adm1021_id,
+	.detect		= adm1021_detect,
+	.address_list	= normal_i2c,
+};
 
 
 module_i2c_driver(adm1021_driver);
 module_i2c_driver(adm1021_driver);
 
 

+ 95 - 136
drivers/hwmon/adm1025.c

@@ -102,47 +102,13 @@ static const int in_scale[6] = { 2500, 2250, 3300, 5000, 12000, 3300 };
 				 (((val) < 0 ? (val) - 500 : \
 				 (((val) < 0 ? (val) - 500 : \
 				   (val) + 500) / 1000))
 				   (val) + 500) / 1000))
 
 
-/*
- * Functions declaration
- */
-
-static int adm1025_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id);
-static int adm1025_detect(struct i2c_client *client,
-			  struct i2c_board_info *info);
-static void adm1025_init_client(struct i2c_client *client);
-static int adm1025_remove(struct i2c_client *client);
-static struct adm1025_data *adm1025_update_device(struct device *dev);
-
-/*
- * Driver data (common to all clients)
- */
-
-static const struct i2c_device_id adm1025_id[] = {
-	{ "adm1025", adm1025 },
-	{ "ne1619", ne1619 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, adm1025_id);
-
-static struct i2c_driver adm1025_driver = {
-	.class		= I2C_CLASS_HWMON,
-	.driver = {
-		.name	= "adm1025",
-	},
-	.probe		= adm1025_probe,
-	.remove		= adm1025_remove,
-	.id_table	= adm1025_id,
-	.detect		= adm1025_detect,
-	.address_list	= normal_i2c,
-};
-
 /*
 /*
  * Client data (each client gets its own)
  * Client data (each client gets its own)
  */
  */
 
 
 struct adm1025_data {
 struct adm1025_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
+	const struct attribute_group *groups[3];
 	struct mutex update_lock;
 	struct mutex update_lock;
 	char valid; /* zero until following fields are valid */
 	char valid; /* zero until following fields are valid */
 	unsigned long last_updated; /* in jiffies */
 	unsigned long last_updated; /* in jiffies */
@@ -158,6 +124,51 @@ struct adm1025_data {
 	u8 vrm;
 	u8 vrm;
 };
 };
 
 
+static struct adm1025_data *adm1025_update_device(struct device *dev)
+{
+	struct adm1025_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
+		int i;
+
+		dev_dbg(&client->dev, "Updating data.\n");
+		for (i = 0; i < 6; i++) {
+			data->in[i] = i2c_smbus_read_byte_data(client,
+				      ADM1025_REG_IN(i));
+			data->in_min[i] = i2c_smbus_read_byte_data(client,
+					  ADM1025_REG_IN_MIN(i));
+			data->in_max[i] = i2c_smbus_read_byte_data(client,
+					  ADM1025_REG_IN_MAX(i));
+		}
+		for (i = 0; i < 2; i++) {
+			data->temp[i] = i2c_smbus_read_byte_data(client,
+					ADM1025_REG_TEMP(i));
+			data->temp_min[i] = i2c_smbus_read_byte_data(client,
+					    ADM1025_REG_TEMP_LOW(i));
+			data->temp_max[i] = i2c_smbus_read_byte_data(client,
+					    ADM1025_REG_TEMP_HIGH(i));
+		}
+		data->alarms = i2c_smbus_read_byte_data(client,
+			       ADM1025_REG_STATUS1)
+			     | (i2c_smbus_read_byte_data(client,
+				ADM1025_REG_STATUS2) << 8);
+		data->vid = (i2c_smbus_read_byte_data(client,
+			     ADM1025_REG_VID) & 0x0f)
+			  | ((i2c_smbus_read_byte_data(client,
+			      ADM1025_REG_VID4) & 0x01) << 4);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
 /*
 /*
  * Sysfs stuff
  * Sysfs stuff
  */
  */
@@ -217,8 +228,8 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
 			  const char *buf, size_t count)
 			  const char *buf, size_t count)
 {
 {
 	int index = to_sensor_dev_attr(attr)->index;
 	int index = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1025_data *data = i2c_get_clientdata(client);
+	struct adm1025_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -238,8 +249,8 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
 			  const char *buf, size_t count)
 			  const char *buf, size_t count)
 {
 {
 	int index = to_sensor_dev_attr(attr)->index;
 	int index = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1025_data *data = i2c_get_clientdata(client);
+	struct adm1025_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -273,8 +284,8 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
 			    const char *buf, size_t count)
 			    const char *buf, size_t count)
 {
 {
 	int index = to_sensor_dev_attr(attr)->index;
 	int index = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1025_data *data = i2c_get_clientdata(client);
+	struct adm1025_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -294,8 +305,8 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 	const char *buf, size_t count)
 	const char *buf, size_t count)
 {
 {
 	int index = to_sensor_dev_attr(attr)->index;
 	int index = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1025_data *data = i2c_get_clientdata(client);
+	struct adm1025_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -470,51 +481,6 @@ static int adm1025_detect(struct i2c_client *client,
 	return 0;
 	return 0;
 }
 }
 
 
-static int adm1025_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id)
-{
-	struct adm1025_data *data;
-	int err;
-	u8 config;
-
-	data = devm_kzalloc(&client->dev, sizeof(struct adm1025_data),
-			    GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	i2c_set_clientdata(client, data);
-	mutex_init(&data->update_lock);
-
-	/* Initialize the ADM1025 chip */
-	adm1025_init_client(client);
-
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&client->dev.kobj, &adm1025_group);
-	if (err)
-		return err;
-
-	/* Pin 11 is either in4 (+12V) or VID4 */
-	config = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG);
-	if (!(config & 0x20)) {
-		err = sysfs_create_group(&client->dev.kobj, &adm1025_group_in4);
-		if (err)
-			goto exit_remove;
-	}
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove;
-	}
-
-	return 0;
-
-exit_remove:
-	sysfs_remove_group(&client->dev.kobj, &adm1025_group);
-	sysfs_remove_group(&client->dev.kobj, &adm1025_group_in4);
-	return err;
-}
-
 static void adm1025_init_client(struct i2c_client *client)
 static void adm1025_init_client(struct i2c_client *client)
 {
 {
 	u8 reg;
 	u8 reg;
@@ -557,61 +523,54 @@ static void adm1025_init_client(struct i2c_client *client)
 					  (reg&0x7E)|0x01);
 					  (reg&0x7E)|0x01);
 }
 }
 
 
-static int adm1025_remove(struct i2c_client *client)
+static int adm1025_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
 {
 {
-	struct adm1025_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &adm1025_group);
-	sysfs_remove_group(&client->dev.kobj, &adm1025_group_in4);
-
-	return 0;
-}
+	struct device *dev = &client->dev;
+	struct device *hwmon_dev;
+	struct adm1025_data *data;
+	u8 config;
 
 
-static struct adm1025_data *adm1025_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1025_data *data = i2c_get_clientdata(client);
+	data = devm_kzalloc(dev, sizeof(struct adm1025_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
 
 
-	mutex_lock(&data->update_lock);
+	i2c_set_clientdata(client, data);
+	data->client = client;
+	mutex_init(&data->update_lock);
 
 
-	if (time_after(jiffies, data->last_updated + HZ * 2) || !data->valid) {
-		int i;
+	/* Initialize the ADM1025 chip */
+	adm1025_init_client(client);
 
 
-		dev_dbg(&client->dev, "Updating data.\n");
-		for (i = 0; i < 6; i++) {
-			data->in[i] = i2c_smbus_read_byte_data(client,
-				      ADM1025_REG_IN(i));
-			data->in_min[i] = i2c_smbus_read_byte_data(client,
-					  ADM1025_REG_IN_MIN(i));
-			data->in_max[i] = i2c_smbus_read_byte_data(client,
-					  ADM1025_REG_IN_MAX(i));
-		}
-		for (i = 0; i < 2; i++) {
-			data->temp[i] = i2c_smbus_read_byte_data(client,
-					ADM1025_REG_TEMP(i));
-			data->temp_min[i] = i2c_smbus_read_byte_data(client,
-					    ADM1025_REG_TEMP_LOW(i));
-			data->temp_max[i] = i2c_smbus_read_byte_data(client,
-					    ADM1025_REG_TEMP_HIGH(i));
-		}
-		data->alarms = i2c_smbus_read_byte_data(client,
-			       ADM1025_REG_STATUS1)
-			     | (i2c_smbus_read_byte_data(client,
-				ADM1025_REG_STATUS2) << 8);
-		data->vid = (i2c_smbus_read_byte_data(client,
-			     ADM1025_REG_VID) & 0x0f)
-			  | ((i2c_smbus_read_byte_data(client,
-			      ADM1025_REG_VID4) & 0x01) << 4);
+	/* sysfs hooks */
+	data->groups[0] = &adm1025_group;
+	/* Pin 11 is either in4 (+12V) or VID4 */
+	config = i2c_smbus_read_byte_data(client, ADM1025_REG_CONFIG);
+	if (!(config & 0x20))
+		data->groups[1] = &adm1025_group_in4;
 
 
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data, data->groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
 
 
-	mutex_unlock(&data->update_lock);
+static const struct i2c_device_id adm1025_id[] = {
+	{ "adm1025", adm1025 },
+	{ "ne1619", ne1619 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, adm1025_id);
 
 
-	return data;
-}
+static struct i2c_driver adm1025_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "adm1025",
+	},
+	.probe		= adm1025_probe,
+	.id_table	= adm1025_id,
+	.detect		= adm1025_detect,
+	.address_list	= normal_i2c,
+};
 
 
 module_i2c_driver(adm1025_driver);
 module_i2c_driver(adm1025_driver);
 
 

+ 272 - 316
drivers/hwmon/adm1026.c

@@ -266,7 +266,8 @@ struct pwm_data {
 };
 };
 
 
 struct adm1026_data {
 struct adm1026_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
+	const struct attribute_group *groups[3];
 
 
 	struct mutex update_lock;
 	struct mutex update_lock;
 	int valid;		/* !=0 if following fields are valid */
 	int valid;		/* !=0 if following fields are valid */
@@ -298,37 +299,6 @@ struct adm1026_data {
 	u8 config3;		/* Register value */
 	u8 config3;		/* Register value */
 };
 };
 
 
-static int adm1026_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id);
-static int adm1026_detect(struct i2c_client *client,
-			  struct i2c_board_info *info);
-static int adm1026_remove(struct i2c_client *client);
-static int adm1026_read_value(struct i2c_client *client, u8 reg);
-static int adm1026_write_value(struct i2c_client *client, u8 reg, int value);
-static void adm1026_print_gpio(struct i2c_client *client);
-static void adm1026_fixup_gpio(struct i2c_client *client);
-static struct adm1026_data *adm1026_update_device(struct device *dev);
-static void adm1026_init_client(struct i2c_client *client);
-
-
-static const struct i2c_device_id adm1026_id[] = {
-	{ "adm1026", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, adm1026_id);
-
-static struct i2c_driver adm1026_driver = {
-	.class		= I2C_CLASS_HWMON,
-	.driver = {
-		.name	= "adm1026",
-	},
-	.probe		= adm1026_probe,
-	.remove		= adm1026_remove,
-	.id_table	= adm1026_id,
-	.detect		= adm1026_detect,
-	.address_list	= normal_i2c,
-};
-
 static int adm1026_read_value(struct i2c_client *client, u8 reg)
 static int adm1026_read_value(struct i2c_client *client, u8 reg)
 {
 {
 	int res;
 	int res;
@@ -357,212 +327,10 @@ static int adm1026_write_value(struct i2c_client *client, u8 reg, int value)
 	return res;
 	return res;
 }
 }
 
 
-static void adm1026_init_client(struct i2c_client *client)
-{
-	int value, i;
-	struct adm1026_data *data = i2c_get_clientdata(client);
-
-	dev_dbg(&client->dev, "Initializing device\n");
-	/* Read chip config */
-	data->config1 = adm1026_read_value(client, ADM1026_REG_CONFIG1);
-	data->config2 = adm1026_read_value(client, ADM1026_REG_CONFIG2);
-	data->config3 = adm1026_read_value(client, ADM1026_REG_CONFIG3);
-
-	/* Inform user of chip config */
-	dev_dbg(&client->dev, "ADM1026_REG_CONFIG1 is: 0x%02x\n",
-		data->config1);
-	if ((data->config1 & CFG1_MONITOR) == 0) {
-		dev_dbg(&client->dev,
-			"Monitoring not currently enabled.\n");
-	}
-	if (data->config1 & CFG1_INT_ENABLE) {
-		dev_dbg(&client->dev,
-			"SMBALERT interrupts are enabled.\n");
-	}
-	if (data->config1 & CFG1_AIN8_9) {
-		dev_dbg(&client->dev,
-			"in8 and in9 enabled. temp3 disabled.\n");
-	} else {
-		dev_dbg(&client->dev,
-			"temp3 enabled.  in8 and in9 disabled.\n");
-	}
-	if (data->config1 & CFG1_THERM_HOT) {
-		dev_dbg(&client->dev,
-			"Automatic THERM, PWM, and temp limits enabled.\n");
-	}
-
-	if (data->config3 & CFG3_GPIO16_ENABLE) {
-		dev_dbg(&client->dev,
-			"GPIO16 enabled.  THERM pin disabled.\n");
-	} else {
-		dev_dbg(&client->dev,
-			"THERM pin enabled.  GPIO16 disabled.\n");
-	}
-	if (data->config3 & CFG3_VREF_250)
-		dev_dbg(&client->dev, "Vref is 2.50 Volts.\n");
-	else
-		dev_dbg(&client->dev, "Vref is 1.82 Volts.\n");
-	/* Read and pick apart the existing GPIO configuration */
-	value = 0;
-	for (i = 0; i <= 15; ++i) {
-		if ((i & 0x03) == 0) {
-			value = adm1026_read_value(client,
-					ADM1026_REG_GPIO_CFG_0_3 + i / 4);
-		}
-		data->gpio_config[i] = value & 0x03;
-		value >>= 2;
-	}
-	data->gpio_config[16] = (data->config3 >> 6) & 0x03;
-
-	/* ... and then print it */
-	adm1026_print_gpio(client);
-
-	/*
-	 * If the user asks us to reprogram the GPIO config, then
-	 * do it now.
-	 */
-	if (gpio_input[0] != -1 || gpio_output[0] != -1
-		|| gpio_inverted[0] != -1 || gpio_normal[0] != -1
-		|| gpio_fan[0] != -1) {
-		adm1026_fixup_gpio(client);
-	}
-
-	/*
-	 * WE INTENTIONALLY make no changes to the limits,
-	 *   offsets, pwms, fans and zones.  If they were
-	 *   configured, we don't want to mess with them.
-	 *   If they weren't, the default is 100% PWM, no
-	 *   control and will suffice until 'sensors -s'
-	 *   can be run by the user.  We DO set the default
-	 *   value for pwm1.auto_pwm_min to its maximum
-	 *   so that enabling automatic pwm fan control
-	 *   without first setting a value for pwm1.auto_pwm_min
-	 *   will not result in potentially dangerous fan speed decrease.
-	 */
-	data->pwm1.auto_pwm_min = 255;
-	/* Start monitoring */
-	value = adm1026_read_value(client, ADM1026_REG_CONFIG1);
-	/* Set MONITOR, clear interrupt acknowledge and s/w reset */
-	value = (value | CFG1_MONITOR) & (~CFG1_INT_CLEAR & ~CFG1_RESET);
-	dev_dbg(&client->dev, "Setting CONFIG to: 0x%02x\n", value);
-	data->config1 = value;
-	adm1026_write_value(client, ADM1026_REG_CONFIG1, value);
-
-	/* initialize fan_div[] to hardware defaults */
-	value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) |
-		(adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8);
-	for (i = 0; i <= 7; ++i) {
-		data->fan_div[i] = DIV_FROM_REG(value & 0x03);
-		value >>= 2;
-	}
-}
-
-static void adm1026_print_gpio(struct i2c_client *client)
-{
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int i;
-
-	dev_dbg(&client->dev, "GPIO config is:\n");
-	for (i = 0; i <= 7; ++i) {
-		if (data->config2 & (1 << i)) {
-			dev_dbg(&client->dev, "\t%sGP%s%d\n",
-				data->gpio_config[i] & 0x02 ? "" : "!",
-				data->gpio_config[i] & 0x01 ? "OUT" : "IN",
-				i);
-		} else {
-			dev_dbg(&client->dev, "\tFAN%d\n", i);
-		}
-	}
-	for (i = 8; i <= 15; ++i) {
-		dev_dbg(&client->dev, "\t%sGP%s%d\n",
-			data->gpio_config[i] & 0x02 ? "" : "!",
-			data->gpio_config[i] & 0x01 ? "OUT" : "IN",
-			i);
-	}
-	if (data->config3 & CFG3_GPIO16_ENABLE) {
-		dev_dbg(&client->dev, "\t%sGP%s16\n",
-			data->gpio_config[16] & 0x02 ? "" : "!",
-			data->gpio_config[16] & 0x01 ? "OUT" : "IN");
-	} else {
-		/* GPIO16 is THERM */
-		dev_dbg(&client->dev, "\tTHERM\n");
-	}
-}
-
-static void adm1026_fixup_gpio(struct i2c_client *client)
-{
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	int i;
-	int value;
-
-	/* Make the changes requested. */
-	/*
-	 * We may need to unlock/stop monitoring or soft-reset the
-	 *    chip before we can make changes.  This hasn't been
-	 *    tested much.  FIXME
-	 */
-
-	/* Make outputs */
-	for (i = 0; i <= 16; ++i) {
-		if (gpio_output[i] >= 0 && gpio_output[i] <= 16)
-			data->gpio_config[gpio_output[i]] |= 0x01;
-		/* if GPIO0-7 is output, it isn't a FAN tach */
-		if (gpio_output[i] >= 0 && gpio_output[i] <= 7)
-			data->config2 |= 1 << gpio_output[i];
-	}
-
-	/* Input overrides output */
-	for (i = 0; i <= 16; ++i) {
-		if (gpio_input[i] >= 0 && gpio_input[i] <= 16)
-			data->gpio_config[gpio_input[i]] &= ~0x01;
-		/* if GPIO0-7 is input, it isn't a FAN tach */
-		if (gpio_input[i] >= 0 && gpio_input[i] <= 7)
-			data->config2 |= 1 << gpio_input[i];
-	}
-
-	/* Inverted */
-	for (i = 0; i <= 16; ++i) {
-		if (gpio_inverted[i] >= 0 && gpio_inverted[i] <= 16)
-			data->gpio_config[gpio_inverted[i]] &= ~0x02;
-	}
-
-	/* Normal overrides inverted */
-	for (i = 0; i <= 16; ++i) {
-		if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16)
-			data->gpio_config[gpio_normal[i]] |= 0x02;
-	}
-
-	/* Fan overrides input and output */
-	for (i = 0; i <= 7; ++i) {
-		if (gpio_fan[i] >= 0 && gpio_fan[i] <= 7)
-			data->config2 &= ~(1 << gpio_fan[i]);
-	}
-
-	/* Write new configs to registers */
-	adm1026_write_value(client, ADM1026_REG_CONFIG2, data->config2);
-	data->config3 = (data->config3 & 0x3f)
-			| ((data->gpio_config[16] & 0x03) << 6);
-	adm1026_write_value(client, ADM1026_REG_CONFIG3, data->config3);
-	for (i = 15, value = 0; i >= 0; --i) {
-		value <<= 2;
-		value |= data->gpio_config[i] & 0x03;
-		if ((i & 0x03) == 0) {
-			adm1026_write_value(client,
-					ADM1026_REG_GPIO_CFG_0_3 + i/4,
-					value);
-			value = 0;
-		}
-	}
-
-	/* Print the new config */
-	adm1026_print_gpio(client);
-}
-
-
 static struct adm1026_data *adm1026_update_device(struct device *dev)
 static struct adm1026_data *adm1026_update_device(struct device *dev)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int i;
 	int i;
 	long value, alarms, gpio;
 	long value, alarms, gpio;
 
 
@@ -728,8 +496,8 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
 {
 {
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	int nr = sensor_attr->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -756,8 +524,8 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
 {
 {
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	int nr = sensor_attr->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -815,8 +583,8 @@ static ssize_t show_in16_min(struct device *dev, struct device_attribute *attr,
 static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr,
 static ssize_t set_in16_min(struct device *dev, struct device_attribute *attr,
 			    const char *buf, size_t count)
 			    const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -840,8 +608,8 @@ static ssize_t show_in16_max(struct device *dev, struct device_attribute *attr,
 static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr,
 static ssize_t set_in16_max(struct device *dev, struct device_attribute *attr,
 			    const char *buf, size_t count)
 			    const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -888,8 +656,8 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 {
 {
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	int nr = sensor_attr->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -923,8 +691,8 @@ fan_offset(8);
 /* Adjust fan_min to account for new fan divisor */
 /* Adjust fan_min to account for new fan divisor */
 static void fixup_fan_min(struct device *dev, int fan, int old_div)
 static void fixup_fan_min(struct device *dev, int fan, int old_div)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int new_min;
 	int new_min;
 	int new_div = data->fan_div[fan];
 	int new_div = data->fan_div[fan];
 
 
@@ -952,8 +720,8 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 {
 {
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	int nr = sensor_attr->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int orig_div, new_div;
 	int orig_div, new_div;
 	int err;
 	int err;
@@ -1024,8 +792,8 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
 {
 {
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	int nr = sensor_attr->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -1053,8 +821,8 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 {
 {
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	int nr = sensor_attr->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -1097,8 +865,8 @@ static ssize_t set_temp_offset(struct device *dev,
 {
 {
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	int nr = sensor_attr->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -1153,8 +921,8 @@ static ssize_t set_temp_auto_point1_temp(struct device *dev,
 {
 {
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	int nr = sensor_attr->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -1192,8 +960,8 @@ static ssize_t show_temp_crit_enable(struct device *dev,
 static ssize_t set_temp_crit_enable(struct device *dev,
 static ssize_t set_temp_crit_enable(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -1233,8 +1001,8 @@ static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
 {
 {
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	int nr = sensor_attr->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -1268,8 +1036,8 @@ static ssize_t set_analog_out_reg(struct device *dev,
 				  struct device_attribute *attr,
 				  struct device_attribute *attr,
 				  const char *buf, size_t count)
 				  const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -1378,8 +1146,8 @@ static ssize_t show_alarm_mask(struct device *dev,
 static ssize_t set_alarm_mask(struct device *dev, struct device_attribute *attr,
 static ssize_t set_alarm_mask(struct device *dev, struct device_attribute *attr,
 			      const char *buf, size_t count)
 			      const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long mask;
 	unsigned long mask;
 	long val;
 	long val;
 	int err;
 	int err;
@@ -1420,8 +1188,8 @@ static ssize_t show_gpio(struct device *dev, struct device_attribute *attr,
 static ssize_t set_gpio(struct device *dev, struct device_attribute *attr,
 static ssize_t set_gpio(struct device *dev, struct device_attribute *attr,
 			const char *buf, size_t count)
 			const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long gpio;
 	long gpio;
 	long val;
 	long val;
 	int err;
 	int err;
@@ -1453,8 +1221,8 @@ static ssize_t show_gpio_mask(struct device *dev, struct device_attribute *attr,
 static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr,
 static ssize_t set_gpio_mask(struct device *dev, struct device_attribute *attr,
 			     const char *buf, size_t count)
 			     const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long mask;
 	long mask;
 	long val;
 	long val;
 	int err;
 	int err;
@@ -1487,8 +1255,8 @@ static ssize_t show_pwm_reg(struct device *dev, struct device_attribute *attr,
 static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr,
 static ssize_t set_pwm_reg(struct device *dev, struct device_attribute *attr,
 			   const char *buf, size_t count)
 			   const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 
 
 	if (data->pwm1.enable == 1) {
 	if (data->pwm1.enable == 1) {
 		long val;
 		long val;
@@ -1517,8 +1285,8 @@ static ssize_t set_auto_pwm_min(struct device *dev,
 				struct device_attribute *attr, const char *buf,
 				struct device_attribute *attr, const char *buf,
 				size_t count)
 				size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -1553,8 +1321,8 @@ static ssize_t show_pwm_enable(struct device *dev,
 static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
 static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *attr,
 			      const char *buf, size_t count)
 			      const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1026_data *data = i2c_get_clientdata(client);
+	struct adm1026_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int old_enable;
 	int old_enable;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
@@ -1829,18 +1597,220 @@ static int adm1026_detect(struct i2c_client *client,
 	return 0;
 	return 0;
 }
 }
 
 
+static void adm1026_print_gpio(struct i2c_client *client)
+{
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int i;
+
+	dev_dbg(&client->dev, "GPIO config is:\n");
+	for (i = 0; i <= 7; ++i) {
+		if (data->config2 & (1 << i)) {
+			dev_dbg(&client->dev, "\t%sGP%s%d\n",
+				data->gpio_config[i] & 0x02 ? "" : "!",
+				data->gpio_config[i] & 0x01 ? "OUT" : "IN",
+				i);
+		} else {
+			dev_dbg(&client->dev, "\tFAN%d\n", i);
+		}
+	}
+	for (i = 8; i <= 15; ++i) {
+		dev_dbg(&client->dev, "\t%sGP%s%d\n",
+			data->gpio_config[i] & 0x02 ? "" : "!",
+			data->gpio_config[i] & 0x01 ? "OUT" : "IN",
+			i);
+	}
+	if (data->config3 & CFG3_GPIO16_ENABLE) {
+		dev_dbg(&client->dev, "\t%sGP%s16\n",
+			data->gpio_config[16] & 0x02 ? "" : "!",
+			data->gpio_config[16] & 0x01 ? "OUT" : "IN");
+	} else {
+		/* GPIO16 is THERM */
+		dev_dbg(&client->dev, "\tTHERM\n");
+	}
+}
+
+static void adm1026_fixup_gpio(struct i2c_client *client)
+{
+	struct adm1026_data *data = i2c_get_clientdata(client);
+	int i;
+	int value;
+
+	/* Make the changes requested. */
+	/*
+	 * We may need to unlock/stop monitoring or soft-reset the
+	 *    chip before we can make changes.  This hasn't been
+	 *    tested much.  FIXME
+	 */
+
+	/* Make outputs */
+	for (i = 0; i <= 16; ++i) {
+		if (gpio_output[i] >= 0 && gpio_output[i] <= 16)
+			data->gpio_config[gpio_output[i]] |= 0x01;
+		/* if GPIO0-7 is output, it isn't a FAN tach */
+		if (gpio_output[i] >= 0 && gpio_output[i] <= 7)
+			data->config2 |= 1 << gpio_output[i];
+	}
+
+	/* Input overrides output */
+	for (i = 0; i <= 16; ++i) {
+		if (gpio_input[i] >= 0 && gpio_input[i] <= 16)
+			data->gpio_config[gpio_input[i]] &= ~0x01;
+		/* if GPIO0-7 is input, it isn't a FAN tach */
+		if (gpio_input[i] >= 0 && gpio_input[i] <= 7)
+			data->config2 |= 1 << gpio_input[i];
+	}
+
+	/* Inverted */
+	for (i = 0; i <= 16; ++i) {
+		if (gpio_inverted[i] >= 0 && gpio_inverted[i] <= 16)
+			data->gpio_config[gpio_inverted[i]] &= ~0x02;
+	}
+
+	/* Normal overrides inverted */
+	for (i = 0; i <= 16; ++i) {
+		if (gpio_normal[i] >= 0 && gpio_normal[i] <= 16)
+			data->gpio_config[gpio_normal[i]] |= 0x02;
+	}
+
+	/* Fan overrides input and output */
+	for (i = 0; i <= 7; ++i) {
+		if (gpio_fan[i] >= 0 && gpio_fan[i] <= 7)
+			data->config2 &= ~(1 << gpio_fan[i]);
+	}
+
+	/* Write new configs to registers */
+	adm1026_write_value(client, ADM1026_REG_CONFIG2, data->config2);
+	data->config3 = (data->config3 & 0x3f)
+			| ((data->gpio_config[16] & 0x03) << 6);
+	adm1026_write_value(client, ADM1026_REG_CONFIG3, data->config3);
+	for (i = 15, value = 0; i >= 0; --i) {
+		value <<= 2;
+		value |= data->gpio_config[i] & 0x03;
+		if ((i & 0x03) == 0) {
+			adm1026_write_value(client,
+					ADM1026_REG_GPIO_CFG_0_3 + i/4,
+					value);
+			value = 0;
+		}
+	}
+
+	/* Print the new config */
+	adm1026_print_gpio(client);
+}
+
+static void adm1026_init_client(struct i2c_client *client)
+{
+	int value, i;
+	struct adm1026_data *data = i2c_get_clientdata(client);
+
+	dev_dbg(&client->dev, "Initializing device\n");
+	/* Read chip config */
+	data->config1 = adm1026_read_value(client, ADM1026_REG_CONFIG1);
+	data->config2 = adm1026_read_value(client, ADM1026_REG_CONFIG2);
+	data->config3 = adm1026_read_value(client, ADM1026_REG_CONFIG3);
+
+	/* Inform user of chip config */
+	dev_dbg(&client->dev, "ADM1026_REG_CONFIG1 is: 0x%02x\n",
+		data->config1);
+	if ((data->config1 & CFG1_MONITOR) == 0) {
+		dev_dbg(&client->dev,
+			"Monitoring not currently enabled.\n");
+	}
+	if (data->config1 & CFG1_INT_ENABLE) {
+		dev_dbg(&client->dev,
+			"SMBALERT interrupts are enabled.\n");
+	}
+	if (data->config1 & CFG1_AIN8_9) {
+		dev_dbg(&client->dev,
+			"in8 and in9 enabled. temp3 disabled.\n");
+	} else {
+		dev_dbg(&client->dev,
+			"temp3 enabled.  in8 and in9 disabled.\n");
+	}
+	if (data->config1 & CFG1_THERM_HOT) {
+		dev_dbg(&client->dev,
+			"Automatic THERM, PWM, and temp limits enabled.\n");
+	}
+
+	if (data->config3 & CFG3_GPIO16_ENABLE) {
+		dev_dbg(&client->dev,
+			"GPIO16 enabled.  THERM pin disabled.\n");
+	} else {
+		dev_dbg(&client->dev,
+			"THERM pin enabled.  GPIO16 disabled.\n");
+	}
+	if (data->config3 & CFG3_VREF_250)
+		dev_dbg(&client->dev, "Vref is 2.50 Volts.\n");
+	else
+		dev_dbg(&client->dev, "Vref is 1.82 Volts.\n");
+	/* Read and pick apart the existing GPIO configuration */
+	value = 0;
+	for (i = 0; i <= 15; ++i) {
+		if ((i & 0x03) == 0) {
+			value = adm1026_read_value(client,
+					ADM1026_REG_GPIO_CFG_0_3 + i / 4);
+		}
+		data->gpio_config[i] = value & 0x03;
+		value >>= 2;
+	}
+	data->gpio_config[16] = (data->config3 >> 6) & 0x03;
+
+	/* ... and then print it */
+	adm1026_print_gpio(client);
+
+	/*
+	 * If the user asks us to reprogram the GPIO config, then
+	 * do it now.
+	 */
+	if (gpio_input[0] != -1 || gpio_output[0] != -1
+		|| gpio_inverted[0] != -1 || gpio_normal[0] != -1
+		|| gpio_fan[0] != -1) {
+		adm1026_fixup_gpio(client);
+	}
+
+	/*
+	 * WE INTENTIONALLY make no changes to the limits,
+	 *   offsets, pwms, fans and zones.  If they were
+	 *   configured, we don't want to mess with them.
+	 *   If they weren't, the default is 100% PWM, no
+	 *   control and will suffice until 'sensors -s'
+	 *   can be run by the user.  We DO set the default
+	 *   value for pwm1.auto_pwm_min to its maximum
+	 *   so that enabling automatic pwm fan control
+	 *   without first setting a value for pwm1.auto_pwm_min
+	 *   will not result in potentially dangerous fan speed decrease.
+	 */
+	data->pwm1.auto_pwm_min = 255;
+	/* Start monitoring */
+	value = adm1026_read_value(client, ADM1026_REG_CONFIG1);
+	/* Set MONITOR, clear interrupt acknowledge and s/w reset */
+	value = (value | CFG1_MONITOR) & (~CFG1_INT_CLEAR & ~CFG1_RESET);
+	dev_dbg(&client->dev, "Setting CONFIG to: 0x%02x\n", value);
+	data->config1 = value;
+	adm1026_write_value(client, ADM1026_REG_CONFIG1, value);
+
+	/* initialize fan_div[] to hardware defaults */
+	value = adm1026_read_value(client, ADM1026_REG_FAN_DIV_0_3) |
+		(adm1026_read_value(client, ADM1026_REG_FAN_DIV_4_7) << 8);
+	for (i = 0; i <= 7; ++i) {
+		data->fan_div[i] = DIV_FROM_REG(value & 0x03);
+		value >>= 2;
+	}
+}
+
 static int adm1026_probe(struct i2c_client *client,
 static int adm1026_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 			 const struct i2c_device_id *id)
 {
 {
+	struct device *dev = &client->dev;
+	struct device *hwmon_dev;
 	struct adm1026_data *data;
 	struct adm1026_data *data;
-	int err;
 
 
-	data = devm_kzalloc(&client->dev, sizeof(struct adm1026_data),
-			    GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(struct adm1026_data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	i2c_set_clientdata(client, data);
 	i2c_set_clientdata(client, data);
+	data->client = client;
 	mutex_init(&data->update_lock);
 	mutex_init(&data->update_lock);
 
 
 	/* Set the VRM version */
 	/* Set the VRM version */
@@ -1849,48 +1819,34 @@ static int adm1026_probe(struct i2c_client *client,
 	/* Initialize the ADM1026 chip */
 	/* Initialize the ADM1026 chip */
 	adm1026_init_client(client);
 	adm1026_init_client(client);
 
 
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&client->dev.kobj, &adm1026_group);
-	if (err)
-		return err;
+	/* sysfs hooks */
+	data->groups[0] = &adm1026_group;
 	if (data->config1 & CFG1_AIN8_9)
 	if (data->config1 & CFG1_AIN8_9)
-		err = sysfs_create_group(&client->dev.kobj,
-					 &adm1026_group_in8_9);
+		data->groups[1] = &adm1026_group_in8_9;
 	else
 	else
-		err = sysfs_create_group(&client->dev.kobj,
-					 &adm1026_group_temp3);
-	if (err)
-		goto exitremove;
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exitremove;
-	}
-
-	return 0;
+		data->groups[1] = &adm1026_group_temp3;
 
 
-	/* Error out and cleanup code */
-exitremove:
-	sysfs_remove_group(&client->dev.kobj, &adm1026_group);
-	if (data->config1 & CFG1_AIN8_9)
-		sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9);
-	else
-		sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3);
-	return err;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data, data->groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
-static int adm1026_remove(struct i2c_client *client)
-{
-	struct adm1026_data *data = i2c_get_clientdata(client);
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &adm1026_group);
-	if (data->config1 & CFG1_AIN8_9)
-		sysfs_remove_group(&client->dev.kobj, &adm1026_group_in8_9);
-	else
-		sysfs_remove_group(&client->dev.kobj, &adm1026_group_temp3);
-	return 0;
-}
+static const struct i2c_device_id adm1026_id[] = {
+	{ "adm1026", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, adm1026_id);
+
+static struct i2c_driver adm1026_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "adm1026",
+	},
+	.probe		= adm1026_probe,
+	.id_table	= adm1026_id,
+	.detect		= adm1026_detect,
+	.address_list	= normal_i2c,
+};
 
 
 module_i2c_driver(adm1026_driver);
 module_i2c_driver(adm1026_driver);
 
 

+ 84 - 124
drivers/hwmon/adm1029.c

@@ -105,46 +105,12 @@ static const u8 ADM1029_REG_FAN_DIV[] = {
 	ADM1029_REG_FAN2_CONFIG,
 	ADM1029_REG_FAN2_CONFIG,
 };
 };
 
 
-/*
- * Functions declaration
- */
-
-static int adm1029_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id);
-static int adm1029_detect(struct i2c_client *client,
-			  struct i2c_board_info *info);
-static int adm1029_remove(struct i2c_client *client);
-static struct adm1029_data *adm1029_update_device(struct device *dev);
-static int adm1029_init_client(struct i2c_client *client);
-
-/*
- * Driver data (common to all clients)
- */
-
-static const struct i2c_device_id adm1029_id[] = {
-	{ "adm1029", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, adm1029_id);
-
-static struct i2c_driver adm1029_driver = {
-	.class		= I2C_CLASS_HWMON,
-	.driver = {
-		.name = "adm1029",
-	},
-	.probe		= adm1029_probe,
-	.remove		= adm1029_remove,
-	.id_table	= adm1029_id,
-	.detect		= adm1029_detect,
-	.address_list	= normal_i2c,
-};
-
 /*
 /*
  * Client data (each client gets its own)
  * Client data (each client gets its own)
  */
  */
 
 
 struct adm1029_data {
 struct adm1029_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
 	struct mutex update_lock;
 	struct mutex update_lock;
 	char valid;		/* zero until following fields are valid */
 	char valid;		/* zero until following fields are valid */
 	unsigned long last_updated;	/* in jiffies */
 	unsigned long last_updated;	/* in jiffies */
@@ -155,6 +121,50 @@ struct adm1029_data {
 	u8 fan_div[ARRAY_SIZE(ADM1029_REG_FAN_DIV)];
 	u8 fan_div[ARRAY_SIZE(ADM1029_REG_FAN_DIV)];
 };
 };
 
 
+/*
+ * function that update the status of the chips (temperature for example)
+ */
+static struct adm1029_data *adm1029_update_device(struct device *dev)
+{
+	struct adm1029_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
+
+	mutex_lock(&data->update_lock);
+	/*
+	 * Use the "cache" Luke, don't recheck values
+	 * if there are already checked not a long time later
+	 */
+	if (time_after(jiffies, data->last_updated + HZ * 2)
+	 || !data->valid) {
+		int nr;
+
+		dev_dbg(&client->dev, "Updating adm1029 data\n");
+
+		for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_TEMP); nr++) {
+			data->temp[nr] =
+			    i2c_smbus_read_byte_data(client,
+						     ADM1029_REG_TEMP[nr]);
+		}
+		for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN); nr++) {
+			data->fan[nr] =
+			    i2c_smbus_read_byte_data(client,
+						     ADM1029_REG_FAN[nr]);
+		}
+		for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN_DIV); nr++) {
+			data->fan_div[nr] =
+			    i2c_smbus_read_byte_data(client,
+						     ADM1029_REG_FAN_DIV[nr]);
+		}
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
 /*
 /*
  * Sysfs stuff
  * Sysfs stuff
  */
  */
@@ -197,8 +207,8 @@ show_fan_div(struct device *dev, struct device_attribute *devattr, char *buf)
 static ssize_t set_fan_div(struct device *dev,
 static ssize_t set_fan_div(struct device *dev,
 	    struct device_attribute *devattr, const char *buf, size_t count)
 	    struct device_attribute *devattr, const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1029_data *data = i2c_get_clientdata(client);
+	struct adm1029_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	u8 reg;
 	u8 reg;
 	long val;
 	long val;
@@ -270,7 +280,7 @@ static SENSOR_DEVICE_ATTR(fan1_div, S_IRUGO | S_IWUSR,
 static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
 static SENSOR_DEVICE_ATTR(fan2_div, S_IRUGO | S_IWUSR,
 			  show_fan_div, set_fan_div, 1);
 			  show_fan_div, set_fan_div, 1);
 
 
-static struct attribute *adm1029_attributes[] = {
+static struct attribute *adm1029_attrs[] = {
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_min.dev_attr.attr,
 	&sensor_dev_attr_temp1_min.dev_attr.attr,
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
@@ -289,9 +299,7 @@ static struct attribute *adm1029_attributes[] = {
 	NULL
 	NULL
 };
 };
 
 
-static const struct attribute_group adm1029_group = {
-	.attrs = adm1029_attributes,
-};
+ATTRIBUTE_GROUPS(adm1029);
 
 
 /*
 /*
  * Real code
  * Real code
@@ -340,48 +348,10 @@ static int adm1029_detect(struct i2c_client *client,
 	return 0;
 	return 0;
 }
 }
 
 
-static int adm1029_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id)
-{
-	struct adm1029_data *data;
-	int err;
-
-	data = devm_kzalloc(&client->dev, sizeof(struct adm1029_data),
-			    GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	i2c_set_clientdata(client, data);
-	mutex_init(&data->update_lock);
-
-	/*
-	 * Initialize the ADM1029 chip
-	 * Check config register
-	 */
-	if (adm1029_init_client(client) == 0)
-		return -ENODEV;
-
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&client->dev.kobj, &adm1029_group);
-	if (err)
-		return err;
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove_files;
-	}
-
-	return 0;
-
- exit_remove_files:
-	sysfs_remove_group(&client->dev.kobj, &adm1029_group);
-	return err;
-}
-
 static int adm1029_init_client(struct i2c_client *client)
 static int adm1029_init_client(struct i2c_client *client)
 {
 {
 	u8 config;
 	u8 config;
+
 	config = i2c_smbus_read_byte_data(client, ADM1029_REG_CONFIG);
 	config = i2c_smbus_read_byte_data(client, ADM1029_REG_CONFIG);
 	if ((config & 0x10) == 0) {
 	if ((config & 0x10) == 0) {
 		i2c_smbus_write_byte_data(client, ADM1029_REG_CONFIG,
 		i2c_smbus_write_byte_data(client, ADM1029_REG_CONFIG,
@@ -396,59 +366,49 @@ static int adm1029_init_client(struct i2c_client *client)
 	return 1;
 	return 1;
 }
 }
 
 
-static int adm1029_remove(struct i2c_client *client)
+static int adm1029_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
 {
 {
-	struct adm1029_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &adm1029_group);
+	struct device *dev = &client->dev;
+	struct adm1029_data *data;
+	struct device *hwmon_dev;
 
 
-	return 0;
-}
+	data = devm_kzalloc(dev, sizeof(struct adm1029_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
 
 
-/*
- * function that update the status of the chips (temperature for example)
- */
-static struct adm1029_data *adm1029_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1029_data *data = i2c_get_clientdata(client);
+	data->client = client;
+	mutex_init(&data->update_lock);
 
 
-	mutex_lock(&data->update_lock);
 	/*
 	/*
-	 * Use the "cache" Luke, don't recheck values
-	 * if there are already checked not a long time later
+	 * Initialize the ADM1029 chip
+	 * Check config register
 	 */
 	 */
-	if (time_after(jiffies, data->last_updated + HZ * 2)
-	 || !data->valid) {
-		int nr;
-
-		dev_dbg(&client->dev, "Updating adm1029 data\n");
-
-		for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_TEMP); nr++) {
-			data->temp[nr] =
-			    i2c_smbus_read_byte_data(client,
-						     ADM1029_REG_TEMP[nr]);
-		}
-		for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN); nr++) {
-			data->fan[nr] =
-			    i2c_smbus_read_byte_data(client,
-						     ADM1029_REG_FAN[nr]);
-		}
-		for (nr = 0; nr < ARRAY_SIZE(ADM1029_REG_FAN_DIV); nr++) {
-			data->fan_div[nr] =
-			    i2c_smbus_read_byte_data(client,
-						     ADM1029_REG_FAN_DIV[nr]);
-		}
+	if (adm1029_init_client(client) == 0)
+		return -ENODEV;
 
 
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data,
+							   adm1029_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
 
 
-	mutex_unlock(&data->update_lock);
+static const struct i2c_device_id adm1029_id[] = {
+	{ "adm1029", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, adm1029_id);
 
 
-	return data;
-}
+static struct i2c_driver adm1029_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name = "adm1029",
+	},
+	.probe		= adm1029_probe,
+	.id_table	= adm1029_id,
+	.detect		= adm1029_detect,
+	.address_list	= normal_i2c,
+};
 
 
 module_i2c_driver(adm1029_driver);
 module_i2c_driver(adm1029_driver);
 
 

+ 157 - 192
drivers/hwmon/adm1031.c

@@ -74,7 +74,8 @@ typedef u8 auto_chan_table_t[8][2];
 
 
 /* Each client has this additional data */
 /* Each client has this additional data */
 struct adm1031_data {
 struct adm1031_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
+	const struct attribute_group *groups[3];
 	struct mutex update_lock;
 	struct mutex update_lock;
 	int chip_type;
 	int chip_type;
 	char valid;		/* !=0 if following fields are valid */
 	char valid;		/* !=0 if following fields are valid */
@@ -105,34 +106,6 @@ struct adm1031_data {
 	s8 temp_crit[3];
 	s8 temp_crit[3];
 };
 };
 
 
-static int adm1031_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id);
-static int adm1031_detect(struct i2c_client *client,
-			  struct i2c_board_info *info);
-static void adm1031_init_client(struct i2c_client *client);
-static int adm1031_remove(struct i2c_client *client);
-static struct adm1031_data *adm1031_update_device(struct device *dev);
-
-static const struct i2c_device_id adm1031_id[] = {
-	{ "adm1030", adm1030 },
-	{ "adm1031", adm1031 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, adm1031_id);
-
-/* This is the driver that will be inserted */
-static struct i2c_driver adm1031_driver = {
-	.class		= I2C_CLASS_HWMON,
-	.driver = {
-		.name = "adm1031",
-	},
-	.probe		= adm1031_probe,
-	.remove		= adm1031_remove,
-	.id_table	= adm1031_id,
-	.detect		= adm1031_detect,
-	.address_list	= normal_i2c,
-};
-
 static inline u8 adm1031_read_value(struct i2c_client *client, u8 reg)
 static inline u8 adm1031_read_value(struct i2c_client *client, u8 reg)
 {
 {
 	return i2c_smbus_read_byte_data(client, reg);
 	return i2c_smbus_read_byte_data(client, reg);
@@ -144,6 +117,96 @@ adm1031_write_value(struct i2c_client *client, u8 reg, unsigned int value)
 	return i2c_smbus_write_byte_data(client, reg, value);
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 }
 
 
+static struct adm1031_data *adm1031_update_device(struct device *dev)
+{
+	struct adm1031_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
+	unsigned long next_update;
+	int chan;
+
+	mutex_lock(&data->update_lock);
+
+	next_update = data->last_updated
+	  + msecs_to_jiffies(data->update_interval);
+	if (time_after(jiffies, next_update) || !data->valid) {
+
+		dev_dbg(&client->dev, "Starting adm1031 update\n");
+		for (chan = 0;
+		     chan < ((data->chip_type == adm1031) ? 3 : 2); chan++) {
+			u8 oldh, newh;
+
+			oldh =
+			    adm1031_read_value(client, ADM1031_REG_TEMP(chan));
+			data->ext_temp[chan] =
+			    adm1031_read_value(client, ADM1031_REG_EXT_TEMP);
+			newh =
+			    adm1031_read_value(client, ADM1031_REG_TEMP(chan));
+			if (newh != oldh) {
+				data->ext_temp[chan] =
+				    adm1031_read_value(client,
+						       ADM1031_REG_EXT_TEMP);
+#ifdef DEBUG
+				oldh =
+				    adm1031_read_value(client,
+						       ADM1031_REG_TEMP(chan));
+
+				/* oldh is actually newer */
+				if (newh != oldh)
+					dev_warn(&client->dev,
+					  "Remote temperature may be wrong.\n");
+#endif
+			}
+			data->temp[chan] = newh;
+
+			data->temp_offset[chan] =
+			    adm1031_read_value(client,
+					       ADM1031_REG_TEMP_OFFSET(chan));
+			data->temp_min[chan] =
+			    adm1031_read_value(client,
+					       ADM1031_REG_TEMP_MIN(chan));
+			data->temp_max[chan] =
+			    adm1031_read_value(client,
+					       ADM1031_REG_TEMP_MAX(chan));
+			data->temp_crit[chan] =
+			    adm1031_read_value(client,
+					       ADM1031_REG_TEMP_CRIT(chan));
+			data->auto_temp[chan] =
+			    adm1031_read_value(client,
+					       ADM1031_REG_AUTO_TEMP(chan));
+
+		}
+
+		data->conf1 = adm1031_read_value(client, ADM1031_REG_CONF1);
+		data->conf2 = adm1031_read_value(client, ADM1031_REG_CONF2);
+
+		data->alarm = adm1031_read_value(client, ADM1031_REG_STATUS(0))
+		    | (adm1031_read_value(client, ADM1031_REG_STATUS(1)) << 8);
+		if (data->chip_type == adm1030)
+			data->alarm &= 0xc0ff;
+
+		for (chan = 0; chan < (data->chip_type == adm1030 ? 1 : 2);
+		     chan++) {
+			data->fan_div[chan] =
+			    adm1031_read_value(client,
+					       ADM1031_REG_FAN_DIV(chan));
+			data->fan_min[chan] =
+			    adm1031_read_value(client,
+					       ADM1031_REG_FAN_MIN(chan));
+			data->fan[chan] =
+			    adm1031_read_value(client,
+					       ADM1031_REG_FAN_SPEED(chan));
+			data->pwm[chan] =
+			  (adm1031_read_value(client,
+					ADM1031_REG_PWM) >> (4 * chan)) & 0x0f;
+		}
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
 
 
 #define TEMP_TO_REG(val)		(((val) < 0 ? ((val - 500) / 1000) : \
 #define TEMP_TO_REG(val)		(((val) < 0 ? ((val - 500) / 1000) : \
 					((val + 500) / 1000)))
 					((val + 500) / 1000)))
@@ -280,8 +343,8 @@ static ssize_t
 set_fan_auto_channel(struct device *dev, struct device_attribute *attr,
 set_fan_auto_channel(struct device *dev, struct device_attribute *attr,
 		     const char *buf, size_t count)
 		     const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
+	struct adm1031_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
 	long val;
 	long val;
 	u8 reg;
 	u8 reg;
@@ -355,8 +418,8 @@ static ssize_t
 set_auto_temp_min(struct device *dev, struct device_attribute *attr,
 set_auto_temp_min(struct device *dev, struct device_attribute *attr,
 		  const char *buf, size_t count)
 		  const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
+	struct adm1031_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
 	long val;
 	long val;
 	int ret;
 	int ret;
@@ -385,8 +448,8 @@ static ssize_t
 set_auto_temp_max(struct device *dev, struct device_attribute *attr,
 set_auto_temp_max(struct device *dev, struct device_attribute *attr,
 		  const char *buf, size_t count)
 		  const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
+	struct adm1031_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
 	long val;
 	long val;
 	int ret;
 	int ret;
@@ -428,8 +491,8 @@ static ssize_t show_pwm(struct device *dev,
 static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
 static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
 		       const char *buf, size_t count)
 		       const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
+	struct adm1031_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
 	long val;
 	long val;
 	int ret, reg;
 	int ret, reg;
@@ -541,8 +604,8 @@ static ssize_t show_fan_min(struct device *dev,
 static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 			   const char *buf, size_t count)
 			   const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
+	struct adm1031_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
 	long val;
 	long val;
 	int ret;
 	int ret;
@@ -565,8 +628,8 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 			   const char *buf, size_t count)
 			   const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
+	struct adm1031_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
 	long val;
 	long val;
 	u8 tmp;
 	u8 tmp;
@@ -667,8 +730,8 @@ static ssize_t set_temp_offset(struct device *dev,
 			       struct device_attribute *attr, const char *buf,
 			       struct device_attribute *attr, const char *buf,
 			       size_t count)
 			       size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
+	struct adm1031_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
 	long val;
 	long val;
 	int ret;
 	int ret;
@@ -688,8 +751,8 @@ static ssize_t set_temp_offset(struct device *dev,
 static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
 static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
 			    const char *buf, size_t count)
 			    const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
+	struct adm1031_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
 	long val;
 	long val;
 	int ret;
 	int ret;
@@ -709,8 +772,8 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
 static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 			    const char *buf, size_t count)
 			    const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
+	struct adm1031_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
 	long val;
 	long val;
 	int ret;
 	int ret;
@@ -730,8 +793,8 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
 static ssize_t set_temp_crit(struct device *dev, struct device_attribute *attr,
 			     const char *buf, size_t count)
 			     const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
+	struct adm1031_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
 	long val;
 	long val;
 	int ret;
 	int ret;
@@ -807,8 +870,7 @@ static const unsigned int update_intervals[] = {
 static ssize_t show_update_interval(struct device *dev,
 static ssize_t show_update_interval(struct device *dev,
 				    struct device_attribute *attr, char *buf)
 				    struct device_attribute *attr, char *buf)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
+	struct adm1031_data *data = dev_get_drvdata(dev);
 
 
 	return sprintf(buf, "%u\n", data->update_interval);
 	return sprintf(buf, "%u\n", data->update_interval);
 }
 }
@@ -817,8 +879,8 @@ static ssize_t set_update_interval(struct device *dev,
 				   struct device_attribute *attr,
 				   struct device_attribute *attr,
 				   const char *buf, size_t count)
 				   const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
+	struct adm1031_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int i, err;
 	int i, err;
 	u8 reg;
 	u8 reg;
@@ -950,64 +1012,6 @@ static int adm1031_detect(struct i2c_client *client,
 	return 0;
 	return 0;
 }
 }
 
 
-static int adm1031_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id)
-{
-	struct adm1031_data *data;
-	int err;
-
-	data = devm_kzalloc(&client->dev, sizeof(struct adm1031_data),
-			    GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	i2c_set_clientdata(client, data);
-	data->chip_type = id->driver_data;
-	mutex_init(&data->update_lock);
-
-	if (data->chip_type == adm1030)
-		data->chan_select_table = &auto_channel_select_table_adm1030;
-	else
-		data->chan_select_table = &auto_channel_select_table_adm1031;
-
-	/* Initialize the ADM1031 chip */
-	adm1031_init_client(client);
-
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&client->dev.kobj, &adm1031_group);
-	if (err)
-		return err;
-
-	if (data->chip_type == adm1031) {
-		err = sysfs_create_group(&client->dev.kobj, &adm1031_group_opt);
-		if (err)
-			goto exit_remove;
-	}
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove;
-	}
-
-	return 0;
-
-exit_remove:
-	sysfs_remove_group(&client->dev.kobj, &adm1031_group);
-	sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt);
-	return err;
-}
-
-static int adm1031_remove(struct i2c_client *client)
-{
-	struct adm1031_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &adm1031_group);
-	sysfs_remove_group(&client->dev.kobj, &adm1031_group_opt);
-	return 0;
-}
-
 static void adm1031_init_client(struct i2c_client *client)
 static void adm1031_init_client(struct i2c_client *client)
 {
 {
 	unsigned int read_val;
 	unsigned int read_val;
@@ -1039,96 +1043,57 @@ static void adm1031_init_client(struct i2c_client *client)
 	data->update_interval = update_intervals[i];
 	data->update_interval = update_intervals[i];
 }
 }
 
 
-static struct adm1031_data *adm1031_update_device(struct device *dev)
+static int adm1031_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm1031_data *data = i2c_get_clientdata(client);
-	unsigned long next_update;
-	int chan;
-
-	mutex_lock(&data->update_lock);
-
-	next_update = data->last_updated
-	  + msecs_to_jiffies(data->update_interval);
-	if (time_after(jiffies, next_update) || !data->valid) {
-
-		dev_dbg(&client->dev, "Starting adm1031 update\n");
-		for (chan = 0;
-		     chan < ((data->chip_type == adm1031) ? 3 : 2); chan++) {
-			u8 oldh, newh;
-
-			oldh =
-			    adm1031_read_value(client, ADM1031_REG_TEMP(chan));
-			data->ext_temp[chan] =
-			    adm1031_read_value(client, ADM1031_REG_EXT_TEMP);
-			newh =
-			    adm1031_read_value(client, ADM1031_REG_TEMP(chan));
-			if (newh != oldh) {
-				data->ext_temp[chan] =
-				    adm1031_read_value(client,
-						       ADM1031_REG_EXT_TEMP);
-#ifdef DEBUG
-				oldh =
-				    adm1031_read_value(client,
-						       ADM1031_REG_TEMP(chan));
+	struct device *dev = &client->dev;
+	struct device *hwmon_dev;
+	struct adm1031_data *data;
 
 
-				/* oldh is actually newer */
-				if (newh != oldh)
-					dev_warn(&client->dev,
-					  "Remote temperature may be wrong.\n");
-#endif
-			}
-			data->temp[chan] = newh;
+	data = devm_kzalloc(dev, sizeof(struct adm1031_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
 
 
-			data->temp_offset[chan] =
-			    adm1031_read_value(client,
-					       ADM1031_REG_TEMP_OFFSET(chan));
-			data->temp_min[chan] =
-			    adm1031_read_value(client,
-					       ADM1031_REG_TEMP_MIN(chan));
-			data->temp_max[chan] =
-			    adm1031_read_value(client,
-					       ADM1031_REG_TEMP_MAX(chan));
-			data->temp_crit[chan] =
-			    adm1031_read_value(client,
-					       ADM1031_REG_TEMP_CRIT(chan));
-			data->auto_temp[chan] =
-			    adm1031_read_value(client,
-					       ADM1031_REG_AUTO_TEMP(chan));
+	i2c_set_clientdata(client, data);
+	data->client = client;
+	data->chip_type = id->driver_data;
+	mutex_init(&data->update_lock);
 
 
-		}
+	if (data->chip_type == adm1030)
+		data->chan_select_table = &auto_channel_select_table_adm1030;
+	else
+		data->chan_select_table = &auto_channel_select_table_adm1031;
 
 
-		data->conf1 = adm1031_read_value(client, ADM1031_REG_CONF1);
-		data->conf2 = adm1031_read_value(client, ADM1031_REG_CONF2);
+	/* Initialize the ADM1031 chip */
+	adm1031_init_client(client);
 
 
-		data->alarm = adm1031_read_value(client, ADM1031_REG_STATUS(0))
-		    | (adm1031_read_value(client, ADM1031_REG_STATUS(1)) << 8);
-		if (data->chip_type == adm1030)
-			data->alarm &= 0xc0ff;
+	/* sysfs hooks */
+	data->groups[0] = &adm1031_group;
+	if (data->chip_type == adm1031)
+		data->groups[1] = &adm1031_group_opt;
 
 
-		for (chan = 0; chan < (data->chip_type == adm1030 ? 1 : 2);
-		     chan++) {
-			data->fan_div[chan] =
-			    adm1031_read_value(client,
-					       ADM1031_REG_FAN_DIV(chan));
-			data->fan_min[chan] =
-			    adm1031_read_value(client,
-					       ADM1031_REG_FAN_MIN(chan));
-			data->fan[chan] =
-			    adm1031_read_value(client,
-					       ADM1031_REG_FAN_SPEED(chan));
-			data->pwm[chan] =
-			  (adm1031_read_value(client,
-					ADM1031_REG_PWM) >> (4 * chan)) & 0x0f;
-		}
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data, data->groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
 
 
-	mutex_unlock(&data->update_lock);
+static const struct i2c_device_id adm1031_id[] = {
+	{ "adm1030", adm1030 },
+	{ "adm1031", adm1031 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, adm1031_id);
 
 
-	return data;
-}
+static struct i2c_driver adm1031_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name = "adm1031",
+	},
+	.probe		= adm1031_probe,
+	.id_table	= adm1031_id,
+	.detect		= adm1031_detect,
+	.address_list	= normal_i2c,
+};
 
 
 module_i2c_driver(adm1031_driver);
 module_i2c_driver(adm1031_driver);
 
 

+ 154 - 185
drivers/hwmon/adm9240.c

@@ -130,38 +130,9 @@ static inline unsigned int AOUT_FROM_REG(u8 reg)
 	return SCALE(reg, 1250, 255);
 	return SCALE(reg, 1250, 255);
 }
 }
 
 
-static int adm9240_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id);
-static int adm9240_detect(struct i2c_client *client,
-			  struct i2c_board_info *info);
-static void adm9240_init_client(struct i2c_client *client);
-static int adm9240_remove(struct i2c_client *client);
-static struct adm9240_data *adm9240_update_device(struct device *dev);
-
-/* driver data */
-static const struct i2c_device_id adm9240_id[] = {
-	{ "adm9240", adm9240 },
-	{ "ds1780", ds1780 },
-	{ "lm81", lm81 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, adm9240_id);
-
-static struct i2c_driver adm9240_driver = {
-	.class		= I2C_CLASS_HWMON,
-	.driver = {
-		.name	= "adm9240",
-	},
-	.probe		= adm9240_probe,
-	.remove		= adm9240_remove,
-	.id_table	= adm9240_id,
-	.detect		= adm9240_detect,
-	.address_list	= normal_i2c,
-};
-
 /* per client data */
 /* per client data */
 struct adm9240_data {
 struct adm9240_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
 	struct mutex update_lock;
 	struct mutex update_lock;
 	char valid;
 	char valid;
 	unsigned long last_updated_measure;
 	unsigned long last_updated_measure;
@@ -181,6 +152,110 @@ struct adm9240_data {
 	u8 vrm;			/* --	vrm set on startup, no accessor */
 	u8 vrm;			/* --	vrm set on startup, no accessor */
 };
 };
 
 
+/* write new fan div, callers must hold data->update_lock */
+static void adm9240_write_fan_div(struct i2c_client *client, int nr,
+		u8 fan_div)
+{
+	u8 reg, old, shift = (nr + 2) * 2;
+
+	reg = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
+	old = (reg >> shift) & 3;
+	reg &= ~(3 << shift);
+	reg |= (fan_div << shift);
+	i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg);
+	dev_dbg(&client->dev,
+		"fan%d clock divider changed from %u to %u\n",
+		nr + 1, 1 << old, 1 << fan_div);
+}
+
+static struct adm9240_data *adm9240_update_device(struct device *dev)
+{
+	struct adm9240_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
+	int i;
+
+	mutex_lock(&data->update_lock);
+
+	/* minimum measurement cycle: 1.75 seconds */
+	if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4))
+			|| !data->valid) {
+
+		for (i = 0; i < 6; i++) { /* read voltages */
+			data->in[i] = i2c_smbus_read_byte_data(client,
+					ADM9240_REG_IN(i));
+		}
+		data->alarms = i2c_smbus_read_byte_data(client,
+					ADM9240_REG_INT(0)) |
+					i2c_smbus_read_byte_data(client,
+					ADM9240_REG_INT(1)) << 8;
+
+		/*
+		 * read temperature: assume temperature changes less than
+		 * 0.5'C per two measurement cycles thus ignore possible
+		 * but unlikely aliasing error on lsb reading. --Grant
+		 */
+		data->temp = ((i2c_smbus_read_byte_data(client,
+					ADM9240_REG_TEMP) << 8) |
+					i2c_smbus_read_byte_data(client,
+					ADM9240_REG_TEMP_CONF)) / 128;
+
+		for (i = 0; i < 2; i++) { /* read fans */
+			data->fan[i] = i2c_smbus_read_byte_data(client,
+					ADM9240_REG_FAN(i));
+
+			/* adjust fan clock divider on overflow */
+			if (data->valid && data->fan[i] == 255 &&
+					data->fan_div[i] < 3) {
+
+				adm9240_write_fan_div(client, i,
+						++data->fan_div[i]);
+
+				/* adjust fan_min if active, but not to 0 */
+				if (data->fan_min[i] < 255 &&
+						data->fan_min[i] >= 2)
+					data->fan_min[i] /= 2;
+			}
+		}
+		data->last_updated_measure = jiffies;
+	}
+
+	/* minimum config reading cycle: 300 seconds */
+	if (time_after(jiffies, data->last_updated_config + (HZ * 300))
+			|| !data->valid) {
+
+		for (i = 0; i < 6; i++) {
+			data->in_min[i] = i2c_smbus_read_byte_data(client,
+					ADM9240_REG_IN_MIN(i));
+			data->in_max[i] = i2c_smbus_read_byte_data(client,
+					ADM9240_REG_IN_MAX(i));
+		}
+		for (i = 0; i < 2; i++) {
+			data->fan_min[i] = i2c_smbus_read_byte_data(client,
+					ADM9240_REG_FAN_MIN(i));
+		}
+		data->temp_max[0] = i2c_smbus_read_byte_data(client,
+				ADM9240_REG_TEMP_MAX(0));
+		data->temp_max[1] = i2c_smbus_read_byte_data(client,
+				ADM9240_REG_TEMP_MAX(1));
+
+		/* read fan divs and 5-bit VID */
+		i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
+		data->fan_div[0] = (i >> 4) & 3;
+		data->fan_div[1] = (i >> 6) & 3;
+		data->vid = i & 0x0f;
+		data->vid |= (i2c_smbus_read_byte_data(client,
+					ADM9240_REG_VID4) & 1) << 4;
+		/* read analog out */
+		data->aout = i2c_smbus_read_byte_data(client,
+				ADM9240_REG_ANALOG_OUT);
+
+		data->last_updated_config = jiffies;
+		data->valid = 1;
+	}
+	mutex_unlock(&data->update_lock);
+	return data;
+}
+
 /*** sysfs accessors ***/
 /*** sysfs accessors ***/
 
 
 /* temperature */
 /* temperature */
@@ -203,8 +278,8 @@ static ssize_t set_max(struct device *dev, struct device_attribute *devattr,
 		const char *buf, size_t count)
 		const char *buf, size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm9240_data *data = i2c_get_clientdata(client);
+	struct adm9240_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -259,8 +334,8 @@ static ssize_t set_in_min(struct device *dev,
 		const char *buf, size_t count)
 		const char *buf, size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm9240_data *data = i2c_get_clientdata(client);
+	struct adm9240_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -281,8 +356,8 @@ static ssize_t set_in_max(struct device *dev,
 		const char *buf, size_t count)
 		const char *buf, size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm9240_data *data = i2c_get_clientdata(client);
+	struct adm9240_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -340,22 +415,6 @@ static ssize_t show_fan_div(struct device *dev,
 	return sprintf(buf, "%d\n", 1 << data->fan_div[attr->index]);
 	return sprintf(buf, "%d\n", 1 << data->fan_div[attr->index]);
 }
 }
 
 
-/* write new fan div, callers must hold data->update_lock */
-static void adm9240_write_fan_div(struct i2c_client *client, int nr,
-		u8 fan_div)
-{
-	u8 reg, old, shift = (nr + 2) * 2;
-
-	reg = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
-	old = (reg >> shift) & 3;
-	reg &= ~(3 << shift);
-	reg |= (fan_div << shift);
-	i2c_smbus_write_byte_data(client, ADM9240_REG_VID_FAN_DIV, reg);
-	dev_dbg(&client->dev,
-		"fan%d clock divider changed from %u to %u\n",
-		nr + 1, 1 << old, 1 << fan_div);
-}
-
 /*
 /*
  * set fan speed low limit:
  * set fan speed low limit:
  *
  *
@@ -372,8 +431,8 @@ static ssize_t set_fan_min(struct device *dev,
 		const char *buf, size_t count)
 		const char *buf, size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm9240_data *data = i2c_get_clientdata(client);
+	struct adm9240_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int nr = attr->index;
 	int nr = attr->index;
 	u8 new_div;
 	u8 new_div;
 	unsigned long val;
 	unsigned long val;
@@ -485,8 +544,8 @@ static ssize_t set_aout(struct device *dev,
 		struct device_attribute *attr,
 		struct device_attribute *attr,
 		const char *buf, size_t count)
 		const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm9240_data *data = i2c_get_clientdata(client);
+	struct adm9240_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -506,8 +565,8 @@ static ssize_t chassis_clear(struct device *dev,
 		struct device_attribute *attr,
 		struct device_attribute *attr,
 		const char *buf, size_t count)
 		const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm9240_data *data = i2c_get_clientdata(client);
+	struct adm9240_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 
 
 	if (kstrtoul(buf, 10, &val) || val != 0)
 	if (kstrtoul(buf, 10, &val) || val != 0)
@@ -524,7 +583,7 @@ static ssize_t chassis_clear(struct device *dev,
 static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IRUGO | S_IWUSR, show_alarm,
 static SENSOR_DEVICE_ATTR(intrusion0_alarm, S_IRUGO | S_IWUSR, show_alarm,
 		chassis_clear, 12);
 		chassis_clear, 12);
 
 
-static struct attribute *adm9240_attributes[] = {
+static struct attribute *adm9240_attrs[] = {
 	&sensor_dev_attr_in0_input.dev_attr.attr,
 	&sensor_dev_attr_in0_input.dev_attr.attr,
 	&sensor_dev_attr_in0_min.dev_attr.attr,
 	&sensor_dev_attr_in0_min.dev_attr.attr,
 	&sensor_dev_attr_in0_max.dev_attr.attr,
 	&sensor_dev_attr_in0_max.dev_attr.attr,
@@ -568,9 +627,7 @@ static struct attribute *adm9240_attributes[] = {
 	NULL
 	NULL
 };
 };
 
 
-static const struct attribute_group adm9240_group = {
-	.attrs = adm9240_attributes,
-};
+ATTRIBUTE_GROUPS(adm9240);
 
 
 
 
 /*** sensor chip detect and driver install ***/
 /*** sensor chip detect and driver install ***/
@@ -620,49 +677,6 @@ static int adm9240_detect(struct i2c_client *new_client,
 	return 0;
 	return 0;
 }
 }
 
 
-static int adm9240_probe(struct i2c_client *new_client,
-			 const struct i2c_device_id *id)
-{
-	struct adm9240_data *data;
-	int err;
-
-	data = devm_kzalloc(&new_client->dev, sizeof(*data), GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	i2c_set_clientdata(new_client, data);
-	mutex_init(&data->update_lock);
-
-	adm9240_init_client(new_client);
-
-	/* populate sysfs filesystem */
-	err = sysfs_create_group(&new_client->dev.kobj, &adm9240_group);
-	if (err)
-		return err;
-
-	data->hwmon_dev = hwmon_device_register(&new_client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove;
-	}
-
-	return 0;
-
-exit_remove:
-	sysfs_remove_group(&new_client->dev.kobj, &adm9240_group);
-	return err;
-}
-
-static int adm9240_remove(struct i2c_client *client)
-{
-	struct adm9240_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &adm9240_group);
-
-	return 0;
-}
-
 static void adm9240_init_client(struct i2c_client *client)
 static void adm9240_init_client(struct i2c_client *client)
 {
 {
 	struct adm9240_data *data = i2c_get_clientdata(client);
 	struct adm9240_data *data = i2c_get_clientdata(client);
@@ -705,93 +719,48 @@ static void adm9240_init_client(struct i2c_client *client)
 	}
 	}
 }
 }
 
 
-static struct adm9240_data *adm9240_update_device(struct device *dev)
+static int adm9240_probe(struct i2c_client *new_client,
+			 const struct i2c_device_id *id)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adm9240_data *data = i2c_get_clientdata(client);
-	int i;
-
-	mutex_lock(&data->update_lock);
-
-	/* minimum measurement cycle: 1.75 seconds */
-	if (time_after(jiffies, data->last_updated_measure + (HZ * 7 / 4))
-			|| !data->valid) {
-
-		for (i = 0; i < 6; i++) { /* read voltages */
-			data->in[i] = i2c_smbus_read_byte_data(client,
-					ADM9240_REG_IN(i));
-		}
-		data->alarms = i2c_smbus_read_byte_data(client,
-					ADM9240_REG_INT(0)) |
-					i2c_smbus_read_byte_data(client,
-					ADM9240_REG_INT(1)) << 8;
-
-		/*
-		 * read temperature: assume temperature changes less than
-		 * 0.5'C per two measurement cycles thus ignore possible
-		 * but unlikely aliasing error on lsb reading. --Grant
-		 */
-		data->temp = ((i2c_smbus_read_byte_data(client,
-					ADM9240_REG_TEMP) << 8) |
-					i2c_smbus_read_byte_data(client,
-					ADM9240_REG_TEMP_CONF)) / 128;
-
-		for (i = 0; i < 2; i++) { /* read fans */
-			data->fan[i] = i2c_smbus_read_byte_data(client,
-					ADM9240_REG_FAN(i));
-
-			/* adjust fan clock divider on overflow */
-			if (data->valid && data->fan[i] == 255 &&
-					data->fan_div[i] < 3) {
+	struct device *dev = &new_client->dev;
+	struct device *hwmon_dev;
+	struct adm9240_data *data;
 
 
-				adm9240_write_fan_div(client, i,
-						++data->fan_div[i]);
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
 
 
-				/* adjust fan_min if active, but not to 0 */
-				if (data->fan_min[i] < 255 &&
-						data->fan_min[i] >= 2)
-					data->fan_min[i] /= 2;
-			}
-		}
-		data->last_updated_measure = jiffies;
-	}
+	i2c_set_clientdata(new_client, data);
+	data->client = new_client;
+	mutex_init(&data->update_lock);
 
 
-	/* minimum config reading cycle: 300 seconds */
-	if (time_after(jiffies, data->last_updated_config + (HZ * 300))
-			|| !data->valid) {
+	adm9240_init_client(new_client);
 
 
-		for (i = 0; i < 6; i++) {
-			data->in_min[i] = i2c_smbus_read_byte_data(client,
-					ADM9240_REG_IN_MIN(i));
-			data->in_max[i] = i2c_smbus_read_byte_data(client,
-					ADM9240_REG_IN_MAX(i));
-		}
-		for (i = 0; i < 2; i++) {
-			data->fan_min[i] = i2c_smbus_read_byte_data(client,
-					ADM9240_REG_FAN_MIN(i));
-		}
-		data->temp_max[0] = i2c_smbus_read_byte_data(client,
-				ADM9240_REG_TEMP_MAX(0));
-		data->temp_max[1] = i2c_smbus_read_byte_data(client,
-				ADM9240_REG_TEMP_MAX(1));
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev,
+							   new_client->name,
+							   data,
+							   adm9240_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
 
 
-		/* read fan divs and 5-bit VID */
-		i = i2c_smbus_read_byte_data(client, ADM9240_REG_VID_FAN_DIV);
-		data->fan_div[0] = (i >> 4) & 3;
-		data->fan_div[1] = (i >> 6) & 3;
-		data->vid = i & 0x0f;
-		data->vid |= (i2c_smbus_read_byte_data(client,
-					ADM9240_REG_VID4) & 1) << 4;
-		/* read analog out */
-		data->aout = i2c_smbus_read_byte_data(client,
-				ADM9240_REG_ANALOG_OUT);
+static const struct i2c_device_id adm9240_id[] = {
+	{ "adm9240", adm9240 },
+	{ "ds1780", ds1780 },
+	{ "lm81", lm81 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, adm9240_id);
 
 
-		data->last_updated_config = jiffies;
-		data->valid = 1;
-	}
-	mutex_unlock(&data->update_lock);
-	return data;
-}
+static struct i2c_driver adm9240_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "adm9240",
+	},
+	.probe		= adm9240_probe,
+	.id_table	= adm9240_id,
+	.detect		= adm9240_detect,
+	.address_list	= normal_i2c,
+};
 
 
 module_i2c_driver(adm9240_driver);
 module_i2c_driver(adm9240_driver);
 
 

+ 1 - 1
drivers/hwmon/ads1015.c

@@ -198,7 +198,7 @@ static int ads1015_get_channels_config_of(struct i2c_client *client)
 		}
 		}
 
 
 		channel = be32_to_cpup(property);
 		channel = be32_to_cpup(property);
-		if (channel > ADS1015_CHANNELS) {
+		if (channel >= ADS1015_CHANNELS) {
 			dev_err(&client->dev,
 			dev_err(&client->dev,
 				"invalid channel index %d on %s\n",
 				"invalid channel index %d on %s\n",
 				channel, node->full_name);
 				channel, node->full_name);

+ 14 - 38
drivers/hwmon/ads7828.c

@@ -50,7 +50,7 @@ enum ads7828_chips { ads7828, ads7830 };
 
 
 /* Client specific data */
 /* Client specific data */
 struct ads7828_data {
 struct ads7828_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
 	struct mutex update_lock;	/* Mutex protecting updates */
 	struct mutex update_lock;	/* Mutex protecting updates */
 	unsigned long last_updated;	/* Last updated time (in jiffies) */
 	unsigned long last_updated;	/* Last updated time (in jiffies) */
 	u16 adc_input[ADS7828_NCH];	/* ADS7828_NCH samples */
 	u16 adc_input[ADS7828_NCH];	/* ADS7828_NCH samples */
@@ -72,8 +72,8 @@ static inline u8 ads7828_cmd_byte(u8 cmd, int ch)
 /* Update data for the device (all 8 channels) */
 /* Update data for the device (all 8 channels) */
 static struct ads7828_data *ads7828_update_device(struct device *dev)
 static struct ads7828_data *ads7828_update_device(struct device *dev)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct ads7828_data *data = i2c_get_clientdata(client);
+	struct ads7828_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 
 
 	mutex_lock(&data->update_lock);
 	mutex_lock(&data->update_lock);
 
 
@@ -116,7 +116,7 @@ static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, ads7828_show_in, NULL, 5);
 static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, ads7828_show_in, NULL, 6);
 static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, ads7828_show_in, NULL, 6);
 static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, ads7828_show_in, NULL, 7);
 static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, ads7828_show_in, NULL, 7);
 
 
-static struct attribute *ads7828_attributes[] = {
+static struct attribute *ads7828_attrs[] = {
 	&sensor_dev_attr_in0_input.dev_attr.attr,
 	&sensor_dev_attr_in0_input.dev_attr.attr,
 	&sensor_dev_attr_in1_input.dev_attr.attr,
 	&sensor_dev_attr_in1_input.dev_attr.attr,
 	&sensor_dev_attr_in2_input.dev_attr.attr,
 	&sensor_dev_attr_in2_input.dev_attr.attr,
@@ -128,29 +128,17 @@ static struct attribute *ads7828_attributes[] = {
 	NULL
 	NULL
 };
 };
 
 
-static const struct attribute_group ads7828_group = {
-	.attrs = ads7828_attributes,
-};
-
-static int ads7828_remove(struct i2c_client *client)
-{
-	struct ads7828_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &ads7828_group);
-
-	return 0;
-}
+ATTRIBUTE_GROUPS(ads7828);
 
 
 static int ads7828_probe(struct i2c_client *client,
 static int ads7828_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 			 const struct i2c_device_id *id)
 {
 {
-	struct ads7828_platform_data *pdata = dev_get_platdata(&client->dev);
+	struct device *dev = &client->dev;
+	struct ads7828_platform_data *pdata = dev_get_platdata(dev);
 	struct ads7828_data *data;
 	struct ads7828_data *data;
-	int err;
+	struct device *hwmon_dev;
 
 
-	data = devm_kzalloc(&client->dev, sizeof(struct ads7828_data),
-			    GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(struct ads7828_data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -182,24 +170,13 @@ static int ads7828_probe(struct i2c_client *client,
 	if (!data->diff_input)
 	if (!data->diff_input)
 		data->cmd_byte |= ADS7828_CMD_SD_SE;
 		data->cmd_byte |= ADS7828_CMD_SD_SE;
 
 
-	i2c_set_clientdata(client, data);
+	data->client = client;
 	mutex_init(&data->update_lock);
 	mutex_init(&data->update_lock);
 
 
-	err = sysfs_create_group(&client->dev.kobj, &ads7828_group);
-	if (err)
-		return err;
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto error;
-	}
-
-	return 0;
-
-error:
-	sysfs_remove_group(&client->dev.kobj, &ads7828_group);
-	return err;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data,
+							   ads7828_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
 static const struct i2c_device_id ads7828_device_ids[] = {
 static const struct i2c_device_id ads7828_device_ids[] = {
@@ -216,7 +193,6 @@ static struct i2c_driver ads7828_driver = {
 
 
 	.id_table = ads7828_device_ids,
 	.id_table = ads7828_device_ids,
 	.probe = ads7828_probe,
 	.probe = ads7828_probe,
-	.remove = ads7828_remove,
 };
 };
 
 
 module_i2c_driver(ads7828_driver);
 module_i2c_driver(ads7828_driver);

+ 20 - 39
drivers/hwmon/adt7411.c

@@ -51,7 +51,7 @@ struct adt7411_data {
 	struct mutex update_lock;
 	struct mutex update_lock;
 	unsigned long next_update;
 	unsigned long next_update;
 	int vref_cached;
 	int vref_cached;
-	struct device *hwmon_dev;
+	struct i2c_client *client;
 };
 };
 
 
 /*
 /*
@@ -111,7 +111,8 @@ static int adt7411_modify_bit(struct i2c_client *client, u8 reg, u8 bit,
 static ssize_t adt7411_show_vdd(struct device *dev,
 static ssize_t adt7411_show_vdd(struct device *dev,
 				struct device_attribute *attr, char *buf)
 				struct device_attribute *attr, char *buf)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
+	struct adt7411_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int ret = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB,
 	int ret = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB,
 			ADT7411_REG_VDD_MSB, 2);
 			ADT7411_REG_VDD_MSB, 2);
 
 
@@ -121,7 +122,8 @@ static ssize_t adt7411_show_vdd(struct device *dev,
 static ssize_t adt7411_show_temp(struct device *dev,
 static ssize_t adt7411_show_temp(struct device *dev,
 			struct device_attribute *attr, char *buf)
 			struct device_attribute *attr, char *buf)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
+	struct adt7411_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int val = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB,
 	int val = adt7411_read_10_bit(client, ADT7411_REG_INT_TEMP_VDD_LSB,
 			ADT7411_REG_INT_TEMP_MSB, 0);
 			ADT7411_REG_INT_TEMP_MSB, 0);
 
 
@@ -137,8 +139,8 @@ static ssize_t adt7411_show_input(struct device *dev,
 				  struct device_attribute *attr, char *buf)
 				  struct device_attribute *attr, char *buf)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7411_data *data = i2c_get_clientdata(client);
+	struct adt7411_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int val;
 	int val;
 	u8 lsb_reg, lsb_shift;
 	u8 lsb_reg, lsb_shift;
 
 
@@ -180,7 +182,8 @@ static ssize_t adt7411_show_bit(struct device *dev,
 				struct device_attribute *attr, char *buf)
 				struct device_attribute *attr, char *buf)
 {
 {
 	struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr);
 	struct sensor_device_attribute_2 *attr2 = to_sensor_dev_attr_2(attr);
-	struct i2c_client *client = to_i2c_client(dev);
+	struct adt7411_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int ret = i2c_smbus_read_byte_data(client, attr2->index);
 	int ret = i2c_smbus_read_byte_data(client, attr2->index);
 
 
 	return ret < 0 ? ret : sprintf(buf, "%u\n", !!(ret & attr2->nr));
 	return ret < 0 ? ret : sprintf(buf, "%u\n", !!(ret & attr2->nr));
@@ -191,8 +194,8 @@ static ssize_t adt7411_set_bit(struct device *dev,
 			       size_t count)
 			       size_t count)
 {
 {
 	struct sensor_device_attribute_2 *s_attr2 = to_sensor_dev_attr_2(attr);
 	struct sensor_device_attribute_2 *s_attr2 = to_sensor_dev_attr_2(attr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7411_data *data = i2c_get_clientdata(client);
+	struct adt7411_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int ret;
 	int ret;
 	unsigned long flag;
 	unsigned long flag;
 
 
@@ -245,9 +248,7 @@ static struct attribute *adt7411_attrs[] = {
 	NULL
 	NULL
 };
 };
 
 
-static const struct attribute_group adt7411_attr_grp = {
-	.attrs = adt7411_attrs,
-};
+ATTRIBUTE_GROUPS(adt7411);
 
 
 static int adt7411_detect(struct i2c_client *client,
 static int adt7411_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 			  struct i2c_board_info *info)
@@ -281,14 +282,17 @@ static int adt7411_detect(struct i2c_client *client,
 static int adt7411_probe(struct i2c_client *client,
 static int adt7411_probe(struct i2c_client *client,
 				   const struct i2c_device_id *id)
 				   const struct i2c_device_id *id)
 {
 {
+	struct device *dev = &client->dev;
 	struct adt7411_data *data;
 	struct adt7411_data *data;
+	struct device *hwmon_dev;
 	int ret;
 	int ret;
 
 
-	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	i2c_set_clientdata(client, data);
 	i2c_set_clientdata(client, data);
+	data->client = client;
 	mutex_init(&data->device_lock);
 	mutex_init(&data->device_lock);
 	mutex_init(&data->update_lock);
 	mutex_init(&data->update_lock);
 
 
@@ -300,32 +304,10 @@ static int adt7411_probe(struct i2c_client *client,
 	/* force update on first occasion */
 	/* force update on first occasion */
 	data->next_update = jiffies;
 	data->next_update = jiffies;
 
 
-	ret = sysfs_create_group(&client->dev.kobj, &adt7411_attr_grp);
-	if (ret)
-		return ret;
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		ret = PTR_ERR(data->hwmon_dev);
-		goto exit_remove;
-	}
-
-	dev_info(&client->dev, "successfully registered\n");
-
-	return 0;
-
- exit_remove:
-	sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
-	return ret;
-}
-
-static int adt7411_remove(struct i2c_client *client)
-{
-	struct adt7411_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
-	return 0;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data,
+							   adt7411_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
 static const struct i2c_device_id adt7411_id[] = {
 static const struct i2c_device_id adt7411_id[] = {
@@ -339,7 +321,6 @@ static struct i2c_driver adt7411_driver = {
 		.name		= "adt7411",
 		.name		= "adt7411",
 	},
 	},
 	.probe  = adt7411_probe,
 	.probe  = adt7411_probe,
-	.remove	= adt7411_remove,
 	.id_table = adt7411_id,
 	.id_table = adt7411_id,
 	.detect = adt7411_detect,
 	.detect = adt7411_detect,
 	.address_list = normal_i2c,
 	.address_list = normal_i2c,

+ 57 - 85
drivers/hwmon/adt7462.c

@@ -202,8 +202,7 @@ static const unsigned short normal_i2c[] = { 0x58, 0x5C, I2C_CLIENT_END };
 	(((value) & prefix##_MASK) >> prefix##_SHIFT)
 	(((value) & prefix##_MASK) >> prefix##_SHIFT)
 
 
 struct adt7462_data {
 struct adt7462_data {
-	struct device		*hwmon_dev;
-	struct attribute_group	attrs;
+	struct i2c_client	*client;
 	struct mutex		lock;
 	struct mutex		lock;
 	char			sensors_valid;
 	char			sensors_valid;
 	char			limits_valid;
 	char			limits_valid;
@@ -232,30 +231,6 @@ struct adt7462_data {
 	u8			alarms[ADT7462_ALARM_REG_COUNT];
 	u8			alarms[ADT7462_ALARM_REG_COUNT];
 };
 };
 
 
-static int adt7462_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id);
-static int adt7462_detect(struct i2c_client *client,
-			  struct i2c_board_info *info);
-static int adt7462_remove(struct i2c_client *client);
-
-static const struct i2c_device_id adt7462_id[] = {
-	{ "adt7462", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, adt7462_id);
-
-static struct i2c_driver adt7462_driver = {
-	.class		= I2C_CLASS_HWMON,
-	.driver = {
-		.name	= "adt7462",
-	},
-	.probe		= adt7462_probe,
-	.remove		= adt7462_remove,
-	.id_table	= adt7462_id,
-	.detect		= adt7462_detect,
-	.address_list	= normal_i2c,
-};
-
 /*
 /*
  * 16-bit registers on the ADT7462 are low-byte first.  The data sheet says
  * 16-bit registers on the ADT7462 are low-byte first.  The data sheet says
  * that the low byte must be read before the high byte.
  * that the low byte must be read before the high byte.
@@ -705,8 +680,8 @@ static int find_trange_value(int trange)
 
 
 static struct adt7462_data *adt7462_update_device(struct device *dev)
 static struct adt7462_data *adt7462_update_device(struct device *dev)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7462_data *data = i2c_get_clientdata(client);
+	struct adt7462_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long local_jiffies = jiffies;
 	unsigned long local_jiffies = jiffies;
 	int i;
 	int i;
 
 
@@ -828,8 +803,8 @@ static ssize_t set_temp_min(struct device *dev,
 			    size_t count)
 			    size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7462_data *data = i2c_get_clientdata(client);
+	struct adt7462_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index))
 	if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index))
@@ -866,8 +841,8 @@ static ssize_t set_temp_max(struct device *dev,
 			    size_t count)
 			    size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7462_data *data = i2c_get_clientdata(client);
+	struct adt7462_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index))
 	if (kstrtol(buf, 10, &temp) || !temp_enabled(data, attr->index))
@@ -929,8 +904,8 @@ static ssize_t set_volt_max(struct device *dev,
 			    size_t count)
 			    size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7462_data *data = i2c_get_clientdata(client);
+	struct adt7462_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int x = voltage_multiplier(data, attr->index);
 	int x = voltage_multiplier(data, attr->index);
 	long temp;
 	long temp;
 
 
@@ -971,8 +946,8 @@ static ssize_t set_volt_min(struct device *dev,
 			    size_t count)
 			    size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7462_data *data = i2c_get_clientdata(client);
+	struct adt7462_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int x = voltage_multiplier(data, attr->index);
 	int x = voltage_multiplier(data, attr->index);
 	long temp;
 	long temp;
 
 
@@ -1061,8 +1036,8 @@ static ssize_t set_fan_min(struct device *dev,
 			   const char *buf, size_t count)
 			   const char *buf, size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7462_data *data = i2c_get_clientdata(client);
+	struct adt7462_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp) || !temp ||
 	if (kstrtol(buf, 10, &temp) || !temp ||
@@ -1109,8 +1084,8 @@ static ssize_t set_force_pwm_max(struct device *dev,
 				 const char *buf,
 				 const char *buf,
 				 size_t count)
 				 size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7462_data *data = i2c_get_clientdata(client);
+	struct adt7462_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 	u8 reg;
 	u8 reg;
 
 
@@ -1142,8 +1117,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
 			const char *buf, size_t count)
 			const char *buf, size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7462_data *data = i2c_get_clientdata(client);
+	struct adt7462_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp))
 	if (kstrtol(buf, 10, &temp))
@@ -1172,8 +1147,8 @@ static ssize_t set_pwm_max(struct device *dev,
 			   const char *buf,
 			   const char *buf,
 			   size_t count)
 			   size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7462_data *data = i2c_get_clientdata(client);
+	struct adt7462_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp))
 	if (kstrtol(buf, 10, &temp))
@@ -1204,8 +1179,8 @@ static ssize_t set_pwm_min(struct device *dev,
 			   size_t count)
 			   size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7462_data *data = i2c_get_clientdata(client);
+	struct adt7462_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp))
 	if (kstrtol(buf, 10, &temp))
@@ -1238,8 +1213,8 @@ static ssize_t set_pwm_hyst(struct device *dev,
 			    size_t count)
 			    size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7462_data *data = i2c_get_clientdata(client);
+	struct adt7462_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp))
 	if (kstrtol(buf, 10, &temp))
@@ -1283,8 +1258,8 @@ static ssize_t set_pwm_tmax(struct device *dev,
 {
 {
 	int temp;
 	int temp;
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7462_data *data = i2c_get_clientdata(client);
+	struct adt7462_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int tmin, trange_value;
 	int tmin, trange_value;
 	long trange;
 	long trange;
 
 
@@ -1324,8 +1299,8 @@ static ssize_t set_pwm_tmin(struct device *dev,
 			    size_t count)
 			    size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7462_data *data = i2c_get_clientdata(client);
+	struct adt7462_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp))
 	if (kstrtol(buf, 10, &temp))
@@ -1381,8 +1356,8 @@ static ssize_t set_pwm_auto(struct device *dev,
 			    size_t count)
 			    size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7462_data *data = i2c_get_clientdata(client);
+	struct adt7462_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp))
 	if (kstrtol(buf, 10, &temp))
@@ -1440,8 +1415,8 @@ static ssize_t set_pwm_auto_temp(struct device *dev,
 				 size_t count)
 				 size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7462_data *data = i2c_get_clientdata(client);
+	struct adt7462_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp))
 	if (kstrtol(buf, 10, &temp))
@@ -1725,7 +1700,7 @@ static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO,
 static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO,
 static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO,
 		    show_pwm_auto_temp, set_pwm_auto_temp, 3);
 		    show_pwm_auto_temp, set_pwm_auto_temp, 3);
 
 
-static struct attribute *adt7462_attr[] = {
+static struct attribute *adt7462_attrs[] = {
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
 	&sensor_dev_attr_temp2_max.dev_attr.attr,
 	&sensor_dev_attr_temp2_max.dev_attr.attr,
 	&sensor_dev_attr_temp3_max.dev_attr.attr,
 	&sensor_dev_attr_temp3_max.dev_attr.attr,
@@ -1896,6 +1871,8 @@ static struct attribute *adt7462_attr[] = {
 	NULL
 	NULL
 };
 };
 
 
+ATTRIBUTE_GROUPS(adt7462);
+
 /* Return 0 if detection is successful, -ENODEV otherwise */
 /* Return 0 if detection is successful, -ENODEV otherwise */
 static int adt7462_detect(struct i2c_client *client,
 static int adt7462_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 			  struct i2c_board_info *info)
@@ -1926,46 +1903,41 @@ static int adt7462_detect(struct i2c_client *client,
 static int adt7462_probe(struct i2c_client *client,
 static int adt7462_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 			 const struct i2c_device_id *id)
 {
 {
+	struct device *dev = &client->dev;
 	struct adt7462_data *data;
 	struct adt7462_data *data;
-	int err;
+	struct device *hwmon_dev;
 
 
-	data = devm_kzalloc(&client->dev, sizeof(struct adt7462_data),
-			    GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(struct adt7462_data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	i2c_set_clientdata(client, data);
+	data->client = client;
 	mutex_init(&data->lock);
 	mutex_init(&data->lock);
 
 
 	dev_info(&client->dev, "%s chip found\n", client->name);
 	dev_info(&client->dev, "%s chip found\n", client->name);
 
 
-	/* Register sysfs hooks */
-	data->attrs.attrs = adt7462_attr;
-	err = sysfs_create_group(&client->dev.kobj, &data->attrs);
-	if (err)
-		return err;
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove;
-	}
-
-	return 0;
-
-exit_remove:
-	sysfs_remove_group(&client->dev.kobj, &data->attrs);
-	return err;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data,
+							   adt7462_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
-static int adt7462_remove(struct i2c_client *client)
-{
-	struct adt7462_data *data = i2c_get_clientdata(client);
+static const struct i2c_device_id adt7462_id[] = {
+	{ "adt7462", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, adt7462_id);
 
 
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &data->attrs);
-	return 0;
-}
+static struct i2c_driver adt7462_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "adt7462",
+	},
+	.probe		= adt7462_probe,
+	.id_table	= adt7462_id,
+	.detect		= adt7462_detect,
+	.address_list	= normal_i2c,
+};
 
 
 module_i2c_driver(adt7462_driver);
 module_i2c_driver(adt7462_driver);
 
 

+ 72 - 91
drivers/hwmon/adt7470.c

@@ -143,8 +143,7 @@ static const unsigned short normal_i2c[] = { 0x2C, 0x2E, 0x2F, I2C_CLIENT_END };
 #define FAN_DATA_VALID(x)	((x) && (x) != FAN_PERIOD_INVALID)
 #define FAN_DATA_VALID(x)	((x) && (x) != FAN_PERIOD_INVALID)
 
 
 struct adt7470_data {
 struct adt7470_data {
-	struct device		*hwmon_dev;
-	struct attribute_group	attrs;
+	struct i2c_client	*client;
 	struct mutex		lock;
 	struct mutex		lock;
 	char			sensors_valid;
 	char			sensors_valid;
 	char			limits_valid;
 	char			limits_valid;
@@ -175,30 +174,6 @@ struct adt7470_data {
 	unsigned int		auto_update_interval;
 	unsigned int		auto_update_interval;
 };
 };
 
 
-static int adt7470_probe(struct i2c_client *client,
-			 const struct i2c_device_id *id);
-static int adt7470_detect(struct i2c_client *client,
-			  struct i2c_board_info *info);
-static int adt7470_remove(struct i2c_client *client);
-
-static const struct i2c_device_id adt7470_id[] = {
-	{ "adt7470", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, adt7470_id);
-
-static struct i2c_driver adt7470_driver = {
-	.class		= I2C_CLASS_HWMON,
-	.driver = {
-		.name	= "adt7470",
-	},
-	.probe		= adt7470_probe,
-	.remove		= adt7470_remove,
-	.id_table	= adt7470_id,
-	.detect		= adt7470_detect,
-	.address_list	= normal_i2c,
-};
-
 /*
 /*
  * 16-bit registers on the ADT7470 are low-byte first.  The data sheet says
  * 16-bit registers on the ADT7470 are low-byte first.  The data sheet says
  * that the low byte must be read before the high byte.
  * that the low byte must be read before the high byte.
@@ -218,18 +193,6 @@ static inline int adt7470_write_word_data(struct i2c_client *client, u8 reg,
 	       || i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
 	       || i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
 }
 }
 
 
-static void adt7470_init_client(struct i2c_client *client)
-{
-	int reg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG);
-
-	if (reg < 0) {
-		dev_err(&client->dev, "cannot read configuration register\n");
-	} else {
-		/* start monitoring (and do a self-test) */
-		i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, reg | 3);
-	}
-}
-
 /* Probe for temperature sensors.  Assumes lock is held */
 /* Probe for temperature sensors.  Assumes lock is held */
 static int adt7470_read_temperatures(struct i2c_client *client,
 static int adt7470_read_temperatures(struct i2c_client *client,
 				     struct adt7470_data *data)
 				     struct adt7470_data *data)
@@ -314,8 +277,8 @@ static int adt7470_update_thread(void *p)
 
 
 static struct adt7470_data *adt7470_update_device(struct device *dev)
 static struct adt7470_data *adt7470_update_device(struct device *dev)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7470_data *data = i2c_get_clientdata(client);
+	struct adt7470_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long local_jiffies = jiffies;
 	unsigned long local_jiffies = jiffies;
 	u8 cfg;
 	u8 cfg;
 	int i;
 	int i;
@@ -445,8 +408,7 @@ static ssize_t set_auto_update_interval(struct device *dev,
 					const char *buf,
 					const char *buf,
 					size_t count)
 					size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7470_data *data = i2c_get_clientdata(client);
+	struct adt7470_data *data = dev_get_drvdata(dev);
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp))
 	if (kstrtol(buf, 10, &temp))
@@ -474,8 +436,7 @@ static ssize_t set_num_temp_sensors(struct device *dev,
 				    const char *buf,
 				    const char *buf,
 				    size_t count)
 				    size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7470_data *data = i2c_get_clientdata(client);
+	struct adt7470_data *data = dev_get_drvdata(dev);
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp))
 	if (kstrtol(buf, 10, &temp))
@@ -507,8 +468,8 @@ static ssize_t set_temp_min(struct device *dev,
 			    size_t count)
 			    size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7470_data *data = i2c_get_clientdata(client);
+	struct adt7470_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp))
 	if (kstrtol(buf, 10, &temp))
@@ -541,8 +502,8 @@ static ssize_t set_temp_max(struct device *dev,
 			    size_t count)
 			    size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7470_data *data = i2c_get_clientdata(client);
+	struct adt7470_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp))
 	if (kstrtol(buf, 10, &temp))
@@ -596,8 +557,8 @@ static ssize_t set_fan_max(struct device *dev,
 			   const char *buf, size_t count)
 			   const char *buf, size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7470_data *data = i2c_get_clientdata(client);
+	struct adt7470_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp) || !temp)
 	if (kstrtol(buf, 10, &temp) || !temp)
@@ -633,8 +594,8 @@ static ssize_t set_fan_min(struct device *dev,
 			   const char *buf, size_t count)
 			   const char *buf, size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7470_data *data = i2c_get_clientdata(client);
+	struct adt7470_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp) || !temp)
 	if (kstrtol(buf, 10, &temp) || !temp)
@@ -677,8 +638,8 @@ static ssize_t set_force_pwm_max(struct device *dev,
 				 const char *buf,
 				 const char *buf,
 				 size_t count)
 				 size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7470_data *data = i2c_get_clientdata(client);
+	struct adt7470_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 	u8 reg;
 	u8 reg;
 
 
@@ -710,8 +671,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *devattr,
 			const char *buf, size_t count)
 			const char *buf, size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7470_data *data = i2c_get_clientdata(client);
+	struct adt7470_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp))
 	if (kstrtol(buf, 10, &temp))
@@ -742,8 +703,8 @@ static ssize_t set_pwm_max(struct device *dev,
 			   size_t count)
 			   size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7470_data *data = i2c_get_clientdata(client);
+	struct adt7470_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp))
 	if (kstrtol(buf, 10, &temp))
@@ -775,8 +736,8 @@ static ssize_t set_pwm_min(struct device *dev,
 			   size_t count)
 			   size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7470_data *data = i2c_get_clientdata(client);
+	struct adt7470_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp))
 	if (kstrtol(buf, 10, &temp))
@@ -818,8 +779,8 @@ static ssize_t set_pwm_tmin(struct device *dev,
 			    size_t count)
 			    size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7470_data *data = i2c_get_clientdata(client);
+	struct adt7470_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long temp;
 	long temp;
 
 
 	if (kstrtol(buf, 10, &temp))
 	if (kstrtol(buf, 10, &temp))
@@ -852,8 +813,8 @@ static ssize_t set_pwm_auto(struct device *dev,
 			    size_t count)
 			    size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7470_data *data = i2c_get_clientdata(client);
+	struct adt7470_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int pwm_auto_reg = ADT7470_REG_PWM_CFG(attr->index);
 	int pwm_auto_reg = ADT7470_REG_PWM_CFG(attr->index);
 	int pwm_auto_reg_mask;
 	int pwm_auto_reg_mask;
 	long temp;
 	long temp;
@@ -913,8 +874,8 @@ static ssize_t set_pwm_auto_temp(struct device *dev,
 				 size_t count)
 				 size_t count)
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct adt7470_data *data = i2c_get_clientdata(client);
+	struct adt7470_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int pwm_auto_reg = ADT7470_REG_PWM_AUTO_TEMP(attr->index);
 	int pwm_auto_reg = ADT7470_REG_PWM_AUTO_TEMP(attr->index);
 	long temp;
 	long temp;
 	u8 reg;
 	u8 reg;
@@ -1131,7 +1092,7 @@ static SENSOR_DEVICE_ATTR(pwm3_auto_channels_temp, S_IWUSR | S_IRUGO,
 static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO,
 static SENSOR_DEVICE_ATTR(pwm4_auto_channels_temp, S_IWUSR | S_IRUGO,
 		    show_pwm_auto_temp, set_pwm_auto_temp, 3);
 		    show_pwm_auto_temp, set_pwm_auto_temp, 3);
 
 
-static struct attribute *adt7470_attr[] = {
+static struct attribute *adt7470_attrs[] = {
 	&dev_attr_alarm_mask.attr,
 	&dev_attr_alarm_mask.attr,
 	&dev_attr_num_temp_sensors.attr,
 	&dev_attr_num_temp_sensors.attr,
 	&dev_attr_auto_update_interval.attr,
 	&dev_attr_auto_update_interval.attr,
@@ -1223,6 +1184,8 @@ static struct attribute *adt7470_attr[] = {
 	NULL
 	NULL
 };
 };
 
 
+ATTRIBUTE_GROUPS(adt7470);
+
 /* Return 0 if detection is successful, -ENODEV otherwise */
 /* Return 0 if detection is successful, -ENODEV otherwise */
 static int adt7470_detect(struct i2c_client *client,
 static int adt7470_detect(struct i2c_client *client,
 			  struct i2c_board_info *info)
 			  struct i2c_board_info *info)
@@ -1250,14 +1213,26 @@ static int adt7470_detect(struct i2c_client *client,
 	return 0;
 	return 0;
 }
 }
 
 
+static void adt7470_init_client(struct i2c_client *client)
+{
+	int reg = i2c_smbus_read_byte_data(client, ADT7470_REG_CFG);
+
+	if (reg < 0) {
+		dev_err(&client->dev, "cannot read configuration register\n");
+	} else {
+		/* start monitoring (and do a self-test) */
+		i2c_smbus_write_byte_data(client, ADT7470_REG_CFG, reg | 3);
+	}
+}
+
 static int adt7470_probe(struct i2c_client *client,
 static int adt7470_probe(struct i2c_client *client,
 			 const struct i2c_device_id *id)
 			 const struct i2c_device_id *id)
 {
 {
+	struct device *dev = &client->dev;
 	struct adt7470_data *data;
 	struct adt7470_data *data;
-	int err;
+	struct device *hwmon_dev;
 
 
-	data = devm_kzalloc(&client->dev, sizeof(struct adt7470_data),
-			    GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(struct adt7470_data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -1265,6 +1240,7 @@ static int adt7470_probe(struct i2c_client *client,
 	data->auto_update_interval = AUTO_UPDATE_INTERVAL;
 	data->auto_update_interval = AUTO_UPDATE_INTERVAL;
 
 
 	i2c_set_clientdata(client, data);
 	i2c_set_clientdata(client, data);
+	data->client = client;
 	mutex_init(&data->lock);
 	mutex_init(&data->lock);
 
 
 	dev_info(&client->dev, "%s chip found\n", client->name);
 	dev_info(&client->dev, "%s chip found\n", client->name);
@@ -1273,32 +1249,21 @@ static int adt7470_probe(struct i2c_client *client,
 	adt7470_init_client(client);
 	adt7470_init_client(client);
 
 
 	/* Register sysfs hooks */
 	/* Register sysfs hooks */
-	data->attrs.attrs = adt7470_attr;
-	err = sysfs_create_group(&client->dev.kobj, &data->attrs);
-	if (err)
-		return err;
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove;
-	}
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data,
+							   adt7470_groups);
+
+	if (IS_ERR(hwmon_dev))
+		return PTR_ERR(hwmon_dev);
 
 
 	init_completion(&data->auto_update_stop);
 	init_completion(&data->auto_update_stop);
 	data->auto_update = kthread_run(adt7470_update_thread, client, "%s",
 	data->auto_update = kthread_run(adt7470_update_thread, client, "%s",
-					dev_name(data->hwmon_dev));
+					dev_name(hwmon_dev));
 	if (IS_ERR(data->auto_update)) {
 	if (IS_ERR(data->auto_update)) {
-		err = PTR_ERR(data->auto_update);
-		goto exit_unregister;
+		return PTR_ERR(data->auto_update);
 	}
 	}
 
 
 	return 0;
 	return 0;
-
-exit_unregister:
-	hwmon_device_unregister(data->hwmon_dev);
-exit_remove:
-	sysfs_remove_group(&client->dev.kobj, &data->attrs);
-	return err;
 }
 }
 
 
 static int adt7470_remove(struct i2c_client *client)
 static int adt7470_remove(struct i2c_client *client)
@@ -1307,11 +1272,27 @@ static int adt7470_remove(struct i2c_client *client)
 
 
 	kthread_stop(data->auto_update);
 	kthread_stop(data->auto_update);
 	wait_for_completion(&data->auto_update_stop);
 	wait_for_completion(&data->auto_update_stop);
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &data->attrs);
 	return 0;
 	return 0;
 }
 }
 
 
+static const struct i2c_device_id adt7470_id[] = {
+	{ "adt7470", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, adt7470_id);
+
+static struct i2c_driver adt7470_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "adt7470",
+	},
+	.probe		= adt7470_probe,
+	.remove		= adt7470_remove,
+	.id_table	= adt7470_id,
+	.detect		= adt7470_detect,
+	.address_list	= normal_i2c,
+};
+
 module_i2c_driver(adt7470_driver);
 module_i2c_driver(adt7470_driver);
 
 
 MODULE_AUTHOR("Darrick J. Wong <darrick.wong@oracle.com>");
 MODULE_AUTHOR("Darrick J. Wong <darrick.wong@oracle.com>");

+ 165 - 232
drivers/hwmon/amc6821.c

@@ -21,7 +21,6 @@
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
  */
 
 
-
 #include <linux/kernel.h>	/* Needed for KERN_INFO */
 #include <linux/kernel.h>	/* Needed for KERN_INFO */
 #include <linux/module.h>
 #include <linux/module.h>
 #include <linux/init.h>
 #include <linux/init.h>
@@ -33,7 +32,6 @@
 #include <linux/err.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 
 
-
 /*
 /*
  * Addresses to scan.
  * Addresses to scan.
  */
  */
@@ -41,8 +39,6 @@
 static const unsigned short normal_i2c[] = {0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e,
 static const unsigned short normal_i2c[] = {0x18, 0x19, 0x1a, 0x2c, 0x2d, 0x2e,
 	0x4c, 0x4d, 0x4e, I2C_CLIENT_END};
 	0x4c, 0x4d, 0x4e, I2C_CLIENT_END};
 
 
-
-
 /*
 /*
  * Insmod parameters
  * Insmod parameters
  */
  */
@@ -53,7 +49,6 @@ module_param(pwminv, int, S_IRUGO);
 static int init = 1; /*Power-on initialization.*/
 static int init = 1; /*Power-on initialization.*/
 module_param(init, int, S_IRUGO);
 module_param(init, int, S_IRUGO);
 
 
-
 enum chips { amc6821 };
 enum chips { amc6821 };
 
 
 #define AMC6821_REG_DEV_ID 0x3D
 #define AMC6821_REG_DEV_ID 0x3D
@@ -152,46 +147,12 @@ static const u8 fan_reg_hi[] = {AMC6821_REG_TDATA_HI,
 			AMC6821_REG_TACH_LLIMITH,
 			AMC6821_REG_TACH_LLIMITH,
 			AMC6821_REG_TACH_HLIMITH, };
 			AMC6821_REG_TACH_HLIMITH, };
 
 
-static int amc6821_probe(
-		struct i2c_client *client,
-		const struct i2c_device_id *id);
-static int amc6821_detect(
-		struct i2c_client *client,
-		struct i2c_board_info *info);
-static int amc6821_init_client(struct i2c_client *client);
-static int amc6821_remove(struct i2c_client *client);
-static struct amc6821_data *amc6821_update_device(struct device *dev);
-
-/*
- * Driver data (common to all clients)
- */
-
-static const struct i2c_device_id amc6821_id[] = {
-	{ "amc6821", amc6821 },
-	{ }
-};
-
-MODULE_DEVICE_TABLE(i2c, amc6821_id);
-
-static struct i2c_driver amc6821_driver = {
-	.class = I2C_CLASS_HWMON,
-	.driver = {
-		.name	= "amc6821",
-	},
-	.probe = amc6821_probe,
-	.remove = amc6821_remove,
-	.id_table = amc6821_id,
-	.detect = amc6821_detect,
-	.address_list = normal_i2c,
-};
-
-
 /*
 /*
  * Client data (each client gets its own)
  * Client data (each client gets its own)
  */
  */
 
 
 struct amc6821_data {
 struct amc6821_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
 	struct mutex update_lock;
 	struct mutex update_lock;
 	char valid; /* zero until following fields are valid */
 	char valid; /* zero until following fields are valid */
 	unsigned long last_updated; /* in jiffies */
 	unsigned long last_updated; /* in jiffies */
@@ -213,6 +174,108 @@ struct amc6821_data {
 	u8 stat2;
 	u8 stat2;
 };
 };
 
 
+static struct amc6821_data *amc6821_update_device(struct device *dev)
+{
+	struct amc6821_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
+	int timeout = HZ;
+	u8 reg;
+	int i;
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + timeout) ||
+			!data->valid) {
+
+		for (i = 0; i < TEMP_IDX_LEN; i++)
+			data->temp[i] = i2c_smbus_read_byte_data(client,
+				temp_reg[i]);
+
+		data->stat1 = i2c_smbus_read_byte_data(client,
+			AMC6821_REG_STAT1);
+		data->stat2 = i2c_smbus_read_byte_data(client,
+			AMC6821_REG_STAT2);
+
+		data->pwm1 = i2c_smbus_read_byte_data(client,
+			AMC6821_REG_DCY);
+		for (i = 0; i < FAN1_IDX_LEN; i++) {
+			data->fan[i] = i2c_smbus_read_byte_data(
+					client,
+					fan_reg_low[i]);
+			data->fan[i] += i2c_smbus_read_byte_data(
+					client,
+					fan_reg_hi[i]) << 8;
+		}
+		data->fan1_div = i2c_smbus_read_byte_data(client,
+			AMC6821_REG_CONF4);
+		data->fan1_div = data->fan1_div & AMC6821_CONF4_PSPR ? 4 : 2;
+
+		data->pwm1_auto_point_pwm[0] = 0;
+		data->pwm1_auto_point_pwm[2] = 255;
+		data->pwm1_auto_point_pwm[1] = i2c_smbus_read_byte_data(client,
+			AMC6821_REG_DCY_LOW_TEMP);
+
+		data->temp1_auto_point_temp[0] =
+			i2c_smbus_read_byte_data(client,
+					AMC6821_REG_PSV_TEMP);
+		data->temp2_auto_point_temp[0] =
+				data->temp1_auto_point_temp[0];
+		reg = i2c_smbus_read_byte_data(client,
+			AMC6821_REG_LTEMP_FAN_CTRL);
+		data->temp1_auto_point_temp[1] = (reg & 0xF8) >> 1;
+		reg &= 0x07;
+		reg = 0x20 >> reg;
+		if (reg > 0)
+			data->temp1_auto_point_temp[2] =
+				data->temp1_auto_point_temp[1] +
+				(data->pwm1_auto_point_pwm[2] -
+				data->pwm1_auto_point_pwm[1]) / reg;
+		else
+			data->temp1_auto_point_temp[2] = 255;
+
+		reg = i2c_smbus_read_byte_data(client,
+			AMC6821_REG_RTEMP_FAN_CTRL);
+		data->temp2_auto_point_temp[1] = (reg & 0xF8) >> 1;
+		reg &= 0x07;
+		reg = 0x20 >> reg;
+		if (reg > 0)
+			data->temp2_auto_point_temp[2] =
+				data->temp2_auto_point_temp[1] +
+				(data->pwm1_auto_point_pwm[2] -
+				data->pwm1_auto_point_pwm[1]) / reg;
+		else
+			data->temp2_auto_point_temp[2] = 255;
+
+		reg = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
+		reg = (reg >> 5) & 0x3;
+		switch (reg) {
+		case 0: /*open loop: software sets pwm1*/
+			data->pwm1_auto_channels_temp = 0;
+			data->pwm1_enable = 1;
+			break;
+		case 2: /*closed loop: remote T (temp2)*/
+			data->pwm1_auto_channels_temp = 2;
+			data->pwm1_enable = 2;
+			break;
+		case 3: /*closed loop: local and remote T (temp2)*/
+			data->pwm1_auto_channels_temp = 3;
+			data->pwm1_enable = 3;
+			break;
+		case 1: /*
+			 * semi-open loop: software sets rpm, chip controls
+			 * pwm1, currently not implemented
+			 */
+			data->pwm1_auto_channels_temp = 0;
+			data->pwm1_enable = 0;
+			break;
+		}
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+	mutex_unlock(&data->update_lock);
+	return data;
+}
 
 
 static ssize_t get_temp(
 static ssize_t get_temp(
 		struct device *dev,
 		struct device *dev,
@@ -225,16 +288,14 @@ static ssize_t get_temp(
 	return sprintf(buf, "%d\n", data->temp[ix] * 1000);
 	return sprintf(buf, "%d\n", data->temp[ix] * 1000);
 }
 }
 
 
-
-
 static ssize_t set_temp(
 static ssize_t set_temp(
 		struct device *dev,
 		struct device *dev,
 		struct device_attribute *attr,
 		struct device_attribute *attr,
 		const char *buf,
 		const char *buf,
 		size_t count)
 		size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct amc6821_data *data = i2c_get_clientdata(client);
+	struct amc6821_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int ix = to_sensor_dev_attr(attr)->index;
 	int ix = to_sensor_dev_attr(attr)->index;
 	long val;
 	long val;
 
 
@@ -253,9 +314,6 @@ static ssize_t set_temp(
 	return count;
 	return count;
 }
 }
 
 
-
-
-
 static ssize_t get_temp_alarm(
 static ssize_t get_temp_alarm(
 	struct device *dev,
 	struct device *dev,
 	struct device_attribute *devattr,
 	struct device_attribute *devattr,
@@ -294,9 +352,6 @@ static ssize_t get_temp_alarm(
 		return sprintf(buf, "0");
 		return sprintf(buf, "0");
 }
 }
 
 
-
-
-
 static ssize_t get_temp2_fault(
 static ssize_t get_temp2_fault(
 		struct device *dev,
 		struct device *dev,
 		struct device_attribute *devattr,
 		struct device_attribute *devattr,
@@ -324,8 +379,8 @@ static ssize_t set_pwm1(
 		const char *buf,
 		const char *buf,
 		size_t count)
 		size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct amc6821_data *data = i2c_get_clientdata(client);
+	struct amc6821_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int ret = kstrtol(buf, 10, &val);
 	int ret = kstrtol(buf, 10, &val);
 	if (ret)
 	if (ret)
@@ -353,18 +408,20 @@ static ssize_t set_pwm1_enable(
 		const char *buf,
 		const char *buf,
 		size_t count)
 		size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct amc6821_data *data = i2c_get_clientdata(client);
+	struct amc6821_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int config = kstrtol(buf, 10, &val);
 	int config = kstrtol(buf, 10, &val);
 	if (config)
 	if (config)
 		return config;
 		return config;
 
 
+	mutex_lock(&data->update_lock);
 	config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
 	config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
 	if (config < 0) {
 	if (config < 0) {
 			dev_err(&client->dev,
 			dev_err(&client->dev,
 			"Error reading configuration register, aborting.\n");
 			"Error reading configuration register, aborting.\n");
-			return config;
+			count = config;
+			goto unlock;
 	}
 	}
 
 
 	switch (val) {
 	switch (val) {
@@ -381,19 +438,19 @@ static ssize_t set_pwm1_enable(
 		config |= AMC6821_CONF1_FDRC1;
 		config |= AMC6821_CONF1_FDRC1;
 		break;
 		break;
 	default:
 	default:
-		return -EINVAL;
+		count = -EINVAL;
+		goto unlock;
 	}
 	}
-	mutex_lock(&data->update_lock);
 	if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF1, config)) {
 	if (i2c_smbus_write_byte_data(client, AMC6821_REG_CONF1, config)) {
 			dev_err(&client->dev,
 			dev_err(&client->dev,
 			"Configuration register write error, aborting.\n");
 			"Configuration register write error, aborting.\n");
 			count = -EIO;
 			count = -EIO;
 	}
 	}
+unlock:
 	mutex_unlock(&data->update_lock);
 	mutex_unlock(&data->update_lock);
 	return count;
 	return count;
 }
 }
 
 
-
 static ssize_t get_pwm1_auto_channels_temp(
 static ssize_t get_pwm1_auto_channels_temp(
 		struct device *dev,
 		struct device *dev,
 		struct device_attribute *devattr,
 		struct device_attribute *devattr,
@@ -403,7 +460,6 @@ static ssize_t get_pwm1_auto_channels_temp(
 	return sprintf(buf, "%d\n", data->pwm1_auto_channels_temp);
 	return sprintf(buf, "%d\n", data->pwm1_auto_channels_temp);
 }
 }
 
 
-
 static ssize_t get_temp_auto_point_temp(
 static ssize_t get_temp_auto_point_temp(
 		struct device *dev,
 		struct device *dev,
 		struct device_attribute *devattr,
 		struct device_attribute *devattr,
@@ -425,7 +481,6 @@ static ssize_t get_temp_auto_point_temp(
 	}
 	}
 }
 }
 
 
-
 static ssize_t get_pwm1_auto_point_pwm(
 static ssize_t get_pwm1_auto_point_pwm(
 		struct device *dev,
 		struct device *dev,
 		struct device_attribute *devattr,
 		struct device_attribute *devattr,
@@ -436,7 +491,6 @@ static ssize_t get_pwm1_auto_point_pwm(
 	return sprintf(buf, "%d\n", data->pwm1_auto_point_pwm[ix]);
 	return sprintf(buf, "%d\n", data->pwm1_auto_point_pwm[ix]);
 }
 }
 
 
-
 static inline ssize_t set_slope_register(struct i2c_client *client,
 static inline ssize_t set_slope_register(struct i2c_client *client,
 		u8 reg,
 		u8 reg,
 		u8 dpwm,
 		u8 dpwm,
@@ -459,16 +513,14 @@ static inline ssize_t set_slope_register(struct i2c_client *client,
 	return 0;
 	return 0;
 }
 }
 
 
-
-
 static ssize_t set_temp_auto_point_temp(
 static ssize_t set_temp_auto_point_temp(
 		struct device *dev,
 		struct device *dev,
 		struct device_attribute *attr,
 		struct device_attribute *attr,
 		const char *buf,
 		const char *buf,
 		size_t count)
 		size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct amc6821_data *data = amc6821_update_device(dev);
 	struct amc6821_data *data = amc6821_update_device(dev);
+	struct i2c_client *client = data->client;
 	int ix = to_sensor_dev_attr_2(attr)->index;
 	int ix = to_sensor_dev_attr_2(attr)->index;
 	int nr = to_sensor_dev_attr_2(attr)->nr;
 	int nr = to_sensor_dev_attr_2(attr)->nr;
 	u8 *ptemp;
 	u8 *ptemp;
@@ -493,8 +545,9 @@ static ssize_t set_temp_auto_point_temp(
 		return -EINVAL;
 		return -EINVAL;
 	}
 	}
 
 
-	data->valid = 0;
 	mutex_lock(&data->update_lock);
 	mutex_lock(&data->update_lock);
+	data->valid = 0;
+
 	switch (ix) {
 	switch (ix) {
 	case 0:
 	case 0:
 		ptemp[0] = clamp_val(val / 1000, 0,
 		ptemp[0] = clamp_val(val / 1000, 0,
@@ -533,16 +586,14 @@ EXIT:
 	return count;
 	return count;
 }
 }
 
 
-
-
 static ssize_t set_pwm1_auto_point_pwm(
 static ssize_t set_pwm1_auto_point_pwm(
 		struct device *dev,
 		struct device *dev,
 		struct device_attribute *attr,
 		struct device_attribute *attr,
 		const char *buf,
 		const char *buf,
 		size_t count)
 		size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct amc6821_data *data = i2c_get_clientdata(client);
+	struct amc6821_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int dpwm;
 	int dpwm;
 	long val;
 	long val;
 	int ret = kstrtol(buf, 10, &val);
 	int ret = kstrtol(buf, 10, &val);
@@ -587,8 +638,6 @@ static ssize_t get_fan(
 	return sprintf(buf, "%d\n", (int)(6000000 / data->fan[ix]));
 	return sprintf(buf, "%d\n", (int)(6000000 / data->fan[ix]));
 }
 }
 
 
-
-
 static ssize_t get_fan1_fault(
 static ssize_t get_fan1_fault(
 		struct device *dev,
 		struct device *dev,
 		struct device_attribute *devattr,
 		struct device_attribute *devattr,
@@ -601,15 +650,13 @@ static ssize_t get_fan1_fault(
 		return sprintf(buf, "0");
 		return sprintf(buf, "0");
 }
 }
 
 
-
-
 static ssize_t set_fan(
 static ssize_t set_fan(
 		struct device *dev,
 		struct device *dev,
 		struct device_attribute *attr,
 		struct device_attribute *attr,
 		const char *buf, size_t count)
 		const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct amc6821_data *data = i2c_get_clientdata(client);
+	struct amc6821_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int ix = to_sensor_dev_attr(attr)->index;
 	int ix = to_sensor_dev_attr(attr)->index;
 	int ret = kstrtol(buf, 10, &val);
 	int ret = kstrtol(buf, 10, &val);
@@ -635,8 +682,6 @@ EXIT:
 	return count;
 	return count;
 }
 }
 
 
-
-
 static ssize_t get_fan1_div(
 static ssize_t get_fan1_div(
 		struct device *dev,
 		struct device *dev,
 		struct device_attribute *devattr,
 		struct device_attribute *devattr,
@@ -651,20 +696,21 @@ static ssize_t set_fan1_div(
 		struct device_attribute *attr,
 		struct device_attribute *attr,
 		const char *buf, size_t count)
 		const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct amc6821_data *data = i2c_get_clientdata(client);
+	struct amc6821_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int config = kstrtol(buf, 10, &val);
 	int config = kstrtol(buf, 10, &val);
 	if (config)
 	if (config)
 		return config;
 		return config;
 
 
+	mutex_lock(&data->update_lock);
 	config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF4);
 	config = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF4);
 	if (config < 0) {
 	if (config < 0) {
 		dev_err(&client->dev,
 		dev_err(&client->dev,
 			"Error reading configuration register, aborting.\n");
 			"Error reading configuration register, aborting.\n");
-		return config;
+		count = config;
+		goto EXIT;
 	}
 	}
-	mutex_lock(&data->update_lock);
 	switch (val) {
 	switch (val) {
 	case 2:
 	case 2:
 		config &= ~AMC6821_CONF4_PSPR;
 		config &= ~AMC6821_CONF4_PSPR;
@@ -688,8 +734,6 @@ EXIT:
 	return count;
 	return count;
 }
 }
 
 
-
-
 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
 static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
 	get_temp, NULL, IDX_TEMP1_INPUT);
 	get_temp, NULL, IDX_TEMP1_INPUT);
 static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, get_temp,
 static SENSOR_DEVICE_ATTR(temp1_min, S_IRUGO | S_IWUSR, get_temp,
@@ -754,8 +798,6 @@ static SENSOR_DEVICE_ATTR_2(temp2_auto_point2_temp, S_IWUSR | S_IRUGO,
 static SENSOR_DEVICE_ATTR_2(temp2_auto_point3_temp, S_IWUSR | S_IRUGO,
 static SENSOR_DEVICE_ATTR_2(temp2_auto_point3_temp, S_IWUSR | S_IRUGO,
 	get_temp_auto_point_temp, set_temp_auto_point_temp, 2, 2);
 	get_temp_auto_point_temp, set_temp_auto_point_temp, 2, 2);
 
 
-
-
 static struct attribute *amc6821_attrs[] = {
 static struct attribute *amc6821_attrs[] = {
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_min.dev_attr.attr,
 	&sensor_dev_attr_temp1_min.dev_attr.attr,
@@ -792,11 +834,7 @@ static struct attribute *amc6821_attrs[] = {
 	NULL
 	NULL
 };
 };
 
 
-static struct attribute_group amc6821_attr_grp = {
-	.attrs = amc6821_attrs,
-};
-
-
+ATTRIBUTE_GROUPS(amc6821);
 
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
 /* Return 0 if detection is successful, -ENODEV otherwise */
 static int amc6821_detect(
 static int amc6821_detect(
@@ -844,53 +882,6 @@ static int amc6821_detect(
 	return 0;
 	return 0;
 }
 }
 
 
-static int amc6821_probe(
-	struct i2c_client *client,
-	const struct i2c_device_id *id)
-{
-	struct amc6821_data *data;
-	int err;
-
-	data = devm_kzalloc(&client->dev, sizeof(struct amc6821_data),
-			    GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	i2c_set_clientdata(client, data);
-	mutex_init(&data->update_lock);
-
-	/*
-	 * Initialize the amc6821 chip
-	 */
-	err = amc6821_init_client(client);
-	if (err)
-		return err;
-
-	err = sysfs_create_group(&client->dev.kobj, &amc6821_attr_grp);
-	if (err)
-		return err;
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (!IS_ERR(data->hwmon_dev))
-		return 0;
-
-	err = PTR_ERR(data->hwmon_dev);
-	dev_err(&client->dev, "error registering hwmon device.\n");
-	sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp);
-	return err;
-}
-
-static int amc6821_remove(struct i2c_client *client)
-{
-	struct amc6821_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp);
-
-	return 0;
-}
-
-
 static int amc6821_init_client(struct i2c_client *client)
 static int amc6821_init_client(struct i2c_client *client)
 {
 {
 	int config;
 	int config;
@@ -977,109 +968,51 @@ static int amc6821_init_client(struct i2c_client *client)
 	return 0;
 	return 0;
 }
 }
 
 
-
-static struct amc6821_data *amc6821_update_device(struct device *dev)
+static int amc6821_probe(struct i2c_client *client,
+			 const struct i2c_device_id *id)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct amc6821_data *data = i2c_get_clientdata(client);
-	int timeout = HZ;
-	u8 reg;
-	int i;
-
-	mutex_lock(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + timeout) ||
-			!data->valid) {
-
-		for (i = 0; i < TEMP_IDX_LEN; i++)
-			data->temp[i] = i2c_smbus_read_byte_data(client,
-				temp_reg[i]);
+	struct device *dev = &client->dev;
+	struct amc6821_data *data;
+	struct device *hwmon_dev;
+	int err;
 
 
-		data->stat1 = i2c_smbus_read_byte_data(client,
-			AMC6821_REG_STAT1);
-		data->stat2 = i2c_smbus_read_byte_data(client,
-			AMC6821_REG_STAT2);
+	data = devm_kzalloc(dev, sizeof(struct amc6821_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
 
 
-		data->pwm1 = i2c_smbus_read_byte_data(client,
-			AMC6821_REG_DCY);
-		for (i = 0; i < FAN1_IDX_LEN; i++) {
-			data->fan[i] = i2c_smbus_read_byte_data(
-					client,
-					fan_reg_low[i]);
-			data->fan[i] += i2c_smbus_read_byte_data(
-					client,
-					fan_reg_hi[i]) << 8;
-		}
-		data->fan1_div = i2c_smbus_read_byte_data(client,
-			AMC6821_REG_CONF4);
-		data->fan1_div = data->fan1_div & AMC6821_CONF4_PSPR ? 4 : 2;
+	data->client = client;
+	mutex_init(&data->update_lock);
 
 
-		data->pwm1_auto_point_pwm[0] = 0;
-		data->pwm1_auto_point_pwm[2] = 255;
-		data->pwm1_auto_point_pwm[1] = i2c_smbus_read_byte_data(client,
-			AMC6821_REG_DCY_LOW_TEMP);
+	/*
+	 * Initialize the amc6821 chip
+	 */
+	err = amc6821_init_client(client);
+	if (err)
+		return err;
 
 
-		data->temp1_auto_point_temp[0] =
-			i2c_smbus_read_byte_data(client,
-					AMC6821_REG_PSV_TEMP);
-		data->temp2_auto_point_temp[0] =
-				data->temp1_auto_point_temp[0];
-		reg = i2c_smbus_read_byte_data(client,
-			AMC6821_REG_LTEMP_FAN_CTRL);
-		data->temp1_auto_point_temp[1] = (reg & 0xF8) >> 1;
-		reg &= 0x07;
-		reg = 0x20 >> reg;
-		if (reg > 0)
-			data->temp1_auto_point_temp[2] =
-				data->temp1_auto_point_temp[1] +
-				(data->pwm1_auto_point_pwm[2] -
-				data->pwm1_auto_point_pwm[1]) / reg;
-		else
-			data->temp1_auto_point_temp[2] = 255;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data,
+							   amc6821_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
 
 
-		reg = i2c_smbus_read_byte_data(client,
-			AMC6821_REG_RTEMP_FAN_CTRL);
-		data->temp2_auto_point_temp[1] = (reg & 0xF8) >> 1;
-		reg &= 0x07;
-		reg = 0x20 >> reg;
-		if (reg > 0)
-			data->temp2_auto_point_temp[2] =
-				data->temp2_auto_point_temp[1] +
-				(data->pwm1_auto_point_pwm[2] -
-				data->pwm1_auto_point_pwm[1]) / reg;
-		else
-			data->temp2_auto_point_temp[2] = 255;
+static const struct i2c_device_id amc6821_id[] = {
+	{ "amc6821", amc6821 },
+	{ }
+};
 
 
-		reg = i2c_smbus_read_byte_data(client, AMC6821_REG_CONF1);
-		reg = (reg >> 5) & 0x3;
-		switch (reg) {
-		case 0: /*open loop: software sets pwm1*/
-			data->pwm1_auto_channels_temp = 0;
-			data->pwm1_enable = 1;
-			break;
-		case 2: /*closed loop: remote T (temp2)*/
-			data->pwm1_auto_channels_temp = 2;
-			data->pwm1_enable = 2;
-			break;
-		case 3: /*closed loop: local and remote T (temp2)*/
-			data->pwm1_auto_channels_temp = 3;
-			data->pwm1_enable = 3;
-			break;
-		case 1: /*
-			 * semi-open loop: software sets rpm, chip controls
-			 * pwm1, currently not implemented
-			 */
-			data->pwm1_auto_channels_temp = 0;
-			data->pwm1_enable = 0;
-			break;
-		}
+MODULE_DEVICE_TABLE(i2c, amc6821_id);
 
 
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-	mutex_unlock(&data->update_lock);
-	return data;
-}
+static struct i2c_driver amc6821_driver = {
+	.class = I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "amc6821",
+	},
+	.probe = amc6821_probe,
+	.id_table = amc6821_id,
+	.detect = amc6821_detect,
+	.address_list = normal_i2c,
+};
 
 
 module_i2c_driver(amc6821_driver);
 module_i2c_driver(amc6821_driver);
 
 

+ 7 - 7
drivers/hwmon/asc7621.c

@@ -300,7 +300,7 @@ static ssize_t store_fan16(struct device *dev,
  * respectively. That doesn't mean that's what the motherboard provides. :)
  * respectively. That doesn't mean that's what the motherboard provides. :)
  */
  */
 
 
-static int asc7621_in_scaling[] = {
+static const int asc7621_in_scaling[] = {
 	2500, 2250, 3300, 5000, 12000
 	2500, 2250, 3300, 5000, 12000
 };
 };
 
 
@@ -451,7 +451,7 @@ static ssize_t store_temp62(struct device *dev,
  * hwmon specs, we synthesize the auto_point_2 from them.
  * hwmon specs, we synthesize the auto_point_2 from them.
  */
  */
 
 
-static u32 asc7621_range_map[] = {
+static const u32 asc7621_range_map[] = {
 	2000, 2500, 3330, 4000, 5000, 6670, 8000, 10000,
 	2000, 2500, 3330, 4000, 5000, 6670, 8000, 10000,
 	13330, 16000, 20000, 26670, 32000, 40000, 53330, 80000,
 	13330, 16000, 20000, 26670, 32000, 40000, 53330, 80000,
 };
 };
@@ -512,7 +512,7 @@ static ssize_t show_pwm_ac(struct device *dev,
 {
 {
 	SETUP_SHOW_DATA_PARAM(dev, attr);
 	SETUP_SHOW_DATA_PARAM(dev, attr);
 	u8 config, altbit, regval;
 	u8 config, altbit, regval;
-	u8 map[] = {
+	const u8 map[] = {
 		0x01, 0x02, 0x04, 0x1f, 0x00, 0x06, 0x07, 0x10,
 		0x01, 0x02, 0x04, 0x1f, 0x00, 0x06, 0x07, 0x10,
 		0x08, 0x0f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f
 		0x08, 0x0f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f, 0x1f
 	};
 	};
@@ -533,7 +533,7 @@ static ssize_t store_pwm_ac(struct device *dev,
 	SETUP_STORE_DATA_PARAM(dev, attr);
 	SETUP_STORE_DATA_PARAM(dev, attr);
 	unsigned long reqval;
 	unsigned long reqval;
 	u8 currval, config, altbit, newval;
 	u8 currval, config, altbit, newval;
-	u16 map[] = {
+	const u16 map[] = {
 		0x04, 0x00, 0x01, 0xff, 0x02, 0xff, 0x05, 0x06,
 		0x04, 0x00, 0x01, 0xff, 0x02, 0xff, 0x05, 0x06,
 		0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
 		0x08, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0x0f,
 		0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
 		0x07, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff,
@@ -651,7 +651,7 @@ static ssize_t store_pwm_enable(struct device *dev,
 	return count;
 	return count;
 }
 }
 
 
-static u32 asc7621_pwm_freq_map[] = {
+static const u32 asc7621_pwm_freq_map[] = {
 	10, 15, 23, 30, 38, 47, 62, 94,
 	10, 15, 23, 30, 38, 47, 62, 94,
 	23000, 24000, 25000, 26000, 27000, 28000, 29000, 30000
 	23000, 24000, 25000, 26000, 27000, 28000, 29000, 30000
 };
 };
@@ -700,7 +700,7 @@ static ssize_t store_pwm_freq(struct device *dev,
 	return count;
 	return count;
 }
 }
 
 
-static u32 asc7621_pwm_auto_spinup_map[] =  {
+static const u32 asc7621_pwm_auto_spinup_map[] =  {
 	0, 100, 250, 400, 700, 1000, 2000, 4000
 	0, 100, 250, 400, 700, 1000, 2000, 4000
 };
 };
 
 
@@ -749,7 +749,7 @@ static ssize_t store_pwm_ast(struct device *dev,
 	return count;
 	return count;
 }
 }
 
 
-static u32 asc7621_temp_smoothing_time_map[] = {
+static const u32 asc7621_temp_smoothing_time_map[] = {
 	35000, 17600, 11800, 7000, 4400, 3000, 1600, 800
 	35000, 17600, 11800, 7000, 4400, 3000, 1600, 800
 };
 };
 
 

+ 21 - 55
drivers/hwmon/atxp1.c

@@ -46,7 +46,7 @@ MODULE_AUTHOR("Sebastian Witt <se.witt@gmx.net>");
 static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END };
 static const unsigned short normal_i2c[] = { 0x37, 0x4e, I2C_CLIENT_END };
 
 
 struct atxp1_data {
 struct atxp1_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
 	struct mutex update_lock;
 	struct mutex update_lock;
 	unsigned long last_updated;
 	unsigned long last_updated;
 	u8 valid;
 	u8 valid;
@@ -61,11 +61,8 @@ struct atxp1_data {
 
 
 static struct atxp1_data *atxp1_update_device(struct device *dev)
 static struct atxp1_data *atxp1_update_device(struct device *dev)
 {
 {
-	struct i2c_client *client;
-	struct atxp1_data *data;
-
-	client = to_i2c_client(dev);
-	data = i2c_get_clientdata(client);
+	struct atxp1_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 
 
 	mutex_lock(&data->update_lock);
 	mutex_lock(&data->update_lock);
 
 
@@ -105,15 +102,12 @@ static ssize_t atxp1_storevcore(struct device *dev,
 				struct device_attribute *attr,
 				struct device_attribute *attr,
 				const char *buf, size_t count)
 				const char *buf, size_t count)
 {
 {
-	struct atxp1_data *data;
-	struct i2c_client *client;
+	struct atxp1_data *data = atxp1_update_device(dev);
+	struct i2c_client *client = data->client;
 	int vid, cvid;
 	int vid, cvid;
 	unsigned long vcore;
 	unsigned long vcore;
 	int err;
 	int err;
 
 
-	client = to_i2c_client(dev);
-	data = atxp1_update_device(dev);
-
 	err = kstrtoul(buf, 10, &vcore);
 	err = kstrtoul(buf, 10, &vcore);
 	if (err)
 	if (err)
 		return err;
 		return err;
@@ -184,14 +178,11 @@ static ssize_t atxp1_storegpio1(struct device *dev,
 				struct device_attribute *attr, const char *buf,
 				struct device_attribute *attr, const char *buf,
 				size_t count)
 				size_t count)
 {
 {
-	struct atxp1_data *data;
-	struct i2c_client *client;
+	struct atxp1_data *data = atxp1_update_device(dev);
+	struct i2c_client *client = data->client;
 	unsigned long value;
 	unsigned long value;
 	int err;
 	int err;
 
 
-	client = to_i2c_client(dev);
-	data = atxp1_update_device(dev);
-
 	err = kstrtoul(buf, 16, &value);
 	err = kstrtoul(buf, 16, &value);
 	if (err)
 	if (err)
 		return err;
 		return err;
@@ -234,7 +225,7 @@ static ssize_t atxp1_storegpio2(struct device *dev,
 				const char *buf, size_t count)
 				const char *buf, size_t count)
 {
 {
 	struct atxp1_data *data = atxp1_update_device(dev);
 	struct atxp1_data *data = atxp1_update_device(dev);
-	struct i2c_client *client = to_i2c_client(dev);
+	struct i2c_client *client = data->client;
 	unsigned long value;
 	unsigned long value;
 	int err;
 	int err;
 
 
@@ -260,17 +251,13 @@ static ssize_t atxp1_storegpio2(struct device *dev,
  */
  */
 static DEVICE_ATTR(gpio2, S_IRUGO | S_IWUSR, atxp1_showgpio2, atxp1_storegpio2);
 static DEVICE_ATTR(gpio2, S_IRUGO | S_IWUSR, atxp1_showgpio2, atxp1_storegpio2);
 
 
-static struct attribute *atxp1_attributes[] = {
+static struct attribute *atxp1_attrs[] = {
 	&dev_attr_gpio1.attr,
 	&dev_attr_gpio1.attr,
 	&dev_attr_gpio2.attr,
 	&dev_attr_gpio2.attr,
 	&dev_attr_cpu0_vid.attr,
 	&dev_attr_cpu0_vid.attr,
 	NULL
 	NULL
 };
 };
-
-static const struct attribute_group atxp1_group = {
-	.attrs = atxp1_attributes,
-};
-
+ATTRIBUTE_GROUPS(atxp1);
 
 
 /* Return 0 if detection is successful, -ENODEV otherwise */
 /* Return 0 if detection is successful, -ENODEV otherwise */
 static int atxp1_detect(struct i2c_client *new_client,
 static int atxp1_detect(struct i2c_client *new_client,
@@ -314,50 +301,30 @@ static int atxp1_detect(struct i2c_client *new_client,
 	return 0;
 	return 0;
 }
 }
 
 
-static int atxp1_probe(struct i2c_client *new_client,
+static int atxp1_probe(struct i2c_client *client,
 		       const struct i2c_device_id *id)
 		       const struct i2c_device_id *id)
 {
 {
+	struct device *dev = &client->dev;
 	struct atxp1_data *data;
 	struct atxp1_data *data;
-	int err;
+	struct device *hwmon_dev;
 
 
-	data = devm_kzalloc(&new_client->dev, sizeof(struct atxp1_data),
-			    GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(struct atxp1_data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	/* Get VRM */
 	/* Get VRM */
 	data->vrm = vid_which_vrm();
 	data->vrm = vid_which_vrm();
 
 
-	i2c_set_clientdata(new_client, data);
+	data->client = client;
 	mutex_init(&data->update_lock);
 	mutex_init(&data->update_lock);
 
 
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&new_client->dev.kobj, &atxp1_group);
-	if (err)
-		return err;
-
-	data->hwmon_dev = hwmon_device_register(&new_client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove_files;
-	}
-
-	dev_info(&new_client->dev, "Using VRM: %d.%d\n",
-			 data->vrm / 10, data->vrm % 10);
-
-	return 0;
-
-exit_remove_files:
-	sysfs_remove_group(&new_client->dev.kobj, &atxp1_group);
-	return err;
-};
-
-static int atxp1_remove(struct i2c_client *client)
-{
-	struct atxp1_data *data = i2c_get_clientdata(client);
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data,
+							   atxp1_groups);
+	if (IS_ERR(hwmon_dev))
+		return PTR_ERR(hwmon_dev);
 
 
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &atxp1_group);
+	dev_info(dev, "Using VRM: %d.%d\n", data->vrm / 10, data->vrm % 10);
 
 
 	return 0;
 	return 0;
 };
 };
@@ -374,7 +341,6 @@ static struct i2c_driver atxp1_driver = {
 		.name	= "atxp1",
 		.name	= "atxp1",
 	},
 	},
 	.probe		= atxp1_probe,
 	.probe		= atxp1_probe,
-	.remove		= atxp1_remove,
 	.id_table	= atxp1_id,
 	.id_table	= atxp1_id,
 	.detect		= atxp1_detect,
 	.detect		= atxp1_detect,
 	.address_list	= normal_i2c,
 	.address_list	= normal_i2c,

+ 17 - 43
drivers/hwmon/ds620.c

@@ -67,7 +67,7 @@ static const u8 DS620_REG_TEMP[3] = {
 
 
 /* Each client has this additional data */
 /* Each client has this additional data */
 struct ds620_data {
 struct ds620_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
 	struct mutex update_lock;
 	struct mutex update_lock;
 	char valid;		/* !=0 if following fields are valid */
 	char valid;		/* !=0 if following fields are valid */
 	unsigned long last_updated;	/* In jiffies */
 	unsigned long last_updated;	/* In jiffies */
@@ -106,8 +106,8 @@ static void ds620_init_client(struct i2c_client *client)
 
 
 static struct ds620_data *ds620_update_client(struct device *dev)
 static struct ds620_data *ds620_update_client(struct device *dev)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct ds620_data *data = i2c_get_clientdata(client);
+	struct ds620_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	struct ds620_data *ret = data;
 	struct ds620_data *ret = data;
 
 
 	mutex_lock(&data->update_lock);
 	mutex_lock(&data->update_lock);
@@ -158,8 +158,8 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *da,
 	long val;
 	long val;
 
 
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
-	struct i2c_client *client = to_i2c_client(dev);
-	struct ds620_data *data = i2c_get_clientdata(client);
+	struct ds620_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 
 
 	res = kstrtol(buf, 10, &val);
 	res = kstrtol(buf, 10, &val);
 
 
@@ -181,13 +181,15 @@ static ssize_t show_alarm(struct device *dev, struct device_attribute *da,
 {
 {
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
 	struct ds620_data *data = ds620_update_client(dev);
 	struct ds620_data *data = ds620_update_client(dev);
-	struct i2c_client *client = to_i2c_client(dev);
+	struct i2c_client *client;
 	u16 conf, new_conf;
 	u16 conf, new_conf;
 	int res;
 	int res;
 
 
 	if (IS_ERR(data))
 	if (IS_ERR(data))
 		return PTR_ERR(data);
 		return PTR_ERR(data);
 
 
+	client = data->client;
+
 	/* reset alarms if necessary */
 	/* reset alarms if necessary */
 	res = i2c_smbus_read_word_swapped(client, DS620_REG_CONF);
 	res = i2c_smbus_read_word_swapped(client, DS620_REG_CONF);
 	if (res < 0)
 	if (res < 0)
@@ -213,7 +215,7 @@ static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, show_alarm, NULL,
 static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL,
 static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, show_alarm, NULL,
 			  DS620_REG_CONFIG_THF);
 			  DS620_REG_CONFIG_THF);
 
 
-static struct attribute *ds620_attributes[] = {
+static struct attribute *ds620_attrs[] = {
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_min.dev_attr.attr,
 	&sensor_dev_attr_temp1_min.dev_attr.attr,
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
 	&sensor_dev_attr_temp1_max.dev_attr.attr,
@@ -222,55 +224,28 @@ static struct attribute *ds620_attributes[] = {
 	NULL
 	NULL
 };
 };
 
 
-static const struct attribute_group ds620_group = {
-	.attrs = ds620_attributes,
-};
+ATTRIBUTE_GROUPS(ds620);
 
 
 static int ds620_probe(struct i2c_client *client,
 static int ds620_probe(struct i2c_client *client,
 		       const struct i2c_device_id *id)
 		       const struct i2c_device_id *id)
 {
 {
+	struct device *dev = &client->dev;
+	struct device *hwmon_dev;
 	struct ds620_data *data;
 	struct ds620_data *data;
-	int err;
 
 
-	data = devm_kzalloc(&client->dev, sizeof(struct ds620_data),
-			    GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(struct ds620_data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	i2c_set_clientdata(client, data);
+	data->client = client;
 	mutex_init(&data->update_lock);
 	mutex_init(&data->update_lock);
 
 
 	/* Initialize the DS620 chip */
 	/* Initialize the DS620 chip */
 	ds620_init_client(client);
 	ds620_init_client(client);
 
 
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&client->dev.kobj, &ds620_group);
-	if (err)
-		return err;
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove_files;
-	}
-
-	dev_info(&client->dev, "temperature sensor found\n");
-
-	return 0;
-
-exit_remove_files:
-	sysfs_remove_group(&client->dev.kobj, &ds620_group);
-	return err;
-}
-
-static int ds620_remove(struct i2c_client *client)
-{
-	struct ds620_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &ds620_group);
-
-	return 0;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data, ds620_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
 static const struct i2c_device_id ds620_id[] = {
 static const struct i2c_device_id ds620_id[] = {
@@ -287,7 +262,6 @@ static struct i2c_driver ds620_driver = {
 		   .name = "ds620",
 		   .name = "ds620",
 	},
 	},
 	.probe = ds620_probe,
 	.probe = ds620_probe,
-	.remove = ds620_remove,
 	.id_table = ds620_id,
 	.id_table = ds620_id,
 };
 };
 
 

+ 1 - 1
drivers/hwmon/emc1403.c

@@ -416,7 +416,7 @@ static bool emc1403_regmap_is_volatile(struct device *dev, unsigned int reg)
 	}
 	}
 }
 }
 
 
-static struct regmap_config emc1403_regmap_config = {
+static const struct regmap_config emc1403_regmap_config = {
 	.reg_bits = 8,
 	.reg_bits = 8,
 	.val_bits = 8,
 	.val_bits = 8,
 	.cache_type = REGCACHE_RBTREE,
 	.cache_type = REGCACHE_RBTREE,

+ 26 - 63
drivers/hwmon/emc2103.c

@@ -66,7 +66,8 @@ struct temperature {
 };
 };
 
 
 struct emc2103_data {
 struct emc2103_data {
-	struct device		*hwmon_dev;
+	struct i2c_client	*client;
+	const struct		attribute_group *groups[4];
 	struct mutex		update_lock;
 	struct mutex		update_lock;
 	bool			valid;		/* registers are valid */
 	bool			valid;		/* registers are valid */
 	bool			fan_rpm_control;
 	bool			fan_rpm_control;
@@ -146,8 +147,8 @@ static void read_fan_config_from_i2c(struct i2c_client *client)
 
 
 static struct emc2103_data *emc2103_update_device(struct device *dev)
 static struct emc2103_data *emc2103_update_device(struct device *dev)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct emc2103_data *data = i2c_get_clientdata(client);
+	struct emc2103_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 
 
 	mutex_lock(&data->update_lock);
 	mutex_lock(&data->update_lock);
 
 
@@ -242,8 +243,8 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *da,
 			    const char *buf, size_t count)
 			    const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(da)->index;
 	int nr = to_sensor_dev_attr(da)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct emc2103_data *data = i2c_get_clientdata(client);
+	struct emc2103_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 
 
 	int result = kstrtol(buf, 10, &val);
 	int result = kstrtol(buf, 10, &val);
@@ -264,8 +265,8 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *da,
 			    const char *buf, size_t count)
 			    const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(da)->index;
 	int nr = to_sensor_dev_attr(da)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct emc2103_data *data = i2c_get_clientdata(client);
+	struct emc2103_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 
 
 	int result = kstrtol(buf, 10, &val);
 	int result = kstrtol(buf, 10, &val);
@@ -310,7 +311,7 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *da,
 			   const char *buf, size_t count)
 			   const char *buf, size_t count)
 {
 {
 	struct emc2103_data *data = emc2103_update_device(dev);
 	struct emc2103_data *data = emc2103_update_device(dev);
-	struct i2c_client *client = to_i2c_client(dev);
+	struct i2c_client *client = data->client;
 	int new_range_bits, old_div = 8 / data->fan_multiplier;
 	int new_range_bits, old_div = 8 / data->fan_multiplier;
 	long new_div;
 	long new_div;
 
 
@@ -385,7 +386,7 @@ static ssize_t set_fan_target(struct device *dev, struct device_attribute *da,
 			      const char *buf, size_t count)
 			      const char *buf, size_t count)
 {
 {
 	struct emc2103_data *data = emc2103_update_device(dev);
 	struct emc2103_data *data = emc2103_update_device(dev);
-	struct i2c_client *client = to_i2c_client(dev);
+	struct i2c_client *client = data->client;
 	unsigned long rpm_target;
 	unsigned long rpm_target;
 
 
 	int result = kstrtoul(buf, 10, &rpm_target);
 	int result = kstrtoul(buf, 10, &rpm_target);
@@ -428,8 +429,8 @@ show_pwm_enable(struct device *dev, struct device_attribute *da, char *buf)
 static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da,
 static ssize_t set_pwm_enable(struct device *dev, struct device_attribute *da,
 			      const char *buf, size_t count)
 			      const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct emc2103_data *data = i2c_get_clientdata(client);
+	struct emc2103_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long new_value;
 	long new_value;
 	u8 conf_reg;
 	u8 conf_reg;
 
 
@@ -580,7 +581,8 @@ static int
 emc2103_probe(struct i2c_client *client, const struct i2c_device_id *id)
 emc2103_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 {
 	struct emc2103_data *data;
 	struct emc2103_data *data;
-	int status;
+	struct device *hwmon_dev;
+	int status, idx = 0;
 
 
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -EIO;
 		return -EIO;
@@ -591,6 +593,7 @@ emc2103_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	i2c_set_clientdata(client, data);
 	i2c_set_clientdata(client, data);
+	data->client = client;
 	mutex_init(&data->update_lock);
 	mutex_init(&data->update_lock);
 
 
 	/* 2103-2 and 2103-4 have 3 external diodes, 2103-1 has 1 */
 	/* 2103-2 and 2103-4 have 3 external diodes, 2103-1 has 1 */
@@ -624,60 +627,21 @@ emc2103_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		}
 		}
 	}
 	}
 
 
-	/* Register sysfs hooks */
-	status = sysfs_create_group(&client->dev.kobj, &emc2103_group);
-	if (status)
-		return status;
-
-	if (data->temp_count >= 3) {
-		status = sysfs_create_group(&client->dev.kobj,
-			&emc2103_temp3_group);
-		if (status)
-			goto exit_remove;
-	}
-
-	if (data->temp_count == 4) {
-		status = sysfs_create_group(&client->dev.kobj,
-			&emc2103_temp4_group);
-		if (status)
-			goto exit_remove_temp3;
-	}
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		status = PTR_ERR(data->hwmon_dev);
-		goto exit_remove_temp4;
-	}
-
-	dev_info(&client->dev, "%s: sensor '%s'\n",
-		 dev_name(data->hwmon_dev), client->name);
-
-	return 0;
-
-exit_remove_temp4:
-	if (data->temp_count == 4)
-		sysfs_remove_group(&client->dev.kobj, &emc2103_temp4_group);
-exit_remove_temp3:
+	/* sysfs hooks */
+	data->groups[idx++] = &emc2103_group;
 	if (data->temp_count >= 3)
 	if (data->temp_count >= 3)
-		sysfs_remove_group(&client->dev.kobj, &emc2103_temp3_group);
-exit_remove:
-	sysfs_remove_group(&client->dev.kobj, &emc2103_group);
-	return status;
-}
-
-static int emc2103_remove(struct i2c_client *client)
-{
-	struct emc2103_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-
+		data->groups[idx++] = &emc2103_temp3_group;
 	if (data->temp_count == 4)
 	if (data->temp_count == 4)
-		sysfs_remove_group(&client->dev.kobj, &emc2103_temp4_group);
+		data->groups[idx++] = &emc2103_temp4_group;
 
 
-	if (data->temp_count >= 3)
-		sysfs_remove_group(&client->dev.kobj, &emc2103_temp3_group);
+	hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev,
+							   client->name, data,
+							   data->groups);
+	if (IS_ERR(hwmon_dev))
+		return PTR_ERR(hwmon_dev);
 
 
-	sysfs_remove_group(&client->dev.kobj, &emc2103_group);
+	dev_info(&client->dev, "%s: sensor '%s'\n",
+		 dev_name(hwmon_dev), client->name);
 
 
 	return 0;
 	return 0;
 }
 }
@@ -717,7 +681,6 @@ static struct i2c_driver emc2103_driver = {
 		.name	= "emc2103",
 		.name	= "emc2103",
 	},
 	},
 	.probe		= emc2103_probe,
 	.probe		= emc2103_probe,
-	.remove		= emc2103_remove,
 	.id_table	= emc2103_ids,
 	.id_table	= emc2103_ids,
 	.detect		= emc2103_detect,
 	.detect		= emc2103_detect,
 	.address_list	= normal_i2c,
 	.address_list	= normal_i2c,

+ 19 - 45
drivers/hwmon/emc6w201.c

@@ -56,7 +56,7 @@ enum subfeature { input, min, max };
  */
  */
 
 
 struct emc6w201_data {
 struct emc6w201_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
 	struct mutex update_lock;
 	struct mutex update_lock;
 	char valid; /* zero until following fields are valid */
 	char valid; /* zero until following fields are valid */
 	unsigned long last_updated; /* in jiffies */
 	unsigned long last_updated; /* in jiffies */
@@ -134,8 +134,8 @@ static int emc6w201_write8(struct i2c_client *client, u8 reg, u8 val)
 
 
 static struct emc6w201_data *emc6w201_update_device(struct device *dev)
 static struct emc6w201_data *emc6w201_update_device(struct device *dev)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct emc6w201_data *data = i2c_get_clientdata(client);
+	struct emc6w201_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int nr;
 	int nr;
 
 
 	mutex_lock(&data->update_lock);
 	mutex_lock(&data->update_lock);
@@ -203,8 +203,8 @@ static ssize_t show_in(struct device *dev, struct device_attribute *devattr,
 static ssize_t set_in(struct device *dev, struct device_attribute *devattr,
 static ssize_t set_in(struct device *dev, struct device_attribute *devattr,
 		      const char *buf, size_t count)
 		      const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct emc6w201_data *data = i2c_get_clientdata(client);
+	struct emc6w201_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int sf = to_sensor_dev_attr_2(devattr)->index;
 	int sf = to_sensor_dev_attr_2(devattr)->index;
 	int nr = to_sensor_dev_attr_2(devattr)->nr;
 	int nr = to_sensor_dev_attr_2(devattr)->nr;
 	int err;
 	int err;
@@ -240,8 +240,8 @@ static ssize_t show_temp(struct device *dev, struct device_attribute *devattr,
 static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
 static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
 			const char *buf, size_t count)
 			const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct emc6w201_data *data = i2c_get_clientdata(client);
+	struct emc6w201_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int sf = to_sensor_dev_attr_2(devattr)->index;
 	int sf = to_sensor_dev_attr_2(devattr)->index;
 	int nr = to_sensor_dev_attr_2(devattr)->nr;
 	int nr = to_sensor_dev_attr_2(devattr)->nr;
 	int err;
 	int err;
@@ -283,8 +283,8 @@ static ssize_t show_fan(struct device *dev, struct device_attribute *devattr,
 static ssize_t set_fan(struct device *dev, struct device_attribute *devattr,
 static ssize_t set_fan(struct device *dev, struct device_attribute *devattr,
 		       const char *buf, size_t count)
 		       const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct emc6w201_data *data = i2c_get_clientdata(client);
+	struct emc6w201_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int sf = to_sensor_dev_attr_2(devattr)->index;
 	int sf = to_sensor_dev_attr_2(devattr)->index;
 	int nr = to_sensor_dev_attr_2(devattr)->nr;
 	int nr = to_sensor_dev_attr_2(devattr)->nr;
 	int err;
 	int err;
@@ -388,7 +388,7 @@ static SENSOR_DEVICE_ATTR_2(fan5_input, S_IRUGO, show_fan, NULL, 4, input);
 static SENSOR_DEVICE_ATTR_2(fan5_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
 static SENSOR_DEVICE_ATTR_2(fan5_min, S_IRUGO | S_IWUSR, show_fan, set_fan,
 			    4, min);
 			    4, min);
 
 
-static struct attribute *emc6w201_attributes[] = {
+static struct attribute *emc6w201_attrs[] = {
 	&sensor_dev_attr_in0_input.dev_attr.attr,
 	&sensor_dev_attr_in0_input.dev_attr.attr,
 	&sensor_dev_attr_in0_min.dev_attr.attr,
 	&sensor_dev_attr_in0_min.dev_attr.attr,
 	&sensor_dev_attr_in0_max.dev_attr.attr,
 	&sensor_dev_attr_in0_max.dev_attr.attr,
@@ -440,9 +440,7 @@ static struct attribute *emc6w201_attributes[] = {
 	NULL
 	NULL
 };
 };
 
 
-static const struct attribute_group emc6w201_group = {
-	.attrs = emc6w201_attributes,
-};
+ATTRIBUTE_GROUPS(emc6w201);
 
 
 /*
 /*
  * Driver interface
  * Driver interface
@@ -488,44 +486,21 @@ static int emc6w201_detect(struct i2c_client *client,
 static int emc6w201_probe(struct i2c_client *client,
 static int emc6w201_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 			  const struct i2c_device_id *id)
 {
 {
+	struct device *dev = &client->dev;
 	struct emc6w201_data *data;
 	struct emc6w201_data *data;
-	int err;
+	struct device *hwmon_dev;
 
 
-	data = devm_kzalloc(&client->dev, sizeof(struct emc6w201_data),
-			    GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(struct emc6w201_data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	i2c_set_clientdata(client, data);
+	data->client = client;
 	mutex_init(&data->update_lock);
 	mutex_init(&data->update_lock);
 
 
-	/* Create sysfs attribute */
-	err = sysfs_create_group(&client->dev.kobj, &emc6w201_group);
-	if (err)
-		return err;
-
-	/* Expose as a hwmon device */
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove;
-	}
-
-	return 0;
-
- exit_remove:
-	sysfs_remove_group(&client->dev.kobj, &emc6w201_group);
-	return err;
-}
-
-static int emc6w201_remove(struct i2c_client *client)
-{
-	struct emc6w201_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &emc6w201_group);
-
-	return 0;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data,
+							   emc6w201_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
 static const struct i2c_device_id emc6w201_id[] = {
 static const struct i2c_device_id emc6w201_id[] = {
@@ -540,7 +515,6 @@ static struct i2c_driver emc6w201_driver = {
 		.name	= "emc6w201",
 		.name	= "emc6w201",
 	},
 	},
 	.probe		= emc6w201_probe,
 	.probe		= emc6w201_probe,
-	.remove		= emc6w201_remove,
 	.id_table	= emc6w201_id,
 	.id_table	= emc6w201_id,
 	.detect		= emc6w201_detect,
 	.detect		= emc6w201_detect,
 	.address_list	= normal_i2c,
 	.address_list	= normal_i2c,

+ 9 - 45
drivers/hwmon/fam15h_power.c

@@ -31,9 +31,6 @@ MODULE_DESCRIPTION("AMD Family 15h CPU processor power monitor");
 MODULE_AUTHOR("Andreas Herrmann <herrmann.der.user@googlemail.com>");
 MODULE_AUTHOR("Andreas Herrmann <herrmann.der.user@googlemail.com>");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 
 
-/* Family 16h Northbridge's function 4 PCI ID */
-#define PCI_DEVICE_ID_AMD_16H_NB_F4	0x1534
-
 /* D18F3 */
 /* D18F3 */
 #define REG_NORTHBRIDGE_CAP		0xe8
 #define REG_NORTHBRIDGE_CAP		0xe8
 
 
@@ -45,7 +42,7 @@ MODULE_LICENSE("GPL");
 #define REG_TDP_LIMIT3			0xe8
 #define REG_TDP_LIMIT3			0xe8
 
 
 struct fam15h_power_data {
 struct fam15h_power_data {
-	struct device *hwmon_dev;
+	struct pci_dev *pdev;
 	unsigned int tdp_to_watts;
 	unsigned int tdp_to_watts;
 	unsigned int base_tdp;
 	unsigned int base_tdp;
 	unsigned int processor_pwr_watts;
 	unsigned int processor_pwr_watts;
@@ -57,8 +54,8 @@ static ssize_t show_power(struct device *dev,
 	u32 val, tdp_limit, running_avg_range;
 	u32 val, tdp_limit, running_avg_range;
 	s32 running_avg_capture;
 	s32 running_avg_capture;
 	u64 curr_pwr_watts;
 	u64 curr_pwr_watts;
-	struct pci_dev *f4 = to_pci_dev(dev);
 	struct fam15h_power_data *data = dev_get_drvdata(dev);
 	struct fam15h_power_data *data = dev_get_drvdata(dev);
+	struct pci_dev *f4 = data->pdev;
 
 
 	pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5),
 	pci_bus_read_config_dword(f4->bus, PCI_DEVFN(PCI_SLOT(f4->devfn), 5),
 				  REG_TDP_RUNNING_AVERAGE, &val);
 				  REG_TDP_RUNNING_AVERAGE, &val);
@@ -96,23 +93,13 @@ static ssize_t show_power_crit(struct device *dev,
 }
 }
 static DEVICE_ATTR(power1_crit, S_IRUGO, show_power_crit, NULL);
 static DEVICE_ATTR(power1_crit, S_IRUGO, show_power_crit, NULL);
 
 
-static ssize_t show_name(struct device *dev,
-			 struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "fam15h_power\n");
-}
-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
-
 static struct attribute *fam15h_power_attrs[] = {
 static struct attribute *fam15h_power_attrs[] = {
 	&dev_attr_power1_input.attr,
 	&dev_attr_power1_input.attr,
 	&dev_attr_power1_crit.attr,
 	&dev_attr_power1_crit.attr,
-	&dev_attr_name.attr,
 	NULL
 	NULL
 };
 };
 
 
-static const struct attribute_group fam15h_power_attr_group = {
-	.attrs	= fam15h_power_attrs,
-};
+ATTRIBUTE_GROUPS(fam15h_power);
 
 
 static bool fam15h_power_is_internal_node0(struct pci_dev *f4)
 static bool fam15h_power_is_internal_node0(struct pci_dev *f4)
 {
 {
@@ -202,7 +189,7 @@ static int fam15h_power_probe(struct pci_dev *pdev,
 {
 {
 	struct fam15h_power_data *data;
 	struct fam15h_power_data *data;
 	struct device *dev = &pdev->dev;
 	struct device *dev = &pdev->dev;
-	int err;
+	struct device *hwmon_dev;
 
 
 	/*
 	/*
 	 * though we ignore every other northbridge, we still have to
 	 * though we ignore every other northbridge, we still have to
@@ -219,34 +206,12 @@ static int fam15h_power_probe(struct pci_dev *pdev,
 		return -ENOMEM;
 		return -ENOMEM;
 
 
 	fam15h_power_init_data(pdev, data);
 	fam15h_power_init_data(pdev, data);
+	data->pdev = pdev;
 
 
-	dev_set_drvdata(dev, data);
-	err = sysfs_create_group(&dev->kobj, &fam15h_power_attr_group);
-	if (err)
-		return err;
-
-	data->hwmon_dev = hwmon_device_register(dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove_group;
-	}
-
-	return 0;
-
-exit_remove_group:
-	sysfs_remove_group(&dev->kobj, &fam15h_power_attr_group);
-	return err;
-}
-
-static void fam15h_power_remove(struct pci_dev *pdev)
-{
-	struct device *dev;
-	struct fam15h_power_data *data;
-
-	dev = &pdev->dev;
-	data = dev_get_drvdata(dev);
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&dev->kobj, &fam15h_power_attr_group);
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, "fam15h_power",
+							   data,
+							   fam15h_power_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
 static const struct pci_device_id fam15h_power_id_table[] = {
 static const struct pci_device_id fam15h_power_id_table[] = {
@@ -260,7 +225,6 @@ static struct pci_driver fam15h_power_driver = {
 	.name = "fam15h_power",
 	.name = "fam15h_power",
 	.id_table = fam15h_power_id_table,
 	.id_table = fam15h_power_id_table,
 	.probe = fam15h_power_probe,
 	.probe = fam15h_power_probe,
-	.remove = fam15h_power_remove,
 	.resume = fam15h_power_resume,
 	.resume = fam15h_power_resume,
 };
 };
 
 

+ 26 - 58
drivers/hwmon/g760a.c

@@ -24,12 +24,6 @@
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
 #include <linux/sysfs.h>
 
 
-static const struct i2c_device_id g760a_id[] = {
-	{ "g760a", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, g760a_id);
-
 enum g760a_regs {
 enum g760a_regs {
 	G760A_REG_SET_CNT = 0x00,
 	G760A_REG_SET_CNT = 0x00,
 	G760A_REG_ACT_CNT = 0x01,
 	G760A_REG_ACT_CNT = 0x01,
@@ -44,7 +38,6 @@ enum g760a_regs {
 
 
 struct g760a_data {
 struct g760a_data {
 	struct i2c_client *client;
 	struct i2c_client *client;
-	struct device *hwmon_dev;
 	struct mutex update_lock;
 	struct mutex update_lock;
 
 
 	/* board specific parameters */
 	/* board specific parameters */
@@ -74,20 +67,6 @@ static inline unsigned int rpm_from_cnt(u8 val, u32 clk, u16 div)
 	return ((val == 0x00) ? 0 : ((clk*30)/(val*div)));
 	return ((val == 0x00) ? 0 : ((clk*30)/(val*div)));
 }
 }
 
 
-/* new-style driver model */
-static int g760a_probe(struct i2c_client *client,
-			const struct i2c_device_id *id);
-static int g760a_remove(struct i2c_client *client);
-
-static struct i2c_driver g760a_driver = {
-	.driver = {
-		.name	= "g760a",
-	},
-	.probe	  = g760a_probe,
-	.remove	  = g760a_remove,
-	.id_table = g760a_id,
-};
-
 /* read/write wrappers */
 /* read/write wrappers */
 static int g760a_read_value(struct i2c_client *client, enum g760a_regs reg)
 static int g760a_read_value(struct i2c_client *client, enum g760a_regs reg)
 {
 {
@@ -106,8 +85,8 @@ static int g760a_write_value(struct i2c_client *client, enum g760a_regs reg,
 
 
 static struct g760a_data *g760a_update_client(struct device *dev)
 static struct g760a_data *g760a_update_client(struct device *dev)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct g760a_data *data = i2c_get_clientdata(client);
+	struct g760a_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 
 
 	mutex_lock(&data->update_lock);
 	mutex_lock(&data->update_lock);
 
 
@@ -163,8 +142,8 @@ static ssize_t get_pwm(struct device *dev, struct device_attribute *da,
 static ssize_t set_pwm(struct device *dev, struct device_attribute *da,
 static ssize_t set_pwm(struct device *dev, struct device_attribute *da,
 		       const char *buf, size_t count)
 		       const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct g760a_data *data = g760a_update_client(dev);
 	struct g760a_data *data = g760a_update_client(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 
 
 	if (kstrtoul(buf, 10, &val))
 	if (kstrtoul(buf, 10, &val))
@@ -182,16 +161,14 @@ static DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, get_pwm, set_pwm);
 static DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL);
 static DEVICE_ATTR(fan1_input, S_IRUGO, show_fan, NULL);
 static DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL);
 static DEVICE_ATTR(fan1_alarm, S_IRUGO, show_fan_alarm, NULL);
 
 
-static struct attribute *g760a_attributes[] = {
+static struct attribute *g760a_attrs[] = {
 	&dev_attr_pwm1.attr,
 	&dev_attr_pwm1.attr,
 	&dev_attr_fan1_input.attr,
 	&dev_attr_fan1_input.attr,
 	&dev_attr_fan1_alarm.attr,
 	&dev_attr_fan1_alarm.attr,
 	NULL
 	NULL
 };
 };
 
 
-static const struct attribute_group g760a_group = {
-	.attrs = g760a_attributes,
-};
+ATTRIBUTE_GROUPS(g760a);
 
 
 /*
 /*
  * new-style driver model code
  * new-style driver model code
@@ -200,20 +177,17 @@ static const struct attribute_group g760a_group = {
 static int g760a_probe(struct i2c_client *client,
 static int g760a_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 			const struct i2c_device_id *id)
 {
 {
+	struct device *dev = &client->dev;
 	struct g760a_data *data;
 	struct g760a_data *data;
-	int err;
+	struct device *hwmon_dev;
 
 
-	if (!i2c_check_functionality(client->adapter,
-				     I2C_FUNC_SMBUS_BYTE_DATA))
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 		return -EIO;
 		return -EIO;
 
 
-	data = devm_kzalloc(&client->dev, sizeof(struct g760a_data),
-			    GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(struct g760a_data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	i2c_set_clientdata(client, data);
-
 	data->client = client;
 	data->client = client;
 	mutex_init(&data->update_lock);
 	mutex_init(&data->update_lock);
 
 
@@ -221,31 +195,25 @@ static int g760a_probe(struct i2c_client *client,
 	data->fan_div = G760A_DEFAULT_FAN_DIV;
 	data->fan_div = G760A_DEFAULT_FAN_DIV;
 	data->clk = G760A_DEFAULT_CLK;
 	data->clk = G760A_DEFAULT_CLK;
 
 
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&client->dev.kobj, &g760a_group);
-	if (err)
-		return err;
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto error_hwmon_device_register;
-	}
-
-	return 0;
-
-error_hwmon_device_register:
-	sysfs_remove_group(&client->dev.kobj, &g760a_group);
-	return err;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data,
+							   g760a_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
-static int g760a_remove(struct i2c_client *client)
-{
-	struct g760a_data *data = i2c_get_clientdata(client);
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &g760a_group);
-	return 0;
-}
+static const struct i2c_device_id g760a_id[] = {
+	{ "g760a", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, g760a_id);
+
+static struct i2c_driver g760a_driver = {
+	.driver = {
+		.name	= "g760a",
+	},
+	.probe	  = g760a_probe,
+	.id_table = g760a_id,
+};
 
 
 module_i2c_driver(g760a_driver);
 module_i2c_driver(g760a_driver);
 
 

+ 29 - 49
drivers/hwmon/g762.c

@@ -128,8 +128,8 @@ enum g762_regs {
 			 G762_REG_FAN_CMD2_GEAR_MODE_1)) >> 2))
 			 G762_REG_FAN_CMD2_GEAR_MODE_1)) >> 2))
 
 
 struct g762_data {
 struct g762_data {
-	struct i2c_client *client;
 	struct device *hwmon_dev;
 	struct device *hwmon_dev;
+	struct i2c_client *client;
 	struct clk *clk;
 	struct clk *clk;
 
 
 	/* update mutex */
 	/* update mutex */
@@ -206,8 +206,8 @@ static inline unsigned char cnt_from_rpm(u32 rpm, u32 clk_freq, u16 p,
 /* helper to grab and cache data, at most one time per second */
 /* helper to grab and cache data, at most one time per second */
 static struct g762_data *g762_update_client(struct device *dev)
 static struct g762_data *g762_update_client(struct device *dev)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct g762_data *data = i2c_get_clientdata(client);
+	struct g762_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int ret = 0;
 	int ret = 0;
 
 
 	mutex_lock(&data->update_lock);
 	mutex_lock(&data->update_lock);
@@ -266,8 +266,7 @@ static struct g762_data *g762_update_client(struct device *dev)
  */
  */
 static int do_set_clk_freq(struct device *dev, unsigned long val)
 static int do_set_clk_freq(struct device *dev, unsigned long val)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct g762_data *data = i2c_get_clientdata(client);
+	struct g762_data *data = dev_get_drvdata(dev);
 
 
 	if (val > 0xffffff)
 	if (val > 0xffffff)
 		return -EINVAL;
 		return -EINVAL;
@@ -282,7 +281,6 @@ static int do_set_clk_freq(struct device *dev, unsigned long val)
 /* Set pwm mode. Accepts either 0 (PWM mode) or 1 (DC mode) */
 /* Set pwm mode. Accepts either 0 (PWM mode) or 1 (DC mode) */
 static int do_set_pwm_mode(struct device *dev, unsigned long val)
 static int do_set_pwm_mode(struct device *dev, unsigned long val)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 	int ret;
 	int ret;
 
 
@@ -301,7 +299,7 @@ static int do_set_pwm_mode(struct device *dev, unsigned long val)
 		ret = -EINVAL;
 		ret = -EINVAL;
 		goto out;
 		goto out;
 	}
 	}
-	ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+	ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1,
 					data->fan_cmd1);
 					data->fan_cmd1);
 	data->valid = false;
 	data->valid = false;
  out:
  out:
@@ -313,7 +311,6 @@ static int do_set_pwm_mode(struct device *dev, unsigned long val)
 /* Set fan clock divisor. Accepts either 1, 2, 4 or 8. */
 /* Set fan clock divisor. Accepts either 1, 2, 4 or 8. */
 static int do_set_fan_div(struct device *dev, unsigned long val)
 static int do_set_fan_div(struct device *dev, unsigned long val)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 	int ret;
 	int ret;
 
 
@@ -342,7 +339,7 @@ static int do_set_fan_div(struct device *dev, unsigned long val)
 		ret = -EINVAL;
 		ret = -EINVAL;
 		goto out;
 		goto out;
 	}
 	}
-	ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+	ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1,
 					data->fan_cmd1);
 					data->fan_cmd1);
 	data->valid = false;
 	data->valid = false;
  out:
  out:
@@ -354,7 +351,6 @@ static int do_set_fan_div(struct device *dev, unsigned long val)
 /* Set fan gear mode. Accepts either 0, 1 or 2. */
 /* Set fan gear mode. Accepts either 0, 1 or 2. */
 static int do_set_fan_gear_mode(struct device *dev, unsigned long val)
 static int do_set_fan_gear_mode(struct device *dev, unsigned long val)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 	int ret;
 	int ret;
 
 
@@ -379,7 +375,7 @@ static int do_set_fan_gear_mode(struct device *dev, unsigned long val)
 		ret = -EINVAL;
 		ret = -EINVAL;
 		goto out;
 		goto out;
 	}
 	}
-	ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD2,
+	ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD2,
 					data->fan_cmd2);
 					data->fan_cmd2);
 	data->valid = false;
 	data->valid = false;
  out:
  out:
@@ -391,7 +387,6 @@ static int do_set_fan_gear_mode(struct device *dev, unsigned long val)
 /* Set number of fan pulses per revolution. Accepts either 2 or 4. */
 /* Set number of fan pulses per revolution. Accepts either 2 or 4. */
 static int do_set_fan_pulses(struct device *dev, unsigned long val)
 static int do_set_fan_pulses(struct device *dev, unsigned long val)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 	int ret;
 	int ret;
 
 
@@ -410,7 +405,7 @@ static int do_set_fan_pulses(struct device *dev, unsigned long val)
 		ret = -EINVAL;
 		ret = -EINVAL;
 		goto out;
 		goto out;
 	}
 	}
-	ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+	ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1,
 					data->fan_cmd1);
 					data->fan_cmd1);
 	data->valid = false;
 	data->valid = false;
  out:
  out:
@@ -422,7 +417,6 @@ static int do_set_fan_pulses(struct device *dev, unsigned long val)
 /* Set fan mode. Accepts either 1 (open-loop) or 2 (closed-loop). */
 /* Set fan mode. Accepts either 1 (open-loop) or 2 (closed-loop). */
 static int do_set_pwm_enable(struct device *dev, unsigned long val)
 static int do_set_pwm_enable(struct device *dev, unsigned long val)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 	int ret;
 	int ret;
 
 
@@ -444,15 +438,15 @@ static int do_set_pwm_enable(struct device *dev, unsigned long val)
 		 * value of 254 if it is 255 when switching to open-loop.
 		 * value of 254 if it is 255 when switching to open-loop.
 		 */
 		 */
 		if (data->set_cnt == 0xff)
 		if (data->set_cnt == 0xff)
-			i2c_smbus_write_byte_data(client, G762_REG_SET_CNT,
-						  254);
+			i2c_smbus_write_byte_data(data->client,
+						  G762_REG_SET_CNT, 254);
 		break;
 		break;
 	default:
 	default:
 		ret = -EINVAL;
 		ret = -EINVAL;
 		goto out;
 		goto out;
 	}
 	}
 
 
-	ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+	ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1,
 					data->fan_cmd1);
 					data->fan_cmd1);
 	data->valid = false;
 	data->valid = false;
  out:
  out:
@@ -464,7 +458,6 @@ static int do_set_pwm_enable(struct device *dev, unsigned long val)
 /* Set PWM polarity. Accepts either 0 (positive duty) or 1 (negative duty) */
 /* Set PWM polarity. Accepts either 0 (positive duty) or 1 (negative duty) */
 static int do_set_pwm_polarity(struct device *dev, unsigned long val)
 static int do_set_pwm_polarity(struct device *dev, unsigned long val)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 	int ret;
 	int ret;
 
 
@@ -483,7 +476,7 @@ static int do_set_pwm_polarity(struct device *dev, unsigned long val)
 		ret = -EINVAL;
 		ret = -EINVAL;
 		goto out;
 		goto out;
 	}
 	}
-	ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+	ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1,
 					data->fan_cmd1);
 					data->fan_cmd1);
 	data->valid = false;
 	data->valid = false;
  out:
  out:
@@ -498,8 +491,8 @@ static int do_set_pwm_polarity(struct device *dev, unsigned long val)
  */
  */
 static int do_set_pwm(struct device *dev, unsigned long val)
 static int do_set_pwm(struct device *dev, unsigned long val)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct g762_data *data = i2c_get_clientdata(client);
+	struct g762_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int ret;
 	int ret;
 
 
 	if (val > 255)
 	if (val > 255)
@@ -519,7 +512,6 @@ static int do_set_pwm(struct device *dev, unsigned long val)
  */
  */
 static int do_set_fan_target(struct device *dev, unsigned long val)
 static int do_set_fan_target(struct device *dev, unsigned long val)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 	int ret;
 	int ret;
 
 
@@ -531,7 +523,7 @@ static int do_set_fan_target(struct device *dev, unsigned long val)
 				     G762_PULSE_FROM_REG(data->fan_cmd1),
 				     G762_PULSE_FROM_REG(data->fan_cmd1),
 				     G762_CLKDIV_FROM_REG(data->fan_cmd1),
 				     G762_CLKDIV_FROM_REG(data->fan_cmd1),
 				     G762_GEARMULT_FROM_REG(data->fan_cmd2));
 				     G762_GEARMULT_FROM_REG(data->fan_cmd2));
-	ret = i2c_smbus_write_byte_data(client, G762_REG_SET_CNT,
+	ret = i2c_smbus_write_byte_data(data->client, G762_REG_SET_CNT,
 					data->set_cnt);
 					data->set_cnt);
 	data->valid = false;
 	data->valid = false;
 	mutex_unlock(&data->update_lock);
 	mutex_unlock(&data->update_lock);
@@ -542,7 +534,6 @@ static int do_set_fan_target(struct device *dev, unsigned long val)
 /* Set fan startup voltage. Accepted values are either 0, 1, 2 or 3. */
 /* Set fan startup voltage. Accepted values are either 0, 1, 2 or 3. */
 static int do_set_fan_startv(struct device *dev, unsigned long val)
 static int do_set_fan_startv(struct device *dev, unsigned long val)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 	int ret;
 	int ret;
 
 
@@ -571,7 +562,7 @@ static int do_set_fan_startv(struct device *dev, unsigned long val)
 		ret = -EINVAL;
 		ret = -EINVAL;
 		goto out;
 		goto out;
 	}
 	}
-	ret = i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD2,
+	ret = i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD2,
 					data->fan_cmd2);
 					data->fan_cmd2);
 	data->valid = false;
 	data->valid = false;
  out:
  out:
@@ -658,15 +649,12 @@ static int g762_of_prop_import_one(struct i2c_client *client,
 				   int (*psetter)(struct device *dev,
 				   int (*psetter)(struct device *dev,
 						  unsigned long val))
 						  unsigned long val))
 {
 {
-	const __be32 *prop;
-	int len, ret;
+	int ret;
 	u32 pval;
 	u32 pval;
 
 
-	prop = of_get_property(client->dev.of_node, pname, &len);
-	if (!prop || len != sizeof(u32))
+	if (of_property_read_u32(client->dev.of_node, pname, &pval))
 		return 0;
 		return 0;
 
 
-	pval = be32_to_cpu(prop[0]);
 	dev_dbg(&client->dev, "found %s (%d)\n", pname, pval);
 	dev_dbg(&client->dev, "found %s (%d)\n", pname, pval);
 	ret = (*psetter)(&client->dev, pval);
 	ret = (*psetter)(&client->dev, pval);
 	if (ret)
 	if (ret)
@@ -1026,7 +1014,7 @@ static DEVICE_ATTR(fan1_pulses, S_IWUSR | S_IRUGO,
 		   get_fan_pulses, set_fan_pulses);
 		   get_fan_pulses, set_fan_pulses);
 
 
 /* Driver data */
 /* Driver data */
-static struct attribute *g762_attributes[] = {
+static struct attribute *g762_attrs[] = {
 	&dev_attr_fan1_input.attr,
 	&dev_attr_fan1_input.attr,
 	&dev_attr_fan1_alarm.attr,
 	&dev_attr_fan1_alarm.attr,
 	&dev_attr_fan1_fault.attr,
 	&dev_attr_fan1_fault.attr,
@@ -1039,9 +1027,7 @@ static struct attribute *g762_attributes[] = {
 	NULL
 	NULL
 };
 };
 
 
-static const struct attribute_group g762_group = {
-	.attrs = g762_attributes,
-};
+ATTRIBUTE_GROUPS(g762);
 
 
 /*
 /*
  * Enable both fan failure detection and fan out of control protection. The
  * Enable both fan failure detection and fan out of control protection. The
@@ -1050,7 +1036,6 @@ static const struct attribute_group g762_group = {
  */
  */
 static inline int g762_fan_init(struct device *dev)
 static inline int g762_fan_init(struct device *dev)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 	struct g762_data *data = g762_update_client(dev);
 
 
 	if (IS_ERR(data))
 	if (IS_ERR(data))
@@ -1060,12 +1045,13 @@ static inline int g762_fan_init(struct device *dev)
 	data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_OOC;
 	data->fan_cmd1 |= G762_REG_FAN_CMD1_DET_FAN_OOC;
 	data->valid = false;
 	data->valid = false;
 
 
-	return i2c_smbus_write_byte_data(client, G762_REG_FAN_CMD1,
+	return i2c_smbus_write_byte_data(data->client, G762_REG_FAN_CMD1,
 					 data->fan_cmd1);
 					 data->fan_cmd1);
 }
 }
 
 
 static int g762_probe(struct i2c_client *client, const struct i2c_device_id *id)
 static int g762_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 {
+	struct device *dev = &client->dev;
 	struct g762_data *data;
 	struct g762_data *data;
 	int ret;
 	int ret;
 
 
@@ -1073,7 +1059,7 @@ static int g762_probe(struct i2c_client *client, const struct i2c_device_id *id)
 				     I2C_FUNC_SMBUS_BYTE_DATA))
 				     I2C_FUNC_SMBUS_BYTE_DATA))
 		return -ENODEV;
 		return -ENODEV;
 
 
-	data = devm_kzalloc(&client->dev, sizeof(struct g762_data), GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(struct g762_data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -1082,7 +1068,7 @@ static int g762_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	mutex_init(&data->update_lock);
 	mutex_init(&data->update_lock);
 
 
 	/* Enable fan failure detection and fan out of control protection */
 	/* Enable fan failure detection and fan out of control protection */
-	ret = g762_fan_init(&client->dev);
+	ret = g762_fan_init(dev);
 	if (ret)
 	if (ret)
 		return ret;
 		return ret;
 
 
@@ -1098,22 +1084,17 @@ static int g762_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	if (ret)
 	if (ret)
 		goto clock_dis;
 		goto clock_dis;
 
 
-	/* Register sysfs hooks */
-	ret = sysfs_create_group(&client->dev.kobj, &g762_group);
-	if (ret)
-		goto clock_dis;
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
+	data->hwmon_dev = devm_hwmon_device_register_with_groups(dev,
+								 client->name,
+								 data,
+								 g762_groups);
 	if (IS_ERR(data->hwmon_dev)) {
 	if (IS_ERR(data->hwmon_dev)) {
 		ret = PTR_ERR(data->hwmon_dev);
 		ret = PTR_ERR(data->hwmon_dev);
-		goto sysfs_rem;
+		goto clock_dis;
 	}
 	}
 
 
 	return 0;
 	return 0;
 
 
- sysfs_rem:
-	sysfs_remove_group(&client->dev.kobj, &g762_group);
-
  clock_dis:
  clock_dis:
 	g762_of_clock_disable(client);
 	g762_of_clock_disable(client);
 
 
@@ -1125,7 +1106,6 @@ static int g762_remove(struct i2c_client *client)
 	struct g762_data *data = i2c_get_clientdata(client);
 	struct g762_data *data = i2c_get_clientdata(client);
 
 
 	hwmon_device_unregister(data->hwmon_dev);
 	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &g762_group);
 	g762_of_clock_disable(client);
 	g762_of_clock_disable(client);
 
 
 	return 0;
 	return 0;

+ 141 - 178
drivers/hwmon/gl518sm.c

@@ -114,7 +114,8 @@ static inline u8 FAN_TO_REG(long rpm, int div)
 
 
 /* Each client has this additional data */
 /* Each client has this additional data */
 struct gl518_data {
 struct gl518_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
+	const struct attribute_group *groups[3];
 	enum chips type;
 	enum chips type;
 
 
 	struct mutex update_lock;
 	struct mutex update_lock;
@@ -137,33 +138,98 @@ struct gl518_data {
 	u8 beep_enable;		/* Boolean */
 	u8 beep_enable;		/* Boolean */
 };
 };
 
 
-static int gl518_probe(struct i2c_client *client,
-		       const struct i2c_device_id *id);
-static int gl518_detect(struct i2c_client *client, struct i2c_board_info *info);
-static void gl518_init_client(struct i2c_client *client);
-static int gl518_remove(struct i2c_client *client);
-static int gl518_read_value(struct i2c_client *client, u8 reg);
-static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value);
-static struct gl518_data *gl518_update_device(struct device *dev);
+/*
+ * Registers 0x07 to 0x0c are word-sized, others are byte-sized
+ * GL518 uses a high-byte first convention, which is exactly opposite to
+ * the SMBus standard.
+ */
+static int gl518_read_value(struct i2c_client *client, u8 reg)
+{
+	if ((reg >= 0x07) && (reg <= 0x0c))
+		return i2c_smbus_read_word_swapped(client, reg);
+	else
+		return i2c_smbus_read_byte_data(client, reg);
+}
 
 
-static const struct i2c_device_id gl518_id[] = {
-	{ "gl518sm", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, gl518_id);
+static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value)
+{
+	if ((reg >= 0x07) && (reg <= 0x0c))
+		return i2c_smbus_write_word_swapped(client, reg, value);
+	else
+		return i2c_smbus_write_byte_data(client, reg, value);
+}
 
 
-/* This is the driver that will be inserted */
-static struct i2c_driver gl518_driver = {
-	.class		= I2C_CLASS_HWMON,
-	.driver = {
-		.name	= "gl518sm",
-	},
-	.probe		= gl518_probe,
-	.remove		= gl518_remove,
-	.id_table	= gl518_id,
-	.detect		= gl518_detect,
-	.address_list	= normal_i2c,
-};
+static struct gl518_data *gl518_update_device(struct device *dev)
+{
+	struct gl518_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
+	int val;
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+		dev_dbg(&client->dev, "Starting gl518 update\n");
+
+		data->alarms = gl518_read_value(client, GL518_REG_INT);
+		data->beep_mask = gl518_read_value(client, GL518_REG_ALARM);
+
+		val = gl518_read_value(client, GL518_REG_VDD_LIMIT);
+		data->voltage_min[0] = val & 0xff;
+		data->voltage_max[0] = (val >> 8) & 0xff;
+		val = gl518_read_value(client, GL518_REG_VIN1_LIMIT);
+		data->voltage_min[1] = val & 0xff;
+		data->voltage_max[1] = (val >> 8) & 0xff;
+		val = gl518_read_value(client, GL518_REG_VIN2_LIMIT);
+		data->voltage_min[2] = val & 0xff;
+		data->voltage_max[2] = (val >> 8) & 0xff;
+		val = gl518_read_value(client, GL518_REG_VIN3_LIMIT);
+		data->voltage_min[3] = val & 0xff;
+		data->voltage_max[3] = (val >> 8) & 0xff;
+
+		val = gl518_read_value(client, GL518_REG_FAN_COUNT);
+		data->fan_in[0] = (val >> 8) & 0xff;
+		data->fan_in[1] = val & 0xff;
+
+		val = gl518_read_value(client, GL518_REG_FAN_LIMIT);
+		data->fan_min[0] = (val >> 8) & 0xff;
+		data->fan_min[1] = val & 0xff;
+
+		data->temp_in = gl518_read_value(client, GL518_REG_TEMP_IN);
+		data->temp_max =
+		    gl518_read_value(client, GL518_REG_TEMP_MAX);
+		data->temp_hyst =
+		    gl518_read_value(client, GL518_REG_TEMP_HYST);
+
+		val = gl518_read_value(client, GL518_REG_MISC);
+		data->fan_div[0] = (val >> 6) & 0x03;
+		data->fan_div[1] = (val >> 4) & 0x03;
+		data->fan_auto1  = (val >> 3) & 0x01;
+
+		data->alarms &= data->alarm_mask;
+
+		val = gl518_read_value(client, GL518_REG_CONF);
+		data->beep_enable = (val >> 2) & 1;
+
+		if (data->type != gl518sm_r00) {
+			data->voltage_in[0] =
+			    gl518_read_value(client, GL518_REG_VDD);
+			data->voltage_in[1] =
+			    gl518_read_value(client, GL518_REG_VIN1);
+			data->voltage_in[2] =
+			    gl518_read_value(client, GL518_REG_VIN2);
+		}
+		data->voltage_in[3] =
+		    gl518_read_value(client, GL518_REG_VIN3);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
 
 
 /*
 /*
  * Sysfs stuff
  * Sysfs stuff
@@ -228,8 +294,8 @@ static ssize_t set_##suffix(struct device *dev,				\
 			    struct device_attribute *attr,		\
 			    struct device_attribute *attr,		\
 			    const char *buf, size_t count)		\
 			    const char *buf, size_t count)		\
 {									\
 {									\
-	struct i2c_client *client = to_i2c_client(dev);			\
-	struct gl518_data *data = i2c_get_clientdata(client);		\
+	struct gl518_data *data = dev_get_drvdata(dev);			\
+	struct i2c_client *client = data->client;			\
 	long val;							\
 	long val;							\
 	int err = kstrtol(buf, 10, &val);				\
 	int err = kstrtol(buf, 10, &val);				\
 	if (err)							\
 	if (err)							\
@@ -247,8 +313,8 @@ static ssize_t set_##suffix(struct device *dev,				\
 			    struct device_attribute *attr,		\
 			    struct device_attribute *attr,		\
 			    const char *buf, size_t count)		\
 			    const char *buf, size_t count)		\
 {									\
 {									\
-	struct i2c_client *client = to_i2c_client(dev);			\
-	struct gl518_data *data = i2c_get_clientdata(client);		\
+	struct gl518_data *data = dev_get_drvdata(dev);			\
+	struct i2c_client *client = data->client;			\
 	int regvalue;							\
 	int regvalue;							\
 	unsigned long val;						\
 	unsigned long val;						\
 	int err = kstrtoul(buf, 10, &val);				\
 	int err = kstrtoul(buf, 10, &val);				\
@@ -286,8 +352,8 @@ set(BEEP_MASK, beep_mask, beep_mask, GL518_REG_ALARM);
 static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 			   const char *buf, size_t count)
 			   const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl518_data *data = i2c_get_clientdata(client);
+	struct gl518_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
 	int regvalue;
 	int regvalue;
 	unsigned long val;
 	unsigned long val;
@@ -319,8 +385,8 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 			   const char *buf, size_t count)
 			   const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl518_data *data = i2c_get_clientdata(client);
+	struct gl518_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
 	int regvalue;
 	int regvalue;
 	unsigned long val;
 	unsigned long val;
@@ -420,8 +486,8 @@ static ssize_t show_beep(struct device *dev, struct device_attribute *attr,
 static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
 static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
 			const char *buf, size_t count)
 			const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl518_data *data = i2c_get_clientdata(client);
+	struct gl518_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int bitnr = to_sensor_dev_attr(attr)->index;
 	int bitnr = to_sensor_dev_attr(attr)->index;
 	unsigned long bit;
 	unsigned long bit;
 	int err;
 	int err;
@@ -539,52 +605,6 @@ static int gl518_detect(struct i2c_client *client, struct i2c_board_info *info)
 	return 0;
 	return 0;
 }
 }
 
 
-static int gl518_probe(struct i2c_client *client,
-		       const struct i2c_device_id *id)
-{
-	struct gl518_data *data;
-	int err, revision;
-
-	data = devm_kzalloc(&client->dev, sizeof(struct gl518_data),
-			    GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	i2c_set_clientdata(client, data);
-	revision = gl518_read_value(client, GL518_REG_REVISION);
-	data->type = revision == 0x80 ? gl518sm_r80 : gl518sm_r00;
-	mutex_init(&data->update_lock);
-
-	/* Initialize the GL518SM chip */
-	data->alarm_mask = 0xff;
-	gl518_init_client(client);
-
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&client->dev.kobj, &gl518_group);
-	if (err)
-		return err;
-	if (data->type == gl518sm_r80) {
-		err = sysfs_create_group(&client->dev.kobj, &gl518_group_r80);
-		if (err)
-			goto exit_remove_files;
-	}
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove_files;
-	}
-
-	return 0;
-
-exit_remove_files:
-	sysfs_remove_group(&client->dev.kobj, &gl518_group);
-	if (data->type == gl518sm_r80)
-		sysfs_remove_group(&client->dev.kobj, &gl518_group_r80);
-	return err;
-}
-
-
 /*
 /*
  * Called when we have found a new GL518SM.
  * Called when we have found a new GL518SM.
  * Note that we preserve D4:NoFan2 and D2:beep_enable.
  * Note that we preserve D4:NoFan2 and D2:beep_enable.
@@ -605,110 +625,53 @@ static void gl518_init_client(struct i2c_client *client)
 	gl518_write_value(client, GL518_REG_CONF, 0x40 | regvalue);
 	gl518_write_value(client, GL518_REG_CONF, 0x40 | regvalue);
 }
 }
 
 
-static int gl518_remove(struct i2c_client *client)
-{
-	struct gl518_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &gl518_group);
-	if (data->type == gl518sm_r80)
-		sysfs_remove_group(&client->dev.kobj, &gl518_group_r80);
-
-	return 0;
-}
-
-/*
- * Registers 0x07 to 0x0c are word-sized, others are byte-sized
- * GL518 uses a high-byte first convention, which is exactly opposite to
- * the SMBus standard.
- */
-static int gl518_read_value(struct i2c_client *client, u8 reg)
-{
-	if ((reg >= 0x07) && (reg <= 0x0c))
-		return i2c_smbus_read_word_swapped(client, reg);
-	else
-		return i2c_smbus_read_byte_data(client, reg);
-}
-
-static int gl518_write_value(struct i2c_client *client, u8 reg, u16 value)
-{
-	if ((reg >= 0x07) && (reg <= 0x0c))
-		return i2c_smbus_write_word_swapped(client, reg, value);
-	else
-		return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-static struct gl518_data *gl518_update_device(struct device *dev)
+static int gl518_probe(struct i2c_client *client,
+		       const struct i2c_device_id *id)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl518_data *data = i2c_get_clientdata(client);
-	int val;
-
-	mutex_lock(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
-		dev_dbg(&client->dev, "Starting gl518 update\n");
-
-		data->alarms = gl518_read_value(client, GL518_REG_INT);
-		data->beep_mask = gl518_read_value(client, GL518_REG_ALARM);
-
-		val = gl518_read_value(client, GL518_REG_VDD_LIMIT);
-		data->voltage_min[0] = val & 0xff;
-		data->voltage_max[0] = (val >> 8) & 0xff;
-		val = gl518_read_value(client, GL518_REG_VIN1_LIMIT);
-		data->voltage_min[1] = val & 0xff;
-		data->voltage_max[1] = (val >> 8) & 0xff;
-		val = gl518_read_value(client, GL518_REG_VIN2_LIMIT);
-		data->voltage_min[2] = val & 0xff;
-		data->voltage_max[2] = (val >> 8) & 0xff;
-		val = gl518_read_value(client, GL518_REG_VIN3_LIMIT);
-		data->voltage_min[3] = val & 0xff;
-		data->voltage_max[3] = (val >> 8) & 0xff;
-
-		val = gl518_read_value(client, GL518_REG_FAN_COUNT);
-		data->fan_in[0] = (val >> 8) & 0xff;
-		data->fan_in[1] = val & 0xff;
-
-		val = gl518_read_value(client, GL518_REG_FAN_LIMIT);
-		data->fan_min[0] = (val >> 8) & 0xff;
-		data->fan_min[1] = val & 0xff;
-
-		data->temp_in = gl518_read_value(client, GL518_REG_TEMP_IN);
-		data->temp_max =
-		    gl518_read_value(client, GL518_REG_TEMP_MAX);
-		data->temp_hyst =
-		    gl518_read_value(client, GL518_REG_TEMP_HYST);
+	struct device *dev = &client->dev;
+	struct device *hwmon_dev;
+	struct gl518_data *data;
+	int revision;
 
 
-		val = gl518_read_value(client, GL518_REG_MISC);
-		data->fan_div[0] = (val >> 6) & 0x03;
-		data->fan_div[1] = (val >> 4) & 0x03;
-		data->fan_auto1  = (val >> 3) & 0x01;
+	data = devm_kzalloc(dev, sizeof(struct gl518_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
 
 
-		data->alarms &= data->alarm_mask;
+	data->client = client;
+	revision = gl518_read_value(client, GL518_REG_REVISION);
+	data->type = revision == 0x80 ? gl518sm_r80 : gl518sm_r00;
+	mutex_init(&data->update_lock);
 
 
-		val = gl518_read_value(client, GL518_REG_CONF);
-		data->beep_enable = (val >> 2) & 1;
+	/* Initialize the GL518SM chip */
+	data->alarm_mask = 0xff;
+	gl518_init_client(client);
 
 
-		if (data->type != gl518sm_r00) {
-			data->voltage_in[0] =
-			    gl518_read_value(client, GL518_REG_VDD);
-			data->voltage_in[1] =
-			    gl518_read_value(client, GL518_REG_VIN1);
-			data->voltage_in[2] =
-			    gl518_read_value(client, GL518_REG_VIN2);
-		}
-		data->voltage_in[3] =
-		    gl518_read_value(client, GL518_REG_VIN3);
+	/* sysfs hooks */
+	data->groups[0] = &gl518_group;
+	if (data->type == gl518sm_r80)
+		data->groups[1] = &gl518_group_r80;
 
 
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data, data->groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
 
 
-	mutex_unlock(&data->update_lock);
+static const struct i2c_device_id gl518_id[] = {
+	{ "gl518sm", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, gl518_id);
 
 
-	return data;
-}
+static struct i2c_driver gl518_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "gl518sm",
+	},
+	.probe		= gl518_probe,
+	.id_table	= gl518_id,
+	.detect		= gl518_detect,
+	.address_list	= normal_i2c,
+};
 
 
 module_i2c_driver(gl518_driver);
 module_i2c_driver(gl518_driver);
 
 

+ 155 - 198
drivers/hwmon/gl520sm.c

@@ -73,41 +73,10 @@ static const u8 GL520_REG_TEMP_MAX_HYST[]	= { 0x06, 0x18 };
 #define GL520_REG_BEEP_MASK		0x10
 #define GL520_REG_BEEP_MASK		0x10
 #define GL520_REG_BEEP_ENABLE		GL520_REG_CONF
 #define GL520_REG_BEEP_ENABLE		GL520_REG_CONF
 
 
-/*
- * Function declarations
- */
-
-static int gl520_probe(struct i2c_client *client,
-		       const struct i2c_device_id *id);
-static int gl520_detect(struct i2c_client *client, struct i2c_board_info *info);
-static void gl520_init_client(struct i2c_client *client);
-static int gl520_remove(struct i2c_client *client);
-static int gl520_read_value(struct i2c_client *client, u8 reg);
-static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value);
-static struct gl520_data *gl520_update_device(struct device *dev);
-
-/* Driver data */
-static const struct i2c_device_id gl520_id[] = {
-	{ "gl520sm", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, gl520_id);
-
-static struct i2c_driver gl520_driver = {
-	.class		= I2C_CLASS_HWMON,
-	.driver = {
-		.name	= "gl520sm",
-	},
-	.probe		= gl520_probe,
-	.remove		= gl520_remove,
-	.id_table	= gl520_id,
-	.detect		= gl520_detect,
-	.address_list	= normal_i2c,
-};
-
 /* Client data */
 /* Client data */
 struct gl520_data {
 struct gl520_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
+	const struct attribute_group *groups[3];
 	struct mutex update_lock;
 	struct mutex update_lock;
 	char valid;		/* zero until the following fields are valid */
 	char valid;		/* zero until the following fields are valid */
 	unsigned long last_updated;	/* in jiffies */
 	unsigned long last_updated;	/* in jiffies */
@@ -131,6 +100,102 @@ struct gl520_data {
 	u8 two_temps;
 	u8 two_temps;
 };
 };
 
 
+/*
+ * Registers 0x07 to 0x0c are word-sized, others are byte-sized
+ * GL520 uses a high-byte first convention
+ */
+static int gl520_read_value(struct i2c_client *client, u8 reg)
+{
+	if ((reg >= 0x07) && (reg <= 0x0c))
+		return i2c_smbus_read_word_swapped(client, reg);
+	else
+		return i2c_smbus_read_byte_data(client, reg);
+}
+
+static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value)
+{
+	if ((reg >= 0x07) && (reg <= 0x0c))
+		return i2c_smbus_write_word_swapped(client, reg, value);
+	else
+		return i2c_smbus_write_byte_data(client, reg, value);
+}
+
+static struct gl520_data *gl520_update_device(struct device *dev)
+{
+	struct gl520_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
+	int val, i;
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
+
+		dev_dbg(&client->dev, "Starting gl520sm update\n");
+
+		data->alarms = gl520_read_value(client, GL520_REG_ALARMS);
+		data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK);
+		data->vid = gl520_read_value(client,
+					     GL520_REG_VID_INPUT) & 0x1f;
+
+		for (i = 0; i < 4; i++) {
+			data->in_input[i] = gl520_read_value(client,
+							GL520_REG_IN_INPUT[i]);
+			val = gl520_read_value(client, GL520_REG_IN_LIMIT[i]);
+			data->in_min[i] = val & 0xff;
+			data->in_max[i] = (val >> 8) & 0xff;
+		}
+
+		val = gl520_read_value(client, GL520_REG_FAN_INPUT);
+		data->fan_input[0] = (val >> 8) & 0xff;
+		data->fan_input[1] = val & 0xff;
+
+		val = gl520_read_value(client, GL520_REG_FAN_MIN);
+		data->fan_min[0] = (val >> 8) & 0xff;
+		data->fan_min[1] = val & 0xff;
+
+		data->temp_input[0] = gl520_read_value(client,
+						GL520_REG_TEMP_INPUT[0]);
+		data->temp_max[0] = gl520_read_value(client,
+						GL520_REG_TEMP_MAX[0]);
+		data->temp_max_hyst[0] = gl520_read_value(client,
+						GL520_REG_TEMP_MAX_HYST[0]);
+
+		val = gl520_read_value(client, GL520_REG_FAN_DIV);
+		data->fan_div[0] = (val >> 6) & 0x03;
+		data->fan_div[1] = (val >> 4) & 0x03;
+		data->fan_off = (val >> 2) & 0x01;
+
+		data->alarms &= data->alarm_mask;
+
+		val = gl520_read_value(client, GL520_REG_CONF);
+		data->beep_enable = !((val >> 2) & 1);
+
+		/* Temp1 and Vin4 are the same input */
+		if (data->two_temps) {
+			data->temp_input[1] = gl520_read_value(client,
+						GL520_REG_TEMP_INPUT[1]);
+			data->temp_max[1] = gl520_read_value(client,
+						GL520_REG_TEMP_MAX[1]);
+			data->temp_max_hyst[1] = gl520_read_value(client,
+						GL520_REG_TEMP_MAX_HYST[1]);
+		} else {
+			data->in_input[4] = gl520_read_value(client,
+						GL520_REG_IN_INPUT[4]);
+			data->in_min[4] = gl520_read_value(client,
+						GL520_REG_IN_MIN[4]);
+			data->in_max[4] = gl520_read_value(client,
+						GL520_REG_IN_MAX[4]);
+		}
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
 /*
 /*
  * Sysfs stuff
  * Sysfs stuff
  */
  */
@@ -191,8 +256,8 @@ static ssize_t get_in_max(struct device *dev, struct device_attribute *attr,
 static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
 static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
 			  const char *buf, size_t count)
 			  const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl520_data *data = i2c_get_clientdata(client);
+	struct gl520_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int n = to_sensor_dev_attr(attr)->index;
 	int n = to_sensor_dev_attr(attr)->index;
 	u8 r;
 	u8 r;
 	long v;
 	long v;
@@ -225,8 +290,8 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
 static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
 static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
 			  const char *buf, size_t count)
 			  const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl520_data *data = i2c_get_clientdata(client);
+	struct gl520_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int n = to_sensor_dev_attr(attr)->index;
 	int n = to_sensor_dev_attr(attr)->index;
 	u8 r;
 	u8 r;
 	long v;
 	long v;
@@ -326,8 +391,8 @@ static ssize_t get_fan_off(struct device *dev, struct device_attribute *attr,
 static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 			   const char *buf, size_t count)
 			   const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl520_data *data = i2c_get_clientdata(client);
+	struct gl520_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int n = to_sensor_dev_attr(attr)->index;
 	int n = to_sensor_dev_attr(attr)->index;
 	u8 r;
 	u8 r;
 	unsigned long v;
 	unsigned long v;
@@ -365,8 +430,8 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 			   const char *buf, size_t count)
 			   const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl520_data *data = i2c_get_clientdata(client);
+	struct gl520_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int n = to_sensor_dev_attr(attr)->index;
 	int n = to_sensor_dev_attr(attr)->index;
 	u8 r;
 	u8 r;
 	unsigned long v;
 	unsigned long v;
@@ -414,8 +479,8 @@ static ssize_t set_fan_div(struct device *dev, struct device_attribute *attr,
 static ssize_t set_fan_off(struct device *dev, struct device_attribute *attr,
 static ssize_t set_fan_off(struct device *dev, struct device_attribute *attr,
 			   const char *buf, size_t count)
 			   const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl520_data *data = i2c_get_clientdata(client);
+	struct gl520_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 r;
 	u8 r;
 	unsigned long v;
 	unsigned long v;
 	int err;
 	int err;
@@ -482,8 +547,8 @@ static ssize_t get_temp_max_hyst(struct device *dev,
 static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 			    const char *buf, size_t count)
 			    const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl520_data *data = i2c_get_clientdata(client);
+	struct gl520_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int n = to_sensor_dev_attr(attr)->index;
 	int n = to_sensor_dev_attr(attr)->index;
 	long v;
 	long v;
 	int err;
 	int err;
@@ -502,8 +567,8 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 static ssize_t set_temp_max_hyst(struct device *dev, struct device_attribute
 static ssize_t set_temp_max_hyst(struct device *dev, struct device_attribute
 				 *attr, const char *buf, size_t count)
 				 *attr, const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl520_data *data = i2c_get_clientdata(client);
+	struct gl520_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int n = to_sensor_dev_attr(attr)->index;
 	int n = to_sensor_dev_attr(attr)->index;
 	long v;
 	long v;
 	int err;
 	int err;
@@ -555,8 +620,8 @@ static ssize_t get_beep_mask(struct device *dev, struct device_attribute *attr,
 static ssize_t set_beep_enable(struct device *dev, struct device_attribute
 static ssize_t set_beep_enable(struct device *dev, struct device_attribute
 			       *attr, const char *buf, size_t count)
 			       *attr, const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl520_data *data = i2c_get_clientdata(client);
+	struct gl520_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 r;
 	u8 r;
 	unsigned long v;
 	unsigned long v;
 	int err;
 	int err;
@@ -579,8 +644,8 @@ static ssize_t set_beep_enable(struct device *dev, struct device_attribute
 static ssize_t set_beep_mask(struct device *dev, struct device_attribute *attr,
 static ssize_t set_beep_mask(struct device *dev, struct device_attribute *attr,
 			     const char *buf, size_t count)
 			     const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl520_data *data = i2c_get_clientdata(client);
+	struct gl520_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long r;
 	unsigned long r;
 	int err;
 	int err;
 
 
@@ -633,8 +698,8 @@ static ssize_t get_beep(struct device *dev, struct device_attribute *attr,
 static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
 static ssize_t set_beep(struct device *dev, struct device_attribute *attr,
 			const char *buf, size_t count)
 			const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl520_data *data = i2c_get_clientdata(client);
+	struct gl520_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int bitnr = to_sensor_dev_attr(attr)->index;
 	int bitnr = to_sensor_dev_attr(attr)->index;
 	unsigned long bit;
 	unsigned long bit;
 
 
@@ -772,52 +837,6 @@ static int gl520_detect(struct i2c_client *client, struct i2c_board_info *info)
 	return 0;
 	return 0;
 }
 }
 
 
-static int gl520_probe(struct i2c_client *client,
-		       const struct i2c_device_id *id)
-{
-	struct gl520_data *data;
-	int err;
-
-	data = devm_kzalloc(&client->dev, sizeof(struct gl520_data),
-			    GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	i2c_set_clientdata(client, data);
-	mutex_init(&data->update_lock);
-
-	/* Initialize the GL520SM chip */
-	gl520_init_client(client);
-
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&client->dev.kobj, &gl520_group);
-	if (err)
-		return err;
-
-	if (data->two_temps)
-		err = sysfs_create_group(&client->dev.kobj, &gl520_group_temp2);
-	else
-		err = sysfs_create_group(&client->dev.kobj, &gl520_group_in4);
-
-	if (err)
-		goto exit_remove_files;
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove_files;
-	}
-
-	return 0;
-
-exit_remove_files:
-	sysfs_remove_group(&client->dev.kobj, &gl520_group);
-	sysfs_remove_group(&client->dev.kobj, &gl520_group_in4);
-	sysfs_remove_group(&client->dev.kobj, &gl520_group_temp2);
-	return err;
-}
-
-
 /* Called when we have found a new GL520SM. */
 /* Called when we have found a new GL520SM. */
 static void gl520_init_client(struct i2c_client *client)
 static void gl520_init_client(struct i2c_client *client)
 {
 {
@@ -856,115 +875,53 @@ static void gl520_init_client(struct i2c_client *client)
 	gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask);
 	gl520_write_value(client, GL520_REG_BEEP_MASK, data->beep_mask);
 }
 }
 
 
-static int gl520_remove(struct i2c_client *client)
+static int gl520_probe(struct i2c_client *client,
+		       const struct i2c_device_id *id)
 {
 {
-	struct gl520_data *data = i2c_get_clientdata(client);
+	struct device *dev = &client->dev;
+	struct device *hwmon_dev;
+	struct gl520_data *data;
 
 
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &gl520_group);
-	sysfs_remove_group(&client->dev.kobj, &gl520_group_in4);
-	sysfs_remove_group(&client->dev.kobj, &gl520_group_temp2);
+	data = devm_kzalloc(dev, sizeof(struct gl520_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
 
 
-	return 0;
-}
+	i2c_set_clientdata(client, data);
+	mutex_init(&data->update_lock);
+	data->client = client;
 
 
+	/* Initialize the GL520SM chip */
+	gl520_init_client(client);
 
 
-/*
- * Registers 0x07 to 0x0c are word-sized, others are byte-sized
- * GL520 uses a high-byte first convention
- */
-static int gl520_read_value(struct i2c_client *client, u8 reg)
-{
-	if ((reg >= 0x07) && (reg <= 0x0c))
-		return i2c_smbus_read_word_swapped(client, reg);
-	else
-		return i2c_smbus_read_byte_data(client, reg);
-}
+	/* sysfs hooks */
+	data->groups[0] = &gl520_group;
 
 
-static int gl520_write_value(struct i2c_client *client, u8 reg, u16 value)
-{
-	if ((reg >= 0x07) && (reg <= 0x0c))
-		return i2c_smbus_write_word_swapped(client, reg, value);
+	if (data->two_temps)
+		data->groups[1] = &gl520_group_temp2;
 	else
 	else
-		return i2c_smbus_write_byte_data(client, reg, value);
-}
-
-
-static struct gl520_data *gl520_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct gl520_data *data = i2c_get_clientdata(client);
-	int val, i;
-
-	mutex_lock(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
-
-		dev_dbg(&client->dev, "Starting gl520sm update\n");
-
-		data->alarms = gl520_read_value(client, GL520_REG_ALARMS);
-		data->beep_mask = gl520_read_value(client, GL520_REG_BEEP_MASK);
-		data->vid = gl520_read_value(client,
-					     GL520_REG_VID_INPUT) & 0x1f;
-
-		for (i = 0; i < 4; i++) {
-			data->in_input[i] = gl520_read_value(client,
-							GL520_REG_IN_INPUT[i]);
-			val = gl520_read_value(client, GL520_REG_IN_LIMIT[i]);
-			data->in_min[i] = val & 0xff;
-			data->in_max[i] = (val >> 8) & 0xff;
-		}
-
-		val = gl520_read_value(client, GL520_REG_FAN_INPUT);
-		data->fan_input[0] = (val >> 8) & 0xff;
-		data->fan_input[1] = val & 0xff;
+		data->groups[1] = &gl520_group_in4;
 
 
-		val = gl520_read_value(client, GL520_REG_FAN_MIN);
-		data->fan_min[0] = (val >> 8) & 0xff;
-		data->fan_min[1] = val & 0xff;
-
-		data->temp_input[0] = gl520_read_value(client,
-						GL520_REG_TEMP_INPUT[0]);
-		data->temp_max[0] = gl520_read_value(client,
-						GL520_REG_TEMP_MAX[0]);
-		data->temp_max_hyst[0] = gl520_read_value(client,
-						GL520_REG_TEMP_MAX_HYST[0]);
-
-		val = gl520_read_value(client, GL520_REG_FAN_DIV);
-		data->fan_div[0] = (val >> 6) & 0x03;
-		data->fan_div[1] = (val >> 4) & 0x03;
-		data->fan_off = (val >> 2) & 0x01;
-
-		data->alarms &= data->alarm_mask;
-
-		val = gl520_read_value(client, GL520_REG_CONF);
-		data->beep_enable = !((val >> 2) & 1);
-
-		/* Temp1 and Vin4 are the same input */
-		if (data->two_temps) {
-			data->temp_input[1] = gl520_read_value(client,
-						GL520_REG_TEMP_INPUT[1]);
-			data->temp_max[1] = gl520_read_value(client,
-						GL520_REG_TEMP_MAX[1]);
-			data->temp_max_hyst[1] = gl520_read_value(client,
-						GL520_REG_TEMP_MAX_HYST[1]);
-		} else {
-			data->in_input[4] = gl520_read_value(client,
-						GL520_REG_IN_INPUT[4]);
-			data->in_min[4] = gl520_read_value(client,
-						GL520_REG_IN_MIN[4]);
-			data->in_max[4] = gl520_read_value(client,
-						GL520_REG_IN_MAX[4]);
-		}
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data, data->groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
 
 
-	mutex_unlock(&data->update_lock);
+static const struct i2c_device_id gl520_id[] = {
+	{ "gl520sm", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, gl520_id);
 
 
-	return data;
-}
+static struct i2c_driver gl520_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "gl520sm",
+	},
+	.probe		= gl520_probe,
+	.id_table	= gl520_id,
+	.detect		= gl520_detect,
+	.address_list	= normal_i2c,
+};
 
 
 module_i2c_driver(gl520_driver);
 module_i2c_driver(gl520_driver);
 
 

+ 5 - 14
drivers/hwmon/gpio-fan.c

@@ -173,7 +173,7 @@ static int get_fan_speed_index(struct gpio_fan_data *fan_data)
 	return -ENODEV;
 	return -ENODEV;
 }
 }
 
 
-static int rpm_to_speed_index(struct gpio_fan_data *fan_data, int rpm)
+static int rpm_to_speed_index(struct gpio_fan_data *fan_data, unsigned long rpm)
 {
 {
 	struct gpio_fan_speed *speed = fan_data->speed;
 	struct gpio_fan_speed *speed = fan_data->speed;
 	int i;
 	int i;
@@ -537,9 +537,10 @@ static int gpio_fan_probe(struct platform_device *pdev)
 	}
 	}
 
 
 	/* Make this driver part of hwmon class. */
 	/* Make this driver part of hwmon class. */
-	fan_data->hwmon_dev = hwmon_device_register_with_groups(&pdev->dev,
-						"gpio_fan", fan_data,
-						gpio_fan_groups);
+	fan_data->hwmon_dev =
+		devm_hwmon_device_register_with_groups(&pdev->dev,
+						       "gpio_fan", fan_data,
+						       gpio_fan_groups);
 	if (IS_ERR(fan_data->hwmon_dev))
 	if (IS_ERR(fan_data->hwmon_dev))
 		return PTR_ERR(fan_data->hwmon_dev);
 		return PTR_ERR(fan_data->hwmon_dev);
 
 
@@ -548,15 +549,6 @@ static int gpio_fan_probe(struct platform_device *pdev)
 	return 0;
 	return 0;
 }
 }
 
 
-static int gpio_fan_remove(struct platform_device *pdev)
-{
-	struct gpio_fan_data *fan_data = platform_get_drvdata(pdev);
-
-	hwmon_device_unregister(fan_data->hwmon_dev);
-
-	return 0;
-}
-
 #ifdef CONFIG_PM_SLEEP
 #ifdef CONFIG_PM_SLEEP
 static int gpio_fan_suspend(struct device *dev)
 static int gpio_fan_suspend(struct device *dev)
 {
 {
@@ -588,7 +580,6 @@ static SIMPLE_DEV_PM_OPS(gpio_fan_pm, gpio_fan_suspend, gpio_fan_resume);
 
 
 static struct platform_driver gpio_fan_driver = {
 static struct platform_driver gpio_fan_driver = {
 	.probe		= gpio_fan_probe,
 	.probe		= gpio_fan_probe,
-	.remove		= gpio_fan_remove,
 	.driver	= {
 	.driver	= {
 		.name	= "gpio-fan",
 		.name	= "gpio-fan",
 		.pm	= GPIO_FAN_PM,
 		.pm	= GPIO_FAN_PM,

+ 23 - 65
drivers/hwmon/hih6130.c

@@ -46,7 +46,7 @@
  * @write_length: length for I2C measurement request
  * @write_length: length for I2C measurement request
  */
  */
 struct hih6130 {
 struct hih6130 {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
 	struct mutex lock;
 	struct mutex lock;
 	bool valid;
 	bool valid;
 	unsigned long last_update;
 	unsigned long last_update;
@@ -62,7 +62,6 @@ struct hih6130 {
  */
  */
 static inline int hih6130_temp_ticks_to_millicelsius(int ticks)
 static inline int hih6130_temp_ticks_to_millicelsius(int ticks)
 {
 {
-
 	ticks = ticks >> 2;
 	ticks = ticks >> 2;
 	/*
 	/*
 	 * from data sheet section 5.0
 	 * from data sheet section 5.0
@@ -78,7 +77,6 @@ static inline int hih6130_temp_ticks_to_millicelsius(int ticks)
  */
  */
 static inline int hih6130_rh_ticks_to_per_cent_mille(int ticks)
 static inline int hih6130_rh_ticks_to_per_cent_mille(int ticks)
 {
 {
-
 	ticks &= ~0xC000; /* clear status bits */
 	ticks &= ~0xC000; /* clear status bits */
 	/*
 	/*
 	 * from data sheet section 4.0
 	 * from data sheet section 4.0
@@ -89,15 +87,16 @@ static inline int hih6130_rh_ticks_to_per_cent_mille(int ticks)
 
 
 /**
 /**
  * hih6130_update_measurements() - get updated measurements from device
  * hih6130_update_measurements() - get updated measurements from device
- * @client: I2C client device
+ * @dev: device
  *
  *
  * Returns 0 on success, else negative errno.
  * Returns 0 on success, else negative errno.
  */
  */
-static int hih6130_update_measurements(struct i2c_client *client)
+static int hih6130_update_measurements(struct device *dev)
 {
 {
+	struct hih6130 *hih6130 = dev_get_drvdata(dev);
+	struct i2c_client *client = hih6130->client;
 	int ret = 0;
 	int ret = 0;
 	int t;
 	int t;
-	struct hih6130 *hih6130 = i2c_get_clientdata(client);
 	unsigned char tmp[4];
 	unsigned char tmp[4];
 	struct i2c_msg msgs[1] = {
 	struct i2c_msg msgs[1] = {
 		{
 		{
@@ -176,9 +175,10 @@ static ssize_t hih6130_show_temperature(struct device *dev,
 					struct device_attribute *attr,
 					struct device_attribute *attr,
 					char *buf)
 					char *buf)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct hih6130 *hih6130 = i2c_get_clientdata(client);
-	int ret = hih6130_update_measurements(client);
+	struct hih6130 *hih6130 = dev_get_drvdata(dev);
+	int ret;
+
+	ret = hih6130_update_measurements(dev);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 	return sprintf(buf, "%d\n", hih6130->temperature);
 	return sprintf(buf, "%d\n", hih6130->temperature);
@@ -196,9 +196,10 @@ static ssize_t hih6130_show_temperature(struct device *dev,
 static ssize_t hih6130_show_humidity(struct device *dev,
 static ssize_t hih6130_show_humidity(struct device *dev,
 				     struct device_attribute *attr, char *buf)
 				     struct device_attribute *attr, char *buf)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct hih6130 *hih6130 = i2c_get_clientdata(client);
-	int ret = hih6130_update_measurements(client);
+	struct hih6130 *hih6130 = dev_get_drvdata(dev);
+	int ret;
+
+	ret = hih6130_update_measurements(dev);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 	return sprintf(buf, "%d\n", hih6130->humidity);
 	return sprintf(buf, "%d\n", hih6130->humidity);
@@ -210,79 +211,37 @@ static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, hih6130_show_temperature,
 static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO, hih6130_show_humidity,
 static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO, hih6130_show_humidity,
 	NULL, 0);
 	NULL, 0);
 
 
-static struct attribute *hih6130_attributes[] = {
+static struct attribute *hih6130_attrs[] = {
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_humidity1_input.dev_attr.attr,
 	&sensor_dev_attr_humidity1_input.dev_attr.attr,
 	NULL
 	NULL
 };
 };
 
 
-static const struct attribute_group hih6130_attr_group = {
-	.attrs = hih6130_attributes,
-};
+ATTRIBUTE_GROUPS(hih6130);
 
 
-/**
- * hih6130_probe() - probe device
- * @client: I2C client device
- * @id: device ID
- *
- * Called by the I2C core when an entry in the ID table matches a
- * device's name.
- * Returns 0 on success.
- */
 static int hih6130_probe(struct i2c_client *client,
 static int hih6130_probe(struct i2c_client *client,
 				   const struct i2c_device_id *id)
 				   const struct i2c_device_id *id)
 {
 {
+	struct device *dev = &client->dev;
 	struct hih6130 *hih6130;
 	struct hih6130 *hih6130;
-	int err;
+	struct device *hwmon_dev;
 
 
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
 	if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C)) {
 		dev_err(&client->dev, "adapter does not support true I2C\n");
 		dev_err(&client->dev, "adapter does not support true I2C\n");
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 
 
-	hih6130 = devm_kzalloc(&client->dev, sizeof(*hih6130), GFP_KERNEL);
+	hih6130 = devm_kzalloc(dev, sizeof(*hih6130), GFP_KERNEL);
 	if (!hih6130)
 	if (!hih6130)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	i2c_set_clientdata(client, hih6130);
-
+	hih6130->client = client;
 	mutex_init(&hih6130->lock);
 	mutex_init(&hih6130->lock);
 
 
-	err = sysfs_create_group(&client->dev.kobj, &hih6130_attr_group);
-	if (err) {
-		dev_dbg(&client->dev, "could not create sysfs files\n");
-		return err;
-	}
-
-	hih6130->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(hih6130->hwmon_dev)) {
-		dev_dbg(&client->dev, "unable to register hwmon device\n");
-		err = PTR_ERR(hih6130->hwmon_dev);
-		goto fail_remove_sysfs;
-	}
-
-	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_QUICK))
-		hih6130->write_length = 1;
-
-	return 0;
-
-fail_remove_sysfs:
-	sysfs_remove_group(&client->dev.kobj, &hih6130_attr_group);
-	return err;
-}
-
-/**
- * hih6130_remove() - remove device
- * @client: I2C client device
- */
-static int hih6130_remove(struct i2c_client *client)
-{
-	struct hih6130 *hih6130 = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(hih6130->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &hih6130_attr_group);
-
-	return 0;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   hih6130,
+							   hih6130_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
 /* Device ID table */
 /* Device ID table */
@@ -295,7 +254,6 @@ MODULE_DEVICE_TABLE(i2c, hih6130_id);
 static struct i2c_driver hih6130_driver = {
 static struct i2c_driver hih6130_driver = {
 	.driver.name = "hih6130",
 	.driver.name = "hih6130",
 	.probe       = hih6130_probe,
 	.probe       = hih6130_probe,
-	.remove      = hih6130_remove,
 	.id_table    = hih6130_id,
 	.id_table    = hih6130_id,
 };
 };
 
 

+ 22 - 47
drivers/hwmon/htu21.c

@@ -31,7 +31,7 @@
 #define HTU21_RH_MEASUREMENT_HM	0xE5
 #define HTU21_RH_MEASUREMENT_HM	0xE5
 
 
 struct htu21 {
 struct htu21 {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
 	struct mutex lock;
 	struct mutex lock;
 	bool valid;
 	bool valid;
 	unsigned long last_update;
 	unsigned long last_update;
@@ -59,10 +59,11 @@ static inline int htu21_rh_ticks_to_per_cent_mille(int ticks)
 	return ((15625 * ticks) >> 13) - 6000;
 	return ((15625 * ticks) >> 13) - 6000;
 }
 }
 
 
-static int htu21_update_measurements(struct i2c_client *client)
+static int htu21_update_measurements(struct device *dev)
 {
 {
+	struct htu21 *htu21 = dev_get_drvdata(dev);
+	struct i2c_client *client = htu21->client;
 	int ret = 0;
 	int ret = 0;
-	struct htu21 *htu21 = i2c_get_clientdata(client);
 
 
 	mutex_lock(&htu21->lock);
 	mutex_lock(&htu21->lock);
 
 
@@ -90,9 +91,10 @@ out:
 static ssize_t htu21_show_temperature(struct device *dev,
 static ssize_t htu21_show_temperature(struct device *dev,
 				      struct device_attribute *attr, char *buf)
 				      struct device_attribute *attr, char *buf)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct htu21 *htu21 = i2c_get_clientdata(client);
-	int ret = htu21_update_measurements(client);
+	struct htu21 *htu21 = dev_get_drvdata(dev);
+	int ret;
+
+	ret = htu21_update_measurements(dev);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 	return sprintf(buf, "%d\n", htu21->temperature);
 	return sprintf(buf, "%d\n", htu21->temperature);
@@ -101,9 +103,10 @@ static ssize_t htu21_show_temperature(struct device *dev,
 static ssize_t htu21_show_humidity(struct device *dev,
 static ssize_t htu21_show_humidity(struct device *dev,
 				   struct device_attribute *attr, char *buf)
 				   struct device_attribute *attr, char *buf)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct htu21 *htu21 = i2c_get_clientdata(client);
-	int ret = htu21_update_measurements(client);
+	struct htu21 *htu21 = dev_get_drvdata(dev);
+	int ret;
+
+	ret = htu21_update_measurements(dev);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 	return sprintf(buf, "%d\n", htu21->humidity);
 	return sprintf(buf, "%d\n", htu21->humidity);
@@ -114,21 +117,20 @@ static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO,
 static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO,
 static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO,
 			  htu21_show_humidity, NULL, 0);
 			  htu21_show_humidity, NULL, 0);
 
 
-static struct attribute *htu21_attributes[] = {
+static struct attribute *htu21_attrs[] = {
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_humidity1_input.dev_attr.attr,
 	&sensor_dev_attr_humidity1_input.dev_attr.attr,
 	NULL
 	NULL
 };
 };
 
 
-static const struct attribute_group htu21_group = {
-	.attrs = htu21_attributes,
-};
+ATTRIBUTE_GROUPS(htu21);
 
 
 static int htu21_probe(struct i2c_client *client,
 static int htu21_probe(struct i2c_client *client,
 		       const struct i2c_device_id *id)
 		       const struct i2c_device_id *id)
 {
 {
+	struct device *dev = &client->dev;
 	struct htu21 *htu21;
 	struct htu21 *htu21;
-	int err;
+	struct device *hwmon_dev;
 
 
 	if (!i2c_check_functionality(client->adapter,
 	if (!i2c_check_functionality(client->adapter,
 				     I2C_FUNC_SMBUS_READ_WORD_DATA)) {
 				     I2C_FUNC_SMBUS_READ_WORD_DATA)) {
@@ -137,43 +139,17 @@ static int htu21_probe(struct i2c_client *client,
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 
 
-	htu21 = devm_kzalloc(&client->dev, sizeof(*htu21), GFP_KERNEL);
+	htu21 = devm_kzalloc(dev, sizeof(*htu21), GFP_KERNEL);
 	if (!htu21)
 	if (!htu21)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	i2c_set_clientdata(client, htu21);
-
+	htu21->client = client;
 	mutex_init(&htu21->lock);
 	mutex_init(&htu21->lock);
 
 
-	err = sysfs_create_group(&client->dev.kobj, &htu21_group);
-	if (err) {
-		dev_dbg(&client->dev, "could not create sysfs files\n");
-		return err;
-	}
-	htu21->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(htu21->hwmon_dev)) {
-		dev_dbg(&client->dev, "unable to register hwmon device\n");
-		err = PTR_ERR(htu21->hwmon_dev);
-		goto error;
-	}
-
-	dev_info(&client->dev, "initialized\n");
-
-	return 0;
-
-error:
-	sysfs_remove_group(&client->dev.kobj, &htu21_group);
-	return err;
-}
-
-static int htu21_remove(struct i2c_client *client)
-{
-	struct htu21 *htu21 = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(htu21->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &htu21_group);
-
-	return 0;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   htu21,
+							   htu21_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
 static const struct i2c_device_id htu21_id[] = {
 static const struct i2c_device_id htu21_id[] = {
@@ -188,7 +164,6 @@ static struct i2c_driver htu21_driver = {
 		.name	= "htu21",
 		.name	= "htu21",
 	},
 	},
 	.probe       = htu21_probe,
 	.probe       = htu21_probe,
-	.remove      = htu21_remove,
 	.id_table    = htu21_id,
 	.id_table    = htu21_id,
 };
 };
 
 

+ 363 - 0
drivers/hwmon/ibmpowernv.c

@@ -0,0 +1,363 @@
+/*
+ * IBM PowerNV platform sensors for temperature/fan/voltage/power
+ * Copyright (C) 2014 IBM
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ * You should have received a copy of the GNU General Public License
+ * along with this program.
+ */
+
+#define DRVNAME		"ibmpowernv"
+#define pr_fmt(fmt)	DRVNAME ": " fmt
+
+#include <linux/init.h>
+#include <linux/module.h>
+#include <linux/kernel.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/of.h>
+#include <linux/slab.h>
+
+#include <linux/platform_device.h>
+#include <asm/opal.h>
+#include <linux/err.h>
+
+#define MAX_ATTR_LEN	32
+
+/* Sensor suffix name from DT */
+#define DT_FAULT_ATTR_SUFFIX		"faulted"
+#define DT_DATA_ATTR_SUFFIX		"data"
+#define DT_THRESHOLD_ATTR_SUFFIX	"thrs"
+
+/*
+ * Enumerates all the types of sensors in the POWERNV platform and does index
+ * into 'struct sensor_group'
+ */
+enum sensors {
+	FAN,
+	AMBIENT_TEMP,
+	POWER_SUPPLY,
+	POWER_INPUT,
+	MAX_SENSOR_TYPE,
+};
+
+static struct sensor_group {
+	const char *name;
+	const char *compatible;
+	struct attribute_group group;
+	u32 attr_count;
+} sensor_groups[] = {
+	{"fan", "ibm,opal-sensor-cooling-fan"},
+	{"temp", "ibm,opal-sensor-amb-temp"},
+	{"in", "ibm,opal-sensor-power-supply"},
+	{"power", "ibm,opal-sensor-power"}
+};
+
+struct sensor_data {
+	u32 id; /* An opaque id of the firmware for each sensor */
+	enum sensors type;
+	char name[MAX_ATTR_LEN];
+	struct device_attribute dev_attr;
+};
+
+struct platform_data {
+	const struct attribute_group *attr_groups[MAX_SENSOR_TYPE + 1];
+	u32 sensors_count; /* Total count of sensors from each group */
+};
+
+/* Platform device representing all the ibmpowernv sensors */
+static struct platform_device *pdevice;
+
+static ssize_t show_sensor(struct device *dev, struct device_attribute *devattr,
+			   char *buf)
+{
+	struct sensor_data *sdata = container_of(devattr, struct sensor_data,
+						 dev_attr);
+	ssize_t ret;
+	u32 x;
+
+	ret = opal_get_sensor_data(sdata->id, &x);
+	if (ret)
+		return ret;
+
+	/* Convert temperature to milli-degrees */
+	if (sdata->type == AMBIENT_TEMP)
+		x *= 1000;
+	/* Convert power to micro-watts */
+	else if (sdata->type == POWER_INPUT)
+		x *= 1000000;
+
+	return sprintf(buf, "%u\n", x);
+}
+
+static int __init get_sensor_index_attr(const char *name, u32 *index,
+					char *attr)
+{
+	char *hash_pos = strchr(name, '#');
+	char buf[8] = { 0 };
+	char *dash_pos;
+	u32 copy_len;
+	int err;
+
+	if (!hash_pos)
+		return -EINVAL;
+
+	dash_pos = strchr(hash_pos, '-');
+	if (!dash_pos)
+		return -EINVAL;
+
+	copy_len = dash_pos - hash_pos - 1;
+	if (copy_len >= sizeof(buf))
+		return -EINVAL;
+
+	strncpy(buf, hash_pos + 1, copy_len);
+
+	err = kstrtou32(buf, 10, index);
+	if (err)
+		return err;
+
+	strncpy(attr, dash_pos + 1, MAX_ATTR_LEN);
+
+	return 0;
+}
+
+/*
+ * This function translates the DT node name into the 'hwmon' attribute name.
+ * IBMPOWERNV device node appear like cooling-fan#2-data, amb-temp#1-thrs etc.
+ * which need to be mapped as fan2_input, temp1_max respectively before
+ * populating them inside hwmon device class.
+ */
+static int __init create_hwmon_attr_name(struct device *dev, enum sensors type,
+					 const char *node_name,
+					 char *hwmon_attr_name)
+{
+	char attr_suffix[MAX_ATTR_LEN];
+	char *attr_name;
+	u32 index;
+	int err;
+
+	err = get_sensor_index_attr(node_name, &index, attr_suffix);
+	if (err) {
+		dev_err(dev, "Sensor device node name '%s' is invalid\n",
+			node_name);
+		return err;
+	}
+
+	if (!strcmp(attr_suffix, DT_FAULT_ATTR_SUFFIX)) {
+		attr_name = "fault";
+	} else if (!strcmp(attr_suffix, DT_DATA_ATTR_SUFFIX)) {
+		attr_name = "input";
+	} else if (!strcmp(attr_suffix, DT_THRESHOLD_ATTR_SUFFIX)) {
+		if (type == AMBIENT_TEMP)
+			attr_name = "max";
+		else if (type == FAN)
+			attr_name = "min";
+		else
+			return -ENOENT;
+	} else {
+		return -ENOENT;
+	}
+
+	snprintf(hwmon_attr_name, MAX_ATTR_LEN, "%s%d_%s",
+		 sensor_groups[type].name, index, attr_name);
+	return 0;
+}
+
+static int __init populate_attr_groups(struct platform_device *pdev)
+{
+	struct platform_data *pdata = platform_get_drvdata(pdev);
+	const struct attribute_group **pgroups = pdata->attr_groups;
+	struct device_node *opal, *np;
+	enum sensors type;
+
+	opal = of_find_node_by_path("/ibm,opal/sensors");
+	if (!opal) {
+		dev_err(&pdev->dev, "Opal node 'sensors' not found\n");
+		return -ENODEV;
+	}
+
+	for_each_child_of_node(opal, np) {
+		if (np->name == NULL)
+			continue;
+
+		for (type = 0; type < MAX_SENSOR_TYPE; type++)
+			if (of_device_is_compatible(np,
+					sensor_groups[type].compatible)) {
+				sensor_groups[type].attr_count++;
+				break;
+			}
+	}
+
+	of_node_put(opal);
+
+	for (type = 0; type < MAX_SENSOR_TYPE; type++) {
+		sensor_groups[type].group.attrs = devm_kzalloc(&pdev->dev,
+					sizeof(struct attribute *) *
+					(sensor_groups[type].attr_count + 1),
+					GFP_KERNEL);
+		if (!sensor_groups[type].group.attrs)
+			return -ENOMEM;
+
+		pgroups[type] = &sensor_groups[type].group;
+		pdata->sensors_count += sensor_groups[type].attr_count;
+		sensor_groups[type].attr_count = 0;
+	}
+
+	return 0;
+}
+
+/*
+ * Iterate through the device tree for each child of 'sensors' node, create
+ * a sysfs attribute file, the file is named by translating the DT node name
+ * to the name required by the higher 'hwmon' driver like fan1_input, temp1_max
+ * etc..
+ */
+static int __init create_device_attrs(struct platform_device *pdev)
+{
+	struct platform_data *pdata = platform_get_drvdata(pdev);
+	const struct attribute_group **pgroups = pdata->attr_groups;
+	struct device_node *opal, *np;
+	struct sensor_data *sdata;
+	u32 sensor_id;
+	enum sensors type;
+	u32 count = 0;
+	int err = 0;
+
+	opal = of_find_node_by_path("/ibm,opal/sensors");
+	sdata = devm_kzalloc(&pdev->dev, pdata->sensors_count * sizeof(*sdata),
+			     GFP_KERNEL);
+	if (!sdata) {
+		err = -ENOMEM;
+		goto exit_put_node;
+	}
+
+	for_each_child_of_node(opal, np) {
+		if (np->name == NULL)
+			continue;
+
+		for (type = 0; type < MAX_SENSOR_TYPE; type++)
+			if (of_device_is_compatible(np,
+					sensor_groups[type].compatible))
+				break;
+
+		if (type == MAX_SENSOR_TYPE)
+			continue;
+
+		if (of_property_read_u32(np, "sensor-id", &sensor_id)) {
+			dev_info(&pdev->dev,
+				 "'sensor-id' missing in the node '%s'\n",
+				 np->name);
+			continue;
+		}
+
+		sdata[count].id = sensor_id;
+		sdata[count].type = type;
+		err = create_hwmon_attr_name(&pdev->dev, type, np->name,
+					     sdata[count].name);
+		if (err)
+			goto exit_put_node;
+
+		sysfs_attr_init(&sdata[count].dev_attr.attr);
+		sdata[count].dev_attr.attr.name = sdata[count].name;
+		sdata[count].dev_attr.attr.mode = S_IRUGO;
+		sdata[count].dev_attr.show = show_sensor;
+
+		pgroups[type]->attrs[sensor_groups[type].attr_count++] =
+				&sdata[count++].dev_attr.attr;
+	}
+
+exit_put_node:
+	of_node_put(opal);
+	return err;
+}
+
+static int __init ibmpowernv_probe(struct platform_device *pdev)
+{
+	struct platform_data *pdata;
+	struct device *hwmon_dev;
+	int err;
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata)
+		return -ENOMEM;
+
+	platform_set_drvdata(pdev, pdata);
+	pdata->sensors_count = 0;
+	err = populate_attr_groups(pdev);
+	if (err)
+		return err;
+
+	/* Create sysfs attribute data for each sensor found in the DT */
+	err = create_device_attrs(pdev);
+	if (err)
+		return err;
+
+	/* Finally, register with hwmon */
+	hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, DRVNAME,
+							   pdata,
+							   pdata->attr_groups);
+
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static struct platform_driver ibmpowernv_driver = {
+	.driver = {
+		.owner = THIS_MODULE,
+		.name = DRVNAME,
+	},
+};
+
+static int __init ibmpowernv_init(void)
+{
+	int err;
+
+	pdevice = platform_device_alloc(DRVNAME, 0);
+	if (!pdevice) {
+		pr_err("Device allocation failed\n");
+		err = -ENOMEM;
+		goto exit;
+	}
+
+	err = platform_device_add(pdevice);
+	if (err) {
+		pr_err("Device addition failed (%d)\n", err);
+		goto exit_device_put;
+	}
+
+	err = platform_driver_probe(&ibmpowernv_driver, ibmpowernv_probe);
+	if (err) {
+		pr_err("Platfrom driver probe failed\n");
+		goto exit_device_del;
+	}
+
+	return 0;
+
+exit_device_del:
+	platform_device_del(pdevice);
+exit_device_put:
+	platform_device_put(pdevice);
+exit:
+	return err;
+}
+
+static void __exit ibmpowernv_exit(void)
+{
+	platform_driver_unregister(&ibmpowernv_driver);
+	platform_device_unregister(pdevice);
+}
+
+MODULE_AUTHOR("Neelesh Gupta <neelegup@linux.vnet.ibm.com>");
+MODULE_DESCRIPTION("IBM POWERNV platform sensors");
+MODULE_LICENSE("GPL");
+
+module_init(ibmpowernv_init);
+module_exit(ibmpowernv_exit);

+ 19 - 47
drivers/hwmon/lineage-pem.c

@@ -125,7 +125,8 @@
 #define FAN_SPEED_LEN		5
 #define FAN_SPEED_LEN		5
 
 
 struct pem_data {
 struct pem_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
+	const struct attribute_group *groups[4];
 
 
 	struct mutex update_lock;
 	struct mutex update_lock;
 	bool valid;
 	bool valid;
@@ -160,8 +161,8 @@ abort:
 
 
 static struct pem_data *pem_update_device(struct device *dev)
 static struct pem_data *pem_update_device(struct device *dev)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct pem_data *data = i2c_get_clientdata(client);
+	struct pem_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	struct pem_data *ret = data;
 	struct pem_data *ret = data;
 
 
 	mutex_lock(&data->update_lock);
 	mutex_lock(&data->update_lock);
@@ -444,18 +445,20 @@ static int pem_probe(struct i2c_client *client,
 		     const struct i2c_device_id *id)
 		     const struct i2c_device_id *id)
 {
 {
 	struct i2c_adapter *adapter = client->adapter;
 	struct i2c_adapter *adapter = client->adapter;
+	struct device *dev = &client->dev;
+	struct device *hwmon_dev;
 	struct pem_data *data;
 	struct pem_data *data;
-	int ret;
+	int ret, idx = 0;
 
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BLOCK_DATA
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BLOCK_DATA
 				     | I2C_FUNC_SMBUS_WRITE_BYTE))
 				     | I2C_FUNC_SMBUS_WRITE_BYTE))
 		return -ENODEV;
 		return -ENODEV;
 
 
-	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(*data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	i2c_set_clientdata(client, data);
+	data->client = client;
 	mutex_init(&data->update_lock);
 	mutex_init(&data->update_lock);
 
 
 	/*
 	/*
@@ -471,14 +474,12 @@ static int pem_probe(struct i2c_client *client,
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
-	dev_info(&client->dev, "Firmware revision %d.%d.%d\n",
+	dev_info(dev, "Firmware revision %d.%d.%d\n",
 		 data->firmware_rev[0], data->firmware_rev[1],
 		 data->firmware_rev[0], data->firmware_rev[1],
 		 data->firmware_rev[2]);
 		 data->firmware_rev[2]);
 
 
-	/* Register sysfs hooks */
-	ret = sysfs_create_group(&client->dev.kobj, &pem_group);
-	if (ret)
-		return ret;
+	/* sysfs hooks */
+	data->groups[idx++] = &pem_group;
 
 
 	/*
 	/*
 	 * Check if input readings are supported.
 	 * Check if input readings are supported.
@@ -501,12 +502,9 @@ static int pem_probe(struct i2c_client *client,
 			    data->input_string[2] || data->input_string[3]))
 			    data->input_string[2] || data->input_string[3]))
 			data->input_length = sizeof(data->input_string);
 			data->input_length = sizeof(data->input_string);
 	}
 	}
-	ret = 0;
-	if (data->input_length) {
-		ret = sysfs_create_group(&client->dev.kobj, &pem_input_group);
-		if (ret)
-			goto out_remove_groups;
-	}
+
+	if (data->input_length)
+		data->groups[idx++] = &pem_input_group;
 
 
 	/*
 	/*
 	 * Check if fan speed readings are supported.
 	 * Check if fan speed readings are supported.
@@ -520,37 +518,12 @@ static int pem_probe(struct i2c_client *client,
 	if (!ret && (data->fan_speed[0] || data->fan_speed[1] ||
 	if (!ret && (data->fan_speed[0] || data->fan_speed[1] ||
 		     data->fan_speed[2] || data->fan_speed[3])) {
 		     data->fan_speed[2] || data->fan_speed[3])) {
 		data->fans_supported = true;
 		data->fans_supported = true;
-		ret = sysfs_create_group(&client->dev.kobj, &pem_fan_group);
-		if (ret)
-			goto out_remove_groups;
-	}
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		ret = PTR_ERR(data->hwmon_dev);
-		goto out_remove_groups;
+		data->groups[idx++] = &pem_fan_group;
 	}
 	}
 
 
-	return 0;
-
-out_remove_groups:
-	sysfs_remove_group(&client->dev.kobj, &pem_input_group);
-	sysfs_remove_group(&client->dev.kobj, &pem_fan_group);
-	sysfs_remove_group(&client->dev.kobj, &pem_group);
-	return ret;
-}
-
-static int pem_remove(struct i2c_client *client)
-{
-	struct pem_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-
-	sysfs_remove_group(&client->dev.kobj, &pem_input_group);
-	sysfs_remove_group(&client->dev.kobj, &pem_fan_group);
-	sysfs_remove_group(&client->dev.kobj, &pem_group);
-
-	return 0;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data, data->groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
 static const struct i2c_device_id pem_id[] = {
 static const struct i2c_device_id pem_id[] = {
@@ -564,7 +537,6 @@ static struct i2c_driver pem_driver = {
 		   .name = "lineage_pem",
 		   .name = "lineage_pem",
 		   },
 		   },
 	.probe = pem_probe,
 	.probe = pem_probe,
-	.remove = pem_remove,
 	.id_table = pem_id,
 	.id_table = pem_id,
 };
 };
 
 

+ 10 - 17
drivers/hwmon/lm63.c

@@ -126,24 +126,17 @@ static const unsigned short normal_i2c[] = { 0x18, 0x4c, 0x4e, I2C_CLIENT_END };
 #define FAN_TO_REG(val)		((val) <= 82 ? 0xFFFC : \
 #define FAN_TO_REG(val)		((val) <= 82 ? 0xFFFC : \
 				 (5400000 / (val)) & 0xFFFC)
 				 (5400000 / (val)) & 0xFFFC)
 #define TEMP8_FROM_REG(reg)	((reg) * 1000)
 #define TEMP8_FROM_REG(reg)	((reg) * 1000)
-#define TEMP8_TO_REG(val)	((val) <= -128000 ? -128 : \
-				 (val) >= 127000 ? 127 : \
-				 (val) < 0 ? ((val) - 500) / 1000 : \
-				 ((val) + 500) / 1000)
-#define TEMP8U_TO_REG(val)	((val) <= 0 ? 0 : \
-				 (val) >= 255000 ? 255 : \
-				 ((val) + 500) / 1000)
+#define TEMP8_TO_REG(val)	DIV_ROUND_CLOSEST(clamp_val((val), -128000, \
+							    127000), 1000)
+#define TEMP8U_TO_REG(val)	DIV_ROUND_CLOSEST(clamp_val((val), 0, \
+							    255000), 1000)
 #define TEMP11_FROM_REG(reg)	((reg) / 32 * 125)
 #define TEMP11_FROM_REG(reg)	((reg) / 32 * 125)
-#define TEMP11_TO_REG(val)	((val) <= -128000 ? 0x8000 : \
-				 (val) >= 127875 ? 0x7FE0 : \
-				 (val) < 0 ? ((val) - 62) / 125 * 32 : \
-				 ((val) + 62) / 125 * 32)
-#define TEMP11U_TO_REG(val)	((val) <= 0 ? 0 : \
-				 (val) >= 255875 ? 0xFFE0 : \
-				 ((val) + 62) / 125 * 32)
-#define HYST_TO_REG(val)	((val) <= 0 ? 0 : \
-				 (val) >= 127000 ? 127 : \
-				 ((val) + 500) / 1000)
+#define TEMP11_TO_REG(val)	(DIV_ROUND_CLOSEST(clamp_val((val), -128000, \
+							     127875), 125) * 32)
+#define TEMP11U_TO_REG(val)	(DIV_ROUND_CLOSEST(clamp_val((val), 0, \
+							     255875), 125) * 32)
+#define HYST_TO_REG(val)	DIV_ROUND_CLOSEST(clamp_val((val), 0, 127000), \
+						  1000)
 
 
 #define UPDATE_INTERVAL(max, rate) \
 #define UPDATE_INTERVAL(max, rate) \
 			((1000 << (LM63_MAX_CONVRATE - (rate))) / (max))
 			((1000 << (LM63_MAX_CONVRATE - (rate))) / (max))

+ 8 - 0
drivers/hwmon/lm75.c

@@ -52,6 +52,7 @@ enum lm75_type {		/* keep sorted in alphabetical order */
 	tmp100,
 	tmp100,
 	tmp101,
 	tmp101,
 	tmp105,
 	tmp105,
+	tmp112,
 	tmp175,
 	tmp175,
 	tmp275,
 	tmp275,
 	tmp75,
 	tmp75,
@@ -255,6 +256,12 @@ lm75_probe(struct i2c_client *client, const struct i2c_device_id *id)
 		data->sample_time = HZ;
 		data->sample_time = HZ;
 		clr_mask |= 1 << 7;		/* not one-shot mode */
 		clr_mask |= 1 << 7;		/* not one-shot mode */
 		break;
 		break;
+	case tmp112:
+		set_mask |= 3 << 5;		/* 12-bit mode */
+		clr_mask |= 1 << 7;		/* not one-shot mode */
+		data->resolution = 12;
+		data->sample_time = HZ / 4;
+		break;
 	case tmp105:
 	case tmp105:
 	case tmp175:
 	case tmp175:
 	case tmp275:
 	case tmp275:
@@ -323,6 +330,7 @@ static const struct i2c_device_id lm75_ids[] = {
 	{ "tmp100", tmp100, },
 	{ "tmp100", tmp100, },
 	{ "tmp101", tmp101, },
 	{ "tmp101", tmp101, },
 	{ "tmp105", tmp105, },
 	{ "tmp105", tmp105, },
+	{ "tmp112", tmp112, },
 	{ "tmp175", tmp175, },
 	{ "tmp175", tmp175, },
 	{ "tmp275", tmp275, },
 	{ "tmp275", tmp275, },
 	{ "tmp75", tmp75, },
 	{ "tmp75", tmp75, },

+ 6 - 5
drivers/hwmon/lm77.c

@@ -80,8 +80,7 @@ struct lm77_data {
  */
  */
 static inline s16 LM77_TEMP_TO_REG(int temp)
 static inline s16 LM77_TEMP_TO_REG(int temp)
 {
 {
-	int ntemp = clamp_val(temp, LM77_TEMP_MIN, LM77_TEMP_MAX);
-	return (ntemp / 500) * 8;
+	return (temp / 500) * 8;
 }
 }
 
 
 static inline int LM77_TEMP_FROM_REG(s16 reg)
 static inline int LM77_TEMP_FROM_REG(s16 reg)
@@ -175,6 +174,7 @@ static ssize_t set_temp(struct device *dev, struct device_attribute *devattr,
 	if (err)
 	if (err)
 		return err;
 		return err;
 
 
+	val = clamp_val(val, LM77_TEMP_MIN, LM77_TEMP_MAX);
 	mutex_lock(&data->update_lock);
 	mutex_lock(&data->update_lock);
 	data->temp[nr] = val;
 	data->temp[nr] = val;
 	lm77_write_value(client, temp_regs[nr], LM77_TEMP_TO_REG(val));
 	lm77_write_value(client, temp_regs[nr], LM77_TEMP_TO_REG(val));
@@ -192,15 +192,16 @@ static ssize_t set_temp_hyst(struct device *dev,
 {
 {
 	struct lm77_data *data = dev_get_drvdata(dev);
 	struct lm77_data *data = dev_get_drvdata(dev);
 	struct i2c_client *client = data->client;
 	struct i2c_client *client = data->client;
-	unsigned long val;
+	long val;
 	int err;
 	int err;
 
 
-	err = kstrtoul(buf, 10, &val);
+	err = kstrtol(buf, 10, &val);
 	if (err)
 	if (err)
 		return err;
 		return err;
 
 
 	mutex_lock(&data->update_lock);
 	mutex_lock(&data->update_lock);
-	data->temp[t_hyst] = data->temp[t_crit] - val;
+	val = clamp_val(data->temp[t_crit] - val, LM77_TEMP_MIN, LM77_TEMP_MAX);
+	data->temp[t_hyst] = val;
 	lm77_write_value(client, LM77_REG_TEMP_HYST,
 	lm77_write_value(client, LM77_REG_TEMP_HYST,
 			 LM77_TEMP_TO_REG(data->temp[t_hyst]));
 			 LM77_TEMP_TO_REG(data->temp[t_hyst]));
 	mutex_unlock(&data->update_lock);
 	mutex_unlock(&data->update_lock);

+ 16 - 84
drivers/hwmon/lm78.c

@@ -108,7 +108,7 @@ static inline int FAN_FROM_REG(u8 val, int div)
  * TEMP: mC (-128C to +127C)
  * TEMP: mC (-128C to +127C)
  * REG: 1C/bit, two's complement
  * REG: 1C/bit, two's complement
  */
  */
-static inline s8 TEMP_TO_REG(int val)
+static inline s8 TEMP_TO_REG(long val)
 {
 {
 	int nval = clamp_val(val, -128000, 127000) ;
 	int nval = clamp_val(val, -128000, 127000) ;
 	return nval < 0 ? (nval - 500) / 1000 : (nval + 500) / 1000;
 	return nval < 0 ? (nval - 500) / 1000 : (nval + 500) / 1000;
@@ -123,7 +123,6 @@ static inline int TEMP_FROM_REG(s8 val)
 
 
 struct lm78_data {
 struct lm78_data {
 	struct i2c_client *client;
 	struct i2c_client *client;
-	struct device *hwmon_dev;
 	struct mutex lock;
 	struct mutex lock;
 	enum chips type;
 	enum chips type;
 
 
@@ -468,7 +467,7 @@ static SENSOR_DEVICE_ATTR(fan2_alarm, S_IRUGO, show_alarm, NULL, 7);
 static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11);
 static SENSOR_DEVICE_ATTR(fan3_alarm, S_IRUGO, show_alarm, NULL, 11);
 static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);
 static SENSOR_DEVICE_ATTR(temp1_alarm, S_IRUGO, show_alarm, NULL, 4);
 
 
-static struct attribute *lm78_attributes[] = {
+static struct attribute *lm78_attrs[] = {
 	&sensor_dev_attr_in0_input.dev_attr.attr,
 	&sensor_dev_attr_in0_input.dev_attr.attr,
 	&sensor_dev_attr_in0_min.dev_attr.attr,
 	&sensor_dev_attr_in0_min.dev_attr.attr,
 	&sensor_dev_attr_in0_max.dev_attr.attr,
 	&sensor_dev_attr_in0_max.dev_attr.attr,
@@ -519,9 +518,7 @@ static struct attribute *lm78_attributes[] = {
 	NULL
 	NULL
 };
 };
 
 
-static const struct attribute_group lm78_group = {
-	.attrs = lm78_attributes,
-};
+ATTRIBUTE_GROUPS(lm78);
 
 
 /*
 /*
  * ISA related code
  * ISA related code
@@ -533,19 +530,6 @@ static struct platform_device *pdev;
 
 
 static unsigned short isa_address = 0x290;
 static unsigned short isa_address = 0x290;
 
 
-/*
- * I2C devices get this name attribute automatically, but for ISA devices
- * we must create it by ourselves.
- */
-static ssize_t show_name(struct device *dev, struct device_attribute
-			 *devattr, char *buf)
-{
-	struct lm78_data *data = dev_get_drvdata(dev);
-
-	return sprintf(buf, "%s\n", data->name);
-}
-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
-
 static struct lm78_data *lm78_data_if_isa(void)
 static struct lm78_data *lm78_data_if_isa(void)
 {
 {
 	return pdev ? platform_get_drvdata(pdev) : NULL;
 	return pdev ? platform_get_drvdata(pdev) : NULL;
@@ -661,46 +645,23 @@ static int lm78_i2c_detect(struct i2c_client *client,
 static int lm78_i2c_probe(struct i2c_client *client,
 static int lm78_i2c_probe(struct i2c_client *client,
 			  const struct i2c_device_id *id)
 			  const struct i2c_device_id *id)
 {
 {
+	struct device *dev = &client->dev;
+	struct device *hwmon_dev;
 	struct lm78_data *data;
 	struct lm78_data *data;
-	int err;
 
 
-	data = devm_kzalloc(&client->dev, sizeof(struct lm78_data), GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(struct lm78_data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	i2c_set_clientdata(client, data);
 	data->client = client;
 	data->client = client;
 	data->type = id->driver_data;
 	data->type = id->driver_data;
 
 
 	/* Initialize the LM78 chip */
 	/* Initialize the LM78 chip */
 	lm78_init_device(data);
 	lm78_init_device(data);
 
 
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&client->dev.kobj, &lm78_group);
-	if (err)
-		return err;
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto error;
-	}
-
-	return 0;
-
-error:
-	sysfs_remove_group(&client->dev.kobj, &lm78_group);
-	return err;
-}
-
-static int lm78_i2c_remove(struct i2c_client *client)
-{
-	struct lm78_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &lm78_group);
-
-	return 0;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data, lm78_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
 static const struct i2c_device_id lm78_i2c_id[] = {
 static const struct i2c_device_id lm78_i2c_id[] = {
@@ -716,7 +677,6 @@ static struct i2c_driver lm78_driver = {
 		.name	= "lm78",
 		.name	= "lm78",
 	},
 	},
 	.probe		= lm78_i2c_probe,
 	.probe		= lm78_i2c_probe,
-	.remove		= lm78_i2c_remove,
 	.id_table	= lm78_i2c_id,
 	.id_table	= lm78_i2c_id,
 	.detect		= lm78_i2c_detect,
 	.detect		= lm78_i2c_detect,
 	.address_list	= normal_i2c,
 	.address_list	= normal_i2c,
@@ -839,17 +799,18 @@ static struct lm78_data *lm78_update_device(struct device *dev)
 #ifdef CONFIG_ISA
 #ifdef CONFIG_ISA
 static int lm78_isa_probe(struct platform_device *pdev)
 static int lm78_isa_probe(struct platform_device *pdev)
 {
 {
-	int err;
+	struct device *dev = &pdev->dev;
+	struct device *hwmon_dev;
 	struct lm78_data *data;
 	struct lm78_data *data;
 	struct resource *res;
 	struct resource *res;
 
 
 	/* Reserve the ISA region */
 	/* Reserve the ISA region */
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	if (!devm_request_region(&pdev->dev, res->start + LM78_ADDR_REG_OFFSET,
+	if (!devm_request_region(dev, res->start + LM78_ADDR_REG_OFFSET,
 				 2, "lm78"))
 				 2, "lm78"))
 		return -EBUSY;
 		return -EBUSY;
 
 
-	data = devm_kzalloc(&pdev->dev, sizeof(struct lm78_data), GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(struct lm78_data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
@@ -868,37 +829,9 @@ static int lm78_isa_probe(struct platform_device *pdev)
 	/* Initialize the LM78 chip */
 	/* Initialize the LM78 chip */
 	lm78_init_device(data);
 	lm78_init_device(data);
 
 
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&pdev->dev.kobj, &lm78_group);
-	if (err)
-		goto exit_remove_files;
-	err = device_create_file(&pdev->dev, &dev_attr_name);
-	if (err)
-		goto exit_remove_files;
-
-	data->hwmon_dev = hwmon_device_register(&pdev->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove_files;
-	}
-
-	return 0;
-
- exit_remove_files:
-	sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
-	device_remove_file(&pdev->dev, &dev_attr_name);
-	return err;
-}
-
-static int lm78_isa_remove(struct platform_device *pdev)
-{
-	struct lm78_data *data = platform_get_drvdata(pdev);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&pdev->dev.kobj, &lm78_group);
-	device_remove_file(&pdev->dev, &dev_attr_name);
-
-	return 0;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, data->name,
+							   data, lm78_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
 static struct platform_driver lm78_isa_driver = {
 static struct platform_driver lm78_isa_driver = {
@@ -907,7 +840,6 @@ static struct platform_driver lm78_isa_driver = {
 		.name	= "lm78",
 		.name	= "lm78",
 	},
 	},
 	.probe		= lm78_isa_probe,
 	.probe		= lm78_isa_probe,
-	.remove		= lm78_isa_remove,
 };
 };
 
 
 /* return 1 if a supported chip is found, 0 otherwise */
 /* return 1 if a supported chip is found, 0 otherwise */

+ 304 - 356
drivers/hwmon/lm85.c

@@ -121,7 +121,6 @@ enum chips {
 #define EMC6D102_REG_EXTEND_ADC3	0x87
 #define EMC6D102_REG_EXTEND_ADC3	0x87
 #define EMC6D102_REG_EXTEND_ADC4	0x88
 #define EMC6D102_REG_EXTEND_ADC4	0x88
 
 
-
 /*
 /*
  * Conversions. Rounding and limit checking is only done on the TO_REG
  * Conversions. Rounding and limit checking is only done on the TO_REG
  * variants. Note that you should be a bit careful with which arguments
  * variants. Note that you should be a bit careful with which arguments
@@ -155,7 +154,7 @@ static inline u16 FAN_TO_REG(unsigned long val)
 
 
 /* Temperature is reported in .001 degC increments */
 /* Temperature is reported in .001 degC increments */
 #define TEMP_TO_REG(val)	\
 #define TEMP_TO_REG(val)	\
-		clamp_val(SCALE(val, 1000, 1), -127, 127)
+		DIV_ROUND_CLOSEST(clamp_val((val), -127000, 127000), 1000)
 #define TEMPEXT_FROM_REG(val, ext)	\
 #define TEMPEXT_FROM_REG(val, ext)	\
 		SCALE(((val) << 4) + (ext), 16, 1000)
 		SCALE(((val) << 4) + (ext), 16, 1000)
 #define TEMP_FROM_REG(val)	((val) * 1000)
 #define TEMP_FROM_REG(val)	((val) * 1000)
@@ -189,7 +188,7 @@ static const int lm85_range_map[] = {
 	13300, 16000, 20000, 26600, 32000, 40000, 53300, 80000
 	13300, 16000, 20000, 26600, 32000, 40000, 53300, 80000
 };
 };
 
 
-static int RANGE_TO_REG(int range)
+static int RANGE_TO_REG(long range)
 {
 {
 	int i;
 	int i;
 
 
@@ -211,7 +210,7 @@ static const int adm1027_freq_map[8] = { /* 1 Hz */
 	11, 15, 22, 29, 35, 44, 59, 88
 	11, 15, 22, 29, 35, 44, 59, 88
 };
 };
 
 
-static int FREQ_TO_REG(const int *map, int freq)
+static int FREQ_TO_REG(const int *map, unsigned long freq)
 {
 {
 	int i;
 	int i;
 
 
@@ -303,7 +302,8 @@ struct lm85_autofan {
  * The structure is dynamically allocated.
  * The structure is dynamically allocated.
  */
  */
 struct lm85_data {
 struct lm85_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
+	const struct attribute_group *groups[6];
 	const int *freq_map;
 	const int *freq_map;
 	enum chips type;
 	enum chips type;
 
 
@@ -334,44 +334,235 @@ struct lm85_data {
 	struct lm85_zone zone[3];
 	struct lm85_zone zone[3];
 };
 };
 
 
-static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info);
-static int lm85_probe(struct i2c_client *client,
-		      const struct i2c_device_id *id);
-static int lm85_remove(struct i2c_client *client);
+static int lm85_read_value(struct i2c_client *client, u8 reg)
+{
+	int res;
 
 
-static int lm85_read_value(struct i2c_client *client, u8 reg);
-static void lm85_write_value(struct i2c_client *client, u8 reg, int value);
-static struct lm85_data *lm85_update_device(struct device *dev);
+	/* What size location is it? */
+	switch (reg) {
+	case LM85_REG_FAN(0):  /* Read WORD data */
+	case LM85_REG_FAN(1):
+	case LM85_REG_FAN(2):
+	case LM85_REG_FAN(3):
+	case LM85_REG_FAN_MIN(0):
+	case LM85_REG_FAN_MIN(1):
+	case LM85_REG_FAN_MIN(2):
+	case LM85_REG_FAN_MIN(3):
+	case LM85_REG_ALARM1:	/* Read both bytes at once */
+		res = i2c_smbus_read_byte_data(client, reg) & 0xff;
+		res |= i2c_smbus_read_byte_data(client, reg + 1) << 8;
+		break;
+	default:	/* Read BYTE data */
+		res = i2c_smbus_read_byte_data(client, reg);
+		break;
+	}
 
 
+	return res;
+}
 
 
-static const struct i2c_device_id lm85_id[] = {
-	{ "adm1027", adm1027 },
-	{ "adt7463", adt7463 },
-	{ "adt7468", adt7468 },
-	{ "lm85", lm85 },
-	{ "lm85b", lm85 },
-	{ "lm85c", lm85 },
-	{ "emc6d100", emc6d100 },
-	{ "emc6d101", emc6d100 },
-	{ "emc6d102", emc6d102 },
-	{ "emc6d103", emc6d103 },
-	{ "emc6d103s", emc6d103s },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, lm85_id);
+static void lm85_write_value(struct i2c_client *client, u8 reg, int value)
+{
+	switch (reg) {
+	case LM85_REG_FAN(0):  /* Write WORD data */
+	case LM85_REG_FAN(1):
+	case LM85_REG_FAN(2):
+	case LM85_REG_FAN(3):
+	case LM85_REG_FAN_MIN(0):
+	case LM85_REG_FAN_MIN(1):
+	case LM85_REG_FAN_MIN(2):
+	case LM85_REG_FAN_MIN(3):
+	/* NOTE: ALARM is read only, so not included here */
+		i2c_smbus_write_byte_data(client, reg, value & 0xff);
+		i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
+		break;
+	default:	/* Write BYTE data */
+		i2c_smbus_write_byte_data(client, reg, value);
+		break;
+	}
+}
 
 
-static struct i2c_driver lm85_driver = {
-	.class		= I2C_CLASS_HWMON,
-	.driver = {
-		.name   = "lm85",
-	},
-	.probe		= lm85_probe,
-	.remove		= lm85_remove,
-	.id_table	= lm85_id,
-	.detect		= lm85_detect,
-	.address_list	= normal_i2c,
-};
+static struct lm85_data *lm85_update_device(struct device *dev)
+{
+	struct lm85_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
+	int i;
+
+	mutex_lock(&data->update_lock);
+
+	if (!data->valid ||
+	     time_after(jiffies, data->last_reading + LM85_DATA_INTERVAL)) {
+		/* Things that change quickly */
+		dev_dbg(&client->dev, "Reading sensor values\n");
+
+		/*
+		 * Have to read extended bits first to "freeze" the
+		 * more significant bits that are read later.
+		 * There are 2 additional resolution bits per channel and we
+		 * have room for 4, so we shift them to the left.
+		 */
+		if (data->type == adm1027 || data->type == adt7463 ||
+		    data->type == adt7468) {
+			int ext1 = lm85_read_value(client,
+						   ADM1027_REG_EXTEND_ADC1);
+			int ext2 =  lm85_read_value(client,
+						    ADM1027_REG_EXTEND_ADC2);
+			int val = (ext1 << 8) + ext2;
+
+			for (i = 0; i <= 4; i++)
+				data->in_ext[i] =
+					((val >> (i * 2)) & 0x03) << 2;
+
+			for (i = 0; i <= 2; i++)
+				data->temp_ext[i] =
+					(val >> ((i + 4) * 2)) & 0x0c;
+		}
+
+		data->vid = lm85_read_value(client, LM85_REG_VID);
+
+		for (i = 0; i <= 3; ++i) {
+			data->in[i] =
+			    lm85_read_value(client, LM85_REG_IN(i));
+			data->fan[i] =
+			    lm85_read_value(client, LM85_REG_FAN(i));
+		}
+
+		if (!data->has_vid5)
+			data->in[4] = lm85_read_value(client, LM85_REG_IN(4));
+
+		if (data->type == adt7468)
+			data->cfg5 = lm85_read_value(client, ADT7468_REG_CFG5);
+
+		for (i = 0; i <= 2; ++i) {
+			data->temp[i] =
+			    lm85_read_value(client, LM85_REG_TEMP(i));
+			data->pwm[i] =
+			    lm85_read_value(client, LM85_REG_PWM(i));
+
+			if (IS_ADT7468_OFF64(data))
+				data->temp[i] -= 64;
+		}
+
+		data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
+
+		if (data->type == emc6d100) {
+			/* Three more voltage sensors */
+			for (i = 5; i <= 7; ++i) {
+				data->in[i] = lm85_read_value(client,
+							EMC6D100_REG_IN(i));
+			}
+			/* More alarm bits */
+			data->alarms |= lm85_read_value(client,
+						EMC6D100_REG_ALARM3) << 16;
+		} else if (data->type == emc6d102 || data->type == emc6d103 ||
+			   data->type == emc6d103s) {
+			/*
+			 * Have to read LSB bits after the MSB ones because
+			 * the reading of the MSB bits has frozen the
+			 * LSBs (backward from the ADM1027).
+			 */
+			int ext1 = lm85_read_value(client,
+						   EMC6D102_REG_EXTEND_ADC1);
+			int ext2 = lm85_read_value(client,
+						   EMC6D102_REG_EXTEND_ADC2);
+			int ext3 = lm85_read_value(client,
+						   EMC6D102_REG_EXTEND_ADC3);
+			int ext4 = lm85_read_value(client,
+						   EMC6D102_REG_EXTEND_ADC4);
+			data->in_ext[0] = ext3 & 0x0f;
+			data->in_ext[1] = ext4 & 0x0f;
+			data->in_ext[2] = ext4 >> 4;
+			data->in_ext[3] = ext3 >> 4;
+			data->in_ext[4] = ext2 >> 4;
+
+			data->temp_ext[0] = ext1 & 0x0f;
+			data->temp_ext[1] = ext2 & 0x0f;
+			data->temp_ext[2] = ext1 >> 4;
+		}
+
+		data->last_reading = jiffies;
+	}  /* last_reading */
+
+	if (!data->valid ||
+	     time_after(jiffies, data->last_config + LM85_CONFIG_INTERVAL)) {
+		/* Things that don't change often */
+		dev_dbg(&client->dev, "Reading config values\n");
+
+		for (i = 0; i <= 3; ++i) {
+			data->in_min[i] =
+			    lm85_read_value(client, LM85_REG_IN_MIN(i));
+			data->in_max[i] =
+			    lm85_read_value(client, LM85_REG_IN_MAX(i));
+			data->fan_min[i] =
+			    lm85_read_value(client, LM85_REG_FAN_MIN(i));
+		}
+
+		if (!data->has_vid5)  {
+			data->in_min[4] = lm85_read_value(client,
+					  LM85_REG_IN_MIN(4));
+			data->in_max[4] = lm85_read_value(client,
+					  LM85_REG_IN_MAX(4));
+		}
+
+		if (data->type == emc6d100) {
+			for (i = 5; i <= 7; ++i) {
+				data->in_min[i] = lm85_read_value(client,
+						EMC6D100_REG_IN_MIN(i));
+				data->in_max[i] = lm85_read_value(client,
+						EMC6D100_REG_IN_MAX(i));
+			}
+		}
+
+		for (i = 0; i <= 2; ++i) {
+			int val;
+
+			data->temp_min[i] =
+			    lm85_read_value(client, LM85_REG_TEMP_MIN(i));
+			data->temp_max[i] =
+			    lm85_read_value(client, LM85_REG_TEMP_MAX(i));
+
+			data->autofan[i].config =
+			    lm85_read_value(client, LM85_REG_AFAN_CONFIG(i));
+			val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i));
+			data->pwm_freq[i] = val & 0x07;
+			data->zone[i].range = val >> 4;
+			data->autofan[i].min_pwm =
+			    lm85_read_value(client, LM85_REG_AFAN_MINPWM(i));
+			data->zone[i].limit =
+			    lm85_read_value(client, LM85_REG_AFAN_LIMIT(i));
+			data->zone[i].critical =
+			    lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i));
+
+			if (IS_ADT7468_OFF64(data)) {
+				data->temp_min[i] -= 64;
+				data->temp_max[i] -= 64;
+				data->zone[i].limit -= 64;
+				data->zone[i].critical -= 64;
+			}
+		}
+
+		if (data->type != emc6d103s) {
+			i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1);
+			data->autofan[0].min_off = (i & 0x20) != 0;
+			data->autofan[1].min_off = (i & 0x40) != 0;
+			data->autofan[2].min_off = (i & 0x80) != 0;
+
+			i = lm85_read_value(client, LM85_REG_AFAN_HYST1);
+			data->zone[0].hyst = i >> 4;
+			data->zone[1].hyst = i & 0x0f;
+
+			i = lm85_read_value(client, LM85_REG_AFAN_HYST2);
+			data->zone[2].hyst = i >> 4;
+		}
+
+		data->last_config = jiffies;
+	}  /* last_config */
+
+	data->valid = 1;
+
+	mutex_unlock(&data->update_lock);
 
 
+	return data;
+}
 
 
 /* 4 Fans */
 /* 4 Fans */
 static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
 static ssize_t show_fan(struct device *dev, struct device_attribute *attr,
@@ -394,8 +585,8 @@ static ssize_t set_fan_min(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 		const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
+	struct lm85_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -460,6 +651,9 @@ static ssize_t store_vrm_reg(struct device *dev, struct device_attribute *attr,
 	if (err)
 	if (err)
 		return err;
 		return err;
 
 
+	if (val > 255)
+		return -EINVAL;
+
 	data->vrm = val;
 	data->vrm = val;
 	return count;
 	return count;
 }
 }
@@ -515,8 +709,8 @@ static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 		const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
+	struct lm85_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -557,8 +751,8 @@ static ssize_t set_pwm_enable(struct device *dev, struct device_attribute
 		*attr, const char *buf, size_t count)
 		*attr, const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
+	struct lm85_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 config;
 	u8 config;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
@@ -615,8 +809,8 @@ static ssize_t set_pwm_freq(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
+	struct lm85_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -682,8 +876,8 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 		const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
+	struct lm85_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -710,8 +904,8 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 		const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
+	struct lm85_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -766,8 +960,8 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 		const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
+	struct lm85_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -797,8 +991,8 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 		const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
+	struct lm85_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -843,8 +1037,8 @@ static ssize_t set_pwm_auto_channels(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
+	struct lm85_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -873,8 +1067,8 @@ static ssize_t set_pwm_auto_pwm_min(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
+	struct lm85_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -902,8 +1096,8 @@ static ssize_t set_pwm_auto_pwm_minctl(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
+	struct lm85_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 tmp;
 	u8 tmp;
 	long val;
 	long val;
 	int err;
 	int err;
@@ -953,8 +1147,8 @@ static ssize_t set_temp_auto_temp_off(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
+	struct lm85_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int min;
 	int min;
 	long val;
 	long val;
 	int err;
 	int err;
@@ -990,8 +1184,8 @@ static ssize_t set_temp_auto_temp_min(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
+	struct lm85_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -1029,8 +1223,8 @@ static ssize_t set_temp_auto_temp_max(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
+	struct lm85_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int min;
 	int min;
 	long val;
 	long val;
 	int err;
 	int err;
@@ -1063,8 +1257,8 @@ static ssize_t set_temp_auto_temp_crit(struct device *dev,
 		struct device_attribute *attr, const char *buf, size_t count)
 		struct device_attribute *attr, const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
+	struct lm85_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -1355,30 +1549,18 @@ static int lm85_detect(struct i2c_client *client, struct i2c_board_info *info)
 	return 0;
 	return 0;
 }
 }
 
 
-static void lm85_remove_files(struct i2c_client *client, struct lm85_data *data)
-{
-	sysfs_remove_group(&client->dev.kobj, &lm85_group);
-	if (data->type != emc6d103s) {
-		sysfs_remove_group(&client->dev.kobj, &lm85_group_minctl);
-		sysfs_remove_group(&client->dev.kobj, &lm85_group_temp_off);
-	}
-	if (!data->has_vid5)
-		sysfs_remove_group(&client->dev.kobj, &lm85_group_in4);
-	if (data->type == emc6d100)
-		sysfs_remove_group(&client->dev.kobj, &lm85_group_in567);
-}
-
-static int lm85_probe(struct i2c_client *client,
-		      const struct i2c_device_id *id)
+static int lm85_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 {
+	struct device *dev = &client->dev;
+	struct device *hwmon_dev;
 	struct lm85_data *data;
 	struct lm85_data *data;
-	int err;
+	int idx = 0;
 
 
-	data = devm_kzalloc(&client->dev, sizeof(struct lm85_data), GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(struct lm85_data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	i2c_set_clientdata(client, data);
+	data->client = client;
 	data->type = id->driver_data;
 	data->type = id->driver_data;
 	mutex_init(&data->update_lock);
 	mutex_init(&data->update_lock);
 
 
@@ -1403,20 +1585,13 @@ static int lm85_probe(struct i2c_client *client,
 	/* Initialize the LM85 chip */
 	/* Initialize the LM85 chip */
 	lm85_init_client(client);
 	lm85_init_client(client);
 
 
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&client->dev.kobj, &lm85_group);
-	if (err)
-		return err;
+	/* sysfs hooks */
+	data->groups[idx++] = &lm85_group;
 
 
 	/* minctl and temp_off exist on all chips except emc6d103s */
 	/* minctl and temp_off exist on all chips except emc6d103s */
 	if (data->type != emc6d103s) {
 	if (data->type != emc6d103s) {
-		err = sysfs_create_group(&client->dev.kobj, &lm85_group_minctl);
-		if (err)
-			goto err_remove_files;
-		err = sysfs_create_group(&client->dev.kobj,
-					 &lm85_group_temp_off);
-		if (err)
-			goto err_remove_files;
+		data->groups[idx++] = &lm85_group_minctl;
+		data->groups[idx++] = &lm85_group_temp_off;
 	}
 	}
 
 
 	/*
 	/*
@@ -1429,271 +1604,44 @@ static int lm85_probe(struct i2c_client *client,
 			data->has_vid5 = true;
 			data->has_vid5 = true;
 	}
 	}
 
 
-	if (!data->has_vid5) {
-		err = sysfs_create_group(&client->dev.kobj, &lm85_group_in4);
-		if (err)
-			goto err_remove_files;
-	}
+	if (!data->has_vid5)
+		data->groups[idx++] = &lm85_group_in4;
 
 
 	/* The EMC6D100 has 3 additional voltage inputs */
 	/* The EMC6D100 has 3 additional voltage inputs */
-	if (data->type == emc6d100) {
-		err = sysfs_create_group(&client->dev.kobj, &lm85_group_in567);
-		if (err)
-			goto err_remove_files;
-	}
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto err_remove_files;
-	}
-
-	return 0;
-
-	/* Error out and cleanup code */
- err_remove_files:
-	lm85_remove_files(client, data);
-	return err;
-}
-
-static int lm85_remove(struct i2c_client *client)
-{
-	struct lm85_data *data = i2c_get_clientdata(client);
-	hwmon_device_unregister(data->hwmon_dev);
-	lm85_remove_files(client, data);
-	return 0;
-}
-
-
-static int lm85_read_value(struct i2c_client *client, u8 reg)
-{
-	int res;
-
-	/* What size location is it? */
-	switch (reg) {
-	case LM85_REG_FAN(0):  /* Read WORD data */
-	case LM85_REG_FAN(1):
-	case LM85_REG_FAN(2):
-	case LM85_REG_FAN(3):
-	case LM85_REG_FAN_MIN(0):
-	case LM85_REG_FAN_MIN(1):
-	case LM85_REG_FAN_MIN(2):
-	case LM85_REG_FAN_MIN(3):
-	case LM85_REG_ALARM1:	/* Read both bytes at once */
-		res = i2c_smbus_read_byte_data(client, reg) & 0xff;
-		res |= i2c_smbus_read_byte_data(client, reg + 1) << 8;
-		break;
-	default:	/* Read BYTE data */
-		res = i2c_smbus_read_byte_data(client, reg);
-		break;
-	}
+	if (data->type == emc6d100)
+		data->groups[idx++] = &lm85_group_in567;
 
 
-	return res;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data, data->groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
-static void lm85_write_value(struct i2c_client *client, u8 reg, int value)
-{
-	switch (reg) {
-	case LM85_REG_FAN(0):  /* Write WORD data */
-	case LM85_REG_FAN(1):
-	case LM85_REG_FAN(2):
-	case LM85_REG_FAN(3):
-	case LM85_REG_FAN_MIN(0):
-	case LM85_REG_FAN_MIN(1):
-	case LM85_REG_FAN_MIN(2):
-	case LM85_REG_FAN_MIN(3):
-	/* NOTE: ALARM is read only, so not included here */
-		i2c_smbus_write_byte_data(client, reg, value & 0xff);
-		i2c_smbus_write_byte_data(client, reg + 1, value >> 8);
-		break;
-	default:	/* Write BYTE data */
-		i2c_smbus_write_byte_data(client, reg, value);
-		break;
-	}
-}
-
-static struct lm85_data *lm85_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm85_data *data = i2c_get_clientdata(client);
-	int i;
-
-	mutex_lock(&data->update_lock);
-
-	if (!data->valid ||
-	     time_after(jiffies, data->last_reading + LM85_DATA_INTERVAL)) {
-		/* Things that change quickly */
-		dev_dbg(&client->dev, "Reading sensor values\n");
-
-		/*
-		 * Have to read extended bits first to "freeze" the
-		 * more significant bits that are read later.
-		 * There are 2 additional resolution bits per channel and we
-		 * have room for 4, so we shift them to the left.
-		 */
-		if (data->type == adm1027 || data->type == adt7463 ||
-		    data->type == adt7468) {
-			int ext1 = lm85_read_value(client,
-						   ADM1027_REG_EXTEND_ADC1);
-			int ext2 =  lm85_read_value(client,
-						    ADM1027_REG_EXTEND_ADC2);
-			int val = (ext1 << 8) + ext2;
-
-			for (i = 0; i <= 4; i++)
-				data->in_ext[i] =
-					((val >> (i * 2)) & 0x03) << 2;
-
-			for (i = 0; i <= 2; i++)
-				data->temp_ext[i] =
-					(val >> ((i + 4) * 2)) & 0x0c;
-		}
-
-		data->vid = lm85_read_value(client, LM85_REG_VID);
-
-		for (i = 0; i <= 3; ++i) {
-			data->in[i] =
-			    lm85_read_value(client, LM85_REG_IN(i));
-			data->fan[i] =
-			    lm85_read_value(client, LM85_REG_FAN(i));
-		}
-
-		if (!data->has_vid5)
-			data->in[4] = lm85_read_value(client, LM85_REG_IN(4));
-
-		if (data->type == adt7468)
-			data->cfg5 = lm85_read_value(client, ADT7468_REG_CFG5);
-
-		for (i = 0; i <= 2; ++i) {
-			data->temp[i] =
-			    lm85_read_value(client, LM85_REG_TEMP(i));
-			data->pwm[i] =
-			    lm85_read_value(client, LM85_REG_PWM(i));
-
-			if (IS_ADT7468_OFF64(data))
-				data->temp[i] -= 64;
-		}
-
-		data->alarms = lm85_read_value(client, LM85_REG_ALARM1);
-
-		if (data->type == emc6d100) {
-			/* Three more voltage sensors */
-			for (i = 5; i <= 7; ++i) {
-				data->in[i] = lm85_read_value(client,
-							EMC6D100_REG_IN(i));
-			}
-			/* More alarm bits */
-			data->alarms |= lm85_read_value(client,
-						EMC6D100_REG_ALARM3) << 16;
-		} else if (data->type == emc6d102 || data->type == emc6d103 ||
-			   data->type == emc6d103s) {
-			/*
-			 * Have to read LSB bits after the MSB ones because
-			 * the reading of the MSB bits has frozen the
-			 * LSBs (backward from the ADM1027).
-			 */
-			int ext1 = lm85_read_value(client,
-						   EMC6D102_REG_EXTEND_ADC1);
-			int ext2 = lm85_read_value(client,
-						   EMC6D102_REG_EXTEND_ADC2);
-			int ext3 = lm85_read_value(client,
-						   EMC6D102_REG_EXTEND_ADC3);
-			int ext4 = lm85_read_value(client,
-						   EMC6D102_REG_EXTEND_ADC4);
-			data->in_ext[0] = ext3 & 0x0f;
-			data->in_ext[1] = ext4 & 0x0f;
-			data->in_ext[2] = ext4 >> 4;
-			data->in_ext[3] = ext3 >> 4;
-			data->in_ext[4] = ext2 >> 4;
-
-			data->temp_ext[0] = ext1 & 0x0f;
-			data->temp_ext[1] = ext2 & 0x0f;
-			data->temp_ext[2] = ext1 >> 4;
-		}
-
-		data->last_reading = jiffies;
-	}  /* last_reading */
-
-	if (!data->valid ||
-	     time_after(jiffies, data->last_config + LM85_CONFIG_INTERVAL)) {
-		/* Things that don't change often */
-		dev_dbg(&client->dev, "Reading config values\n");
-
-		for (i = 0; i <= 3; ++i) {
-			data->in_min[i] =
-			    lm85_read_value(client, LM85_REG_IN_MIN(i));
-			data->in_max[i] =
-			    lm85_read_value(client, LM85_REG_IN_MAX(i));
-			data->fan_min[i] =
-			    lm85_read_value(client, LM85_REG_FAN_MIN(i));
-		}
-
-		if (!data->has_vid5)  {
-			data->in_min[4] = lm85_read_value(client,
-					  LM85_REG_IN_MIN(4));
-			data->in_max[4] = lm85_read_value(client,
-					  LM85_REG_IN_MAX(4));
-		}
-
-		if (data->type == emc6d100) {
-			for (i = 5; i <= 7; ++i) {
-				data->in_min[i] = lm85_read_value(client,
-						EMC6D100_REG_IN_MIN(i));
-				data->in_max[i] = lm85_read_value(client,
-						EMC6D100_REG_IN_MAX(i));
-			}
-		}
-
-		for (i = 0; i <= 2; ++i) {
-			int val;
-
-			data->temp_min[i] =
-			    lm85_read_value(client, LM85_REG_TEMP_MIN(i));
-			data->temp_max[i] =
-			    lm85_read_value(client, LM85_REG_TEMP_MAX(i));
-
-			data->autofan[i].config =
-			    lm85_read_value(client, LM85_REG_AFAN_CONFIG(i));
-			val = lm85_read_value(client, LM85_REG_AFAN_RANGE(i));
-			data->pwm_freq[i] = val & 0x07;
-			data->zone[i].range = val >> 4;
-			data->autofan[i].min_pwm =
-			    lm85_read_value(client, LM85_REG_AFAN_MINPWM(i));
-			data->zone[i].limit =
-			    lm85_read_value(client, LM85_REG_AFAN_LIMIT(i));
-			data->zone[i].critical =
-			    lm85_read_value(client, LM85_REG_AFAN_CRITICAL(i));
-
-			if (IS_ADT7468_OFF64(data)) {
-				data->temp_min[i] -= 64;
-				data->temp_max[i] -= 64;
-				data->zone[i].limit -= 64;
-				data->zone[i].critical -= 64;
-			}
-		}
-
-		if (data->type != emc6d103s) {
-			i = lm85_read_value(client, LM85_REG_AFAN_SPIKE1);
-			data->autofan[0].min_off = (i & 0x20) != 0;
-			data->autofan[1].min_off = (i & 0x40) != 0;
-			data->autofan[2].min_off = (i & 0x80) != 0;
-
-			i = lm85_read_value(client, LM85_REG_AFAN_HYST1);
-			data->zone[0].hyst = i >> 4;
-			data->zone[1].hyst = i & 0x0f;
-
-			i = lm85_read_value(client, LM85_REG_AFAN_HYST2);
-			data->zone[2].hyst = i >> 4;
-		}
-
-		data->last_config = jiffies;
-	}  /* last_config */
-
-	data->valid = 1;
-
-	mutex_unlock(&data->update_lock);
+static const struct i2c_device_id lm85_id[] = {
+	{ "adm1027", adm1027 },
+	{ "adt7463", adt7463 },
+	{ "adt7468", adt7468 },
+	{ "lm85", lm85 },
+	{ "lm85b", lm85 },
+	{ "lm85c", lm85 },
+	{ "emc6d100", emc6d100 },
+	{ "emc6d101", emc6d100 },
+	{ "emc6d102", emc6d102 },
+	{ "emc6d103", emc6d103 },
+	{ "emc6d103s", emc6d103s },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, lm85_id);
 
 
-	return data;
-}
+static struct i2c_driver lm85_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name   = "lm85",
+	},
+	.probe		= lm85_probe,
+	.id_table	= lm85_id,
+	.detect		= lm85_detect,
+	.address_list	= normal_i2c,
+};
 
 
 module_i2c_driver(lm85_driver);
 module_i2c_driver(lm85_driver);
 
 

+ 66 - 88
drivers/hwmon/lm93.c

@@ -207,7 +207,7 @@ struct block1_t {
  * Client-specific data
  * Client-specific data
  */
  */
 struct lm93_data {
 struct lm93_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
 
 
 	struct mutex update_lock;
 	struct mutex update_lock;
 	unsigned long last_updated;	/* In jiffies */
 	unsigned long last_updated;	/* In jiffies */
@@ -919,8 +919,8 @@ static void lm93_read_block(struct i2c_client *client, u8 fbn, u8 *values)
 
 
 static struct lm93_data *lm93_update_device(struct device *dev)
 static struct lm93_data *lm93_update_device(struct device *dev)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	const unsigned long interval = HZ + (HZ / 2);
 	const unsigned long interval = HZ + (HZ / 2);
 
 
 	mutex_lock(&data->update_lock);
 	mutex_lock(&data->update_lock);
@@ -1158,8 +1158,8 @@ static ssize_t store_in_min(struct device *dev, struct device_attribute *attr,
 			    const char *buf, size_t count)
 			    const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int vccp = nr - 6;
 	int vccp = nr - 6;
 	long vid;
 	long vid;
 	unsigned long val;
 	unsigned long val;
@@ -1239,8 +1239,8 @@ static ssize_t store_in_max(struct device *dev, struct device_attribute *attr,
 			    const char *buf, size_t count)
 			    const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int vccp = nr - 6;
 	int vccp = nr - 6;
 	long vid;
 	long vid;
 	unsigned long val;
 	unsigned long val;
@@ -1323,8 +1323,8 @@ static ssize_t store_temp_min(struct device *dev, struct device_attribute *attr,
 			      const char *buf, size_t count)
 			      const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -1358,8 +1358,8 @@ static ssize_t store_temp_max(struct device *dev, struct device_attribute *attr,
 			      const char *buf, size_t count)
 			      const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -1394,8 +1394,8 @@ static ssize_t store_temp_auto_base(struct device *dev,
 					const char *buf, size_t count)
 					const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -1430,8 +1430,8 @@ static ssize_t store_temp_auto_boost(struct device *dev,
 				     const char *buf, size_t count)
 				     const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -1469,8 +1469,8 @@ static ssize_t store_temp_auto_boost_hyst(struct device *dev,
 					  const char *buf, size_t count)
 					  const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -1520,8 +1520,8 @@ static ssize_t store_temp_auto_offset(struct device *dev,
 	struct sensor_device_attribute_2 *s_attr = to_sensor_dev_attr_2(attr);
 	struct sensor_device_attribute_2 *s_attr = to_sensor_dev_attr_2(attr);
 	int nr = s_attr->index;
 	int nr = s_attr->index;
 	int ofs = s_attr->nr;
 	int ofs = s_attr->nr;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -1632,8 +1632,8 @@ static ssize_t store_temp_auto_pwm_min(struct device *dev,
 					const char *buf, size_t count)
 					const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 reg, ctl4;
 	u8 reg, ctl4;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
@@ -1680,8 +1680,8 @@ static ssize_t store_temp_auto_offset_hyst(struct device *dev,
 						const char *buf, size_t count)
 						const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 reg;
 	u8 reg;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
@@ -1741,8 +1741,8 @@ static ssize_t store_fan_min(struct device *dev, struct device_attribute *attr,
 				const char *buf, size_t count)
 				const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -1824,8 +1824,8 @@ static ssize_t store_fan_smart_tach(struct device *dev,
 					const char *buf, size_t count)
 					const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -1880,8 +1880,8 @@ static ssize_t store_pwm(struct device *dev, struct device_attribute *attr,
 				const char *buf, size_t count)
 				const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 ctl2, ctl4;
 	u8 ctl2, ctl4;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
@@ -1928,8 +1928,8 @@ static ssize_t store_pwm_enable(struct device *dev,
 				const char *buf, size_t count)
 				const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 ctl2;
 	u8 ctl2;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
@@ -2006,8 +2006,8 @@ static ssize_t store_pwm_freq(struct device *dev,
 				const char *buf, size_t count)
 				const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 ctl4;
 	u8 ctl4;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
@@ -2046,8 +2046,8 @@ static ssize_t store_pwm_auto_channels(struct device *dev,
 					const char *buf, size_t count)
 					const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -2087,8 +2087,8 @@ static ssize_t store_pwm_auto_spinup_min(struct device *dev,
 						const char *buf, size_t count)
 						const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 ctl3, ctl4;
 	u8 ctl3, ctl4;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
@@ -2130,8 +2130,8 @@ static ssize_t store_pwm_auto_spinup_time(struct device *dev,
 						const char *buf, size_t count)
 						const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 ctl3;
 	u8 ctl3;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
@@ -2168,8 +2168,8 @@ static ssize_t store_pwm_auto_prochot_ramp(struct device *dev,
 						struct device_attribute *attr,
 						struct device_attribute *attr,
 						const char *buf, size_t count)
 						const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 ramp;
 	u8 ramp;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
@@ -2202,8 +2202,8 @@ static ssize_t store_pwm_auto_vrdhot_ramp(struct device *dev,
 						struct device_attribute *attr,
 						struct device_attribute *attr,
 						const char *buf, size_t count)
 						const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 ramp;
 	u8 ramp;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
@@ -2270,8 +2270,8 @@ static ssize_t store_prochot_max(struct device *dev,
 					const char *buf, size_t count)
 					const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -2308,8 +2308,8 @@ static ssize_t store_prochot_override(struct device *dev,
 					const char *buf, size_t count)
 					const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -2351,8 +2351,8 @@ static ssize_t store_prochot_interval(struct device *dev,
 					const char *buf, size_t count)
 					const char *buf, size_t count)
 {
 {
 	int nr = (to_sensor_dev_attr(attr))->index;
 	int nr = (to_sensor_dev_attr(attr))->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 tmp;
 	u8 tmp;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
@@ -2390,8 +2390,8 @@ static ssize_t store_prochot_override_duty_cycle(struct device *dev,
 						struct device_attribute *attr,
 						struct device_attribute *attr,
 						const char *buf, size_t count)
 						const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -2423,8 +2423,8 @@ static ssize_t store_prochot_short(struct device *dev,
 					struct device_attribute *attr,
 					struct device_attribute *attr,
 					const char *buf, size_t count)
 					const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct lm93_data *data = i2c_get_clientdata(client);
+	struct lm93_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -2631,9 +2631,7 @@ static struct attribute *lm93_attrs[] = {
 	NULL
 	NULL
 };
 };
 
 
-static struct attribute_group lm93_attr_grp = {
-	.attrs = lm93_attrs,
-};
+ATTRIBUTE_GROUPS(lm93);
 
 
 static void lm93_init_client(struct i2c_client *client)
 static void lm93_init_client(struct i2c_client *client)
 {
 {
@@ -2726,61 +2724,42 @@ static int lm93_detect(struct i2c_client *client, struct i2c_board_info *info)
 static int lm93_probe(struct i2c_client *client,
 static int lm93_probe(struct i2c_client *client,
 		      const struct i2c_device_id *id)
 		      const struct i2c_device_id *id)
 {
 {
+	struct device *dev = &client->dev;
 	struct lm93_data *data;
 	struct lm93_data *data;
-	int err, func;
+	struct device *hwmon_dev;
+	int func;
 	void (*update)(struct lm93_data *, struct i2c_client *);
 	void (*update)(struct lm93_data *, struct i2c_client *);
 
 
 	/* choose update routine based on bus capabilities */
 	/* choose update routine based on bus capabilities */
 	func = i2c_get_functionality(client->adapter);
 	func = i2c_get_functionality(client->adapter);
 	if (((LM93_SMBUS_FUNC_FULL & func) == LM93_SMBUS_FUNC_FULL) &&
 	if (((LM93_SMBUS_FUNC_FULL & func) == LM93_SMBUS_FUNC_FULL) &&
 			(!disable_block)) {
 			(!disable_block)) {
-		dev_dbg(&client->dev, "using SMBus block data transactions\n");
+		dev_dbg(dev, "using SMBus block data transactions\n");
 		update = lm93_update_client_full;
 		update = lm93_update_client_full;
 	} else if ((LM93_SMBUS_FUNC_MIN & func) == LM93_SMBUS_FUNC_MIN) {
 	} else if ((LM93_SMBUS_FUNC_MIN & func) == LM93_SMBUS_FUNC_MIN) {
-		dev_dbg(&client->dev,
-			"disabled SMBus block data transactions\n");
+		dev_dbg(dev, "disabled SMBus block data transactions\n");
 		update = lm93_update_client_min;
 		update = lm93_update_client_min;
 	} else {
 	} else {
-		dev_dbg(&client->dev,
-			"detect failed, smbus byte and/or word data not supported!\n");
+		dev_dbg(dev, "detect failed, smbus byte and/or word data not supported!\n");
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 
 
-	data = devm_kzalloc(&client->dev, sizeof(struct lm93_data), GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(struct lm93_data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
-	i2c_set_clientdata(client, data);
 
 
 	/* housekeeping */
 	/* housekeeping */
+	data->client = client;
 	data->update = update;
 	data->update = update;
 	mutex_init(&data->update_lock);
 	mutex_init(&data->update_lock);
 
 
 	/* initialize the chip */
 	/* initialize the chip */
 	lm93_init_client(client);
 	lm93_init_client(client);
 
 
-	err = sysfs_create_group(&client->dev.kobj, &lm93_attr_grp);
-	if (err)
-		return err;
-
-	/* Register hwmon driver class */
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (!IS_ERR(data->hwmon_dev))
-		return 0;
-
-	err = PTR_ERR(data->hwmon_dev);
-	dev_err(&client->dev, "error registering hwmon device.\n");
-	sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp);
-	return err;
-}
-
-static int lm93_remove(struct i2c_client *client)
-{
-	struct lm93_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &lm93_attr_grp);
-
-	return 0;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data,
+							   lm93_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
 static const struct i2c_device_id lm93_id[] = {
 static const struct i2c_device_id lm93_id[] = {
@@ -2796,7 +2775,6 @@ static struct i2c_driver lm93_driver = {
 		.name	= "lm93",
 		.name	= "lm93",
 	},
 	},
 	.probe		= lm93_probe,
 	.probe		= lm93_probe,
-	.remove		= lm93_remove,
 	.id_table	= lm93_id,
 	.id_table	= lm93_id,
 	.detect		= lm93_detect,
 	.detect		= lm93_detect,
 	.address_list	= normal_i2c,
 	.address_list	= normal_i2c,

+ 1 - 1
drivers/hwmon/ltc2945.c

@@ -469,7 +469,7 @@ static struct attribute *ltc2945_attrs[] = {
 };
 };
 ATTRIBUTE_GROUPS(ltc2945);
 ATTRIBUTE_GROUPS(ltc2945);
 
 
-static struct regmap_config ltc2945_regmap_config = {
+static const struct regmap_config ltc2945_regmap_config = {
 	.reg_bits = 8,
 	.reg_bits = 8,
 	.val_bits = 8,
 	.val_bits = 8,
 	.max_register = LTC2945_MIN_ADIN_THRES_L,
 	.max_register = LTC2945_MIN_ADIN_THRES_L,

+ 1 - 1
drivers/hwmon/ltc4222.c

@@ -186,7 +186,7 @@ static struct attribute *ltc4222_attrs[] = {
 };
 };
 ATTRIBUTE_GROUPS(ltc4222);
 ATTRIBUTE_GROUPS(ltc4222);
 
 
-static struct regmap_config ltc4222_regmap_config = {
+static const struct regmap_config ltc4222_regmap_config = {
 	.reg_bits = 8,
 	.reg_bits = 8,
 	.val_bits = 8,
 	.val_bits = 8,
 	.max_register = LTC4222_ADC_CONTROL,
 	.max_register = LTC4222_ADC_CONTROL,

+ 1 - 1
drivers/hwmon/ltc4260.c

@@ -150,7 +150,7 @@ static struct attribute *ltc4260_attrs[] = {
 };
 };
 ATTRIBUTE_GROUPS(ltc4260);
 ATTRIBUTE_GROUPS(ltc4260);
 
 
-static struct regmap_config ltc4260_regmap_config = {
+static const struct regmap_config ltc4260_regmap_config = {
 	.reg_bits = 8,
 	.reg_bits = 8,
 	.val_bits = 8,
 	.val_bits = 8,
 	.max_register = LTC4260_ADIN,
 	.max_register = LTC4260_ADIN,

+ 1 - 4
drivers/hwmon/max16065.c

@@ -642,10 +642,7 @@ static int max16065_probe(struct i2c_client *client,
 
 
 	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
 	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
 							   data, data->groups);
 							   data, data->groups);
-	if (unlikely(IS_ERR(hwmon_dev)))
-		return PTR_ERR(hwmon_dev);
-
-	return 0;
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
 static const struct i2c_device_id max16065_id[] = {
 static const struct i2c_device_id max16065_id[] = {

+ 1 - 1
drivers/hwmon/max1668.c

@@ -30,7 +30,7 @@
 #include <linux/mutex.h>
 #include <linux/mutex.h>
 
 
 /* Addresses to scan */
 /* Addresses to scan */
-static unsigned short max1668_addr_list[] = {
+static const unsigned short max1668_addr_list[] = {
 	0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };
 	0x18, 0x19, 0x1a, 0x29, 0x2a, 0x2b, 0x4c, 0x4d, 0x4e, I2C_CLIENT_END };
 
 
 /* max1668 registers */
 /* max1668 registers */

+ 1 - 1
drivers/hwmon/max6639.c

@@ -35,7 +35,7 @@
 #include <linux/i2c/max6639.h>
 #include <linux/i2c/max6639.h>
 
 
 /* Addresses to scan */
 /* Addresses to scan */
-static unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END };
+static const unsigned short normal_i2c[] = { 0x2c, 0x2e, 0x2f, I2C_CLIENT_END };
 
 
 /* The MAX6639 registers, valid channel numbers: 0, 1 */
 /* The MAX6639 registers, valid channel numbers: 0, 1 */
 #define MAX6639_REG_TEMP(ch)			(0x00 + (ch))
 #define MAX6639_REG_TEMP(ch)			(0x00 + (ch))

+ 7 - 9
drivers/hwmon/max6697.c

@@ -495,15 +495,13 @@ static void max6697_get_config_of(struct device_node *node,
 	int len;
 	int len;
 	const __be32 *prop;
 	const __be32 *prop;
 
 
-	prop = of_get_property(node, "smbus-timeout-disable", &len);
-	if (prop)
-		pdata->smbus_timeout_disable = true;
-	prop = of_get_property(node, "extended-range-enable", &len);
-	if (prop)
-		pdata->extended_range_enable = true;
-	prop = of_get_property(node, "beta-compensation-enable", &len);
-	if (prop)
-		pdata->beta_compensation = true;
+	pdata->smbus_timeout_disable =
+		of_property_read_bool(node, "smbus-timeout-disable");
+	pdata->extended_range_enable =
+		of_property_read_bool(node, "extended-range-enable");
+	pdata->beta_compensation =
+		of_property_read_bool(node, "beta-compensation-enable");
+
 	prop = of_get_property(node, "alert-mask", &len);
 	prop = of_get_property(node, "alert-mask", &len);
 	if (prop && len == sizeof(u32))
 	if (prop && len == sizeof(u32))
 		pdata->alert_mask = be32_to_cpu(prop[0]);
 		pdata->alert_mask = be32_to_cpu(prop[0]);

+ 7 - 7
drivers/hwmon/nct6775.c

@@ -735,7 +735,6 @@ struct nct6775_data {
 	enum kinds kind;
 	enum kinds kind;
 	const char *name;
 	const char *name;
 
 
-	int num_attr_groups;
 	const struct attribute_group *groups[6];
 	const struct attribute_group *groups[6];
 
 
 	u16 reg_temp[5][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst,
 	u16 reg_temp[5][NUM_TEMP]; /* 0=temp, 1=temp_over, 2=temp_hyst,
@@ -3276,6 +3275,7 @@ static int nct6775_probe(struct platform_device *pdev)
 	u8 cr2a;
 	u8 cr2a;
 	struct attribute_group *group;
 	struct attribute_group *group;
 	struct device *hwmon_dev;
 	struct device *hwmon_dev;
+	int num_attr_groups = 0;
 
 
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
 	if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH,
 	if (!devm_request_region(&pdev->dev, res->start, IOREGION_LENGTH,
@@ -3907,29 +3907,29 @@ static int nct6775_probe(struct platform_device *pdev)
 	if (IS_ERR(group))
 	if (IS_ERR(group))
 		return PTR_ERR(group);
 		return PTR_ERR(group);
 
 
-	data->groups[data->num_attr_groups++] = group;
+	data->groups[num_attr_groups++] = group;
 
 
 	group = nct6775_create_attr_group(dev, &nct6775_in_template_group,
 	group = nct6775_create_attr_group(dev, &nct6775_in_template_group,
 					  fls(data->have_in));
 					  fls(data->have_in));
 	if (IS_ERR(group))
 	if (IS_ERR(group))
 		return PTR_ERR(group);
 		return PTR_ERR(group);
 
 
-	data->groups[data->num_attr_groups++] = group;
+	data->groups[num_attr_groups++] = group;
 
 
 	group = nct6775_create_attr_group(dev, &nct6775_fan_template_group,
 	group = nct6775_create_attr_group(dev, &nct6775_fan_template_group,
 					  fls(data->has_fan));
 					  fls(data->has_fan));
 	if (IS_ERR(group))
 	if (IS_ERR(group))
 		return PTR_ERR(group);
 		return PTR_ERR(group);
 
 
-	data->groups[data->num_attr_groups++] = group;
+	data->groups[num_attr_groups++] = group;
 
 
 	group = nct6775_create_attr_group(dev, &nct6775_temp_template_group,
 	group = nct6775_create_attr_group(dev, &nct6775_temp_template_group,
 					  fls(data->have_temp));
 					  fls(data->have_temp));
 	if (IS_ERR(group))
 	if (IS_ERR(group))
 		return PTR_ERR(group);
 		return PTR_ERR(group);
 
 
-	data->groups[data->num_attr_groups++] = group;
-	data->groups[data->num_attr_groups++] = &nct6775_group_other;
+	data->groups[num_attr_groups++] = group;
+	data->groups[num_attr_groups++] = &nct6775_group_other;
 
 
 	hwmon_dev = devm_hwmon_device_register_with_groups(dev, data->name,
 	hwmon_dev = devm_hwmon_device_register_with_groups(dev, data->name,
 							   data, data->groups);
 							   data, data->groups);
@@ -4221,7 +4221,7 @@ static void __exit sensors_nct6775_exit(void)
 }
 }
 
 
 MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
 MODULE_AUTHOR("Guenter Roeck <linux@roeck-us.net>");
-MODULE_DESCRIPTION("NCT6775F/NCT6776F/NCT6779D driver");
+MODULE_DESCRIPTION("NCT6106D/NCT6775F/NCT6776F/NCT6779D/NCT6791D driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 
 
 module_init(sensors_nct6775_init);
 module_init(sensors_nct6775_init);

+ 49 - 1
drivers/hwmon/ntc_thermistor.c

@@ -51,6 +51,7 @@ static const struct platform_device_id ntc_thermistor_id[] = {
 	{ "ncp21wb473", TYPE_NCPXXWB473 },
 	{ "ncp21wb473", TYPE_NCPXXWB473 },
 	{ "ncp03wb473", TYPE_NCPXXWB473 },
 	{ "ncp03wb473", TYPE_NCPXXWB473 },
 	{ "ncp15wl333", TYPE_NCPXXWL333 },
 	{ "ncp15wl333", TYPE_NCPXXWL333 },
+	{ "b57330v2103", TYPE_B57330V2103},
 	{ },
 	{ },
 };
 };
 
 
@@ -133,6 +134,47 @@ static const struct ntc_compensation ncpXXwl333[] = {
 	{ .temp_c	= 125, .ohm	= 707 },
 	{ .temp_c	= 125, .ohm	= 707 },
 };
 };
 
 
+/*
+ * The following compensation table is from the specification of EPCOS NTC
+ * Thermistors Datasheet
+ */
+static const struct ntc_compensation b57330v2103[] = {
+	{ .temp_c	= -40, .ohm	= 190030 },
+	{ .temp_c	= -35, .ohm	= 145360 },
+	{ .temp_c	= -30, .ohm	= 112060 },
+	{ .temp_c	= -25, .ohm	= 87041 },
+	{ .temp_c	= -20, .ohm	= 68104 },
+	{ .temp_c	= -15, .ohm	= 53665 },
+	{ .temp_c	= -10, .ohm	= 42576 },
+	{ .temp_c	= -5, .ohm	= 34001 },
+	{ .temp_c	= 0, .ohm	= 27326 },
+	{ .temp_c	= 5, .ohm	= 22096 },
+	{ .temp_c	= 10, .ohm	= 17973 },
+	{ .temp_c	= 15, .ohm	= 14703 },
+	{ .temp_c	= 20, .ohm	= 12090 },
+	{ .temp_c	= 25, .ohm	= 10000 },
+	{ .temp_c	= 30, .ohm	= 8311 },
+	{ .temp_c	= 35, .ohm	= 6941 },
+	{ .temp_c	= 40, .ohm	= 5825 },
+	{ .temp_c	= 45, .ohm	= 4911 },
+	{ .temp_c	= 50, .ohm	= 4158 },
+	{ .temp_c	= 55, .ohm	= 3536 },
+	{ .temp_c	= 60, .ohm	= 3019 },
+	{ .temp_c	= 65, .ohm	= 2588 },
+	{ .temp_c	= 70, .ohm	= 2227 },
+	{ .temp_c	= 75, .ohm	= 1924 },
+	{ .temp_c	= 80, .ohm	= 1668 },
+	{ .temp_c	= 85, .ohm	= 1451 },
+	{ .temp_c	= 90, .ohm	= 1266 },
+	{ .temp_c	= 95, .ohm	= 1108 },
+	{ .temp_c	= 100, .ohm	= 973 },
+	{ .temp_c	= 105, .ohm	= 857 },
+	{ .temp_c	= 110, .ohm	= 757 },
+	{ .temp_c	= 115, .ohm	= 671 },
+	{ .temp_c	= 120, .ohm	= 596 },
+	{ .temp_c	= 125, .ohm	= 531 },
+};
+
 struct ntc_data {
 struct ntc_data {
 	struct device *hwmon_dev;
 	struct device *hwmon_dev;
 	struct ntc_thermistor_platform_data *pdata;
 	struct ntc_thermistor_platform_data *pdata;
@@ -173,6 +215,8 @@ static const struct of_device_id ntc_match[] = {
 		.data = &ntc_thermistor_id[3] },
 		.data = &ntc_thermistor_id[3] },
 	{ .compatible = "murata,ncp15wl333",
 	{ .compatible = "murata,ncp15wl333",
 		.data = &ntc_thermistor_id[4] },
 		.data = &ntc_thermistor_id[4] },
+	{ .compatible = "epcos,b57330v2103",
+		.data = &ntc_thermistor_id[5]},
 
 
 	/* Usage of vendor name "ntc" is deprecated */
 	/* Usage of vendor name "ntc" is deprecated */
 	{ .compatible = "ntc,ncp15wb473",
 	{ .compatible = "ntc,ncp15wb473",
@@ -490,6 +534,10 @@ static int ntc_thermistor_probe(struct platform_device *pdev)
 		data->comp = ncpXXwl333;
 		data->comp = ncpXXwl333;
 		data->n_comp = ARRAY_SIZE(ncpXXwl333);
 		data->n_comp = ARRAY_SIZE(ncpXXwl333);
 		break;
 		break;
+	case TYPE_B57330V2103:
+		data->comp = b57330v2103;
+		data->n_comp = ARRAY_SIZE(b57330v2103);
+		break;
 	default:
 	default:
 		dev_err(&pdev->dev, "Unknown device type: %lu(%s)\n",
 		dev_err(&pdev->dev, "Unknown device type: %lu(%s)\n",
 				pdev_id->driver_data, pdev_id->name);
 				pdev_id->driver_data, pdev_id->name);
@@ -546,7 +594,7 @@ static struct platform_driver ntc_thermistor_driver = {
 
 
 module_platform_driver(ntc_thermistor_driver);
 module_platform_driver(ntc_thermistor_driver);
 
 
-MODULE_DESCRIPTION("NTC Thermistor Driver from Murata");
+MODULE_DESCRIPTION("NTC Thermistor Driver");
 MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
 MODULE_AUTHOR("MyungJoo Ham <myungjoo.ham@samsung.com>");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:ntc-thermistor");
 MODULE_ALIAS("platform:ntc-thermistor");

+ 11 - 2
drivers/hwmon/pmbus/Kconfig

@@ -20,8 +20,7 @@ config SENSORS_PMBUS
 	help
 	help
 	  If you say yes here you get hardware monitoring support for generic
 	  If you say yes here you get hardware monitoring support for generic
 	  PMBus devices, including but not limited to ADP4000, BMR453, BMR454,
 	  PMBus devices, including but not limited to ADP4000, BMR453, BMR454,
-	  MDT040, NCP4200, NCP4208, PDT003, PDT006, PDT012, UDT020, TPS40400,
-	  and TPS40422.
+	  MDT040, NCP4200, NCP4208, PDT003, PDT006, PDT012, UDT020, and TPS40400.
 
 
 	  This driver can also be built as a module. If so, the module will
 	  This driver can also be built as a module. If so, the module will
 	  be called pmbus.
 	  be called pmbus.
@@ -87,6 +86,16 @@ config SENSORS_MAX8688
 	  This driver can also be built as a module. If so, the module will
 	  This driver can also be built as a module. If so, the module will
 	  be called max8688.
 	  be called max8688.
 
 
+config SENSORS_TPS40422
+	tristate "TI TPS40422"
+	default n
+	help
+	  If you say yes here you get hardware monitoring support for TI
+	  TPS40422.
+
+	  This driver can also be built as a module. If so, the module will
+	  be called tps40422.
+
 config SENSORS_UCD9000
 config SENSORS_UCD9000
 	tristate "TI UCD90120, UCD90124, UCD9090, UCD90910"
 	tristate "TI UCD90120, UCD90124, UCD9090, UCD90910"
 	default n
 	default n

+ 1 - 0
drivers/hwmon/pmbus/Makefile

@@ -10,6 +10,7 @@ obj-$(CONFIG_SENSORS_LTC2978)	+= ltc2978.o
 obj-$(CONFIG_SENSORS_MAX16064)	+= max16064.o
 obj-$(CONFIG_SENSORS_MAX16064)	+= max16064.o
 obj-$(CONFIG_SENSORS_MAX34440)	+= max34440.o
 obj-$(CONFIG_SENSORS_MAX34440)	+= max34440.o
 obj-$(CONFIG_SENSORS_MAX8688)	+= max8688.o
 obj-$(CONFIG_SENSORS_MAX8688)	+= max8688.o
+obj-$(CONFIG_SENSORS_TPS40422)	+= tps40422.o
 obj-$(CONFIG_SENSORS_UCD9000)	+= ucd9000.o
 obj-$(CONFIG_SENSORS_UCD9000)	+= ucd9000.o
 obj-$(CONFIG_SENSORS_UCD9200)	+= ucd9200.o
 obj-$(CONFIG_SENSORS_UCD9200)	+= ucd9200.o
 obj-$(CONFIG_SENSORS_ZL6100)	+= zl6100.o
 obj-$(CONFIG_SENSORS_ZL6100)	+= zl6100.o

+ 0 - 1
drivers/hwmon/pmbus/pmbus.c

@@ -193,7 +193,6 @@ static const struct i2c_device_id pmbus_id[] = {
 	{"pdt012", 1},
 	{"pdt012", 1},
 	{"pmbus", 0},
 	{"pmbus", 0},
 	{"tps40400", 1},
 	{"tps40400", 1},
-	{"tps40422", 2},
 	{"udt020", 1},
 	{"udt020", 1},
 	{}
 	{}
 };
 };

+ 64 - 0
drivers/hwmon/pmbus/tps40422.c

@@ -0,0 +1,64 @@
+/*
+ * Hardware monitoring driver for TI TPS40422
+ *
+ * Copyright (c) 2014 Nokia Solutions and Networks.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include "pmbus.h"
+
+static struct pmbus_driver_info tps40422_info = {
+	.pages = 2,
+	.format[PSC_VOLTAGE_IN] = linear,
+	.format[PSC_VOLTAGE_OUT] = linear,
+	.format[PSC_TEMPERATURE] = linear,
+	.func[0] = PMBUS_HAVE_VOUT | PMBUS_HAVE_TEMP2
+		| PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_TEMP
+		| PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
+	.func[1] = PMBUS_HAVE_VOUT | PMBUS_HAVE_TEMP2
+		| PMBUS_HAVE_STATUS_VOUT | PMBUS_HAVE_STATUS_TEMP
+		| PMBUS_HAVE_IOUT | PMBUS_HAVE_STATUS_IOUT,
+};
+
+static int tps40422_probe(struct i2c_client *client,
+			  const struct i2c_device_id *id)
+{
+	return pmbus_do_probe(client, id, &tps40422_info);
+}
+
+static const struct i2c_device_id tps40422_id[] = {
+	{"tps40422", 0},
+	{}
+};
+
+MODULE_DEVICE_TABLE(i2c, tps40422_id);
+
+/* This is the driver that will be inserted */
+static struct i2c_driver tps40422_driver = {
+	.driver = {
+		   .name = "tps40422",
+		   },
+	.probe = tps40422_probe,
+	.remove = pmbus_do_remove,
+	.id_table = tps40422_id,
+};
+
+module_i2c_driver(tps40422_driver);
+
+MODULE_AUTHOR("Zhu Laiwen <richard.zhu@nsn.com>");
+MODULE_DESCRIPTION("PMBus driver for TI TPS40422");
+MODULE_LICENSE("GPL");

+ 391 - 0
drivers/hwmon/powr1220.c

@@ -0,0 +1,391 @@
+/*
+ * powr1220.c - Driver for the Lattice POWR1220 programmable power supply
+ * and monitor. Users can read all ADC inputs along with their labels
+ * using the sysfs nodes.
+ *
+ * Copyright (c) 2014 Echo360 http://www.echo360.com
+ * Scott Kanowitz <skanowitz@echo360.com> <scott.kanowitz@gmail.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/jiffies.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/delay.h>
+
+#define ADC_STEP_MV			2
+#define ADC_MAX_LOW_MEASUREMENT_MV	2000
+
+enum powr1220_regs {
+	VMON_STATUS0,
+	VMON_STATUS1,
+	VMON_STATUS2,
+	OUTPUT_STATUS0,
+	OUTPUT_STATUS1,
+	OUTPUT_STATUS2,
+	INPUT_STATUS,
+	ADC_VALUE_LOW,
+	ADC_VALUE_HIGH,
+	ADC_MUX,
+	UES_BYTE0,
+	UES_BYTE1,
+	UES_BYTE2,
+	UES_BYTE3,
+	GP_OUTPUT1,
+	GP_OUTPUT2,
+	GP_OUTPUT3,
+	INPUT_VALUE,
+	RESET,
+	TRIM1_TRIM,
+	TRIM2_TRIM,
+	TRIM3_TRIM,
+	TRIM4_TRIM,
+	TRIM5_TRIM,
+	TRIM6_TRIM,
+	TRIM7_TRIM,
+	TRIM8_TRIM,
+	MAX_POWR1220_REGS
+};
+
+enum powr1220_adc_values {
+	VMON1,
+	VMON2,
+	VMON3,
+	VMON4,
+	VMON5,
+	VMON6,
+	VMON7,
+	VMON8,
+	VMON9,
+	VMON10,
+	VMON11,
+	VMON12,
+	VCCA,
+	VCCINP,
+	MAX_POWR1220_ADC_VALUES
+};
+
+struct powr1220_data {
+	struct i2c_client *client;
+	struct mutex update_lock;
+	bool adc_valid[MAX_POWR1220_ADC_VALUES];
+	 /* the next value is in jiffies */
+	unsigned long adc_last_updated[MAX_POWR1220_ADC_VALUES];
+
+	/* values */
+	int adc_maxes[MAX_POWR1220_ADC_VALUES];
+	int adc_values[MAX_POWR1220_ADC_VALUES];
+};
+
+static const char * const input_names[] = {
+	[VMON1]    = "vmon1",
+	[VMON2]    = "vmon2",
+	[VMON3]    = "vmon3",
+	[VMON4]    = "vmon4",
+	[VMON5]    = "vmon5",
+	[VMON6]    = "vmon6",
+	[VMON7]    = "vmon7",
+	[VMON8]    = "vmon8",
+	[VMON9]    = "vmon9",
+	[VMON10]   = "vmon10",
+	[VMON11]   = "vmon11",
+	[VMON12]   = "vmon12",
+	[VCCA]     = "vcca",
+	[VCCINP]   = "vccinp",
+};
+
+/* Reads the specified ADC channel */
+static int powr1220_read_adc(struct device *dev, int ch_num)
+{
+	struct powr1220_data *data = dev_get_drvdata(dev);
+	int reading;
+	int result;
+	int adc_range = 0;
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->adc_last_updated[ch_num] + HZ) ||
+			!data->adc_valid[ch_num]) {
+		/*
+		 * figure out if we need to use the attenuator for
+		 * high inputs or inputs that we don't yet have a measurement
+		 * for. We dynamically set the attenuator depending on the
+		 * max reading.
+		 */
+		if (data->adc_maxes[ch_num] > ADC_MAX_LOW_MEASUREMENT_MV ||
+				data->adc_maxes[ch_num] == 0)
+			adc_range = 1 << 4;
+
+		/* set the attenuator and mux */
+		result = i2c_smbus_write_byte_data(data->client, ADC_MUX,
+				adc_range | ch_num);
+		if (result)
+			goto exit;
+
+		/*
+		 * wait at least Tconvert time (200 us) for the
+		 * conversion to complete
+		 */
+		udelay(200);
+
+		/* get the ADC reading */
+		result = i2c_smbus_read_byte_data(data->client, ADC_VALUE_LOW);
+		if (result < 0)
+			goto exit;
+
+		reading = result >> 4;
+
+		/* get the upper half of the reading */
+		result = i2c_smbus_read_byte_data(data->client, ADC_VALUE_HIGH);
+		if (result < 0)
+			goto exit;
+
+		reading |= result << 4;
+
+		/* now convert the reading to a voltage */
+		reading *= ADC_STEP_MV;
+		data->adc_values[ch_num] = reading;
+		data->adc_valid[ch_num] = true;
+		data->adc_last_updated[ch_num] = jiffies;
+		result = reading;
+
+		if (reading > data->adc_maxes[ch_num])
+			data->adc_maxes[ch_num] = reading;
+	} else {
+		result = data->adc_values[ch_num];
+	}
+
+exit:
+	mutex_unlock(&data->update_lock);
+
+	return result;
+}
+
+/* Shows the voltage associated with the specified ADC channel */
+static ssize_t powr1220_show_voltage(struct device *dev,
+	struct device_attribute *dev_attr, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
+	int adc_val = powr1220_read_adc(dev, attr->index);
+
+	if (adc_val < 0)
+		return adc_val;
+
+	return sprintf(buf, "%d\n", adc_val);
+}
+
+/* Shows the maximum setting associated with the specified ADC channel */
+static ssize_t powr1220_show_max(struct device *dev,
+	struct device_attribute *dev_attr, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
+	struct powr1220_data *data = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%d\n", data->adc_maxes[attr->index]);
+}
+
+/* Shows the label associated with the specified ADC channel */
+static ssize_t powr1220_show_label(struct device *dev,
+	struct device_attribute *dev_attr, char *buf)
+{
+	struct sensor_device_attribute *attr = to_sensor_dev_attr(dev_attr);
+
+	return sprintf(buf, "%s\n", input_names[attr->index]);
+}
+
+static SENSOR_DEVICE_ATTR(in0_input, S_IRUGO, powr1220_show_voltage, NULL,
+	VMON1);
+static SENSOR_DEVICE_ATTR(in1_input, S_IRUGO, powr1220_show_voltage, NULL,
+	VMON2);
+static SENSOR_DEVICE_ATTR(in2_input, S_IRUGO, powr1220_show_voltage, NULL,
+	VMON3);
+static SENSOR_DEVICE_ATTR(in3_input, S_IRUGO, powr1220_show_voltage, NULL,
+	VMON4);
+static SENSOR_DEVICE_ATTR(in4_input, S_IRUGO, powr1220_show_voltage, NULL,
+	VMON5);
+static SENSOR_DEVICE_ATTR(in5_input, S_IRUGO, powr1220_show_voltage, NULL,
+	VMON6);
+static SENSOR_DEVICE_ATTR(in6_input, S_IRUGO, powr1220_show_voltage, NULL,
+	VMON7);
+static SENSOR_DEVICE_ATTR(in7_input, S_IRUGO, powr1220_show_voltage, NULL,
+	VMON8);
+static SENSOR_DEVICE_ATTR(in8_input, S_IRUGO, powr1220_show_voltage, NULL,
+	VMON9);
+static SENSOR_DEVICE_ATTR(in9_input, S_IRUGO, powr1220_show_voltage, NULL,
+	VMON10);
+static SENSOR_DEVICE_ATTR(in10_input, S_IRUGO, powr1220_show_voltage, NULL,
+	VMON11);
+static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, powr1220_show_voltage, NULL,
+	VMON12);
+static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, powr1220_show_voltage, NULL,
+	VCCA);
+static SENSOR_DEVICE_ATTR(in13_input, S_IRUGO, powr1220_show_voltage, NULL,
+	VCCINP);
+
+static SENSOR_DEVICE_ATTR(in0_highest, S_IRUGO, powr1220_show_max, NULL,
+	VMON1);
+static SENSOR_DEVICE_ATTR(in1_highest, S_IRUGO, powr1220_show_max, NULL,
+	VMON2);
+static SENSOR_DEVICE_ATTR(in2_highest, S_IRUGO, powr1220_show_max, NULL,
+	VMON3);
+static SENSOR_DEVICE_ATTR(in3_highest, S_IRUGO, powr1220_show_max, NULL,
+	VMON4);
+static SENSOR_DEVICE_ATTR(in4_highest, S_IRUGO, powr1220_show_max, NULL,
+	VMON5);
+static SENSOR_DEVICE_ATTR(in5_highest, S_IRUGO, powr1220_show_max, NULL,
+	VMON6);
+static SENSOR_DEVICE_ATTR(in6_highest, S_IRUGO, powr1220_show_max, NULL,
+	VMON7);
+static SENSOR_DEVICE_ATTR(in7_highest, S_IRUGO, powr1220_show_max, NULL,
+	VMON8);
+static SENSOR_DEVICE_ATTR(in8_highest, S_IRUGO, powr1220_show_max, NULL,
+	VMON9);
+static SENSOR_DEVICE_ATTR(in9_highest, S_IRUGO, powr1220_show_max, NULL,
+	VMON10);
+static SENSOR_DEVICE_ATTR(in10_highest, S_IRUGO, powr1220_show_max, NULL,
+	VMON11);
+static SENSOR_DEVICE_ATTR(in11_highest, S_IRUGO, powr1220_show_max, NULL,
+	VMON12);
+static SENSOR_DEVICE_ATTR(in12_highest, S_IRUGO, powr1220_show_max, NULL,
+	VCCA);
+static SENSOR_DEVICE_ATTR(in13_highest, S_IRUGO, powr1220_show_max, NULL,
+	VCCINP);
+
+static SENSOR_DEVICE_ATTR(in0_label, S_IRUGO, powr1220_show_label, NULL,
+	VMON1);
+static SENSOR_DEVICE_ATTR(in1_label, S_IRUGO, powr1220_show_label, NULL,
+	VMON2);
+static SENSOR_DEVICE_ATTR(in2_label, S_IRUGO, powr1220_show_label, NULL,
+	VMON3);
+static SENSOR_DEVICE_ATTR(in3_label, S_IRUGO, powr1220_show_label, NULL,
+	VMON4);
+static SENSOR_DEVICE_ATTR(in4_label, S_IRUGO, powr1220_show_label, NULL,
+	VMON5);
+static SENSOR_DEVICE_ATTR(in5_label, S_IRUGO, powr1220_show_label, NULL,
+	VMON6);
+static SENSOR_DEVICE_ATTR(in6_label, S_IRUGO, powr1220_show_label, NULL,
+	VMON7);
+static SENSOR_DEVICE_ATTR(in7_label, S_IRUGO, powr1220_show_label, NULL,
+	VMON8);
+static SENSOR_DEVICE_ATTR(in8_label, S_IRUGO, powr1220_show_label, NULL,
+	VMON9);
+static SENSOR_DEVICE_ATTR(in9_label, S_IRUGO, powr1220_show_label, NULL,
+	VMON10);
+static SENSOR_DEVICE_ATTR(in10_label, S_IRUGO, powr1220_show_label, NULL,
+	VMON11);
+static SENSOR_DEVICE_ATTR(in11_label, S_IRUGO, powr1220_show_label, NULL,
+	VMON12);
+static SENSOR_DEVICE_ATTR(in12_label, S_IRUGO, powr1220_show_label, NULL,
+	VCCA);
+static SENSOR_DEVICE_ATTR(in13_label, S_IRUGO, powr1220_show_label, NULL,
+	VCCINP);
+
+static struct attribute *powr1220_attrs[] = {
+	&sensor_dev_attr_in0_input.dev_attr.attr,
+	&sensor_dev_attr_in1_input.dev_attr.attr,
+	&sensor_dev_attr_in2_input.dev_attr.attr,
+	&sensor_dev_attr_in3_input.dev_attr.attr,
+	&sensor_dev_attr_in4_input.dev_attr.attr,
+	&sensor_dev_attr_in5_input.dev_attr.attr,
+	&sensor_dev_attr_in6_input.dev_attr.attr,
+	&sensor_dev_attr_in7_input.dev_attr.attr,
+	&sensor_dev_attr_in8_input.dev_attr.attr,
+	&sensor_dev_attr_in9_input.dev_attr.attr,
+	&sensor_dev_attr_in10_input.dev_attr.attr,
+	&sensor_dev_attr_in11_input.dev_attr.attr,
+	&sensor_dev_attr_in12_input.dev_attr.attr,
+	&sensor_dev_attr_in13_input.dev_attr.attr,
+
+	&sensor_dev_attr_in0_highest.dev_attr.attr,
+	&sensor_dev_attr_in1_highest.dev_attr.attr,
+	&sensor_dev_attr_in2_highest.dev_attr.attr,
+	&sensor_dev_attr_in3_highest.dev_attr.attr,
+	&sensor_dev_attr_in4_highest.dev_attr.attr,
+	&sensor_dev_attr_in5_highest.dev_attr.attr,
+	&sensor_dev_attr_in6_highest.dev_attr.attr,
+	&sensor_dev_attr_in7_highest.dev_attr.attr,
+	&sensor_dev_attr_in8_highest.dev_attr.attr,
+	&sensor_dev_attr_in9_highest.dev_attr.attr,
+	&sensor_dev_attr_in10_highest.dev_attr.attr,
+	&sensor_dev_attr_in11_highest.dev_attr.attr,
+	&sensor_dev_attr_in12_highest.dev_attr.attr,
+	&sensor_dev_attr_in13_highest.dev_attr.attr,
+
+	&sensor_dev_attr_in0_label.dev_attr.attr,
+	&sensor_dev_attr_in1_label.dev_attr.attr,
+	&sensor_dev_attr_in2_label.dev_attr.attr,
+	&sensor_dev_attr_in3_label.dev_attr.attr,
+	&sensor_dev_attr_in4_label.dev_attr.attr,
+	&sensor_dev_attr_in5_label.dev_attr.attr,
+	&sensor_dev_attr_in6_label.dev_attr.attr,
+	&sensor_dev_attr_in7_label.dev_attr.attr,
+	&sensor_dev_attr_in8_label.dev_attr.attr,
+	&sensor_dev_attr_in9_label.dev_attr.attr,
+	&sensor_dev_attr_in10_label.dev_attr.attr,
+	&sensor_dev_attr_in11_label.dev_attr.attr,
+	&sensor_dev_attr_in12_label.dev_attr.attr,
+	&sensor_dev_attr_in13_label.dev_attr.attr,
+
+	NULL
+};
+
+ATTRIBUTE_GROUPS(powr1220);
+
+static int powr1220_probe(struct i2c_client *client,
+		const struct i2c_device_id *id)
+{
+	struct powr1220_data *data;
+	struct device *hwmon_dev;
+
+	if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	mutex_init(&data->update_lock);
+	data->client = client;
+
+	hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev,
+			client->name, data, powr1220_groups);
+
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+static const struct i2c_device_id powr1220_ids[] = {
+	{ "powr1220", 0, },
+	{ }
+};
+
+MODULE_DEVICE_TABLE(i2c, powr1220_ids);
+
+static struct i2c_driver powr1220_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "powr1220",
+	},
+	.probe		= powr1220_probe,
+	.id_table	= powr1220_ids,
+};
+
+module_i2c_driver(powr1220_driver);
+
+MODULE_AUTHOR("Scott Kanowitz");
+MODULE_DESCRIPTION("POWR1220 driver");
+MODULE_LICENSE("GPL");

+ 193 - 0
drivers/hwmon/pwm-fan.c

@@ -0,0 +1,193 @@
+/*
+ * pwm-fan.c - Hwmon driver for fans connected to PWM lines.
+ *
+ * Copyright (c) 2014 Samsung Electronics Co., Ltd.
+ *
+ * Author: Kamil Debski <k.debski@samsung.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/module.h>
+#include <linux/mutex.h>
+#include <linux/of.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/sysfs.h>
+
+#define MAX_PWM 255
+
+struct pwm_fan_ctx {
+	struct mutex lock;
+	struct pwm_device *pwm;
+	unsigned char pwm_value;
+};
+
+static ssize_t set_pwm(struct device *dev, struct device_attribute *attr,
+		       const char *buf, size_t count)
+{
+	struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
+	unsigned long pwm, duty;
+	ssize_t ret;
+
+	if (kstrtoul(buf, 10, &pwm) || pwm > MAX_PWM)
+		return -EINVAL;
+
+	mutex_lock(&ctx->lock);
+
+	if (ctx->pwm_value == pwm)
+		goto exit_set_pwm_no_change;
+
+	if (pwm == 0) {
+		pwm_disable(ctx->pwm);
+		goto exit_set_pwm;
+	}
+
+	duty = DIV_ROUND_UP(pwm * (ctx->pwm->period - 1), MAX_PWM);
+	ret = pwm_config(ctx->pwm, duty, ctx->pwm->period);
+	if (ret)
+		goto exit_set_pwm_err;
+
+	if (ctx->pwm_value == 0) {
+		ret = pwm_enable(ctx->pwm);
+		if (ret)
+			goto exit_set_pwm_err;
+	}
+
+exit_set_pwm:
+	ctx->pwm_value = pwm;
+exit_set_pwm_no_change:
+	ret = count;
+exit_set_pwm_err:
+	mutex_unlock(&ctx->lock);
+	return ret;
+}
+
+static ssize_t show_pwm(struct device *dev,
+			struct device_attribute *attr, char *buf)
+{
+	struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
+
+	return sprintf(buf, "%u\n", ctx->pwm_value);
+}
+
+
+static SENSOR_DEVICE_ATTR(pwm1, S_IRUGO | S_IWUSR, show_pwm, set_pwm, 0);
+
+static struct attribute *pwm_fan_attrs[] = {
+	&sensor_dev_attr_pwm1.dev_attr.attr,
+	NULL,
+};
+
+ATTRIBUTE_GROUPS(pwm_fan);
+
+static int pwm_fan_probe(struct platform_device *pdev)
+{
+	struct device *hwmon;
+	struct pwm_fan_ctx *ctx;
+	int duty_cycle;
+	int ret;
+
+	ctx = devm_kzalloc(&pdev->dev, sizeof(*ctx), GFP_KERNEL);
+	if (!ctx)
+		return -ENOMEM;
+
+	mutex_init(&ctx->lock);
+
+	ctx->pwm = devm_of_pwm_get(&pdev->dev, pdev->dev.of_node, NULL);
+	if (IS_ERR(ctx->pwm)) {
+		dev_err(&pdev->dev, "Could not get PWM\n");
+		return PTR_ERR(ctx->pwm);
+	}
+
+	platform_set_drvdata(pdev, ctx);
+
+	/* Set duty cycle to maximum allowed */
+	duty_cycle = ctx->pwm->period - 1;
+	ctx->pwm_value = MAX_PWM;
+
+	ret = pwm_config(ctx->pwm, duty_cycle, ctx->pwm->period);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to configure PWM\n");
+		return ret;
+	}
+
+	/* Enbale PWM output */
+	ret = pwm_enable(ctx->pwm);
+	if (ret) {
+		dev_err(&pdev->dev, "Failed to enable PWM\n");
+		return ret;
+	}
+
+	hwmon = devm_hwmon_device_register_with_groups(&pdev->dev, "pwmfan",
+						       ctx, pwm_fan_groups);
+	if (IS_ERR(hwmon)) {
+		dev_err(&pdev->dev, "Failed to register hwmon device\n");
+		pwm_disable(ctx->pwm);
+		return PTR_ERR(hwmon);
+	}
+	return 0;
+}
+
+static int pwm_fan_remove(struct platform_device *pdev)
+{
+	struct pwm_fan_ctx *ctx = platform_get_drvdata(pdev);
+
+	if (ctx->pwm_value)
+		pwm_disable(ctx->pwm);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pwm_fan_suspend(struct device *dev)
+{
+	struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
+
+	if (ctx->pwm_value)
+		pwm_disable(ctx->pwm);
+	return 0;
+}
+
+static int pwm_fan_resume(struct device *dev)
+{
+	struct pwm_fan_ctx *ctx = dev_get_drvdata(dev);
+
+	if (ctx->pwm_value)
+		return pwm_enable(ctx->pwm);
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(pwm_fan_pm, pwm_fan_suspend, pwm_fan_resume);
+
+static struct of_device_id of_pwm_fan_match[] = {
+	{ .compatible = "pwm-fan", },
+	{},
+};
+
+static struct platform_driver pwm_fan_driver = {
+	.probe		= pwm_fan_probe,
+	.remove		= pwm_fan_remove,
+	.driver	= {
+		.name		= "pwm-fan",
+		.pm		= &pwm_fan_pm,
+		.of_match_table	= of_pwm_fan_match,
+	},
+};
+
+module_platform_driver(pwm_fan_driver);
+
+MODULE_AUTHOR("Kamil Debski <k.debski@samsung.com>");
+MODULE_ALIAS("platform:pwm-fan");
+MODULE_DESCRIPTION("PWM FAN driver");
+MODULE_LICENSE("GPL");

+ 22 - 60
drivers/hwmon/sht21.c

@@ -45,7 +45,7 @@
  * @humidity: cached humidity measurement value
  * @humidity: cached humidity measurement value
  */
  */
 struct sht21 {
 struct sht21 {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
 	struct mutex lock;
 	struct mutex lock;
 	char valid;
 	char valid;
 	unsigned long last_update;
 	unsigned long last_update;
@@ -85,14 +85,15 @@ static inline int sht21_rh_ticks_to_per_cent_mille(int ticks)
 
 
 /**
 /**
  * sht21_update_measurements() - get updated measurements from device
  * sht21_update_measurements() - get updated measurements from device
- * @client: I2C client device
+ * @dev: device
  *
  *
  * Returns 0 on success, else negative errno.
  * Returns 0 on success, else negative errno.
  */
  */
-static int sht21_update_measurements(struct i2c_client *client)
+static int sht21_update_measurements(struct device *dev)
 {
 {
 	int ret = 0;
 	int ret = 0;
-	struct sht21 *sht21 = i2c_get_clientdata(client);
+	struct sht21 *sht21 = dev_get_drvdata(dev);
+	struct i2c_client *client = sht21->client;
 
 
 	mutex_lock(&sht21->lock);
 	mutex_lock(&sht21->lock);
 	/*
 	/*
@@ -133,9 +134,10 @@ static ssize_t sht21_show_temperature(struct device *dev,
 	struct device_attribute *attr,
 	struct device_attribute *attr,
 	char *buf)
 	char *buf)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct sht21 *sht21 = i2c_get_clientdata(client);
-	int ret = sht21_update_measurements(client);
+	struct sht21 *sht21 = dev_get_drvdata(dev);
+	int ret;
+
+	ret = sht21_update_measurements(dev);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 	return sprintf(buf, "%d\n", sht21->temperature);
 	return sprintf(buf, "%d\n", sht21->temperature);
@@ -154,9 +156,10 @@ static ssize_t sht21_show_humidity(struct device *dev,
 	struct device_attribute *attr,
 	struct device_attribute *attr,
 	char *buf)
 	char *buf)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct sht21 *sht21 = i2c_get_clientdata(client);
-	int ret = sht21_update_measurements(client);
+	struct sht21 *sht21 = dev_get_drvdata(dev);
+	int ret;
+
+	ret = sht21_update_measurements(dev);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 	return sprintf(buf, "%d\n", sht21->humidity);
 	return sprintf(buf, "%d\n", sht21->humidity);
@@ -168,30 +171,20 @@ static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, sht21_show_temperature,
 static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO, sht21_show_humidity,
 static SENSOR_DEVICE_ATTR(humidity1_input, S_IRUGO, sht21_show_humidity,
 	NULL, 0);
 	NULL, 0);
 
 
-static struct attribute *sht21_attributes[] = {
+static struct attribute *sht21_attrs[] = {
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_humidity1_input.dev_attr.attr,
 	&sensor_dev_attr_humidity1_input.dev_attr.attr,
 	NULL
 	NULL
 };
 };
 
 
-static const struct attribute_group sht21_attr_group = {
-	.attrs = sht21_attributes,
-};
+ATTRIBUTE_GROUPS(sht21);
 
 
-/**
- * sht21_probe() - probe device
- * @client: I2C client device
- * @id: device ID
- *
- * Called by the I2C core when an entry in the ID table matches a
- * device's name.
- * Returns 0 on success.
- */
 static int sht21_probe(struct i2c_client *client,
 static int sht21_probe(struct i2c_client *client,
 	const struct i2c_device_id *id)
 	const struct i2c_device_id *id)
 {
 {
+	struct device *dev = &client->dev;
+	struct device *hwmon_dev;
 	struct sht21 *sht21;
 	struct sht21 *sht21;
-	int err;
 
 
 	if (!i2c_check_functionality(client->adapter,
 	if (!i2c_check_functionality(client->adapter,
 				     I2C_FUNC_SMBUS_WORD_DATA)) {
 				     I2C_FUNC_SMBUS_WORD_DATA)) {
@@ -200,47 +193,17 @@ static int sht21_probe(struct i2c_client *client,
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
 
 
-	sht21 = devm_kzalloc(&client->dev, sizeof(*sht21), GFP_KERNEL);
+	sht21 = devm_kzalloc(dev, sizeof(*sht21), GFP_KERNEL);
 	if (!sht21)
 	if (!sht21)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	i2c_set_clientdata(client, sht21);
+	sht21->client = client;
 
 
 	mutex_init(&sht21->lock);
 	mutex_init(&sht21->lock);
 
 
-	err = sysfs_create_group(&client->dev.kobj, &sht21_attr_group);
-	if (err) {
-		dev_dbg(&client->dev, "could not create sysfs files\n");
-		return err;
-	}
-	sht21->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(sht21->hwmon_dev)) {
-		dev_dbg(&client->dev, "unable to register hwmon device\n");
-		err = PTR_ERR(sht21->hwmon_dev);
-		goto fail_remove_sysfs;
-	}
-
-	dev_info(&client->dev, "initialized\n");
-
-	return 0;
-
-fail_remove_sysfs:
-	sysfs_remove_group(&client->dev.kobj, &sht21_attr_group);
-	return err;
-}
-
-/**
- * sht21_remove() - remove device
- * @client: I2C client device
- */
-static int sht21_remove(struct i2c_client *client)
-{
-	struct sht21 *sht21 = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(sht21->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &sht21_attr_group);
-
-	return 0;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   sht21, sht21_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
 /* Device ID table */
 /* Device ID table */
@@ -253,7 +216,6 @@ MODULE_DEVICE_TABLE(i2c, sht21_id);
 static struct i2c_driver sht21_driver = {
 static struct i2c_driver sht21_driver = {
 	.driver.name = "sht21",
 	.driver.name = "sht21",
 	.probe       = sht21_probe,
 	.probe       = sht21_probe,
-	.remove      = sht21_remove,
 	.id_table    = sht21_id,
 	.id_table    = sht21_id,
 };
 };
 
 

+ 1 - 1
drivers/hwmon/sis5595.c

@@ -159,7 +159,7 @@ static inline int TEMP_FROM_REG(s8 val)
 {
 {
 	return val * 830 + 52120;
 	return val * 830 + 52120;
 }
 }
-static inline s8 TEMP_TO_REG(int val)
+static inline s8 TEMP_TO_REG(long val)
 {
 {
 	int nval = clamp_val(val, -54120, 157530) ;
 	int nval = clamp_val(val, -54120, 157530) ;
 	return nval < 0 ? (nval - 5212 - 415) / 830 : (nval - 5212 + 415) / 830;
 	return nval < 0 ? (nval - 5212 - 415) / 830 : (nval - 5212 + 415) / 830;

+ 16 - 28
drivers/hwmon/smm665.c

@@ -140,7 +140,7 @@ enum chips { smm465, smm665, smm665c, smm764, smm766 };
 struct smm665_data {
 struct smm665_data {
 	enum chips type;
 	enum chips type;
 	int conversion_time;		/* ADC conversion time */
 	int conversion_time;		/* ADC conversion time */
-	struct device *hwmon_dev;
+	struct i2c_client *client;
 	struct mutex update_lock;
 	struct mutex update_lock;
 	bool valid;
 	bool valid;
 	unsigned long last_updated;	/* in jiffies */
 	unsigned long last_updated;	/* in jiffies */
@@ -239,8 +239,8 @@ static int smm665_read_adc(struct smm665_data *data, int adc)
 
 
 static struct smm665_data *smm665_update_device(struct device *dev)
 static struct smm665_data *smm665_update_device(struct device *dev)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct smm665_data *data = i2c_get_clientdata(client);
+	struct smm665_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	struct smm665_data *ret = data;
 	struct smm665_data *ret = data;
 
 
 	mutex_lock(&data->update_lock);
 	mutex_lock(&data->update_lock);
@@ -315,32 +315,28 @@ static int smm665_convert(u16 adcval, int index)
 
 
 static int smm665_get_min(struct device *dev, int index)
 static int smm665_get_min(struct device *dev, int index)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct smm665_data *data = i2c_get_clientdata(client);
+	struct smm665_data *data = dev_get_drvdata(dev);
 
 
 	return data->alarm_min_limit[index];
 	return data->alarm_min_limit[index];
 }
 }
 
 
 static int smm665_get_max(struct device *dev, int index)
 static int smm665_get_max(struct device *dev, int index)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct smm665_data *data = i2c_get_clientdata(client);
+	struct smm665_data *data = dev_get_drvdata(dev);
 
 
 	return data->alarm_max_limit[index];
 	return data->alarm_max_limit[index];
 }
 }
 
 
 static int smm665_get_lcrit(struct device *dev, int index)
 static int smm665_get_lcrit(struct device *dev, int index)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct smm665_data *data = i2c_get_clientdata(client);
+	struct smm665_data *data = dev_get_drvdata(dev);
 
 
 	return data->critical_min_limit[index];
 	return data->critical_min_limit[index];
 }
 }
 
 
 static int smm665_get_crit(struct device *dev, int index)
 static int smm665_get_crit(struct device *dev, int index)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct smm665_data *data = i2c_get_clientdata(client);
+	struct smm665_data *data = dev_get_drvdata(dev);
 
 
 	return data->critical_max_limit[index];
 	return data->critical_max_limit[index];
 }
 }
@@ -486,7 +482,7 @@ SMM665_ATTR(temp1, crit_alarm, SMM665_FAULT_TEMP);
  * Finally, construct an array of pointers to members of the above objects,
  * Finally, construct an array of pointers to members of the above objects,
  * as required for sysfs_create_group()
  * as required for sysfs_create_group()
  */
  */
-static struct attribute *smm665_attributes[] = {
+static struct attribute *smm665_attrs[] = {
 	&sensor_dev_attr_in1_input.dev_attr.attr,
 	&sensor_dev_attr_in1_input.dev_attr.attr,
 	&sensor_dev_attr_in1_min.dev_attr.attr,
 	&sensor_dev_attr_in1_min.dev_attr.attr,
 	&sensor_dev_attr_in1_max.dev_attr.attr,
 	&sensor_dev_attr_in1_max.dev_attr.attr,
@@ -567,15 +563,14 @@ static struct attribute *smm665_attributes[] = {
 	NULL,
 	NULL,
 };
 };
 
 
-static const struct attribute_group smm665_group = {
-	.attrs = smm665_attributes,
-};
+ATTRIBUTE_GROUPS(smm665);
 
 
 static int smm665_probe(struct i2c_client *client,
 static int smm665_probe(struct i2c_client *client,
 			const struct i2c_device_id *id)
 			const struct i2c_device_id *id)
 {
 {
 	struct i2c_adapter *adapter = client->adapter;
 	struct i2c_adapter *adapter = client->adapter;
 	struct smm665_data *data;
 	struct smm665_data *data;
+	struct device *hwmon_dev;
 	int i, ret;
 	int i, ret;
 
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA
@@ -592,6 +587,7 @@ static int smm665_probe(struct i2c_client *client,
 	i2c_set_clientdata(client, data);
 	i2c_set_clientdata(client, data);
 	mutex_init(&data->update_lock);
 	mutex_init(&data->update_lock);
 
 
+	data->client = client;
 	data->type = id->driver_data;
 	data->type = id->driver_data;
 	data->cmdreg = i2c_new_dummy(adapter, (client->addr & ~SMM665_REGMASK)
 	data->cmdreg = i2c_new_dummy(adapter, (client->addr & ~SMM665_REGMASK)
 				     | SMM665_CMDREG_BASE);
 				     | SMM665_CMDREG_BASE);
@@ -662,21 +658,16 @@ static int smm665_probe(struct i2c_client *client,
 			data->alarm_max_limit[i] = smm665_convert(val, i);
 			data->alarm_max_limit[i] = smm665_convert(val, i);
 	}
 	}
 
 
-	/* Register sysfs hooks */
-	ret = sysfs_create_group(&client->dev.kobj, &smm665_group);
-	if (ret)
+	hwmon_dev = devm_hwmon_device_register_with_groups(&client->dev,
+							   client->name, data,
+							   smm665_groups);
+	if (IS_ERR(hwmon_dev)) {
+		ret = PTR_ERR(hwmon_dev);
 		goto out_unregister;
 		goto out_unregister;
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		ret = PTR_ERR(data->hwmon_dev);
-		goto out_remove_group;
 	}
 	}
 
 
 	return 0;
 	return 0;
 
 
-out_remove_group:
-	sysfs_remove_group(&client->dev.kobj, &smm665_group);
 out_unregister:
 out_unregister:
 	i2c_unregister_device(data->cmdreg);
 	i2c_unregister_device(data->cmdreg);
 	return ret;
 	return ret;
@@ -687,9 +678,6 @@ static int smm665_remove(struct i2c_client *client)
 	struct smm665_data *data = i2c_get_clientdata(client);
 	struct smm665_data *data = i2c_get_clientdata(client);
 
 
 	i2c_unregister_device(data->cmdreg);
 	i2c_unregister_device(data->cmdreg);
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &smm665_group);
-
 	return 0;
 	return 0;
 }
 }
 
 

+ 55 - 60
drivers/hwmon/smsc47m1.c

@@ -142,11 +142,6 @@ struct smsc47m1_sio_data {
 	u8 activate;		/* Remember initial device state */
 	u8 activate;		/* Remember initial device state */
 };
 };
 
 
-
-static int __exit smsc47m1_remove(struct platform_device *pdev);
-static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
-		int init);
-
 static inline int smsc47m1_read_value(struct smsc47m1_data *data, u8 reg)
 static inline int smsc47m1_read_value(struct smsc47m1_data *data, u8 reg)
 {
 {
 	return inb_p(data->addr + reg);
 	return inb_p(data->addr + reg);
@@ -158,13 +153,54 @@ static inline void smsc47m1_write_value(struct smsc47m1_data *data, u8 reg,
 	outb_p(value, data->addr + reg);
 	outb_p(value, data->addr + reg);
 }
 }
 
 
-static struct platform_driver smsc47m1_driver = {
-	.driver = {
-		.owner	= THIS_MODULE,
-		.name	= DRVNAME,
-	},
-	.remove		= __exit_p(smsc47m1_remove),
-};
+static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
+		int init)
+{
+	struct smsc47m1_data *data = dev_get_drvdata(dev);
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) {
+		int i, fan_nr;
+		fan_nr = data->type == smsc47m2 ? 3 : 2;
+
+		for (i = 0; i < fan_nr; i++) {
+			data->fan[i] = smsc47m1_read_value(data,
+				       SMSC47M1_REG_FAN[i]);
+			data->fan_preload[i] = smsc47m1_read_value(data,
+					       SMSC47M1_REG_FAN_PRELOAD[i]);
+			data->pwm[i] = smsc47m1_read_value(data,
+				       SMSC47M1_REG_PWM[i]);
+		}
+
+		i = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV);
+		data->fan_div[0] = (i >> 4) & 0x03;
+		data->fan_div[1] = i >> 6;
+
+		data->alarms = smsc47m1_read_value(data,
+			       SMSC47M1_REG_ALARM) >> 6;
+		/* Clear alarms if needed */
+		if (data->alarms)
+			smsc47m1_write_value(data, SMSC47M1_REG_ALARM, 0xC0);
+
+		if (fan_nr >= 3) {
+			data->fan_div[2] = (smsc47m1_read_value(data,
+					    SMSC47M2_REG_FANDIV3) >> 4) & 0x03;
+			data->alarms |= (smsc47m1_read_value(data,
+					 SMSC47M2_REG_ALARM6) & 0x40) >> 4;
+			/* Clear alarm if needed */
+			if (data->alarms & 0x04)
+				smsc47m1_write_value(data,
+						     SMSC47M2_REG_ALARM6,
+						     0x40);
+		}
+
+		data->last_updated = jiffies;
+	}
+
+	mutex_unlock(&data->update_lock);
+	return data;
+}
 
 
 static ssize_t get_fan(struct device *dev, struct device_attribute
 static ssize_t get_fan(struct device *dev, struct device_attribute
 		       *devattr, char *buf)
 		       *devattr, char *buf)
@@ -811,54 +847,13 @@ static int __exit smsc47m1_remove(struct platform_device *pdev)
 	return 0;
 	return 0;
 }
 }
 
 
-static struct smsc47m1_data *smsc47m1_update_device(struct device *dev,
-		int init)
-{
-	struct smsc47m1_data *data = dev_get_drvdata(dev);
-
-	mutex_lock(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2) || init) {
-		int i, fan_nr;
-		fan_nr = data->type == smsc47m2 ? 3 : 2;
-
-		for (i = 0; i < fan_nr; i++) {
-			data->fan[i] = smsc47m1_read_value(data,
-				       SMSC47M1_REG_FAN[i]);
-			data->fan_preload[i] = smsc47m1_read_value(data,
-					       SMSC47M1_REG_FAN_PRELOAD[i]);
-			data->pwm[i] = smsc47m1_read_value(data,
-				       SMSC47M1_REG_PWM[i]);
-		}
-
-		i = smsc47m1_read_value(data, SMSC47M1_REG_FANDIV);
-		data->fan_div[0] = (i >> 4) & 0x03;
-		data->fan_div[1] = i >> 6;
-
-		data->alarms = smsc47m1_read_value(data,
-			       SMSC47M1_REG_ALARM) >> 6;
-		/* Clear alarms if needed */
-		if (data->alarms)
-			smsc47m1_write_value(data, SMSC47M1_REG_ALARM, 0xC0);
-
-		if (fan_nr >= 3) {
-			data->fan_div[2] = (smsc47m1_read_value(data,
-					    SMSC47M2_REG_FANDIV3) >> 4) & 0x03;
-			data->alarms |= (smsc47m1_read_value(data,
-					 SMSC47M2_REG_ALARM6) & 0x40) >> 4;
-			/* Clear alarm if needed */
-			if (data->alarms & 0x04)
-				smsc47m1_write_value(data,
-						     SMSC47M2_REG_ALARM6,
-						     0x40);
-		}
-
-		data->last_updated = jiffies;
-	}
-
-	mutex_unlock(&data->update_lock);
-	return data;
-}
+static struct platform_driver smsc47m1_driver = {
+	.driver = {
+		.owner	= THIS_MODULE,
+		.name	= DRVNAME,
+	},
+	.remove		= __exit_p(smsc47m1_remove),
+};
 
 
 static int __init smsc47m1_device_add(unsigned short address,
 static int __init smsc47m1_device_add(unsigned short address,
 				      const struct smsc47m1_sio_data *sio_data)
 				      const struct smsc47m1_sio_data *sio_data)

+ 99 - 133
drivers/hwmon/smsc47m192.c

@@ -95,7 +95,8 @@ static inline int TEMP_FROM_REG(s8 val)
 }
 }
 
 
 struct smsc47m192_data {
 struct smsc47m192_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
+	const struct attribute_group *groups[3];
 	struct mutex update_lock;
 	struct mutex update_lock;
 	char valid;		/* !=0 if following fields are valid */
 	char valid;		/* !=0 if following fields are valid */
 	unsigned long last_updated;	/* In jiffies */
 	unsigned long last_updated;	/* In jiffies */
@@ -112,30 +113,69 @@ struct smsc47m192_data {
 	u8 vrm;
 	u8 vrm;
 };
 };
 
 
-static int smsc47m192_probe(struct i2c_client *client,
-			    const struct i2c_device_id *id);
-static int smsc47m192_detect(struct i2c_client *client,
-			     struct i2c_board_info *info);
-static int smsc47m192_remove(struct i2c_client *client);
-static struct smsc47m192_data *smsc47m192_update_device(struct device *dev);
+static struct smsc47m192_data *smsc47m192_update_device(struct device *dev)
+{
+	struct smsc47m192_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
+	int i, config;
 
 
-static const struct i2c_device_id smsc47m192_id[] = {
-	{ "smsc47m192", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, smsc47m192_id);
+	mutex_lock(&data->update_lock);
 
 
-static struct i2c_driver smsc47m192_driver = {
-	.class		= I2C_CLASS_HWMON,
-	.driver = {
-		.name	= "smsc47m192",
-	},
-	.probe		= smsc47m192_probe,
-	.remove		= smsc47m192_remove,
-	.id_table	= smsc47m192_id,
-	.detect		= smsc47m192_detect,
-	.address_list	= normal_i2c,
-};
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	 || !data->valid) {
+		u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
+
+		dev_dbg(&client->dev, "Starting smsc47m192 update\n");
+
+		for (i = 0; i <= 7; i++) {
+			data->in[i] = i2c_smbus_read_byte_data(client,
+						SMSC47M192_REG_IN(i));
+			data->in_min[i] = i2c_smbus_read_byte_data(client,
+						SMSC47M192_REG_IN_MIN(i));
+			data->in_max[i] = i2c_smbus_read_byte_data(client,
+						SMSC47M192_REG_IN_MAX(i));
+		}
+		for (i = 0; i < 3; i++) {
+			data->temp[i] = i2c_smbus_read_byte_data(client,
+						SMSC47M192_REG_TEMP[i]);
+			data->temp_max[i] = i2c_smbus_read_byte_data(client,
+						SMSC47M192_REG_TEMP_MAX[i]);
+			data->temp_min[i] = i2c_smbus_read_byte_data(client,
+						SMSC47M192_REG_TEMP_MIN[i]);
+		}
+		for (i = 1; i < 3; i++)
+			data->temp_offset[i] = i2c_smbus_read_byte_data(client,
+						SMSC47M192_REG_TEMP_OFFSET(i));
+		/*
+		 * first offset is temp_offset[0] if SFR bit 4 is set,
+		 * temp_offset[1] otherwise
+		 */
+		if (sfr & 0x10) {
+			data->temp_offset[0] = data->temp_offset[1];
+			data->temp_offset[1] = 0;
+		} else
+			data->temp_offset[0] = 0;
+
+		data->vid = i2c_smbus_read_byte_data(client, SMSC47M192_REG_VID)
+			    & 0x0f;
+		config = i2c_smbus_read_byte_data(client,
+						  SMSC47M192_REG_CONFIG);
+		if (config & 0x20)
+			data->vid |= (i2c_smbus_read_byte_data(client,
+					SMSC47M192_REG_VID4) & 0x01) << 4;
+		data->alarms = i2c_smbus_read_byte_data(client,
+						SMSC47M192_REG_ALARM1) |
+			       (i2c_smbus_read_byte_data(client,
+						SMSC47M192_REG_ALARM2) << 8);
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
 
 
 /* Voltages */
 /* Voltages */
 static ssize_t show_in(struct device *dev, struct device_attribute *attr,
 static ssize_t show_in(struct device *dev, struct device_attribute *attr,
@@ -170,8 +210,8 @@ static ssize_t set_in_min(struct device *dev, struct device_attribute *attr,
 {
 {
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	int nr = sensor_attr->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct smsc47m192_data *data = i2c_get_clientdata(client);
+	struct smsc47m192_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -192,8 +232,8 @@ static ssize_t set_in_max(struct device *dev, struct device_attribute *attr,
 {
 {
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	int nr = sensor_attr->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct smsc47m192_data *data = i2c_get_clientdata(client);
+	struct smsc47m192_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -259,8 +299,8 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
 {
 {
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	int nr = sensor_attr->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct smsc47m192_data *data = i2c_get_clientdata(client);
+	struct smsc47m192_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -281,8 +321,8 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 {
 {
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	int nr = sensor_attr->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct smsc47m192_data *data = i2c_get_clientdata(client);
+	struct smsc47m192_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -312,8 +352,8 @@ static ssize_t set_temp_offset(struct device *dev, struct device_attribute
 {
 {
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	struct sensor_device_attribute *sensor_attr = to_sensor_dev_attr(attr);
 	int nr = sensor_attr->index;
 	int nr = sensor_attr->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct smsc47m192_data *data = i2c_get_clientdata(client);
+	struct smsc47m192_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
 	u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
 	long val;
 	long val;
 	int err;
 	int err;
@@ -552,124 +592,50 @@ static int smsc47m192_detect(struct i2c_client *client,
 static int smsc47m192_probe(struct i2c_client *client,
 static int smsc47m192_probe(struct i2c_client *client,
 			    const struct i2c_device_id *id)
 			    const struct i2c_device_id *id)
 {
 {
+	struct device *dev = &client->dev;
+	struct device *hwmon_dev;
 	struct smsc47m192_data *data;
 	struct smsc47m192_data *data;
 	int config;
 	int config;
-	int err;
 
 
-	data = devm_kzalloc(&client->dev, sizeof(struct smsc47m192_data),
-			    GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(struct smsc47m192_data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	i2c_set_clientdata(client, data);
+	data->client = client;
 	data->vrm = vid_which_vrm();
 	data->vrm = vid_which_vrm();
 	mutex_init(&data->update_lock);
 	mutex_init(&data->update_lock);
 
 
 	/* Initialize the SMSC47M192 chip */
 	/* Initialize the SMSC47M192 chip */
 	smsc47m192_init_client(client);
 	smsc47m192_init_client(client);
 
 
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&client->dev.kobj, &smsc47m192_group);
-	if (err)
-		return err;
-
+	/* sysfs hooks */
+	data->groups[0] = &smsc47m192_group;
 	/* Pin 110 is either in4 (+12V) or VID4 */
 	/* Pin 110 is either in4 (+12V) or VID4 */
 	config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG);
 	config = i2c_smbus_read_byte_data(client, SMSC47M192_REG_CONFIG);
-	if (!(config & 0x20)) {
-		err = sysfs_create_group(&client->dev.kobj,
-					 &smsc47m192_group_in4);
-		if (err)
-			goto exit_remove_files;
-	}
-
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove_files;
-	}
-
-	return 0;
-
-exit_remove_files:
-	sysfs_remove_group(&client->dev.kobj, &smsc47m192_group);
-	sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4);
-	return err;
-}
-
-static int smsc47m192_remove(struct i2c_client *client)
-{
-	struct smsc47m192_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &smsc47m192_group);
-	sysfs_remove_group(&client->dev.kobj, &smsc47m192_group_in4);
+	if (!(config & 0x20))
+		data->groups[1] = &smsc47m192_group_in4;
 
 
-	return 0;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data, data->groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
-static struct smsc47m192_data *smsc47m192_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct smsc47m192_data *data = i2c_get_clientdata(client);
-	int i, config;
-
-	mutex_lock(&data->update_lock);
-
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	 || !data->valid) {
-		u8 sfr = i2c_smbus_read_byte_data(client, SMSC47M192_REG_SFR);
-
-		dev_dbg(&client->dev, "Starting smsc47m192 update\n");
-
-		for (i = 0; i <= 7; i++) {
-			data->in[i] = i2c_smbus_read_byte_data(client,
-						SMSC47M192_REG_IN(i));
-			data->in_min[i] = i2c_smbus_read_byte_data(client,
-						SMSC47M192_REG_IN_MIN(i));
-			data->in_max[i] = i2c_smbus_read_byte_data(client,
-						SMSC47M192_REG_IN_MAX(i));
-		}
-		for (i = 0; i < 3; i++) {
-			data->temp[i] = i2c_smbus_read_byte_data(client,
-						SMSC47M192_REG_TEMP[i]);
-			data->temp_max[i] = i2c_smbus_read_byte_data(client,
-						SMSC47M192_REG_TEMP_MAX[i]);
-			data->temp_min[i] = i2c_smbus_read_byte_data(client,
-						SMSC47M192_REG_TEMP_MIN[i]);
-		}
-		for (i = 1; i < 3; i++)
-			data->temp_offset[i] = i2c_smbus_read_byte_data(client,
-						SMSC47M192_REG_TEMP_OFFSET(i));
-		/*
-		 * first offset is temp_offset[0] if SFR bit 4 is set,
-		 * temp_offset[1] otherwise
-		 */
-		if (sfr & 0x10) {
-			data->temp_offset[0] = data->temp_offset[1];
-			data->temp_offset[1] = 0;
-		} else
-			data->temp_offset[0] = 0;
-
-		data->vid = i2c_smbus_read_byte_data(client, SMSC47M192_REG_VID)
-			    & 0x0f;
-		config = i2c_smbus_read_byte_data(client,
-						  SMSC47M192_REG_CONFIG);
-		if (config & 0x20)
-			data->vid |= (i2c_smbus_read_byte_data(client,
-					SMSC47M192_REG_VID4) & 0x01) << 4;
-		data->alarms = i2c_smbus_read_byte_data(client,
-						SMSC47M192_REG_ALARM1) |
-			       (i2c_smbus_read_byte_data(client,
-						SMSC47M192_REG_ALARM2) << 8);
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	mutex_unlock(&data->update_lock);
+static const struct i2c_device_id smsc47m192_id[] = {
+	{ "smsc47m192", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, smsc47m192_id);
 
 
-	return data;
-}
+static struct i2c_driver smsc47m192_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "smsc47m192",
+	},
+	.probe		= smsc47m192_probe,
+	.id_table	= smsc47m192_id,
+	.detect		= smsc47m192_detect,
+	.address_list	= normal_i2c,
+};
 
 
 module_i2c_driver(smsc47m192_driver);
 module_i2c_driver(smsc47m192_driver);
 
 

+ 88 - 124
drivers/hwmon/thmc50.c

@@ -68,7 +68,8 @@ static const u8 THMC50_REG_TEMP_DEFAULT[] = { 0x17, 0x18, 0x18 };
 
 
 /* Each client has this additional data */
 /* Each client has this additional data */
 struct thmc50_data {
 struct thmc50_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
+	const struct attribute_group *groups[3];
 
 
 	struct mutex update_lock;
 	struct mutex update_lock;
 	enum chips type;
 	enum chips type;
@@ -85,32 +86,47 @@ struct thmc50_data {
 	u8 alarms;
 	u8 alarms;
 };
 };
 
 
-static int thmc50_detect(struct i2c_client *client,
-			 struct i2c_board_info *info);
-static int thmc50_probe(struct i2c_client *client,
-			const struct i2c_device_id *id);
-static int thmc50_remove(struct i2c_client *client);
-static void thmc50_init_client(struct i2c_client *client);
-static struct thmc50_data *thmc50_update_device(struct device *dev);
+static struct thmc50_data *thmc50_update_device(struct device *dev)
+{
+	struct thmc50_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
+	int timeout = HZ / 5 + (data->type == thmc50 ? HZ : 0);
 
 
-static const struct i2c_device_id thmc50_id[] = {
-	{ "adm1022", adm1022 },
-	{ "thmc50", thmc50 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, thmc50_id);
+	mutex_lock(&data->update_lock);
 
 
-static struct i2c_driver thmc50_driver = {
-	.class = I2C_CLASS_HWMON,
-	.driver = {
-		.name = "thmc50",
-	},
-	.probe = thmc50_probe,
-	.remove = thmc50_remove,
-	.id_table = thmc50_id,
-	.detect = thmc50_detect,
-	.address_list = normal_i2c,
-};
+	if (time_after(jiffies, data->last_updated + timeout)
+	    || !data->valid) {
+
+		int temps = data->has_temp3 ? 3 : 2;
+		int i;
+		int prog = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);
+
+		prog &= THMC50_REG_CONF_PROGRAMMED;
+
+		for (i = 0; i < temps; i++) {
+			data->temp_input[i] = i2c_smbus_read_byte_data(client,
+						THMC50_REG_TEMP[i]);
+			data->temp_max[i] = i2c_smbus_read_byte_data(client,
+						THMC50_REG_TEMP_MAX[i]);
+			data->temp_min[i] = i2c_smbus_read_byte_data(client,
+						THMC50_REG_TEMP_MIN[i]);
+			data->temp_critical[i] =
+				i2c_smbus_read_byte_data(client,
+					prog ? THMC50_REG_TEMP_CRITICAL[i]
+					     : THMC50_REG_TEMP_DEFAULT[i]);
+		}
+		data->analog_out =
+		    i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT);
+		data->alarms =
+		    i2c_smbus_read_byte_data(client, THMC50_REG_INTR);
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
 
 
 static ssize_t show_analog_out(struct device *dev,
 static ssize_t show_analog_out(struct device *dev,
 			       struct device_attribute *attr, char *buf)
 			       struct device_attribute *attr, char *buf)
@@ -123,8 +139,8 @@ static ssize_t set_analog_out(struct device *dev,
 			      struct device_attribute *attr,
 			      struct device_attribute *attr,
 			      const char *buf, size_t count)
 			      const char *buf, size_t count)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct thmc50_data *data = i2c_get_clientdata(client);
+	struct thmc50_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	int config;
 	int config;
 	unsigned long tmp;
 	unsigned long tmp;
 	int err;
 	int err;
@@ -177,8 +193,8 @@ static ssize_t set_temp_min(struct device *dev, struct device_attribute *attr,
 			    const char *buf, size_t count)
 			    const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct thmc50_data *data = i2c_get_clientdata(client);
+	struct thmc50_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -206,8 +222,8 @@ static ssize_t set_temp_max(struct device *dev, struct device_attribute *attr,
 			    const char *buf, size_t count)
 			    const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct thmc50_data *data = i2c_get_clientdata(client);
+	struct thmc50_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -355,67 +371,9 @@ static int thmc50_detect(struct i2c_client *client,
 	return 0;
 	return 0;
 }
 }
 
 
-static int thmc50_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
-{
-	struct thmc50_data *data;
-	int err;
-
-	data = devm_kzalloc(&client->dev, sizeof(struct thmc50_data),
-			    GFP_KERNEL);
-	if (!data)
-		return -ENOMEM;
-
-	i2c_set_clientdata(client, data);
-	data->type = id->driver_data;
-	mutex_init(&data->update_lock);
-
-	thmc50_init_client(client);
-
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&client->dev.kobj, &thmc50_group);
-	if (err)
-		return err;
-
-	/* Register ADM1022 sysfs hooks */
-	if (data->has_temp3) {
-		err = sysfs_create_group(&client->dev.kobj, &temp3_group);
-		if (err)
-			goto exit_remove_sysfs_thmc50;
-	}
-
-	/* Register a new directory entry with module sensors */
-	data->hwmon_dev = hwmon_device_register(&client->dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove_sysfs;
-	}
-
-	return 0;
-
-exit_remove_sysfs:
-	if (data->has_temp3)
-		sysfs_remove_group(&client->dev.kobj, &temp3_group);
-exit_remove_sysfs_thmc50:
-	sysfs_remove_group(&client->dev.kobj, &thmc50_group);
-	return err;
-}
-
-static int thmc50_remove(struct i2c_client *client)
+static void thmc50_init_client(struct thmc50_data *data)
 {
 {
-	struct thmc50_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &thmc50_group);
-	if (data->has_temp3)
-		sysfs_remove_group(&client->dev.kobj, &temp3_group);
-
-	return 0;
-}
-
-static void thmc50_init_client(struct i2c_client *client)
-{
-	struct thmc50_data *data = i2c_get_clientdata(client);
+	struct i2c_client *client = data->client;
 	int config;
 	int config;
 
 
 	data->analog_out = i2c_smbus_read_byte_data(client,
 	data->analog_out = i2c_smbus_read_byte_data(client,
@@ -433,48 +391,54 @@ static void thmc50_init_client(struct i2c_client *client)
 	i2c_smbus_write_byte_data(client, THMC50_REG_CONF, config);
 	i2c_smbus_write_byte_data(client, THMC50_REG_CONF, config);
 }
 }
 
 
-static struct thmc50_data *thmc50_update_device(struct device *dev)
+static int thmc50_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
 {
 {
-	struct i2c_client *client = to_i2c_client(dev);
-	struct thmc50_data *data = i2c_get_clientdata(client);
-	int timeout = HZ / 5 + (data->type == thmc50 ? HZ : 0);
+	struct device *dev = &client->dev;
+	struct thmc50_data *data;
+	struct device *hwmon_dev;
+	int idx = 0;
 
 
-	mutex_lock(&data->update_lock);
+	data = devm_kzalloc(dev, sizeof(struct thmc50_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
 
 
-	if (time_after(jiffies, data->last_updated + timeout)
-	    || !data->valid) {
+	data->client = client;
+	data->type = id->driver_data;
+	mutex_init(&data->update_lock);
 
 
-		int temps = data->has_temp3 ? 3 : 2;
-		int i;
-		int prog = i2c_smbus_read_byte_data(client, THMC50_REG_CONF);
+	thmc50_init_client(data);
 
 
-		prog &= THMC50_REG_CONF_PROGRAMMED;
+	/* sysfs hooks */
+	data->groups[idx++] = &thmc50_group;
 
 
-		for (i = 0; i < temps; i++) {
-			data->temp_input[i] = i2c_smbus_read_byte_data(client,
-						THMC50_REG_TEMP[i]);
-			data->temp_max[i] = i2c_smbus_read_byte_data(client,
-						THMC50_REG_TEMP_MAX[i]);
-			data->temp_min[i] = i2c_smbus_read_byte_data(client,
-						THMC50_REG_TEMP_MIN[i]);
-			data->temp_critical[i] =
-				i2c_smbus_read_byte_data(client,
-					prog ? THMC50_REG_TEMP_CRITICAL[i]
-					     : THMC50_REG_TEMP_DEFAULT[i]);
-		}
-		data->analog_out =
-		    i2c_smbus_read_byte_data(client, THMC50_REG_ANALOG_OUT);
-		data->alarms =
-		    i2c_smbus_read_byte_data(client, THMC50_REG_INTR);
-		data->last_updated = jiffies;
-		data->valid = 1;
-	}
-
-	mutex_unlock(&data->update_lock);
+	/* Register additional ADM1022 sysfs hooks */
+	if (data->has_temp3)
+		data->groups[idx++] = &temp3_group;
 
 
-	return data;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data, data->groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
+static const struct i2c_device_id thmc50_id[] = {
+	{ "adm1022", adm1022 },
+	{ "thmc50", thmc50 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, thmc50_id);
+
+static struct i2c_driver thmc50_driver = {
+	.class = I2C_CLASS_HWMON,
+	.driver = {
+		.name = "thmc50",
+	},
+	.probe = thmc50_probe,
+	.id_table = thmc50_id,
+	.detect = thmc50_detect,
+	.address_list = normal_i2c,
+};
+
 module_i2c_driver(thmc50_driver);
 module_i2c_driver(thmc50_driver);
 
 
 MODULE_AUTHOR("Krzysztof Helt <krzysztof.h1@wp.pl>");
 MODULE_AUTHOR("Krzysztof Helt <krzysztof.h1@wp.pl>");

+ 206 - 0
drivers/hwmon/tmp103.c

@@ -0,0 +1,206 @@
+/*
+ * Texas Instruments TMP103 SMBus temperature sensor driver
+ * Copyright (C) 2014 Heiko Schocher <hs@denx.de>
+ *
+ * Based on:
+ * Texas Instruments TMP102 SMBus temperature sensor driver
+ *
+ * Copyright (C) 2010 Steven King <sfking@fdwdc.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License as published by
+ * the Free Software Foundation; either version 2 of the License, or
+ * (at your option) any later version.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/err.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/jiffies.h>
+#include <linux/regmap.h>
+
+#define TMP103_TEMP_REG		0x00
+#define TMP103_CONF_REG		0x01
+#define TMP103_TLOW_REG		0x02
+#define TMP103_THIGH_REG	0x03
+
+#define TMP103_CONF_M0		0x01
+#define TMP103_CONF_M1		0x02
+#define TMP103_CONF_LC		0x04
+#define TMP103_CONF_FL		0x08
+#define TMP103_CONF_FH		0x10
+#define TMP103_CONF_CR0		0x20
+#define TMP103_CONF_CR1		0x40
+#define TMP103_CONF_ID		0x80
+#define TMP103_CONF_SD		(TMP103_CONF_M1)
+#define TMP103_CONF_SD_MASK	(TMP103_CONF_M0 | TMP103_CONF_M1)
+
+#define TMP103_CONFIG		(TMP103_CONF_CR1 | TMP103_CONF_M1)
+#define TMP103_CONFIG_MASK	(TMP103_CONF_CR0 | TMP103_CONF_CR1 | \
+				 TMP103_CONF_M0 | TMP103_CONF_M1)
+
+static inline int tmp103_reg_to_mc(s8 val)
+{
+	return val * 1000;
+}
+
+static inline u8 tmp103_mc_to_reg(int val)
+{
+	return DIV_ROUND_CLOSEST(val, 1000);
+}
+
+static ssize_t tmp103_show_temp(struct device *dev,
+				struct device_attribute *attr,
+				char *buf)
+{
+	struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
+	struct regmap *regmap = dev_get_drvdata(dev);
+	unsigned int regval;
+	int ret;
+
+	ret = regmap_read(regmap, sda->index, &regval);
+	if (ret < 0)
+		return ret;
+
+	return sprintf(buf, "%d\n", tmp103_reg_to_mc(regval));
+}
+
+static ssize_t tmp103_set_temp(struct device *dev,
+			       struct device_attribute *attr,
+			       const char *buf, size_t count)
+{
+	struct sensor_device_attribute *sda = to_sensor_dev_attr(attr);
+	struct regmap *regmap = dev_get_drvdata(dev);
+	long val;
+	int ret;
+
+	if (kstrtol(buf, 10, &val) < 0)
+		return -EINVAL;
+
+	val = clamp_val(val, -55000, 127000);
+	ret = regmap_write(regmap, sda->index, tmp103_mc_to_reg(val));
+	return ret ? ret : count;
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, tmp103_show_temp, NULL ,
+			  TMP103_TEMP_REG);
+
+static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO, tmp103_show_temp,
+			  tmp103_set_temp, TMP103_TLOW_REG);
+
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO, tmp103_show_temp,
+			  tmp103_set_temp, TMP103_THIGH_REG);
+
+static struct attribute *tmp103_attrs[] = {
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	&sensor_dev_attr_temp1_min.dev_attr.attr,
+	&sensor_dev_attr_temp1_max.dev_attr.attr,
+	NULL
+};
+ATTRIBUTE_GROUPS(tmp103);
+
+static bool tmp103_regmap_is_volatile(struct device *dev, unsigned int reg)
+{
+	return reg == TMP103_TEMP_REG;
+}
+
+static const struct regmap_config tmp103_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = TMP103_THIGH_REG,
+	.volatile_reg = tmp103_regmap_is_volatile,
+};
+
+static int tmp103_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct device *dev = &client->dev;
+	struct device *hwmon_dev;
+	struct regmap *regmap;
+	int ret;
+
+	if (!i2c_check_functionality(client->adapter,
+				     I2C_FUNC_SMBUS_BYTE_DATA)) {
+		dev_err(&client->dev,
+			"adapter doesn't support SMBus byte transactions\n");
+		return -ENODEV;
+	}
+
+	regmap = devm_regmap_init_i2c(client, &tmp103_regmap_config);
+	if (IS_ERR(regmap)) {
+		dev_err(dev, "failed to allocate register map\n");
+		return PTR_ERR(regmap);
+	}
+
+	ret = regmap_update_bits(regmap, TMP103_CONF_REG, TMP103_CONFIG_MASK,
+				 TMP103_CONFIG);
+	if (ret < 0) {
+		dev_err(&client->dev, "error writing config register\n");
+		return ret;
+	}
+
+	i2c_set_clientdata(client, regmap);
+	hwmon_dev = hwmon_device_register_with_groups(dev, client->name,
+						      regmap, tmp103_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
+}
+
+#ifdef CONFIG_PM
+static int tmp103_suspend(struct device *dev)
+{
+	struct regmap *regmap = dev_get_drvdata(dev);
+
+	return regmap_update_bits(regmap, TMP103_CONF_REG,
+				  TMP103_CONF_SD_MASK, 0);
+}
+
+static int tmp103_resume(struct device *dev)
+{
+	struct regmap *regmap = dev_get_drvdata(dev);
+
+	return regmap_update_bits(regmap, TMP103_CONF_REG,
+				  TMP103_CONF_SD_MASK, TMP103_CONF_SD);
+}
+
+static const struct dev_pm_ops tmp103_dev_pm_ops = {
+	.suspend	= tmp103_suspend,
+	.resume		= tmp103_resume,
+};
+
+#define TMP103_DEV_PM_OPS (&tmp103_dev_pm_ops)
+#else
+#define	TMP103_DEV_PM_OPS NULL
+#endif /* CONFIG_PM */
+
+static const struct i2c_device_id tmp103_id[] = {
+	{ "tmp103", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, tmp103_id);
+
+static struct i2c_driver tmp103_driver = {
+	.driver = {
+		.name	= "tmp103",
+		.pm	= TMP103_DEV_PM_OPS,
+	},
+	.probe		= tmp103_probe,
+	.id_table	= tmp103_id,
+};
+
+module_i2c_driver(tmp103_driver);
+
+MODULE_AUTHOR("Heiko Schocher <hs@denx.de>");
+MODULE_DESCRIPTION("Texas Instruments TMP103 temperature sensor driver");
+MODULE_LICENSE("GPL");

+ 31 - 8
drivers/hwmon/tmp421.c

@@ -13,15 +13,11 @@
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  * GNU General Public License for more details.
  * GNU General Public License for more details.
- *
- * You should have received a copy of the GNU General Public License
- * along with this program; if not, write to the Free Software
- * Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
  */
  */
 
 
 /*
 /*
  * Driver for the Texas Instruments TMP421 SMBus temperature sensor IC.
  * Driver for the Texas Instruments TMP421 SMBus temperature sensor IC.
- * Supported models: TMP421, TMP422, TMP423
+ * Supported models: TMP421, TMP422, TMP423, TMP441, TMP442
  */
  */
 
 
 #include <linux/module.h>
 #include <linux/module.h>
@@ -39,9 +35,10 @@
 static const unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f,
 static const unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f,
 					     I2C_CLIENT_END };
 					     I2C_CLIENT_END };
 
 
-enum chips { tmp421, tmp422, tmp423 };
+enum chips { tmp421, tmp422, tmp423, tmp441, tmp442 };
 
 
 /* The TMP421 registers */
 /* The TMP421 registers */
+#define TMP421_STATUS_REG			0x08
 #define TMP421_CONFIG_REG_1			0x09
 #define TMP421_CONFIG_REG_1			0x09
 #define TMP421_CONVERSION_RATE_REG		0x0B
 #define TMP421_CONVERSION_RATE_REG		0x0B
 #define TMP421_MANUFACTURER_ID_REG		0xFE
 #define TMP421_MANUFACTURER_ID_REG		0xFE
@@ -59,11 +56,15 @@ static const u8 TMP421_TEMP_LSB[4]		= { 0x10, 0x11, 0x12, 0x13 };
 #define TMP421_DEVICE_ID			0x21
 #define TMP421_DEVICE_ID			0x21
 #define TMP422_DEVICE_ID			0x22
 #define TMP422_DEVICE_ID			0x22
 #define TMP423_DEVICE_ID			0x23
 #define TMP423_DEVICE_ID			0x23
+#define TMP441_DEVICE_ID			0x41
+#define TMP442_DEVICE_ID			0x42
 
 
 static const struct i2c_device_id tmp421_id[] = {
 static const struct i2c_device_id tmp421_id[] = {
 	{ "tmp421", 2 },
 	{ "tmp421", 2 },
 	{ "tmp422", 3 },
 	{ "tmp422", 3 },
 	{ "tmp423", 4 },
 	{ "tmp423", 4 },
+	{ "tmp441", 2 },
+	{ "tmp442", 3 },
 	{ }
 	{ }
 };
 };
 MODULE_DEVICE_TABLE(i2c, tmp421_id);
 MODULE_DEVICE_TABLE(i2c, tmp421_id);
@@ -234,7 +235,9 @@ static int tmp421_detect(struct i2c_client *client,
 {
 {
 	enum chips kind;
 	enum chips kind;
 	struct i2c_adapter *adapter = client->adapter;
 	struct i2c_adapter *adapter = client->adapter;
-	const char *names[] = { "TMP421", "TMP422", "TMP423" };
+	const char * const names[] = { "TMP421", "TMP422", "TMP423",
+				       "TMP441", "TMP442" };
+	int addr = client->addr;
 	u8 reg;
 	u8 reg;
 
 
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
 	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
@@ -244,17 +247,37 @@ static int tmp421_detect(struct i2c_client *client,
 	if (reg != TMP421_MANUFACTURER_ID)
 	if (reg != TMP421_MANUFACTURER_ID)
 		return -ENODEV;
 		return -ENODEV;
 
 
+	reg = i2c_smbus_read_byte_data(client, TMP421_CONVERSION_RATE_REG);
+	if (reg & 0xf8)
+		return -ENODEV;
+
+	reg = i2c_smbus_read_byte_data(client, TMP421_STATUS_REG);
+	if (reg & 0x7f)
+		return -ENODEV;
+
 	reg = i2c_smbus_read_byte_data(client, TMP421_DEVICE_ID_REG);
 	reg = i2c_smbus_read_byte_data(client, TMP421_DEVICE_ID_REG);
 	switch (reg) {
 	switch (reg) {
 	case TMP421_DEVICE_ID:
 	case TMP421_DEVICE_ID:
 		kind = tmp421;
 		kind = tmp421;
 		break;
 		break;
 	case TMP422_DEVICE_ID:
 	case TMP422_DEVICE_ID:
+		if (addr == 0x2a)
+			return -ENODEV;
 		kind = tmp422;
 		kind = tmp422;
 		break;
 		break;
 	case TMP423_DEVICE_ID:
 	case TMP423_DEVICE_ID:
+		if (addr != 0x4c && addr != 0x4d)
+			return -ENODEV;
 		kind = tmp423;
 		kind = tmp423;
 		break;
 		break;
+	case TMP441_DEVICE_ID:
+		kind = tmp441;
+		break;
+	case TMP442_DEVICE_ID:
+		if (addr != 0x4c && addr != 0x4d)
+			return -ENODEV;
+		kind = tmp442;
+		break;
 	default:
 	default:
 		return -ENODEV;
 		return -ENODEV;
 	}
 	}
@@ -305,5 +328,5 @@ static struct i2c_driver tmp421_driver = {
 module_i2c_driver(tmp421_driver);
 module_i2c_driver(tmp421_driver);
 
 
 MODULE_AUTHOR("Andre Prendel <andre.prendel@gmx.de>");
 MODULE_AUTHOR("Andre Prendel <andre.prendel@gmx.de>");
-MODULE_DESCRIPTION("Texas Instruments TMP421/422/423 temperature sensor driver");
+MODULE_DESCRIPTION("Texas Instruments TMP421/422/423/441/442 temperature sensor driver");
 MODULE_LICENSE("GPL");
 MODULE_LICENSE("GPL");

+ 6 - 32
drivers/hwmon/twl4030-madc-hwmon.c

@@ -74,7 +74,7 @@ static SENSOR_DEVICE_ATTR(in11_input, S_IRUGO, madc_read, NULL, 11);
 static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, madc_read, NULL, 12);
 static SENSOR_DEVICE_ATTR(in12_input, S_IRUGO, madc_read, NULL, 12);
 static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, madc_read, NULL, 15);
 static SENSOR_DEVICE_ATTR(in15_input, S_IRUGO, madc_read, NULL, 15);
 
 
-static struct attribute *twl4030_madc_attributes[] = {
+static struct attribute *twl4030_madc_attrs[] = {
 	&sensor_dev_attr_in0_input.dev_attr.attr,
 	&sensor_dev_attr_in0_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_temp1_input.dev_attr.attr,
 	&sensor_dev_attr_in2_input.dev_attr.attr,
 	&sensor_dev_attr_in2_input.dev_attr.attr,
@@ -91,46 +91,20 @@ static struct attribute *twl4030_madc_attributes[] = {
 	&sensor_dev_attr_in15_input.dev_attr.attr,
 	&sensor_dev_attr_in15_input.dev_attr.attr,
 	NULL
 	NULL
 };
 };
-
-static const struct attribute_group twl4030_madc_group = {
-	.attrs = twl4030_madc_attributes,
-};
+ATTRIBUTE_GROUPS(twl4030_madc);
 
 
 static int twl4030_madc_hwmon_probe(struct platform_device *pdev)
 static int twl4030_madc_hwmon_probe(struct platform_device *pdev)
 {
 {
-	int ret;
 	struct device *hwmon;
 	struct device *hwmon;
 
 
-	ret = sysfs_create_group(&pdev->dev.kobj, &twl4030_madc_group);
-	if (ret)
-		goto err_sysfs;
-	hwmon = hwmon_device_register(&pdev->dev);
-	if (IS_ERR(hwmon)) {
-		dev_err(&pdev->dev, "hwmon_device_register failed.\n");
-		ret = PTR_ERR(hwmon);
-		goto err_reg;
-	}
-
-	return 0;
-
-err_reg:
-	sysfs_remove_group(&pdev->dev.kobj, &twl4030_madc_group);
-err_sysfs:
-
-	return ret;
-}
-
-static int twl4030_madc_hwmon_remove(struct platform_device *pdev)
-{
-	hwmon_device_unregister(&pdev->dev);
-	sysfs_remove_group(&pdev->dev.kobj, &twl4030_madc_group);
-
-	return 0;
+	hwmon = devm_hwmon_device_register_with_groups(&pdev->dev,
+						       "twl4030_madc", NULL,
+						       twl4030_madc_groups);
+	return PTR_ERR_OR_ZERO(hwmon);
 }
 }
 
 
 static struct platform_driver twl4030_madc_hwmon_driver = {
 static struct platform_driver twl4030_madc_hwmon_driver = {
 	.probe = twl4030_madc_hwmon_probe,
 	.probe = twl4030_madc_hwmon_probe,
-	.remove = twl4030_madc_hwmon_remove,
 	.driver = {
 	.driver = {
 		   .name = "twl4030_madc_hwmon",
 		   .name = "twl4030_madc_hwmon",
 		   .owner = THIS_MODULE,
 		   .owner = THIS_MODULE,

+ 6 - 9
drivers/hwmon/w83791d.c

@@ -249,19 +249,16 @@ static u8 fan_to_reg(long rpm, int div)
  * the bottom 7 bits will always be zero
  * the bottom 7 bits will always be zero
  */
  */
 #define TEMP23_FROM_REG(val)	((val) / 128 * 500)
 #define TEMP23_FROM_REG(val)	((val) / 128 * 500)
-#define TEMP23_TO_REG(val)	((val) <= -128000 ? 0x8000 : \
-				 (val) >= 127500 ? 0x7F80 : \
-				 (val) < 0 ? ((val) - 250) / 500 * 128 : \
-				 ((val) + 250) / 500 * 128)
+#define TEMP23_TO_REG(val)	(DIV_ROUND_CLOSEST(clamp_val((val), -128000, \
+						   127500), 500) * 128)
 
 
 /* for thermal cruise target temp, 7-bits, LSB = 1 degree Celsius */
 /* for thermal cruise target temp, 7-bits, LSB = 1 degree Celsius */
-#define TARGET_TEMP_TO_REG(val)		((val) < 0 ? 0 : \
-					(val) >= 127000 ? 127 : \
-					((val) + 500) / 1000)
+#define TARGET_TEMP_TO_REG(val)	DIV_ROUND_CLOSEST(clamp_val((val), 0, 127000), \
+						  1000)
 
 
 /* for thermal cruise temp tolerance, 4-bits, LSB = 1 degree Celsius */
 /* for thermal cruise temp tolerance, 4-bits, LSB = 1 degree Celsius */
-#define TOL_TEMP_TO_REG(val)		((val) >= 15000 ? 15 : \
-					((val) + 500) / 1000)
+#define TOL_TEMP_TO_REG(val)	DIV_ROUND_CLOSEST(clamp_val((val), 0, 15000), \
+						  1000)
 
 
 #define BEEP_MASK_TO_REG(val)		((val) & 0xffffff)
 #define BEEP_MASK_TO_REG(val)		((val) & 0xffffff)
 #define BEEP_MASK_FROM_REG(val)		((val) & 0xffffff)
 #define BEEP_MASK_FROM_REG(val)		((val) & 0xffffff)

+ 126 - 163
drivers/hwmon/w83l786ng.c

@@ -124,7 +124,7 @@ DIV_TO_REG(long val)
 }
 }
 
 
 struct w83l786ng_data {
 struct w83l786ng_data {
-	struct device *hwmon_dev;
+	struct i2c_client *client;
 	struct mutex update_lock;
 	struct mutex update_lock;
 	char valid;			/* !=0 if following fields are valid */
 	char valid;			/* !=0 if following fields are valid */
 	unsigned long last_updated;	/* In jiffies */
 	unsigned long last_updated;	/* In jiffies */
@@ -148,32 +148,6 @@ struct w83l786ng_data {
 	u8 tolerance[2];
 	u8 tolerance[2];
 };
 };
 
 
-static int w83l786ng_probe(struct i2c_client *client,
-			   const struct i2c_device_id *id);
-static int w83l786ng_detect(struct i2c_client *client,
-			    struct i2c_board_info *info);
-static int w83l786ng_remove(struct i2c_client *client);
-static void w83l786ng_init_client(struct i2c_client *client);
-static struct w83l786ng_data *w83l786ng_update_device(struct device *dev);
-
-static const struct i2c_device_id w83l786ng_id[] = {
-	{ "w83l786ng", 0 },
-	{ }
-};
-MODULE_DEVICE_TABLE(i2c, w83l786ng_id);
-
-static struct i2c_driver w83l786ng_driver = {
-	.class		= I2C_CLASS_HWMON,
-	.driver = {
-		   .name = "w83l786ng",
-	},
-	.probe		= w83l786ng_probe,
-	.remove		= w83l786ng_remove,
-	.id_table	= w83l786ng_id,
-	.detect		= w83l786ng_detect,
-	.address_list	= normal_i2c,
-};
-
 static u8
 static u8
 w83l786ng_read_value(struct i2c_client *client, u8 reg)
 w83l786ng_read_value(struct i2c_client *client, u8 reg)
 {
 {
@@ -186,6 +160,77 @@ w83l786ng_write_value(struct i2c_client *client, u8 reg, u8 value)
 	return i2c_smbus_write_byte_data(client, reg, value);
 	return i2c_smbus_write_byte_data(client, reg, value);
 }
 }
 
 
+static struct w83l786ng_data *w83l786ng_update_device(struct device *dev)
+{
+	struct w83l786ng_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
+	int i, j;
+	u8 reg_tmp, pwmcfg;
+
+	mutex_lock(&data->update_lock);
+	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+	    || !data->valid) {
+		dev_dbg(&client->dev, "Updating w83l786ng data.\n");
+
+		/* Update the voltages measured value and limits */
+		for (i = 0; i < 3; i++) {
+			data->in[i] = w83l786ng_read_value(client,
+			    W83L786NG_REG_IN(i));
+			data->in_min[i] = w83l786ng_read_value(client,
+			    W83L786NG_REG_IN_MIN(i));
+			data->in_max[i] = w83l786ng_read_value(client,
+			    W83L786NG_REG_IN_MAX(i));
+		}
+
+		/* Update the fan counts and limits */
+		for (i = 0; i < 2; i++) {
+			data->fan[i] = w83l786ng_read_value(client,
+			    W83L786NG_REG_FAN(i));
+			data->fan_min[i] = w83l786ng_read_value(client,
+			    W83L786NG_REG_FAN_MIN(i));
+		}
+
+		/* Update the fan divisor */
+		reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_FAN_DIV);
+		data->fan_div[0] = reg_tmp & 0x07;
+		data->fan_div[1] = (reg_tmp >> 4) & 0x07;
+
+		pwmcfg = w83l786ng_read_value(client, W83L786NG_REG_FAN_CFG);
+		for (i = 0; i < 2; i++) {
+			data->pwm_mode[i] =
+			    ((pwmcfg >> W83L786NG_PWM_MODE_SHIFT[i]) & 1)
+			    ? 0 : 1;
+			data->pwm_enable[i] =
+			    ((pwmcfg >> W83L786NG_PWM_ENABLE_SHIFT[i]) & 3) + 1;
+			data->pwm[i] =
+			    (w83l786ng_read_value(client, W83L786NG_REG_PWM[i])
+			     & 0x0f) * 0x11;
+		}
+
+
+		/* Update the temperature sensors */
+		for (i = 0; i < 2; i++) {
+			for (j = 0; j < 3; j++) {
+				data->temp[i][j] = w83l786ng_read_value(client,
+				    W83L786NG_REG_TEMP[i][j]);
+			}
+		}
+
+		/* Update Smart Fan I/II tolerance */
+		reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_TOLERANCE);
+		data->tolerance[0] = reg_tmp & 0x0f;
+		data->tolerance[1] = (reg_tmp >> 4) & 0x0f;
+
+		data->last_updated = jiffies;
+		data->valid = 1;
+
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
 /* following are the sysfs callback functions */
 /* following are the sysfs callback functions */
 #define show_in_reg(reg) \
 #define show_in_reg(reg) \
 static ssize_t \
 static ssize_t \
@@ -207,8 +252,8 @@ store_in_##reg(struct device *dev, struct device_attribute *attr, \
 	       const char *buf, size_t count) \
 	       const char *buf, size_t count) \
 { \
 { \
 	int nr = to_sensor_dev_attr(attr)->index; \
 	int nr = to_sensor_dev_attr(attr)->index; \
-	struct i2c_client *client = to_i2c_client(dev); \
-	struct w83l786ng_data *data = i2c_get_clientdata(client); \
+	struct w83l786ng_data *data = dev_get_drvdata(dev); \
+	struct i2c_client *client = data->client; \
 	unsigned long val; \
 	unsigned long val; \
 	int err = kstrtoul(buf, 10, &val); \
 	int err = kstrtoul(buf, 10, &val); \
 	if (err) \
 	if (err) \
@@ -260,8 +305,8 @@ store_fan_min(struct device *dev, struct device_attribute *attr,
 	      const char *buf, size_t count)
 	      const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83l786ng_data *data = i2c_get_clientdata(client);
+	struct w83l786ng_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -298,8 +343,8 @@ store_fan_div(struct device *dev, struct device_attribute *attr,
 	      const char *buf, size_t count)
 	      const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83l786ng_data *data = i2c_get_clientdata(client);
+	struct w83l786ng_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 
 
 	unsigned long min;
 	unsigned long min;
 	u8 tmp_fan_div;
 	u8 tmp_fan_div;
@@ -389,8 +434,8 @@ store_temp(struct device *dev, struct device_attribute *attr,
 	    to_sensor_dev_attr_2(attr);
 	    to_sensor_dev_attr_2(attr);
 	int nr = sensor_attr->nr;
 	int nr = sensor_attr->nr;
 	int index = sensor_attr->index;
 	int index = sensor_attr->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83l786ng_data *data = i2c_get_clientdata(client);
+	struct w83l786ng_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	long val;
 	long val;
 	int err;
 	int err;
 
 
@@ -444,8 +489,8 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
 	       const char *buf, size_t count)
 	       const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83l786ng_data *data = i2c_get_clientdata(client);
+	struct w83l786ng_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 reg;
 	u8 reg;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
@@ -472,8 +517,8 @@ store_pwm(struct device *dev, struct device_attribute *attr,
 	  const char *buf, size_t count)
 	  const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83l786ng_data *data = i2c_get_clientdata(client);
+	struct w83l786ng_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
 
 
@@ -496,8 +541,8 @@ store_pwm_enable(struct device *dev, struct device_attribute *attr,
 		 const char *buf, size_t count)
 		 const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83l786ng_data *data = i2c_get_clientdata(client);
+	struct w83l786ng_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 reg;
 	u8 reg;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
@@ -552,8 +597,8 @@ store_tolerance(struct device *dev, struct device_attribute *attr,
 		const char *buf, size_t count)
 		const char *buf, size_t count)
 {
 {
 	int nr = to_sensor_dev_attr(attr)->index;
 	int nr = to_sensor_dev_attr(attr)->index;
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83l786ng_data *data = i2c_get_clientdata(client);
+	struct w83l786ng_data *data = dev_get_drvdata(dev);
+	struct i2c_client *client = data->client;
 	u8 tol_tmp, tol_mask;
 	u8 tol_tmp, tol_mask;
 	unsigned long val;
 	unsigned long val;
 	int err;
 	int err;
@@ -608,7 +653,7 @@ static struct sensor_device_attribute sda_tolerance[] = {
 #define TOLERANCE_UNIT_ATTRS(X)	\
 #define TOLERANCE_UNIT_ATTRS(X)	\
 	&sda_tolerance[X].dev_attr.attr
 	&sda_tolerance[X].dev_attr.attr
 
 
-static struct attribute *w83l786ng_attributes[] = {
+static struct attribute *w83l786ng_attrs[] = {
 	IN_UNIT_ATTRS(0),
 	IN_UNIT_ATTRS(0),
 	IN_UNIT_ATTRS(1),
 	IN_UNIT_ATTRS(1),
 	IN_UNIT_ATTRS(2),
 	IN_UNIT_ATTRS(2),
@@ -623,9 +668,7 @@ static struct attribute *w83l786ng_attributes[] = {
 	NULL
 	NULL
 };
 };
 
 
-static const struct attribute_group w83l786ng_group = {
-	.attrs = w83l786ng_attributes,
-};
+ATTRIBUTE_GROUPS(w83l786ng);
 
 
 static int
 static int
 w83l786ng_detect(struct i2c_client *client, struct i2c_board_info *info)
 w83l786ng_detect(struct i2c_client *client, struct i2c_board_info *info)
@@ -662,20 +705,33 @@ w83l786ng_detect(struct i2c_client *client, struct i2c_board_info *info)
 	return 0;
 	return 0;
 }
 }
 
 
+static void w83l786ng_init_client(struct i2c_client *client)
+{
+	u8 tmp;
+
+	if (reset)
+		w83l786ng_write_value(client, W83L786NG_REG_CONFIG, 0x80);
+
+	/* Start monitoring */
+	tmp = w83l786ng_read_value(client, W83L786NG_REG_CONFIG);
+	if (!(tmp & 0x01))
+		w83l786ng_write_value(client, W83L786NG_REG_CONFIG, tmp | 0x01);
+}
+
 static int
 static int
 w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id)
 w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id)
 {
 {
 	struct device *dev = &client->dev;
 	struct device *dev = &client->dev;
 	struct w83l786ng_data *data;
 	struct w83l786ng_data *data;
-	int i, err = 0;
+	struct device *hwmon_dev;
+	int i;
 	u8 reg_tmp;
 	u8 reg_tmp;
 
 
-	data = devm_kzalloc(&client->dev, sizeof(struct w83l786ng_data),
-			    GFP_KERNEL);
+	data = devm_kzalloc(dev, sizeof(struct w83l786ng_data), GFP_KERNEL);
 	if (!data)
 	if (!data)
 		return -ENOMEM;
 		return -ENOMEM;
 
 
-	i2c_set_clientdata(client, data);
+	data->client = client;
 	mutex_init(&data->update_lock);
 	mutex_init(&data->update_lock);
 
 
 	/* Initialize the chip */
 	/* Initialize the chip */
@@ -692,121 +748,28 @@ w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id)
 	data->fan_div[0] = reg_tmp & 0x07;
 	data->fan_div[0] = reg_tmp & 0x07;
 	data->fan_div[1] = (reg_tmp >> 4) & 0x07;
 	data->fan_div[1] = (reg_tmp >> 4) & 0x07;
 
 
-	/* Register sysfs hooks */
-	err = sysfs_create_group(&client->dev.kobj, &w83l786ng_group);
-	if (err)
-		goto exit_remove;
-
-	data->hwmon_dev = hwmon_device_register(dev);
-	if (IS_ERR(data->hwmon_dev)) {
-		err = PTR_ERR(data->hwmon_dev);
-		goto exit_remove;
-	}
-
-	return 0;
-
-	/* Unregister sysfs hooks */
-
-exit_remove:
-	sysfs_remove_group(&client->dev.kobj, &w83l786ng_group);
-	return err;
-}
-
-static int
-w83l786ng_remove(struct i2c_client *client)
-{
-	struct w83l786ng_data *data = i2c_get_clientdata(client);
-
-	hwmon_device_unregister(data->hwmon_dev);
-	sysfs_remove_group(&client->dev.kobj, &w83l786ng_group);
-
-	return 0;
+	hwmon_dev = devm_hwmon_device_register_with_groups(dev, client->name,
+							   data,
+							   w83l786ng_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
-static void
-w83l786ng_init_client(struct i2c_client *client)
-{
-	u8 tmp;
-
-	if (reset)
-		w83l786ng_write_value(client, W83L786NG_REG_CONFIG, 0x80);
-
-	/* Start monitoring */
-	tmp = w83l786ng_read_value(client, W83L786NG_REG_CONFIG);
-	if (!(tmp & 0x01))
-		w83l786ng_write_value(client, W83L786NG_REG_CONFIG, tmp | 0x01);
-}
-
-static struct w83l786ng_data *w83l786ng_update_device(struct device *dev)
-{
-	struct i2c_client *client = to_i2c_client(dev);
-	struct w83l786ng_data *data = i2c_get_clientdata(client);
-	int i, j;
-	u8 reg_tmp, pwmcfg;
-
-	mutex_lock(&data->update_lock);
-	if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
-	    || !data->valid) {
-		dev_dbg(&client->dev, "Updating w83l786ng data.\n");
-
-		/* Update the voltages measured value and limits */
-		for (i = 0; i < 3; i++) {
-			data->in[i] = w83l786ng_read_value(client,
-			    W83L786NG_REG_IN(i));
-			data->in_min[i] = w83l786ng_read_value(client,
-			    W83L786NG_REG_IN_MIN(i));
-			data->in_max[i] = w83l786ng_read_value(client,
-			    W83L786NG_REG_IN_MAX(i));
-		}
-
-		/* Update the fan counts and limits */
-		for (i = 0; i < 2; i++) {
-			data->fan[i] = w83l786ng_read_value(client,
-			    W83L786NG_REG_FAN(i));
-			data->fan_min[i] = w83l786ng_read_value(client,
-			    W83L786NG_REG_FAN_MIN(i));
-		}
-
-		/* Update the fan divisor */
-		reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_FAN_DIV);
-		data->fan_div[0] = reg_tmp & 0x07;
-		data->fan_div[1] = (reg_tmp >> 4) & 0x07;
-
-		pwmcfg = w83l786ng_read_value(client, W83L786NG_REG_FAN_CFG);
-		for (i = 0; i < 2; i++) {
-			data->pwm_mode[i] =
-			    ((pwmcfg >> W83L786NG_PWM_MODE_SHIFT[i]) & 1)
-			    ? 0 : 1;
-			data->pwm_enable[i] =
-			    ((pwmcfg >> W83L786NG_PWM_ENABLE_SHIFT[i]) & 3) + 1;
-			data->pwm[i] =
-			    (w83l786ng_read_value(client, W83L786NG_REG_PWM[i])
-			     & 0x0f) * 0x11;
-		}
-
-
-		/* Update the temperature sensors */
-		for (i = 0; i < 2; i++) {
-			for (j = 0; j < 3; j++) {
-				data->temp[i][j] = w83l786ng_read_value(client,
-				    W83L786NG_REG_TEMP[i][j]);
-			}
-		}
-
-		/* Update Smart Fan I/II tolerance */
-		reg_tmp = w83l786ng_read_value(client, W83L786NG_REG_TOLERANCE);
-		data->tolerance[0] = reg_tmp & 0x0f;
-		data->tolerance[1] = (reg_tmp >> 4) & 0x0f;
-
-		data->last_updated = jiffies;
-		data->valid = 1;
-
-	}
-
-	mutex_unlock(&data->update_lock);
+static const struct i2c_device_id w83l786ng_id[] = {
+	{ "w83l786ng", 0 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, w83l786ng_id);
 
 
-	return data;
-}
+static struct i2c_driver w83l786ng_driver = {
+	.class		= I2C_CLASS_HWMON,
+	.driver = {
+		   .name = "w83l786ng",
+	},
+	.probe		= w83l786ng_probe,
+	.id_table	= w83l786ng_id,
+	.detect		= w83l786ng_detect,
+	.address_list	= normal_i2c,
+};
 
 
 module_i2c_driver(w83l786ng_driver);
 module_i2c_driver(w83l786ng_driver);
 
 

+ 11 - 61
drivers/hwmon/wm831x-hwmon.c

@@ -29,17 +29,6 @@
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/core.h>
 #include <linux/mfd/wm831x/auxadc.h>
 #include <linux/mfd/wm831x/auxadc.h>
 
 
-struct wm831x_hwmon {
-	struct wm831x *wm831x;
-	struct device *classdev;
-};
-
-static ssize_t show_name(struct device *dev,
-			 struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "wm831x\n");
-}
-
 static const char * const input_names[] = {
 static const char * const input_names[] = {
 	[WM831X_AUX_SYSVDD]    = "SYSVDD",
 	[WM831X_AUX_SYSVDD]    = "SYSVDD",
 	[WM831X_AUX_USB]       = "USB",
 	[WM831X_AUX_USB]       = "USB",
@@ -50,15 +39,14 @@ static const char * const input_names[] = {
 	[WM831X_AUX_BATT_TEMP] = "Battery",
 	[WM831X_AUX_BATT_TEMP] = "Battery",
 };
 };
 
 
-
 static ssize_t show_voltage(struct device *dev,
 static ssize_t show_voltage(struct device *dev,
 			    struct device_attribute *attr, char *buf)
 			    struct device_attribute *attr, char *buf)
 {
 {
-	struct wm831x_hwmon *hwmon = dev_get_drvdata(dev);
+	struct wm831x *wm831x = dev_get_drvdata(dev);
 	int channel = to_sensor_dev_attr(attr)->index;
 	int channel = to_sensor_dev_attr(attr)->index;
 	int ret;
 	int ret;
 
 
-	ret = wm831x_auxadc_read_uv(hwmon->wm831x, channel);
+	ret = wm831x_auxadc_read_uv(wm831x, channel);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
@@ -68,11 +56,11 @@ static ssize_t show_voltage(struct device *dev,
 static ssize_t show_chip_temp(struct device *dev,
 static ssize_t show_chip_temp(struct device *dev,
 			      struct device_attribute *attr, char *buf)
 			      struct device_attribute *attr, char *buf)
 {
 {
-	struct wm831x_hwmon *hwmon = dev_get_drvdata(dev);
+	struct wm831x *wm831x = dev_get_drvdata(dev);
 	int channel = to_sensor_dev_attr(attr)->index;
 	int channel = to_sensor_dev_attr(attr)->index;
 	int ret;
 	int ret;
 
 
-	ret = wm831x_auxadc_read(hwmon->wm831x, channel);
+	ret = wm831x_auxadc_read(wm831x, channel);
 	if (ret < 0)
 	if (ret < 0)
 		return ret;
 		return ret;
 
 
@@ -100,8 +88,6 @@ static ssize_t show_label(struct device *dev,
 	static SENSOR_DEVICE_ATTR(in##id##_label, S_IRUGO, show_label,	\
 	static SENSOR_DEVICE_ATTR(in##id##_label, S_IRUGO, show_label,	\
 				  NULL, name)
 				  NULL, name)
 
 
-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
-
 WM831X_VOLTAGE(0, WM831X_AUX_AUX1);
 WM831X_VOLTAGE(0, WM831X_AUX_AUX1);
 WM831X_VOLTAGE(1, WM831X_AUX_AUX2);
 WM831X_VOLTAGE(1, WM831X_AUX_AUX2);
 WM831X_VOLTAGE(2, WM831X_AUX_AUX3);
 WM831X_VOLTAGE(2, WM831X_AUX_AUX3);
@@ -126,9 +112,7 @@ static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_voltage, NULL,
 static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_label, NULL,
 static SENSOR_DEVICE_ATTR(temp2_label, S_IRUGO, show_label, NULL,
 			  WM831X_AUX_BATT_TEMP);
 			  WM831X_AUX_BATT_TEMP);
 
 
-static struct attribute *wm831x_attributes[] = {
-	&dev_attr_name.attr,
-
+static struct attribute *wm831x_attrs[] = {
 	&sensor_dev_attr_in0_input.dev_attr.attr,
 	&sensor_dev_attr_in0_input.dev_attr.attr,
 	&sensor_dev_attr_in1_input.dev_attr.attr,
 	&sensor_dev_attr_in1_input.dev_attr.attr,
 	&sensor_dev_attr_in2_input.dev_attr.attr,
 	&sensor_dev_attr_in2_input.dev_attr.attr,
@@ -153,55 +137,21 @@ static struct attribute *wm831x_attributes[] = {
 	NULL
 	NULL
 };
 };
 
 
-static const struct attribute_group wm831x_attr_group = {
-	.attrs	= wm831x_attributes,
-};
+ATTRIBUTE_GROUPS(wm831x);
 
 
 static int wm831x_hwmon_probe(struct platform_device *pdev)
 static int wm831x_hwmon_probe(struct platform_device *pdev)
 {
 {
 	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
 	struct wm831x *wm831x = dev_get_drvdata(pdev->dev.parent);
-	struct wm831x_hwmon *hwmon;
-	int ret;
-
-	hwmon = devm_kzalloc(&pdev->dev, sizeof(struct wm831x_hwmon),
-			     GFP_KERNEL);
-	if (!hwmon)
-		return -ENOMEM;
-
-	hwmon->wm831x = wm831x;
-
-	ret = sysfs_create_group(&pdev->dev.kobj, &wm831x_attr_group);
-	if (ret)
-		return ret;
-
-	hwmon->classdev = hwmon_device_register(&pdev->dev);
-	if (IS_ERR(hwmon->classdev)) {
-		ret = PTR_ERR(hwmon->classdev);
-		goto err_sysfs;
-	}
-
-	platform_set_drvdata(pdev, hwmon);
-
-	return 0;
-
-err_sysfs:
-	sysfs_remove_group(&pdev->dev.kobj, &wm831x_attr_group);
-	return ret;
-}
-
-static int wm831x_hwmon_remove(struct platform_device *pdev)
-{
-	struct wm831x_hwmon *hwmon = platform_get_drvdata(pdev);
-
-	hwmon_device_unregister(hwmon->classdev);
-	sysfs_remove_group(&pdev->dev.kobj, &wm831x_attr_group);
+	struct device *hwmon_dev;
 
 
-	return 0;
+	hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, "wm831x",
+							   wm831x,
+							   wm831x_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
 static struct platform_driver wm831x_hwmon_driver = {
 static struct platform_driver wm831x_hwmon_driver = {
 	.probe = wm831x_hwmon_probe,
 	.probe = wm831x_hwmon_probe,
-	.remove = wm831x_hwmon_remove,
 	.driver = {
 	.driver = {
 		.name = "wm831x-hwmon",
 		.name = "wm831x-hwmon",
 		.owner = THIS_MODULE,
 		.owner = THIS_MODULE,

+ 7 - 43
drivers/hwmon/wm8350-hwmon.c

@@ -28,19 +28,12 @@
 #include <linux/mfd/wm8350/core.h>
 #include <linux/mfd/wm8350/core.h>
 #include <linux/mfd/wm8350/comparator.h>
 #include <linux/mfd/wm8350/comparator.h>
 
 
-static ssize_t show_name(struct device *dev,
-			 struct device_attribute *attr, char *buf)
-{
-	return sprintf(buf, "wm8350\n");
-}
-
 static const char * const input_names[] = {
 static const char * const input_names[] = {
 	[WM8350_AUXADC_USB]  = "USB",
 	[WM8350_AUXADC_USB]  = "USB",
 	[WM8350_AUXADC_LINE] = "Line",
 	[WM8350_AUXADC_LINE] = "Line",
 	[WM8350_AUXADC_BATT] = "Battery",
 	[WM8350_AUXADC_BATT] = "Battery",
 };
 };
 
 
-
 static ssize_t show_voltage(struct device *dev,
 static ssize_t show_voltage(struct device *dev,
 			    struct device_attribute *attr, char *buf)
 			    struct device_attribute *attr, char *buf)
 {
 {
@@ -68,15 +61,11 @@ static ssize_t show_label(struct device *dev,
 	static SENSOR_DEVICE_ATTR(in##id##_label, S_IRUGO, show_label,	\
 	static SENSOR_DEVICE_ATTR(in##id##_label, S_IRUGO, show_label,	\
 				  NULL, name)
 				  NULL, name)
 
 
-static DEVICE_ATTR(name, S_IRUGO, show_name, NULL);
-
 WM8350_NAMED_VOLTAGE(0, WM8350_AUXADC_USB);
 WM8350_NAMED_VOLTAGE(0, WM8350_AUXADC_USB);
 WM8350_NAMED_VOLTAGE(1, WM8350_AUXADC_BATT);
 WM8350_NAMED_VOLTAGE(1, WM8350_AUXADC_BATT);
 WM8350_NAMED_VOLTAGE(2, WM8350_AUXADC_LINE);
 WM8350_NAMED_VOLTAGE(2, WM8350_AUXADC_LINE);
 
 
-static struct attribute *wm8350_attributes[] = {
-	&dev_attr_name.attr,
-
+static struct attribute *wm8350_attrs[] = {
 	&sensor_dev_attr_in0_input.dev_attr.attr,
 	&sensor_dev_attr_in0_input.dev_attr.attr,
 	&sensor_dev_attr_in0_label.dev_attr.attr,
 	&sensor_dev_attr_in0_label.dev_attr.attr,
 	&sensor_dev_attr_in1_input.dev_attr.attr,
 	&sensor_dev_attr_in1_input.dev_attr.attr,
@@ -87,46 +76,21 @@ static struct attribute *wm8350_attributes[] = {
 	NULL,
 	NULL,
 };
 };
 
 
-static const struct attribute_group wm8350_attr_group = {
-	.attrs	= wm8350_attributes,
-};
+ATTRIBUTE_GROUPS(wm8350);
 
 
 static int wm8350_hwmon_probe(struct platform_device *pdev)
 static int wm8350_hwmon_probe(struct platform_device *pdev)
 {
 {
 	struct wm8350 *wm8350 = platform_get_drvdata(pdev);
 	struct wm8350 *wm8350 = platform_get_drvdata(pdev);
-	int ret;
-
-	ret = sysfs_create_group(&pdev->dev.kobj, &wm8350_attr_group);
-	if (ret)
-		goto err;
-
-	wm8350->hwmon.classdev = hwmon_device_register(&pdev->dev);
-	if (IS_ERR(wm8350->hwmon.classdev)) {
-		ret = PTR_ERR(wm8350->hwmon.classdev);
-		goto err_group;
-	}
-
-	return 0;
-
-err_group:
-	sysfs_remove_group(&pdev->dev.kobj, &wm8350_attr_group);
-err:
-	return ret;
-}
-
-static int wm8350_hwmon_remove(struct platform_device *pdev)
-{
-	struct wm8350 *wm8350 = platform_get_drvdata(pdev);
-
-	hwmon_device_unregister(wm8350->hwmon.classdev);
-	sysfs_remove_group(&pdev->dev.kobj, &wm8350_attr_group);
+	struct device *hwmon_dev;
 
 
-	return 0;
+	hwmon_dev = devm_hwmon_device_register_with_groups(&pdev->dev, "wm8350",
+							   wm8350,
+							   wm8350_groups);
+	return PTR_ERR_OR_ZERO(hwmon_dev);
 }
 }
 
 
 static struct platform_driver wm8350_hwmon_driver = {
 static struct platform_driver wm8350_hwmon_driver = {
 	.probe = wm8350_hwmon_probe,
 	.probe = wm8350_hwmon_probe,
-	.remove = wm8350_hwmon_remove,
 	.driver = {
 	.driver = {
 		.name = "wm8350-hwmon",
 		.name = "wm8350-hwmon",
 		.owner = THIS_MODULE,
 		.owner = THIS_MODULE,

+ 1 - 0
include/linux/platform_data/ntc_thermistor.h

@@ -26,6 +26,7 @@ struct iio_channel;
 enum ntc_thermistor_type {
 enum ntc_thermistor_type {
 	TYPE_NCPXXWB473,
 	TYPE_NCPXXWB473,
 	TYPE_NCPXXWL333,
 	TYPE_NCPXXWL333,
+	TYPE_B57330V2103,
 };
 };
 
 
 struct ntc_thermistor_platform_data {
 struct ntc_thermistor_platform_data {