Merge tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck...
Linus Torvalds [Mon, 1 Oct 2012 20:50:06 +0000 (13:50 -0700)]
Pull hwmon updates from Guenter Roeck:
 "New drivers for: MCP3221, ADT7410, MAX197

  Chip support added to existing drivers: LM71, LM74, MAX1110, MAX1112,
  MAX1113, INA220, INA230, MCP3221

  Cleanup: Use devm_ functions, fixed build warnings, removed deprecated
  sysfs attributes, code simplifications, dropped dependencies on
  EXPERIMENTAL"

* tag 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/groeck/linux-staging: (64 commits)
  hwmon: (mcp3021) Add MCP3221 support
  hwmon: (mcp3021) Prepare MCP3021 driver to support other chips
  hwmon: (w83791d) Drop unnecessary compare statements
  hwmon: (lm93) Drop unnecessary compare statement
  hwmon: (lm70) Simplify show_name function
  hwmon: (adcxx) Simplify show_name function
  hwmon: Drop dependencies on EXPERIMENTAL
  hwmon: (it87) Fix Kconfig for IT87 driver
  hwmon: (sht15) move header to linux/platform_data/
  hwmon: (asus_atk0110) Remove useless kfree
  hwmon: (ina2xx) Add support for INA220 and INA230
  hwmon: (ina2xx) Use structure array to distinguish chip types
  hwmon: (max1111) Add support for MAX1110, MAX1112, and MAX1113
  hwmon: (lm70) Add support for LM71 and LM74
  hwmon: (Documentation) Update feature-removal-schedule.txt
  hwmon: (w83793) Remove legacy chassis intrusion detection sysfs attributes
  hwmon: (w83792d) Remove legacy chassis intrusion detection attributes
  hwmon: (adm9240) Remove legacy chassis intrusion detection sysfs attribute
  hwmon: (lm70) Allow 4wire SPI bus with LM70
  hwmon: (sht15) remove multiple driver registration
  ...

61 files changed:
Documentation/feature-removal-schedule.txt
Documentation/hwmon/adt7410 [new file with mode: 0644]
Documentation/hwmon/ina2xx
Documentation/hwmon/lm70
Documentation/hwmon/max197 [new file with mode: 0644]
Documentation/hwmon/mcp3021
arch/arm/mach-pxa/stargate2.c
drivers/hwmon/Kconfig
drivers/hwmon/Makefile
drivers/hwmon/abituguru.c
drivers/hwmon/abituguru3.c
drivers/hwmon/ad7314.c
drivers/hwmon/ad7414.c
drivers/hwmon/ad7418.c
drivers/hwmon/adcxx.c
drivers/hwmon/adm1029.c
drivers/hwmon/adm9240.c
drivers/hwmon/ads1015.c
drivers/hwmon/ads7828.c
drivers/hwmon/ads7871.c
drivers/hwmon/adt7410.c [new file with mode: 0644]
drivers/hwmon/adt7411.c
drivers/hwmon/adt7462.c
drivers/hwmon/adt7470.c
drivers/hwmon/amc6821.c
drivers/hwmon/asb100.c
drivers/hwmon/asus_atk0110.c
drivers/hwmon/dme1737.c
drivers/hwmon/ds620.c
drivers/hwmon/emc1403.c
drivers/hwmon/emc2103.c
drivers/hwmon/f71882fg.c
drivers/hwmon/f75375s.c
drivers/hwmon/fam15h_power.c
drivers/hwmon/g760a.c
drivers/hwmon/ina2xx.c
drivers/hwmon/jz4740-hwmon.c
drivers/hwmon/lm70.c
drivers/hwmon/lm93.c
drivers/hwmon/lm95241.c
drivers/hwmon/lm95245.c
drivers/hwmon/ltc4151.c
drivers/hwmon/ltc4215.c
drivers/hwmon/ltc4245.c
drivers/hwmon/max1111.c
drivers/hwmon/max1668.c
drivers/hwmon/max197.c [new file with mode: 0644]
drivers/hwmon/mcp3021.c
drivers/hwmon/sch5627.c
drivers/hwmon/sch5636.c
drivers/hwmon/sch56xx-common.c
drivers/hwmon/sht15.c
drivers/hwmon/sht21.c
drivers/hwmon/via-cputemp.c
drivers/hwmon/vt8231.c
drivers/hwmon/w83791d.c
drivers/hwmon/w83792d.c
drivers/hwmon/w83793.c
drivers/hwmon/w83l786ng.c
include/linux/platform_data/max197.h [new file with mode: 0644]
include/linux/platform_data/sht15.h [moved from include/linux/sht15.h with 99% similarity]

index 43975ba..72bab3f 100644 (file)
@@ -357,16 +357,6 @@ Who:       Wey-Yi Guy <wey-yi.w.guy@intel.com>
 
 ----------------------------
 
-What:  Legacy, non-standard chassis intrusion detection interface.
-When:  June 2011
-Why:   The adm9240, w83792d and w83793 hardware monitoring drivers have
-       legacy interfaces for chassis intrusion detection. A standard
-       interface has been added to each driver, so the legacy interface
-       can be removed.
-Who:   Jean Delvare <khali@linux-fr.org>
-
-----------------------------
-
 What:  i2c_driver.attach_adapter
        i2c_driver.detach_adapter
 When:  September 2011
diff --git a/Documentation/hwmon/adt7410 b/Documentation/hwmon/adt7410
new file mode 100644 (file)
index 0000000..9600400
--- /dev/null
@@ -0,0 +1,51 @@
+Kernel driver adt7410
+=====================
+
+Supported chips:
+  * Analog Devices ADT7410
+    Prefix: 'adt7410'
+    Addresses scanned: I2C 0x48 - 0x4B
+    Datasheet: Publicly available at the Analog Devices website
+               http://www.analog.com/static/imported-files/data_sheets/ADT7410.pdf
+
+Author: Hartmut Knaack <knaack.h@gmx.de>
+
+Description
+-----------
+
+The ADT7410 is a temperature sensor with rated temperature range of -55°C to
++150°C. It has a high accuracy of +/-0.5°C and can be operated at a resolution
+of 13 bits (0.0625°C) or 16 bits (0.0078°C). The sensor provides an INT pin to
+indicate that a minimum or maximum temperature set point has been exceeded, as
+well as a critical temperature (CT) pin to indicate that the critical
+temperature set point has been exceeded. Both pins can be set up with a common
+hysteresis of 0°C - 15°C and a fault queue, ranging from 1 to 4 events. Both
+pins can individually set to be active-low or active-high, while the whole
+device can either run in comparator mode or interrupt mode. The ADT7410
+supports continous temperature sampling, as well as sampling one temperature
+value per second or even justget one sample on demand for power saving.
+Besides, it can completely power down its ADC, if power management is
+required.
+
+Configuration Notes
+-------------------
+
+Since the device uses one hysteresis value, which is an offset to minimum,
+maximum and critical temperature, it can only be set for temp#_max_hyst.
+However, temp#_min_hyst and temp#_crit_hyst show their corresponding
+hysteresis.
+The device is set to 16 bit resolution and comparator mode.
+
+sysfs-Interface
+---------------
+
+temp#_input            - temperature input
+temp#_min              - temperature minimum setpoint
+temp#_max              - temperature maximum setpoint
+temp#_crit             - critical temperature setpoint
+temp#_min_hyst         - hysteresis for temperature minimum (read-only)
+temp#_max_hyst         - hysteresis for temperature maximum (read/write)
+temp#_crit_hyst                - hysteresis for critical temperature (read-only)
+temp#_min_alarm                - temperature minimum alarm flag
+temp#_max_alarm                - temperature maximum alarm flag
+temp#_crit_alarm       - critical temperature alarm flag
index f50a6cc..03444f9 100644 (file)
@@ -8,12 +8,24 @@ Supported chips:
     Datasheet: Publicly available at the Texas Instruments website
                http://www.ti.com/
 
+  * Texas Instruments INA220
+    Prefix: 'ina220'
+    Addresses: I2C 0x40 - 0x4f
+    Datasheet: Publicly available at the Texas Instruments website
+               http://www.ti.com/
+
   * Texas Instruments INA226
     Prefix: 'ina226'
     Addresses: I2C 0x40 - 0x4f
     Datasheet: Publicly available at the Texas Instruments website
                http://www.ti.com/
 
+  * Texas Instruments INA230
+    Prefix: 'ina230'
+    Addresses: I2C 0x40 - 0x4f
+    Datasheet: Publicly available at the Texas Instruments website
+               http://www.ti.com/
+
 Author: Lothar Felten <l-felten@ti.com>
 
 Description
@@ -23,7 +35,13 @@ The INA219 is a high-side current shunt and power monitor with an I2C
 interface. The INA219 monitors both shunt drop and supply voltage, with
 programmable conversion times and filtering.
 
+The INA220 is a high or low side current shunt and power monitor with an I2C
+interface. The INA220 monitors both shunt drop and supply voltage.
+
 The INA226 is a current shunt and power monitor with an I2C interface.
 The INA226 monitors both a shunt voltage drop and bus supply voltage.
 
+The INA230 is a high or low side current shunt and power monitor with an I2C
+interface. The INA230 monitors both a shunt voltage drop and bus supply voltage.
+
 The shunt value in micro-ohms can be set via platform data.
index 0d24029..86d1829 100644 (file)
@@ -6,6 +6,10 @@ Supported chips:
     Datasheet: http://www.national.com/pf/LM/LM70.html
   * Texas Instruments TMP121/TMP123
     Information: http://focus.ti.com/docs/prod/folders/print/tmp121.html
+  * National Semiconductor LM71
+    Datasheet: http://www.ti.com/product/LM71
+  * National Semiconductor LM74
+    Datasheet: http://www.ti.com/product/LM74
 
 Author:
         Kaiwan N Billimoria <kaiwan@designergraphix.com>
@@ -31,9 +35,11 @@ As a real (in-tree) example of this "SPI protocol driver" interfacing
 with a "SPI master controller driver", see drivers/spi/spi_lm70llp.c
 and its associated documentation.
 
-The TMP121/TMP123 are very similar; main differences are 4 wire SPI inter-
-face (read only) and 13-bit temperature data (0.0625 degrees celsius reso-
-lution).
+The LM74 and TMP121/TMP123 are very similar; main difference is 13-bit
+temperature data (0.0625 degrees celsius resolution).
+
+The LM71 is also very similar; main difference is 14-bit temperature
+data (0.03125 degrees celsius resolution).
 
 Thanks to
 ---------
diff --git a/Documentation/hwmon/max197 b/Documentation/hwmon/max197
new file mode 100644 (file)
index 0000000..8d89b90
--- /dev/null
@@ -0,0 +1,60 @@
+Maxim MAX197 driver
+===================
+
+Author:
+  * Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+
+Supported chips:
+  * Maxim MAX197
+    Prefix: 'max197'
+    Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX197.pdf
+
+  * Maxim MAX199
+    Prefix: 'max199'
+    Datasheet: http://datasheets.maxim-ic.com/en/ds/MAX199.pdf
+
+Description
+-----------
+
+The A/D converters MAX197, and MAX199 are both 8-Channel, Multi-Range, 5V,
+12-Bit DAS with 8+4 Bus Interface and Fault Protection.
+
+The available ranges for the MAX197 are {0,-5V} to 5V, and {0,-10V} to 10V,
+while they are {0,-2V} to 2V, and {0,-4V} to 4V on the MAX199.
+
+Platform data
+-------------
+
+The MAX197 platform data (defined in linux/platform_data/max197.h) should be
+filled with a pointer to a conversion function, defined like:
+
+    int convert(u8 ctrl);
+
+ctrl is the control byte to write to start a new conversion.
+On success, the function must return the 12-bit raw value read from the chip,
+or a negative error code otherwise.
+
+Control byte format:
+
+Bit     Name       Description
+7,6     PD1,PD0    Clock and Power-Down modes
+5       ACQMOD     Internal or External Controlled Acquisition
+4       RNG        Full-scale voltage magnitude at the input
+3       BIP        Unipolar or Bipolar conversion mode
+2,1,0   A2,A1,A0   Channel
+
+Sysfs interface
+---------------
+
+* in[0-7]_input: The conversion value for the corresponding channel.
+                 RO
+
+* in[0-7]_min:   The lower limit (in mV) for the corresponding channel.
+                 For the MAX197, it will be adjusted to -10000, -5000, or 0.
+                 For the MAX199, it will be adjusted to -4000, -2000, or 0.
+                 RW
+
+* in[0-7]_max:   The higher limit (in mV) for the corresponding channel.
+                 For the MAX197, it will be adjusted to 0, 5000, or 10000.
+                 For the MAX199, it will be adjusted to 0, 2000, or 4000.
+                 RW
index 325fd87..74a6b72 100644 (file)
@@ -5,18 +5,25 @@ Supported chips:
   * Microchip Technology MCP3021
     Prefix: 'mcp3021'
     Datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/21805a.pdf
+  * Microchip Technology MCP3221
+    Prefix: 'mcp3221'
+    Datasheet: http://ww1.microchip.com/downloads/en/DeviceDoc/21732c.pdf
 
-Author: Mingkai Hu
+Authors:
+   Mingkai Hu
+   Sven Schuchmann <schuchmann@schleissheimer.de>
 
 Description
 -----------
 
-This driver implements support for the Microchip Technology MCP3021 chip.
+This driver implements support for the Microchip Technology MCP3021 and
+MCP3221 chip.
 
 The Microchip Technology Inc. MCP3021 is a successive approximation A/D
-converter (ADC) with 10-bit resolution.
-This device provides one single-ended input with very low power consumption.
-Communication to the MCP3021 is performed using a 2-wire I2C compatible
-interface. Standard (100 kHz) and Fast (400 kHz) I2C modes are available.
-The default I2C device address is 0x4d (contact the Microchip factory for
-additional address options).
+converter (ADC) with 10-bit resolution. The MCP3221 has 12-bit resolution.
+
+These devices provide one single-ended input with very low power consumption.
+Communication to the MCP3021/MCP3221  is performed using a 2-wire I2C
+compatible interface. Standard (100 kHz) and Fast (400 kHz) I2C modes are
+available. The default I2C device address is 0x4d (contact the Microchip
+factory for additional address options).
index 30b1b0b..0701ca7 100644 (file)
@@ -52,7 +52,7 @@
 #include <linux/spi/spi.h>
 #include <linux/spi/pxa2xx_spi.h>
 #include <linux/mfd/da903x.h>
-#include <linux/sht15.h>
+#include <linux/platform_data/sht15.h>
 
 #include "devices.h"
 #include "generic.h"
index b0a2e4c..c74e73b 100644 (file)
@@ -41,7 +41,7 @@ comment "Native drivers"
 
 config SENSORS_ABITUGURU
        tristate "Abit uGuru (rev 1 & 2)"
-       depends on X86 && DMI && EXPERIMENTAL
+       depends on X86 && DMI
        help
          If you say yes here you get support for the sensor part of the first
          and second revision of the Abit uGuru chip. The voltage and frequency
@@ -56,7 +56,7 @@ config SENSORS_ABITUGURU
 
 config SENSORS_ABITUGURU3
        tristate "Abit uGuru (rev 3)"
-       depends on X86 && DMI && EXPERIMENTAL
+       depends on X86 && DMI
        help
          If you say yes here you get support for the sensor part of the
          third revision of the Abit uGuru chip. Only reading the sensors
@@ -70,7 +70,7 @@ config SENSORS_ABITUGURU3
 
 config SENSORS_AD7314
        tristate "Analog Devices AD7314 and compatibles"
-       depends on SPI && EXPERIMENTAL
+       depends on SPI
        help
          If you say yes here you get support for the Analog Devices
          AD7314, ADT7301 and ADT7302 temperature sensors.
@@ -80,7 +80,7 @@ config SENSORS_AD7314
 
 config SENSORS_AD7414
        tristate "Analog Devices AD7414"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for the Analog Devices
          AD7414 temperature monitoring chip.
@@ -90,7 +90,7 @@ config SENSORS_AD7414
 
 config SENSORS_AD7418
        tristate "Analog Devices AD7416, AD7417 and AD7418"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for the Analog Devices
          AD7416, AD7417 and AD7418 temperature monitoring chips.
@@ -100,7 +100,7 @@ config SENSORS_AD7418
 
 config SENSORS_ADCXX
        tristate "National Semiconductor ADCxxxSxxx"
-       depends on SPI_MASTER && EXPERIMENTAL
+       depends on SPI_MASTER
        help
          If you say yes here you get support for the National Semiconductor
          ADC<bb><c>S<sss> chip family, where
@@ -179,9 +179,19 @@ config SENSORS_ADM9240
          This driver can also be built as a module.  If so, the module
          will be called adm9240.
 
+config SENSORS_ADT7410
+       tristate "Analog Devices ADT7410"
+       depends on I2C
+       help
+         If you say yes here you get support for the Analog Devices
+         ADT7410 temperature monitoring chip.
+
+         This driver can also be built as a module. If so, the module
+         will be called adt7410.
+
 config SENSORS_ADT7411
        tristate "Analog Devices ADT7411"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for the Analog Devices
          ADT7411 voltage and temperature monitoring chip.
@@ -191,7 +201,7 @@ config SENSORS_ADT7411
 
 config SENSORS_ADT7462
        tristate "Analog Devices ADT7462"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for the Analog Devices
          ADT7462 temperature monitoring chips.
@@ -201,7 +211,7 @@ config SENSORS_ADT7462
 
 config SENSORS_ADT7470
        tristate "Analog Devices ADT7470"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for the Analog Devices
          ADT7470 temperature monitoring chips.
@@ -236,7 +246,7 @@ config SENSORS_ASC7621
 
 config SENSORS_K8TEMP
        tristate "AMD Athlon64/FX or Opteron temperature sensor"
-       depends on X86 && PCI && EXPERIMENTAL
+       depends on X86 && PCI
        help
          If you say yes here you get support for the temperature
          sensor(s) inside your CPU. Supported is whole AMD K8
@@ -271,7 +281,7 @@ config SENSORS_FAM15H_POWER
 
 config SENSORS_ASB100
        tristate "Asus ASB100 Bach"
-       depends on X86 && I2C && EXPERIMENTAL
+       depends on X86 && I2C
        select HWMON_VID
        help
          If you say yes here you get support for the ASB100 Bach sensor
@@ -282,7 +292,7 @@ config SENSORS_ASB100
 
 config SENSORS_ATXP1
        tristate "Attansic ATXP1 VID controller"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        select HWMON_VID
        help
          If you say yes here you get support for the Attansic ATXP1 VID
@@ -336,7 +346,7 @@ config SENSORS_EXYNOS4_TMU
 
 config SENSORS_I5K_AMB
        tristate "FB-DIMM AMB temperature sensor on Intel 5000 series chipsets"
-       depends on PCI && EXPERIMENTAL
+       depends on PCI
        help
          If you say yes here you get support for FB-DIMM AMB temperature
          monitoring chips on systems with the Intel 5000 series chipset.
@@ -445,7 +455,7 @@ config SENSORS_GPIO_FAN
 
 config SENSORS_HIH6130
        tristate "Honeywell Humidicon HIH-6130 humidity/temperature sensor"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for Honeywell Humidicon
          HIH-6130 and HIH-6131 Humidicon humidity sensors.
@@ -455,7 +465,7 @@ config SENSORS_HIH6130
 
 config SENSORS_CORETEMP
        tristate "Intel Core/Core2/Atom temperature sensor"
-       depends on X86 && PCI && EXPERIMENTAL
+       depends on X86 && PCI
        help
          If you say yes here you get support for the temperature
          sensor inside your CPU. Most of the family 6 CPUs
@@ -495,8 +505,8 @@ config SENSORS_IT87
        select HWMON_VID
        help
          If you say yes here you get support for ITE IT8705F, IT8712F,
-         IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F and IT8758E
-         sensor chips, and the SiS960 clone.
+         IT8716F, IT8718F, IT8720F, IT8721F, IT8726F, IT8728F, IT8758E,
+         IT8782F, and IT8783E/F sensor chips, and the SiS950 clone.
 
          This driver can also be built as a module.  If so, the module
          will be called it87.
@@ -527,7 +537,7 @@ config SENSORS_JC42
 
 config SENSORS_LINEAGE
        tristate "Lineage Compact Power Line Power Entry Module"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for the Lineage Compact Power Line
          series of DC/DC and AC/DC converters such as CP1800, CP2000AC,
@@ -550,12 +560,12 @@ config SENSORS_LM63
          will be called lm63.
 
 config SENSORS_LM70
-       tristate "National Semiconductor LM70 / Texas Instruments TMP121"
+       tristate "National Semiconductor LM70 and compatibles"
        depends on SPI_MASTER
        help
          If you say yes here you get support for the National Semiconductor
-         LM70 and Texas Instruments TMP121/TMP123 digital temperature
-         sensor chips.
+         LM70, LM71, LM74 and Texas Instruments TMP121/TMP123 digital tempera-
+         ture sensor chips.
 
          This driver can also be built as a module.  If so, the module
          will be called lm70.
@@ -709,7 +719,7 @@ config SENSORS_LTC4151
 
 config SENSORS_LTC4215
        tristate "Linear Technology LTC4215"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        default n
        help
          If you say yes here you get support for Linear Technology LTC4215
@@ -720,7 +730,7 @@ config SENSORS_LTC4215
 
 config SENSORS_LTC4245
        tristate "Linear Technology LTC4245"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        default n
        help
          If you say yes here you get support for Linear Technology LTC4245
@@ -731,7 +741,7 @@ config SENSORS_LTC4245
 
 config SENSORS_LTC4261
        tristate "Linear Technology LTC4261"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        default n
        help
          If you say yes here you get support for Linear Technology LTC4261
@@ -752,7 +762,7 @@ config SENSORS_LM95241
 
 config SENSORS_LM95245
        tristate "National Semiconductor LM95245 sensor chip"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for LM95245 sensor chip.
 
@@ -760,10 +770,11 @@ config SENSORS_LM95245
          will be called lm95245.
 
 config SENSORS_MAX1111
-       tristate "Maxim MAX1111 Multichannel, Serial 8-bit ADC chip"
+       tristate "Maxim MAX1111 Serial 8-bit ADC chip and compatibles"
        depends on SPI_MASTER
        help
-         Say y here to support Maxim's MAX1111 ADC chips.
+         Say y here to support Maxim's MAX1110, MAX1111, MAX1112, and MAX1113
+         ADC chips.
 
          This driver can also be built as a module.  If so, the module
          will be called max1111.
@@ -795,7 +806,7 @@ config SENSORS_MAX1619
 
 config SENSORS_MAX1668
        tristate "Maxim MAX1668 and compatibles"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for MAX1668, MAX1989 and
          MAX1805 chips.
@@ -803,9 +814,18 @@ config SENSORS_MAX1668
          This driver can also be built as a module.  If so, the module
          will be called max1668.
 
+config SENSORS_MAX197
+       tristate "Maxim MAX197 and compatibles"
+       help
+         Support for the Maxim MAX197 A/D converter.
+         Support will include, but not be limited to, MAX197, and MAX199.
+
+         This driver can also be built as a module. If so, the module
+         will be called max197.
+
 config SENSORS_MAX6639
        tristate "Maxim MAX6639 sensor chip"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for the MAX6639
          sensor chips.
@@ -815,7 +835,7 @@ config SENSORS_MAX6639
 
 config SENSORS_MAX6642
        tristate "Maxim MAX6642 sensor chip"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for MAX6642 sensor chip.
          MAX6642 is a SMBus-Compatible Remote/Local Temperature Sensor
@@ -826,7 +846,7 @@ config SENSORS_MAX6642
 
 config SENSORS_MAX6650
        tristate "Maxim MAX6650 sensor chip"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for the MAX6650 / MAX6651
          sensor chips.
@@ -835,18 +855,18 @@ config SENSORS_MAX6650
          will be called max6650.
 
 config SENSORS_MCP3021
-       tristate "Microchip MCP3021"
-       depends on I2C && EXPERIMENTAL
+       tristate "Microchip MCP3021 and compatibles"
+       depends on I2C
        help
-         If you say yes here you get support for the MCP3021 chip
-         that is a A/D converter (ADC) with 10-bit resolution.
+         If you say yes here you get support for MCP3021 and MCP3221.
+         The MCP3021 is a A/D converter (ADC) with 10-bit and the MCP3221
+         with 12-bit resolution.
 
          This driver can also be built as a module.  If so, the module
          will be called mcp3021.
 
 config SENSORS_NTC_THERMISTOR
        tristate "NTC thermistor support"
-       depends on EXPERIMENTAL
        help
          This driver supports NTC thermistors sensor reading and its
          interpretation. The driver can also monitor the temperature and
@@ -951,7 +971,7 @@ config SENSORS_SIS5595
 
 config SENSORS_SMM665
        tristate "Summit Microelectronics SMM665"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        default n
        help
          If you say yes here you get support for the hardware monitoring
@@ -966,7 +986,7 @@ config SENSORS_SMM665
 
 config SENSORS_DME1737
        tristate "SMSC DME1737, SCH311x and compatibles"
-       depends on I2C && EXPERIMENTAL && !PPC
+       depends on I2C && !PPC
        select HWMON_VID
        help
          If you say yes here you get support for the hardware monitoring
@@ -1042,7 +1062,7 @@ config SENSORS_SMSC47M192
 
 config SENSORS_SMSC47B397
        tristate "SMSC LPC47B397-NC"
-       depends on EXPERIMENTAL && !PPC
+       depends on !PPC
        help
          If you say yes here you get support for the SMSC LPC47B397-NC
          sensor chip.
@@ -1116,7 +1136,7 @@ config SENSORS_ADS7871
 
 config SENSORS_AMC6821
        tristate "Texas Instruments AMC6821"
-       depends on I2C  && EXPERIMENTAL
+       depends on I2C 
        help
          If you say yes here you get support for the Texas Instruments
          AMC6821 hardware monitoring chips.
@@ -1125,11 +1145,11 @@ config SENSORS_AMC6821
          will be called amc6821.
 
 config SENSORS_INA2XX
-       tristate "Texas Instruments INA219, INA226"
-       depends on I2C && EXPERIMENTAL
+       tristate "Texas Instruments INA219 and compatibles"
+       depends on I2C
        help
-         If you say yes here you get support for INA219 and INA226 power
-         monitor chips.
+         If you say yes here you get support for INA219, INA220, INA226, and
+         INA230 power monitor chips.
 
          The INA2xx driver is configured for the default configuration of
          the part as described in the datasheet.
@@ -1149,7 +1169,7 @@ config SENSORS_THMC50
 
 config SENSORS_TMP102
        tristate "Texas Instruments TMP102"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for Texas Instruments TMP102
          sensor chips.
@@ -1159,7 +1179,7 @@ config SENSORS_TMP102
 
 config SENSORS_TMP401
        tristate "Texas Instruments TMP401 and compatibles"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for Texas Instruments TMP401 and
          TMP411 temperature sensor chips.
@@ -1169,7 +1189,7 @@ config SENSORS_TMP401
 
 config SENSORS_TMP421
        tristate "Texas Instruments TMP421 and compatible"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for Texas Instruments TMP421,
          TMP422 and TMP423 temperature sensor chips.
@@ -1261,7 +1281,7 @@ config SENSORS_W83792D
 
 config SENSORS_W83793
        tristate "Winbond W83793"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        select HWMON_VID
        help
          If you say yes here you get support for the Winbond W83793
@@ -1273,7 +1293,7 @@ config SENSORS_W83793
 
 config SENSORS_W83795
        tristate "Winbond/Nuvoton W83795G/ADG"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for the Winbond W83795G and
          W83795ADG hardware monitoring chip, including manual fan speed
@@ -1284,7 +1304,7 @@ config SENSORS_W83795
 
 config SENSORS_W83795_FANCTRL
        boolean "Include automatic fan control support (DANGEROUS)"
-       depends on SENSORS_W83795 && EXPERIMENTAL
+       depends on SENSORS_W83795
        default n
        help
          If you say yes here, support for automatic fan speed control
@@ -1301,7 +1321,7 @@ config SENSORS_W83795_FANCTRL
 
 config SENSORS_W83L785TS
        tristate "Winbond W83L785TS-S"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for the Winbond W83L785TS-S
          sensor chip, which is used on the Asus A7N8X, among other
@@ -1312,7 +1332,7 @@ config SENSORS_W83L785TS
 
 config SENSORS_W83L786NG
        tristate "Winbond W83L786NG, W83L786NR"
-       depends on I2C && EXPERIMENTAL
+       depends on I2C
        help
          If you say yes here you get support for the Winbond W83L786NG
          and W83L786NR sensor chips.
@@ -1427,7 +1447,7 @@ config SENSORS_ACPI_POWER
 
 config SENSORS_ATK0110
        tristate "ASUS ATK0110"
-       depends on X86 && EXPERIMENTAL
+       depends on X86
        help
          If you say yes here you get support for the ACPI hardware
          monitoring interface found in many ASUS motherboards. This
index 7aa9811..a62ce17 100644 (file)
@@ -34,6 +34,7 @@ obj-$(CONFIG_SENSORS_ADM9240) += adm9240.o
 obj-$(CONFIG_SENSORS_ADS1015)  += ads1015.o
 obj-$(CONFIG_SENSORS_ADS7828)  += ads7828.o
 obj-$(CONFIG_SENSORS_ADS7871)  += ads7871.o
+obj-$(CONFIG_SENSORS_ADT7410)  += adt7410.o
 obj-$(CONFIG_SENSORS_ADT7411)  += adt7411.o
 obj-$(CONFIG_SENSORS_ADT7462)  += adt7462.o
 obj-$(CONFIG_SENSORS_ADT7470)  += adt7470.o
@@ -94,6 +95,7 @@ obj-$(CONFIG_SENSORS_MAX1111) += max1111.o
 obj-$(CONFIG_SENSORS_MAX16065) += max16065.o
 obj-$(CONFIG_SENSORS_MAX1619)  += max1619.o
 obj-$(CONFIG_SENSORS_MAX1668)  += max1668.o
+obj-$(CONFIG_SENSORS_MAX197)   += max197.o
 obj-$(CONFIG_SENSORS_MAX6639)  += max6639.o
 obj-$(CONFIG_SENSORS_MAX6642)  += max6642.o
 obj-$(CONFIG_SENSORS_MAX6650)  += max6650.o
index d4419b4..78b8179 100644 (file)
@@ -1278,7 +1278,8 @@ static int __devinit abituguru_probe(struct platform_device *pdev)
                0x00, 0x01, 0x03, 0x04, 0x0A, 0x08, 0x0E, 0x02,
                0x09, 0x06, 0x05, 0x0B, 0x0F, 0x0D, 0x07, 0x0C };
 
-       data = kzalloc(sizeof(struct abituguru_data), GFP_KERNEL);
+       data = devm_kzalloc(&pdev->dev, sizeof(struct abituguru_data),
+                           GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
@@ -1430,8 +1431,6 @@ abituguru_probe_error:
        for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++)
                device_remove_file(&pdev->dev,
                        &abituguru_sysfs_attr[i].dev_attr);
-       platform_set_drvdata(pdev, NULL);
-       kfree(data);
        return res;
 }
 
@@ -1446,8 +1445,6 @@ static int __devexit abituguru_remove(struct platform_device *pdev)
        for (i = 0; i < ARRAY_SIZE(abituguru_sysfs_attr); i++)
                device_remove_file(&pdev->dev,
                        &abituguru_sysfs_attr[i].dev_attr);
-       platform_set_drvdata(pdev, NULL);
-       kfree(data);
 
        return 0;
 }
index 5d582ae..b174b8b 100644 (file)
@@ -976,7 +976,8 @@ static int __devinit abituguru3_probe(struct platform_device *pdev)
        u8 buf[2];
        u16 id;
 
-       data = kzalloc(sizeof(struct abituguru3_data), GFP_KERNEL);
+       data = devm_kzalloc(&pdev->dev, sizeof(struct abituguru3_data),
+                           GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
@@ -1068,7 +1069,6 @@ abituguru3_probe_error:
        for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++)
                device_remove_file(&pdev->dev,
                        &abituguru3_sysfs_attr[i].dev_attr);
-       kfree(data);
        return res;
 }
 
@@ -1084,8 +1084,6 @@ static int __devexit abituguru3_remove(struct platform_device *pdev)
        for (i = 0; i < ARRAY_SIZE(abituguru3_sysfs_attr); i++)
                device_remove_file(&pdev->dev,
                        &abituguru3_sysfs_attr[i].dev_attr);
-       kfree(data);
-
        return 0;
 }
 
index f915eb1..37c01e7 100644 (file)
@@ -112,16 +112,16 @@ static int __devinit ad7314_probe(struct spi_device *spi_dev)
        int ret;
        struct ad7314_data *chip;
 
-       chip = kzalloc(sizeof(*chip), GFP_KERNEL);
-       if (chip == NULL) {
-               ret = -ENOMEM;
-               goto error_ret;
-       }
+       chip = devm_kzalloc(&spi_dev->dev, sizeof(*chip), GFP_KERNEL);
+       if (chip == NULL)
+               return -ENOMEM;
+
        dev_set_drvdata(&spi_dev->dev, chip);
 
        ret = sysfs_create_group(&spi_dev->dev.kobj, &ad7314_group);
        if (ret < 0)
-               goto error_free_chip;
+               return ret;
+
        chip->hwmon_dev = hwmon_device_register(&spi_dev->dev);
        if (IS_ERR(chip->hwmon_dev)) {
                ret = PTR_ERR(chip->hwmon_dev);
@@ -132,9 +132,6 @@ static int __devinit ad7314_probe(struct spi_device *spi_dev)
        return 0;
 error_remove_group:
        sysfs_remove_group(&spi_dev->dev.kobj, &ad7314_group);
-error_free_chip:
-       kfree(chip);
-error_ret:
        return ret;
 }
 
@@ -144,7 +141,6 @@ static int __devexit ad7314_remove(struct spi_device *spi_dev)
 
        hwmon_device_unregister(chip->hwmon_dev);
        sysfs_remove_group(&spi_dev->dev.kobj, &ad7314_group);
-       kfree(chip);
 
        return 0;
 }
index 06d2d60..b420fb3 100644 (file)
@@ -185,16 +185,13 @@ static int ad7414_probe(struct i2c_client *client,
        int err;
 
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA |
-                                    I2C_FUNC_SMBUS_READ_WORD_DATA)) {
-               err = -EOPNOTSUPP;
-               goto exit;
-       }
+                                    I2C_FUNC_SMBUS_READ_WORD_DATA))
+               return -EOPNOTSUPP;
 
-       data = kzalloc(sizeof(struct ad7414_data), GFP_KERNEL);
-       if (!data) {
-               err = -ENOMEM;
-               goto exit;
-       }
+       data = devm_kzalloc(&client->dev, sizeof(struct ad7414_data),
+                           GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        i2c_set_clientdata(client, data);
        mutex_init(&data->lock);
@@ -214,7 +211,7 @@ static int ad7414_probe(struct i2c_client *client,
        /* Register sysfs hooks */
        err = sysfs_create_group(&client->dev.kobj, &ad7414_group);
        if (err)
-               goto exit_free;
+               return err;
 
        data->hwmon_dev = hwmon_device_register(&client->dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -226,9 +223,6 @@ static int ad7414_probe(struct i2c_client *client,
 
 exit_remove:
        sysfs_remove_group(&client->dev.kobj, &ad7414_group);
-exit_free:
-       kfree(data);
-exit:
        return err;
 }
 
@@ -238,7 +232,6 @@ static int __devexit ad7414_remove(struct i2c_client *client)
 
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &ad7414_group);
-       kfree(data);
        return 0;
 }
 
index a50a6be..57d4a62 100644 (file)
@@ -227,16 +227,13 @@ static int ad7418_probe(struct i2c_client *client,
        int err;
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA |
-                                       I2C_FUNC_SMBUS_WORD_DATA)) {
-               err = -EOPNOTSUPP;
-               goto exit;
-       }
+                                       I2C_FUNC_SMBUS_WORD_DATA))
+               return -EOPNOTSUPP;
 
-       data = kzalloc(sizeof(struct ad7418_data), GFP_KERNEL);
-       if (!data) {
-               err = -ENOMEM;
-               goto exit;
-       }
+       data = devm_kzalloc(&client->dev, sizeof(struct ad7418_data),
+                           GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        i2c_set_clientdata(client, data);
 
@@ -268,7 +265,7 @@ static int ad7418_probe(struct i2c_client *client,
        /* Register sysfs hooks */
        err = sysfs_create_group(&client->dev.kobj, &data->attrs);
        if (err)
-               goto exit_free;
+               return err;
 
        data->hwmon_dev = hwmon_device_register(&client->dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -280,9 +277,6 @@ static int ad7418_probe(struct i2c_client *client,
 
 exit_remove:
        sysfs_remove_group(&client->dev.kobj, &data->attrs);
-exit_free:
-       kfree(data);
-exit:
        return err;
 }
 
@@ -291,7 +285,6 @@ 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);
-       kfree(data);
        return 0;
 }
 
index a3d3183..f4c5867 100644 (file)
@@ -141,10 +141,7 @@ static ssize_t adcxx_set_max(struct device *dev,
 static ssize_t adcxx_show_name(struct device *dev, struct device_attribute
                              *devattr, char *buf)
 {
-       struct spi_device *spi = to_spi_device(dev);
-       struct adcxx *adc = spi_get_drvdata(spi);
-
-       return sprintf(buf, "adcxx%ds\n", adc->channels);
+       return sprintf(buf, "%s\n", to_spi_device(dev)->modalias);
 }
 
 static struct sensor_device_attribute ad_input[] = {
@@ -171,7 +168,7 @@ static int __devinit adcxx_probe(struct spi_device *spi)
        int status;
        int i;
 
-       adc = kzalloc(sizeof *adc, GFP_KERNEL);
+       adc = devm_kzalloc(&spi->dev, sizeof(*adc), GFP_KERNEL);
        if (!adc)
                return -ENOMEM;
 
@@ -208,7 +205,6 @@ out_err:
 
        spi_set_drvdata(spi, NULL);
        mutex_unlock(&adc->lock);
-       kfree(adc);
        return status;
 }
 
@@ -224,7 +220,6 @@ static int __devexit adcxx_remove(struct spi_device *spi)
 
        spi_set_drvdata(spi, NULL);
        mutex_unlock(&adc->lock);
-       kfree(adc);
 
        return 0;
 }
index 80cc465..97f4718 100644 (file)
@@ -342,11 +342,10 @@ static int adm1029_probe(struct i2c_client *client,
        struct adm1029_data *data;
        int err;
 
-       data = kzalloc(sizeof(struct adm1029_data), GFP_KERNEL);
-       if (!data) {
-               err = -ENOMEM;
-               goto exit;
-       }
+       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);
@@ -355,15 +354,13 @@ static int adm1029_probe(struct i2c_client *client,
         * Initialize the ADM1029 chip
         * Check config register
         */
-       if (adm1029_init_client(client) == 0) {
-               err = -ENODEV;
-               goto exit_free;
-       }
+       if (adm1029_init_client(client) == 0)
+               return -ENODEV;
 
        /* Register sysfs hooks */
        err = sysfs_create_group(&client->dev.kobj, &adm1029_group);
        if (err)
-               goto exit_free;
+               return err;
 
        data->hwmon_dev = hwmon_device_register(&client->dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -375,9 +372,6 @@ static int adm1029_probe(struct i2c_client *client,
 
  exit_remove_files:
        sysfs_remove_group(&client->dev.kobj, &adm1029_group);
- exit_free:
-       kfree(data);
- exit:
        return err;
 }
 
@@ -405,7 +399,6 @@ static int adm1029_remove(struct i2c_client *client)
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &adm1029_group);
 
-       kfree(data);
        return 0;
 }
 
index 5a78d10..8b24d1a 100644 (file)
@@ -500,31 +500,6 @@ static ssize_t set_aout(struct device *dev,
 }
 static DEVICE_ATTR(aout_output, S_IRUGO | S_IWUSR, show_aout, set_aout);
 
-/* chassis_clear */
-static ssize_t chassis_clear_legacy(struct device *dev,
-               struct device_attribute *attr,
-               const char *buf, size_t count)
-{
-       struct i2c_client *client = to_i2c_client(dev);
-       long val;
-       int err;
-
-       err = kstrtol(buf, 10, &val);
-       if (err)
-               return err;
-
-       dev_warn(dev, "Attribute chassis_clear is deprecated, "
-                "use intrusion0_alarm instead\n");
-
-       if (val == 1) {
-               i2c_smbus_write_byte_data(client,
-                               ADM9240_REG_CHASSIS_CLEAR, 0x80);
-               dev_dbg(&client->dev, "chassis intrusion latch cleared\n");
-       }
-       return count;
-}
-static DEVICE_ATTR(chassis_clear, S_IWUSR, NULL, chassis_clear_legacy);
-
 static ssize_t chassis_clear(struct device *dev,
                struct device_attribute *attr,
                const char *buf, size_t count)
@@ -586,7 +561,6 @@ static struct attribute *adm9240_attributes[] = {
        &sensor_dev_attr_fan2_alarm.dev_attr.attr,
        &dev_attr_alarms.attr,
        &dev_attr_aout_output.attr,
-       &dev_attr_chassis_clear.attr,
        &sensor_dev_attr_intrusion0_alarm.dev_attr.attr,
        &dev_attr_cpu0_vid.attr,
        NULL
index 1958f03..2798246 100644 (file)
@@ -156,7 +156,6 @@ static int ads1015_remove(struct i2c_client *client)
        hwmon_device_unregister(data->hwmon_dev);
        for (k = 0; k < ADS1015_CHANNELS; ++k)
                device_remove_file(&client->dev, &ads1015_in[k].dev_attr);
-       kfree(data);
        return 0;
 }
 
@@ -254,11 +253,10 @@ static int ads1015_probe(struct i2c_client *client,
        int err;
        unsigned int k;
 
-       data = kzalloc(sizeof(struct ads1015_data), GFP_KERNEL);
-       if (!data) {
-               err = -ENOMEM;
-               goto exit;
-       }
+       data = devm_kzalloc(&client->dev, sizeof(struct ads1015_data),
+                           GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        i2c_set_clientdata(client, data);
        mutex_init(&data->update_lock);
@@ -284,8 +282,6 @@ static int ads1015_probe(struct i2c_client *client,
 exit_remove:
        for (k = 0; k < ADS1015_CHANNELS; ++k)
                device_remove_file(&client->dev, &ads1015_in[k].dev_attr);
-       kfree(data);
-exit:
        return err;
 }
 
index bf3fdf4..1f9e8af 100644 (file)
@@ -154,7 +154,6 @@ 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);
-       kfree(i2c_get_clientdata(client));
        return 0;
 }
 
@@ -217,11 +216,10 @@ static int ads7828_probe(struct i2c_client *client,
        struct ads7828_data *data;
        int err;
 
-       data = kzalloc(sizeof(struct ads7828_data), GFP_KERNEL);
-       if (!data) {
-               err = -ENOMEM;
-               goto exit;
-       }
+       data = devm_kzalloc(&client->dev, sizeof(struct ads7828_data),
+                           GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        i2c_set_clientdata(client, data);
        mutex_init(&data->update_lock);
@@ -229,7 +227,7 @@ static int ads7828_probe(struct i2c_client *client,
        /* Register sysfs hooks */
        err = sysfs_create_group(&client->dev.kobj, &ads7828_group);
        if (err)
-               goto exit_free;
+               return err;
 
        data->hwmon_dev = hwmon_device_register(&client->dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -241,9 +239,6 @@ static int ads7828_probe(struct i2c_client *client,
 
 exit_remove:
        sysfs_remove_group(&client->dev.kobj, &ads7828_group);
-exit_free:
-       kfree(data);
-exit:
        return err;
 }
 
index 7bf4ce3..1b53aa4 100644 (file)
@@ -198,20 +198,17 @@ static int __devinit ads7871_probe(struct spi_device *spi)
         * because there is no other error checking on an SPI bus
         * we need to make sure we really have a chip
         */
-       if (val != ret) {
-               err = -ENODEV;
-               goto exit;
-       }
+       if (val != ret)
+               return -ENODEV;
 
-       pdata = kzalloc(sizeof(struct ads7871_data), GFP_KERNEL);
-       if (!pdata) {
-               err = -ENOMEM;
-               goto exit;
-       }
+       pdata = devm_kzalloc(&spi->dev, sizeof(struct ads7871_data),
+                            GFP_KERNEL);
+       if (!pdata)
+               return -ENOMEM;
 
        err = sysfs_create_group(&spi->dev.kobj, &ads7871_group);
        if (err < 0)
-               goto error_free;
+               return err;
 
        spi_set_drvdata(spi, pdata);
 
@@ -225,9 +222,6 @@ static int __devinit ads7871_probe(struct spi_device *spi)
 
 error_remove:
        sysfs_remove_group(&spi->dev.kobj, &ads7871_group);
-error_free:
-       kfree(pdata);
-exit:
        return err;
 }
 
@@ -237,7 +231,6 @@ static int __devexit ads7871_remove(struct spi_device *spi)
 
        hwmon_device_unregister(pdata->hwmon_dev);
        sysfs_remove_group(&spi->dev.kobj, &ads7871_group);
-       kfree(pdata);
        return 0;
 }
 
diff --git a/drivers/hwmon/adt7410.c b/drivers/hwmon/adt7410.c
new file mode 100644 (file)
index 0000000..030c8d7
--- /dev/null
@@ -0,0 +1,464 @@
+/*
+ * adt7410.c - Part of lm_sensors, Linux kernel modules for hardware
+ *      monitoring
+ * This driver handles the ADT7410 and compatible digital temperature sensors.
+ * Hartmut Knaack <knaack.h@gmx.de> 2012-07-22
+ * based on lm75.c by Frodo Looijaard <frodol@dds.nl>
+ * and adt7410.c from iio-staging by Sonic Zhang <sonic.zhang@analog.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.
+ *
+ * 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.
+ */
+
+#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>
+
+/*
+ * ADT7410 registers definition
+ */
+
+#define ADT7410_TEMPERATURE            0
+#define ADT7410_STATUS                 2
+#define ADT7410_CONFIG                 3
+#define ADT7410_T_ALARM_HIGH           4
+#define ADT7410_T_ALARM_LOW            6
+#define ADT7410_T_CRIT                 8
+#define ADT7410_T_HYST                 0xA
+
+/*
+ * ADT7410 status
+ */
+#define ADT7410_STAT_T_LOW             (1 << 4)
+#define ADT7410_STAT_T_HIGH            (1 << 5)
+#define ADT7410_STAT_T_CRIT            (1 << 6)
+#define ADT7410_STAT_NOT_RDY           (1 << 7)
+
+/*
+ * ADT7410 config
+ */
+#define ADT7410_FAULT_QUEUE_MASK       (1 << 0 | 1 << 1)
+#define ADT7410_CT_POLARITY            (1 << 2)
+#define ADT7410_INT_POLARITY           (1 << 3)
+#define ADT7410_EVENT_MODE             (1 << 4)
+#define ADT7410_MODE_MASK              (1 << 5 | 1 << 6)
+#define ADT7410_FULL                   (0 << 5 | 0 << 6)
+#define ADT7410_PD                     (1 << 5 | 1 << 6)
+#define ADT7410_RESOLUTION             (1 << 7)
+
+/*
+ * ADT7410 masks
+ */
+#define ADT7410_T13_VALUE_MASK                 0xFFF8
+#define ADT7410_T_HYST_MASK                    0xF
+
+/* straight from the datasheet */
+#define ADT7410_TEMP_MIN (-55000)
+#define ADT7410_TEMP_MAX 150000
+
+enum adt7410_type {            /* keep sorted in alphabetical order */
+       adt7410,
+};
+
+/* Addresses scanned */
+static const unsigned short normal_i2c[] = { 0x48, 0x49, 0x4a, 0x4b,
+                                       I2C_CLIENT_END };
+
+static const u8 ADT7410_REG_TEMP[4] = {
+       ADT7410_TEMPERATURE,            /* input */
+       ADT7410_T_ALARM_HIGH,           /* high */
+       ADT7410_T_ALARM_LOW,            /* low */
+       ADT7410_T_CRIT,                 /* critical */
+};
+
+/* Each client has this additional data */
+struct adt7410_data {
+       struct device           *hwmon_dev;
+       struct mutex            update_lock;
+       u8                      config;
+       u8                      oldconfig;
+       bool                    valid;          /* true if registers valid */
+       unsigned long           last_updated;   /* In jiffies */
+       s16                     temp[4];        /* Register values,
+                                                  0 = input
+                                                  1 = high
+                                                  2 = low
+                                                  3 = critical */
+       u8                      hyst;           /* hysteresis offset */
+};
+
+/*
+ * adt7410 register access by I2C
+ */
+static int adt7410_temp_ready(struct i2c_client *client)
+{
+       int i, status;
+
+       for (i = 0; i < 6; i++) {
+               status = i2c_smbus_read_byte_data(client, ADT7410_STATUS);
+               if (status < 0)
+                       return status;
+               if (!(status & ADT7410_STAT_NOT_RDY))
+                       return 0;
+               msleep(60);
+       }
+       return -ETIMEDOUT;
+}
+
+static struct adt7410_data *adt7410_update_device(struct device *dev)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct adt7410_data *data = i2c_get_clientdata(client);
+       struct adt7410_data *ret = data;
+       mutex_lock(&data->update_lock);
+
+       if (time_after(jiffies, data->last_updated + HZ + HZ / 2)
+           || !data->valid) {
+               int i, status;
+
+               dev_dbg(&client->dev, "Starting update\n");
+
+               status = adt7410_temp_ready(client); /* check for new value */
+               if (unlikely(status)) {
+                       ret = ERR_PTR(status);
+                       goto abort;
+               }
+               for (i = 0; i < ARRAY_SIZE(data->temp); i++) {
+                       status = i2c_smbus_read_word_swapped(client,
+                                                       ADT7410_REG_TEMP[i]);
+                       if (unlikely(status < 0)) {
+                               dev_dbg(dev,
+                                       "Failed to read value: reg %d, error %d\n",
+                                       ADT7410_REG_TEMP[i], status);
+                               ret = ERR_PTR(status);
+                               goto abort;
+                       }
+                       data->temp[i] = status;
+               }
+               status = i2c_smbus_read_byte_data(client, ADT7410_T_HYST);
+               if (unlikely(status < 0)) {
+                       dev_dbg(dev,
+                               "Failed to read value: reg %d, error %d\n",
+                               ADT7410_T_HYST, status);
+                       ret = ERR_PTR(status);
+                       goto abort;
+               }
+               data->hyst = status;
+               data->last_updated = jiffies;
+               data->valid = true;
+       }
+
+abort:
+       mutex_unlock(&data->update_lock);
+       return ret;
+}
+
+static s16 ADT7410_TEMP_TO_REG(long temp)
+{
+       return DIV_ROUND_CLOSEST(SENSORS_LIMIT(temp, ADT7410_TEMP_MIN,
+                                              ADT7410_TEMP_MAX) * 128, 1000);
+}
+
+static int ADT7410_REG_TO_TEMP(struct adt7410_data *data, s16 reg)
+{
+       /* in 13 bit mode, bits 0-2 are status flags - mask them out */
+       if (!(data->config & ADT7410_RESOLUTION))
+               reg &= ADT7410_T13_VALUE_MASK;
+       /*
+        * temperature is stored in twos complement format, in steps of
+        * 1/128°C
+        */
+       return DIV_ROUND_CLOSEST(reg * 1000, 128);
+}
+
+/*-----------------------------------------------------------------------*/
+
+/* sysfs attributes for hwmon */
+
+static ssize_t adt7410_show_temp(struct device *dev,
+                                struct device_attribute *da, char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+       struct adt7410_data *data = adt7410_update_device(dev);
+
+       if (IS_ERR(data))
+               return PTR_ERR(data);
+
+       return sprintf(buf, "%d\n", ADT7410_REG_TO_TEMP(data,
+                      data->temp[attr->index]));
+}
+
+static ssize_t adt7410_set_temp(struct device *dev,
+                               struct device_attribute *da,
+                               const char *buf, size_t count)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+       struct i2c_client *client = to_i2c_client(dev);
+       struct adt7410_data *data = i2c_get_clientdata(client);
+       int nr = attr->index;
+       long temp;
+       int ret;
+
+       ret = kstrtol(buf, 10, &temp);
+       if (ret)
+               return ret;
+
+       mutex_lock(&data->update_lock);
+       data->temp[nr] = ADT7410_TEMP_TO_REG(temp);
+       ret = i2c_smbus_write_word_swapped(client, ADT7410_REG_TEMP[nr],
+                                          data->temp[nr]);
+       if (ret)
+               count = ret;
+       mutex_unlock(&data->update_lock);
+       return count;
+}
+
+static ssize_t adt7410_show_t_hyst(struct device *dev,
+                                  struct device_attribute *da,
+                                  char *buf)
+{
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+       struct adt7410_data *data;
+       int nr = attr->index;
+       int hyst;
+
+       data = adt7410_update_device(dev);
+       if (IS_ERR(data))
+               return PTR_ERR(data);
+       hyst = (data->hyst & ADT7410_T_HYST_MASK) * 1000;
+
+       /*
+        * hysteresis is stored as a 4 bit offset in the device, convert it
+        * to an absolute value
+        */
+       if (nr == 2)    /* min has positive offset, others have negative */
+               hyst = -hyst;
+       return sprintf(buf, "%d\n",
+                      ADT7410_REG_TO_TEMP(data, data->temp[nr]) - hyst);
+}
+
+static ssize_t adt7410_set_t_hyst(struct device *dev,
+                                 struct device_attribute *da,
+                                 const char *buf, size_t count)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct adt7410_data *data = i2c_get_clientdata(client);
+       int limit, ret;
+       long hyst;
+
+       ret = kstrtol(buf, 10, &hyst);
+       if (ret)
+               return ret;
+       /* convert absolute hysteresis value to a 4 bit delta value */
+       limit = ADT7410_REG_TO_TEMP(data, data->temp[1]);
+       hyst = SENSORS_LIMIT(hyst, ADT7410_TEMP_MIN, ADT7410_TEMP_MAX);
+       data->hyst = SENSORS_LIMIT(DIV_ROUND_CLOSEST(limit - hyst, 1000),
+                                  0, ADT7410_T_HYST_MASK);
+       ret = i2c_smbus_write_byte_data(client, ADT7410_T_HYST, data->hyst);
+       if (ret)
+               return ret;
+
+       return count;
+}
+
+static ssize_t adt7410_show_alarm(struct device *dev,
+                                 struct device_attribute *da,
+                                 char *buf)
+{
+       struct i2c_client *client = to_i2c_client(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
+       int ret;
+
+       ret = i2c_smbus_read_byte_data(client, ADT7410_STATUS);
+       if (ret < 0)
+               return ret;
+
+       return sprintf(buf, "%d\n", !!(ret & attr->index));
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, adt7410_show_temp, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp1_max, S_IWUSR | S_IRUGO,
+                         adt7410_show_temp, adt7410_set_temp, 1);
+static SENSOR_DEVICE_ATTR(temp1_min, S_IWUSR | S_IRUGO,
+                         adt7410_show_temp, adt7410_set_temp, 2);
+static SENSOR_DEVICE_ATTR(temp1_crit, S_IWUSR | S_IRUGO,
+                         adt7410_show_temp, adt7410_set_temp, 3);
+static SENSOR_DEVICE_ATTR(temp1_max_hyst, S_IWUSR | S_IRUGO,
+                         adt7410_show_t_hyst, adt7410_set_t_hyst, 1);
+static SENSOR_DEVICE_ATTR(temp1_min_hyst, S_IRUGO,
+                         adt7410_show_t_hyst, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp1_crit_hyst, S_IRUGO,
+                         adt7410_show_t_hyst, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp1_min_alarm, S_IRUGO, adt7410_show_alarm,
+                         NULL, ADT7410_STAT_T_LOW);
+static SENSOR_DEVICE_ATTR(temp1_max_alarm, S_IRUGO, adt7410_show_alarm,
+                         NULL, ADT7410_STAT_T_HIGH);
+static SENSOR_DEVICE_ATTR(temp1_crit_alarm, S_IRUGO, adt7410_show_alarm,
+                         NULL, ADT7410_STAT_T_CRIT);
+
+static struct attribute *adt7410_attributes[] = {
+       &sensor_dev_attr_temp1_input.dev_attr.attr,
+       &sensor_dev_attr_temp1_max.dev_attr.attr,
+       &sensor_dev_attr_temp1_min.dev_attr.attr,
+       &sensor_dev_attr_temp1_crit.dev_attr.attr,
+       &sensor_dev_attr_temp1_max_hyst.dev_attr.attr,
+       &sensor_dev_attr_temp1_min_hyst.dev_attr.attr,
+       &sensor_dev_attr_temp1_crit_hyst.dev_attr.attr,
+       &sensor_dev_attr_temp1_min_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp1_max_alarm.dev_attr.attr,
+       &sensor_dev_attr_temp1_crit_alarm.dev_attr.attr,
+       NULL
+};
+
+static const struct attribute_group adt7410_group = {
+       .attrs = adt7410_attributes,
+};
+
+/*-----------------------------------------------------------------------*/
+
+/* device probe and removal */
+
+static int adt7410_probe(struct i2c_client *client,
+                        const struct i2c_device_id *id)
+{
+       struct adt7410_data *data;
+       int ret;
+
+       if (!i2c_check_functionality(client->adapter,
+                       I2C_FUNC_SMBUS_BYTE_DATA | I2C_FUNC_SMBUS_WORD_DATA))
+               return -ENODEV;
+
+       data = devm_kzalloc(&client->dev, sizeof(struct adt7410_data),
+                           GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
+
+       i2c_set_clientdata(client, data);
+       mutex_init(&data->update_lock);
+
+       /* configure as specified */
+       ret = i2c_smbus_read_byte_data(client, ADT7410_CONFIG);
+       if (ret < 0) {
+               dev_dbg(&client->dev, "Can't read config? %d\n", ret);
+               return ret;
+       }
+       data->oldconfig = ret;
+       /*
+        * Set to 16 bit resolution, continous conversion and comparator mode.
+        */
+       data->config = ret | ADT7410_FULL | ADT7410_RESOLUTION |
+                       ADT7410_EVENT_MODE;
+       if (data->config != data->oldconfig) {
+               ret = i2c_smbus_write_byte_data(client, ADT7410_CONFIG,
+                                               data->config);
+               if (ret)
+                       return ret;
+       }
+       dev_dbg(&client->dev, "Config %02x\n", data->config);
+
+       /* Register sysfs hooks */
+       ret = sysfs_create_group(&client->dev.kobj, &adt7410_group);
+       if (ret)
+               goto exit_restore;
+
+       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, "sensor '%s'\n", client->name);
+
+       return 0;
+
+exit_remove:
+       sysfs_remove_group(&client->dev.kobj, &adt7410_group);
+exit_restore:
+       i2c_smbus_write_byte_data(client, ADT7410_CONFIG, data->oldconfig);
+       return ret;
+}
+
+static int adt7410_remove(struct i2c_client *client)
+{
+       struct adt7410_data *data = i2c_get_clientdata(client);
+
+       hwmon_device_unregister(data->hwmon_dev);
+       sysfs_remove_group(&client->dev.kobj, &adt7410_group);
+       if (data->oldconfig != data->config)
+               i2c_smbus_write_byte_data(client, ADT7410_CONFIG,
+                                         data->oldconfig);
+       return 0;
+}
+
+static const struct i2c_device_id adt7410_ids[] = {
+       { "adt7410", adt7410, },
+       { /* LIST END */ }
+};
+MODULE_DEVICE_TABLE(i2c, adt7410_ids);
+
+#ifdef CONFIG_PM
+static int adt7410_suspend(struct device *dev)
+{
+       int ret;
+       struct i2c_client *client = to_i2c_client(dev);
+       struct adt7410_data *data = i2c_get_clientdata(client);
+
+       ret = i2c_smbus_write_byte_data(client, ADT7410_CONFIG,
+                                       data->config | ADT7410_PD);
+       return ret;
+}
+
+static int adt7410_resume(struct device *dev)
+{
+       int ret;
+       struct i2c_client *client = to_i2c_client(dev);
+       struct adt7410_data *data = i2c_get_clientdata(client);
+
+       ret = i2c_smbus_write_byte_data(client, ADT7410_CONFIG, data->config);
+       return ret;
+}
+
+static const struct dev_pm_ops adt7410_dev_pm_ops = {
+       .suspend        = adt7410_suspend,
+       .resume         = adt7410_resume,
+};
+#define ADT7410_DEV_PM_OPS (&adt7410_dev_pm_ops)
+#else
+#define ADT7410_DEV_PM_OPS NULL
+#endif /* CONFIG_PM */
+
+static struct i2c_driver adt7410_driver = {
+       .class          = I2C_CLASS_HWMON,
+       .driver = {
+               .name   = "adt7410",
+               .pm     = ADT7410_DEV_PM_OPS,
+       },
+       .probe          = adt7410_probe,
+       .remove         = adt7410_remove,
+       .id_table       = adt7410_ids,
+       .address_list   = normal_i2c,
+};
+
+module_i2c_driver(adt7410_driver);
+
+MODULE_AUTHOR("Hartmut Knaack");
+MODULE_DESCRIPTION("ADT7410 driver");
+MODULE_LICENSE("GPL");
index 71bacc5..fe72c69 100644 (file)
@@ -283,7 +283,7 @@ static int __devinit adt7411_probe(struct i2c_client *client,
        struct adt7411_data *data;
        int ret;
 
-       data = kzalloc(sizeof(*data), GFP_KERNEL);
+       data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
@@ -294,14 +294,14 @@ static int __devinit adt7411_probe(struct i2c_client *client,
        ret = adt7411_modify_bit(client, ADT7411_REG_CFG1,
                                 ADT7411_CFG1_START_MONITOR, 1);
        if (ret < 0)
-               goto exit_free;
+               return ret;
 
        /* force update on first occasion */
        data->next_update = jiffies;
 
        ret = sysfs_create_group(&client->dev.kobj, &adt7411_attr_grp);
        if (ret)
-               goto exit_free;
+               return ret;
 
        data->hwmon_dev = hwmon_device_register(&client->dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -315,8 +315,6 @@ static int __devinit adt7411_probe(struct i2c_client *client,
 
  exit_remove:
        sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
- exit_free:
-       kfree(data);
        return ret;
 }
 
@@ -326,7 +324,6 @@ static int __devexit adt7411_remove(struct i2c_client *client)
 
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &adt7411_attr_grp);
-       kfree(data);
        return 0;
 }
 
index 339269f..baee482 100644 (file)
@@ -1931,11 +1931,10 @@ static int adt7462_probe(struct i2c_client *client,
        struct adt7462_data *data;
        int err;
 
-       data = kzalloc(sizeof(struct adt7462_data), GFP_KERNEL);
-       if (!data) {
-               err = -ENOMEM;
-               goto exit;
-       }
+       data = devm_kzalloc(&client->dev, sizeof(struct adt7462_data),
+                           GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        i2c_set_clientdata(client, data);
        mutex_init(&data->lock);
@@ -1946,7 +1945,7 @@ static int adt7462_probe(struct i2c_client *client,
        data->attrs.attrs = adt7462_attr;
        err = sysfs_create_group(&client->dev.kobj, &data->attrs);
        if (err)
-               goto exit_free;
+               return err;
 
        data->hwmon_dev = hwmon_device_register(&client->dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -1958,9 +1957,6 @@ static int adt7462_probe(struct i2c_client *client,
 
 exit_remove:
        sysfs_remove_group(&client->dev.kobj, &data->attrs);
-exit_free:
-       kfree(data);
-exit:
        return err;
 }
 
@@ -1970,7 +1966,6 @@ static int adt7462_remove(struct i2c_client *client)
 
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &data->attrs);
-       kfree(data);
        return 0;
 }
 
index 54ec890..39ecb1a 100644 (file)
@@ -1256,11 +1256,10 @@ static int adt7470_probe(struct i2c_client *client,
        struct adt7470_data *data;
        int err;
 
-       data = kzalloc(sizeof(struct adt7470_data), GFP_KERNEL);
-       if (!data) {
-               err = -ENOMEM;
-               goto exit;
-       }
+       data = devm_kzalloc(&client->dev, sizeof(struct adt7470_data),
+                           GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        data->num_temp_sensors = -1;
        data->auto_update_interval = AUTO_UPDATE_INTERVAL;
@@ -1277,7 +1276,7 @@ static int adt7470_probe(struct i2c_client *client,
        data->attrs.attrs = adt7470_attr;
        err = sysfs_create_group(&client->dev.kobj, &data->attrs);
        if (err)
-               goto exit_free;
+               return err;
 
        data->hwmon_dev = hwmon_device_register(&client->dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -1299,9 +1298,6 @@ exit_unregister:
        hwmon_device_unregister(data->hwmon_dev);
 exit_remove:
        sysfs_remove_group(&client->dev.kobj, &data->attrs);
-exit_free:
-       kfree(data);
-exit:
        return err;
 }
 
@@ -1313,7 +1309,6 @@ static int adt7470_remove(struct i2c_client *client)
        wait_for_completion(&data->auto_update_stop);
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &data->attrs);
-       kfree(data);
        return 0;
 }
 
index f600fa1..ae482e3 100644 (file)
@@ -862,12 +862,10 @@ static int amc6821_probe(
        struct amc6821_data *data;
        int err;
 
-       data = kzalloc(sizeof(struct amc6821_data), GFP_KERNEL);
-       if (!data) {
-               dev_err(&client->dev, "out of memory.\n");
+       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);
@@ -877,11 +875,11 @@ static int amc6821_probe(
         */
        err = amc6821_init_client(client);
        if (err)
-               goto err_free;
+               return err;
 
        err = sysfs_create_group(&client->dev.kobj, &amc6821_attr_grp);
        if (err)
-               goto err_free;
+               return err;
 
        data->hwmon_dev = hwmon_device_register(&client->dev);
        if (!IS_ERR(data->hwmon_dev))
@@ -890,8 +888,6 @@ static int amc6821_probe(
        err = PTR_ERR(data->hwmon_dev);
        dev_err(&client->dev, "error registering hwmon device.\n");
        sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp);
-err_free:
-       kfree(data);
        return err;
 }
 
@@ -902,8 +898,6 @@ static int amc6821_remove(struct i2c_client *client)
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &amc6821_attr_grp);
 
-       kfree(data);
-
        return 0;
 }
 
index 4b8814d..a227be4 100644 (file)
@@ -787,12 +787,10 @@ static int asb100_probe(struct i2c_client *client,
        int err;
        struct asb100_data *data;
 
-       data = kzalloc(sizeof(struct asb100_data), GFP_KERNEL);
-       if (!data) {
-               pr_debug("probe failed, kzalloc failed!\n");
-               err = -ENOMEM;
-               goto ERROR0;
-       }
+       data = devm_kzalloc(&client->dev, sizeof(struct asb100_data),
+                           GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        i2c_set_clientdata(client, data);
        mutex_init(&data->lock);
@@ -801,7 +799,7 @@ static int asb100_probe(struct i2c_client *client,
        /* Attach secondary lm75 clients */
        err = asb100_detect_subclients(client);
        if (err)
-               goto ERROR1;
+               return err;
 
        /* Initialize the chip */
        asb100_init_client(client);
@@ -829,9 +827,6 @@ ERROR4:
 ERROR3:
        i2c_unregister_device(data->lm75[1]);
        i2c_unregister_device(data->lm75[0]);
-ERROR1:
-       kfree(data);
-ERROR0:
        return err;
 }
 
@@ -845,8 +840,6 @@ static int asb100_remove(struct i2c_client *client)
        i2c_unregister_device(data->lm75[1]);
        i2c_unregister_device(data->lm75[0]);
 
-       kfree(data);
-
        return 0;
 }
 
index 4ee5789..cccb0e9 100644 (file)
@@ -962,7 +962,6 @@ static int atk_add_sensor(struct atk_data *data, union acpi_object *obj)
 
        return 1;
 out:
-       kfree(sensor->acpi_name);
        kfree(sensor);
        return err;
 }
index e7c6a19..fe0eeec 100644 (file)
@@ -2475,11 +2475,9 @@ static int dme1737_i2c_probe(struct i2c_client *client,
        struct device *dev = &client->dev;
        int err;
 
-       data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL);
-       if (!data) {
-               err = -ENOMEM;
-               goto exit;
-       }
+       data = devm_kzalloc(dev, sizeof(struct dme1737_data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        i2c_set_clientdata(client, data);
        data->type = id->driver_data;
@@ -2491,14 +2489,14 @@ static int dme1737_i2c_probe(struct i2c_client *client,
        err = dme1737_init_device(dev);
        if (err) {
                dev_err(dev, "Failed to initialize device.\n");
-               goto exit_kfree;
+               return err;
        }
 
        /* Create sysfs files */
        err = dme1737_create_files(dev);
        if (err) {
                dev_err(dev, "Failed to create sysfs files.\n");
-               goto exit_kfree;
+               return err;
        }
 
        /* Register device */
@@ -2513,9 +2511,6 @@ static int dme1737_i2c_probe(struct i2c_client *client,
 
 exit_remove:
        dme1737_remove_files(dev);
-exit_kfree:
-       kfree(data);
-exit:
        return err;
 }
 
@@ -2526,7 +2521,6 @@ static int dme1737_i2c_remove(struct i2c_client *client)
        hwmon_device_unregister(data->hwmon_dev);
        dme1737_remove_files(&client->dev);
 
-       kfree(data);
        return 0;
 }
 
@@ -2645,19 +2639,16 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev)
        int err;
 
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-       if (!request_region(res->start, DME1737_EXTENT, "dme1737")) {
+       if (!devm_request_region(dev, res->start, DME1737_EXTENT, "dme1737")) {
                dev_err(dev, "Failed to request region 0x%04x-0x%04x.\n",
                        (unsigned short)res->start,
                        (unsigned short)res->start + DME1737_EXTENT - 1);
-               err = -EBUSY;
-               goto exit;
+               return -EBUSY;
        }
 
-       data = kzalloc(sizeof(struct dme1737_data), GFP_KERNEL);
-       if (!data) {
-               err = -ENOMEM;
-               goto exit_release_region;
-       }
+       data = devm_kzalloc(dev, sizeof(struct dme1737_data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        data->addr = res->start;
        platform_set_drvdata(pdev, data);
@@ -2683,8 +2674,7 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev)
                           (device == SCH5127_DEVICE)) {
                        data->type = sch5127;
                } else {
-                       err = -ENODEV;
-                       goto exit_kfree;
+                       return -ENODEV;
                }
        }
 
@@ -2703,14 +2693,14 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev)
        err = dme1737_init_device(dev);
        if (err) {
                dev_err(dev, "Failed to initialize device.\n");
-               goto exit_kfree;
+               return err;
        }
 
        /* Create sysfs files */
        err = dme1737_create_files(dev);
        if (err) {
                dev_err(dev, "Failed to create sysfs files.\n");
-               goto exit_kfree;
+               return err;
        }
 
        /* Register device */
@@ -2725,12 +2715,6 @@ static int __devinit dme1737_isa_probe(struct platform_device *pdev)
 
 exit_remove_files:
        dme1737_remove_files(dev);
-exit_kfree:
-       platform_set_drvdata(pdev, NULL);
-       kfree(data);
-exit_release_region:
-       release_region(res->start, DME1737_EXTENT);
-exit:
        return err;
 }
 
@@ -2740,9 +2724,6 @@ static int __devexit dme1737_isa_remove(struct platform_device *pdev)
 
        hwmon_device_unregister(data->hwmon_dev);
        dme1737_remove_files(&pdev->dev);
-       release_region(data->addr, DME1737_EXTENT);
-       platform_set_drvdata(pdev, NULL);
-       kfree(data);
 
        return 0;
 }
index 50663ef..f1d6b42 100644 (file)
@@ -232,11 +232,10 @@ static int ds620_probe(struct i2c_client *client,
        struct ds620_data *data;
        int err;
 
-       data = kzalloc(sizeof(struct ds620_data), GFP_KERNEL);
-       if (!data) {
-               err = -ENOMEM;
-               goto exit;
-       }
+       data = devm_kzalloc(&client->dev, sizeof(struct ds620_data),
+                           GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        i2c_set_clientdata(client, data);
        mutex_init(&data->update_lock);
@@ -247,7 +246,7 @@ static int ds620_probe(struct i2c_client *client,
        /* Register sysfs hooks */
        err = sysfs_create_group(&client->dev.kobj, &ds620_group);
        if (err)
-               goto exit_free;
+               return err;
 
        data->hwmon_dev = hwmon_device_register(&client->dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -261,9 +260,6 @@ static int ds620_probe(struct i2c_client *client,
 
 exit_remove_files:
        sysfs_remove_group(&client->dev.kobj, &ds620_group);
-exit_free:
-       kfree(data);
-exit:
        return err;
 }
 
@@ -274,8 +270,6 @@ static int ds620_remove(struct i2c_client *client)
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &ds620_group);
 
-       kfree(data);
-
        return 0;
 }
 
index 149dcb0..68ab94b 100644 (file)
@@ -306,11 +306,10 @@ static int emc1403_probe(struct i2c_client *client,
        int res;
        struct thermal_data *data;
 
-       data = kzalloc(sizeof(struct thermal_data), GFP_KERNEL);
-       if (data == NULL) {
-               dev_warn(&client->dev, "out of memory");
+       data = devm_kzalloc(&client->dev, sizeof(struct thermal_data),
+                           GFP_KERNEL);
+       if (data == NULL)
                return -ENOMEM;
-       }
 
        i2c_set_clientdata(client, data);
        mutex_init(&data->mutex);
@@ -319,21 +318,19 @@ static int emc1403_probe(struct i2c_client *client,
        res = sysfs_create_group(&client->dev.kobj, &m_thermal_gr);
        if (res) {
                dev_warn(&client->dev, "create group failed\n");
-               goto thermal_error1;
+               return res;
        }
        data->hwmon_dev = hwmon_device_register(&client->dev);
        if (IS_ERR(data->hwmon_dev)) {
                res = PTR_ERR(data->hwmon_dev);
                dev_warn(&client->dev, "register hwmon dev failed\n");
-               goto thermal_error2;
+               goto thermal_error;
        }
        dev_info(&client->dev, "EMC1403 Thermal chip found\n");
-       return res;
+       return 0;
 
-thermal_error2:
+thermal_error:
        sysfs_remove_group(&client->dev.kobj, &m_thermal_gr);
-thermal_error1:
-       kfree(data);
        return res;
 }
 
@@ -343,7 +340,6 @@ static int emc1403_remove(struct i2c_client *client)
 
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &m_thermal_gr);
-       kfree(data);
        return 0;
 }
 
index 7bb8e88..77f434c 100644 (file)
@@ -590,7 +590,8 @@ emc2103_probe(struct i2c_client *client, const struct i2c_device_id *id)
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_SMBUS_BYTE_DATA))
                return -EIO;
 
-       data = kzalloc(sizeof(struct emc2103_data), GFP_KERNEL);
+       data = devm_kzalloc(&client->dev, sizeof(struct emc2103_data),
+                           GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
@@ -608,7 +609,7 @@ emc2103_probe(struct i2c_client *client, const struct i2c_device_id *id)
                if (status < 0) {
                        dev_dbg(&client->dev, "reg 0x%02x, err %d\n", REG_CONF1,
                                status);
-                       goto exit_free;
+                       return status;
                }
 
                /* detect current state of hardware */
@@ -631,7 +632,7 @@ 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)
-               goto exit_free;
+               return status;
 
        if (data->temp_count >= 3) {
                status = sysfs_create_group(&client->dev.kobj,
@@ -666,8 +667,6 @@ exit_remove_temp3:
                sysfs_remove_group(&client->dev.kobj, &emc2103_temp3_group);
 exit_remove:
        sysfs_remove_group(&client->dev.kobj, &emc2103_group);
-exit_free:
-       kfree(data);
        return status;
 }
 
@@ -685,7 +684,6 @@ static int emc2103_remove(struct i2c_client *client)
 
        sysfs_remove_group(&client->dev.kobj, &emc2103_group);
 
-       kfree(data);
        return 0;
 }
 
index 6d12263..50e4ce2 100644 (file)
@@ -2274,7 +2274,8 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
        int err, i;
        u8 start_reg, reg;
 
-       data = kzalloc(sizeof(struct f71882fg_data), GFP_KERNEL);
+       data = devm_kzalloc(&pdev->dev, sizeof(struct f71882fg_data),
+                           GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
@@ -2288,13 +2289,11 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
        start_reg = f71882fg_read8(data, F71882FG_REG_START);
        if (start_reg & 0x04) {
                dev_warn(&pdev->dev, "Hardware monitor is powered down\n");
-               err = -ENODEV;
-               goto exit_free;
+               return -ENODEV;
        }
        if (!(start_reg & 0x03)) {
                dev_warn(&pdev->dev, "Hardware monitoring not activated\n");
-               err = -ENODEV;
-               goto exit_free;
+               return -ENODEV;
        }
 
        /* Register sysfs interface files */
@@ -2422,8 +2421,6 @@ static int __devinit f71882fg_probe(struct platform_device *pdev)
 exit_unregister_sysfs:
        f71882fg_remove(pdev); /* Will unregister the sysfs files for us */
        return err; /* f71882fg_remove() also frees our data */
-exit_free:
-       kfree(data);
        return err;
 }
 
@@ -2525,17 +2522,13 @@ static int f71882fg_remove(struct platform_device *pdev)
                                ARRAY_SIZE(fxxxx_auto_pwm_attr[0]) * nr_fans);
                }
        }
-
-       platform_set_drvdata(pdev, NULL);
-       kfree(data);
-
        return 0;
 }
 
-static int __init f71882fg_find(int sioaddr, unsigned short *address,
-       struct f71882fg_sio_data *sio_data)
+static int __init f71882fg_find(int sioaddr, struct f71882fg_sio_data *sio_data)
 {
        u16 devid;
+       unsigned short address;
        int err = superio_enter(sioaddr);
        if (err)
                return err;
@@ -2603,25 +2596,25 @@ static int __init f71882fg_find(int sioaddr, unsigned short *address,
                goto exit;
        }
 
-       *address = superio_inw(sioaddr, SIO_REG_ADDR);
-       if (*address == 0) {
+       address = superio_inw(sioaddr, SIO_REG_ADDR);
+       if (address == 0) {
                pr_warn("Base address not set\n");
                err = -ENODEV;
                goto exit;
        }
-       *address &= ~(REGION_LENGTH - 1);       /* Ignore 3 LSB */
+       address &= ~(REGION_LENGTH - 1);        /* Ignore 3 LSB */
 
-       err = 0;
+       err = address;
        pr_info("Found %s chip at %#x, revision %d\n",
-               f71882fg_names[sio_data->type], (unsigned int)*address,
+               f71882fg_names[sio_data->type], (unsigned int)address,
                (int)superio_inb(sioaddr, SIO_REG_DEVREV));
 exit:
        superio_exit(sioaddr);
        return err;
 }
 
-static int __init f71882fg_device_add(unsigned short address,
-       const struct f71882fg_sio_data *sio_data)
+static int __init f71882fg_device_add(int address,
+                                     const struct f71882fg_sio_data *sio_data)
 {
        struct resource res = {
                .start  = address,
@@ -2668,19 +2661,21 @@ exit_device_put:
 
 static int __init f71882fg_init(void)
 {
-       int err = -ENODEV;
-       unsigned short address;
+       int err;
+       int address;
        struct f71882fg_sio_data sio_data;
 
        memset(&sio_data, 0, sizeof(sio_data));
 
-       if (f71882fg_find(0x2e, &address, &sio_data) &&
-           f71882fg_find(0x4e, &address, &sio_data))
-               goto exit;
+       address = f71882fg_find(0x2e, &sio_data);
+       if (address < 0)
+               address = f71882fg_find(0x4e, &sio_data);
+       if (address < 0)
+               return address;
 
        err = platform_driver_register(&f71882fg_driver);
        if (err)
-               goto exit;
+               return err;
 
        err = f71882fg_device_add(address, &sio_data);
        if (err)
@@ -2690,7 +2685,6 @@ static int __init f71882fg_init(void)
 
 exit_driver:
        platform_driver_unregister(&f71882fg_driver);
-exit:
        return err;
 }
 
index ece4159..f7dba22 100644 (file)
@@ -838,7 +838,8 @@ static int f75375_probe(struct i2c_client *client,
        if (!i2c_check_functionality(client->adapter,
                                I2C_FUNC_SMBUS_BYTE_DATA))
                return -EIO;
-       data = kzalloc(sizeof(struct f75375_data), GFP_KERNEL);
+       data = devm_kzalloc(&client->dev, sizeof(struct f75375_data),
+                           GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
@@ -848,7 +849,7 @@ static int f75375_probe(struct i2c_client *client,
 
        err = sysfs_create_group(&client->dev.kobj, &f75375_group);
        if (err)
-               goto exit_free;
+               return err;
 
        if (data->kind != f75373) {
                err = sysfs_chmod_file(&client->dev.kobj,
@@ -875,8 +876,6 @@ static int f75375_probe(struct i2c_client *client,
 
 exit_remove:
        sysfs_remove_group(&client->dev.kobj, &f75375_group);
-exit_free:
-       kfree(data);
        return err;
 }
 
@@ -885,7 +884,6 @@ static int f75375_remove(struct i2c_client *client)
        struct f75375_data *data = i2c_get_clientdata(client);
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &f75375_group);
-       kfree(data);
        return 0;
 }
 
index af69073..68ad7d2 100644 (file)
@@ -198,7 +198,7 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev,
                                        const struct pci_device_id *id)
 {
        struct fam15h_power_data *data;
-       struct device *dev;
+       struct device *dev = &pdev->dev;
        int err;
 
        /*
@@ -208,23 +208,19 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev,
         */
        tweak_runavg_range(pdev);
 
-       if (!fam15h_power_is_internal_node0(pdev)) {
-               err = -ENODEV;
-               goto exit;
-       }
+       if (!fam15h_power_is_internal_node0(pdev))
+               return -ENODEV;
+
+       data = devm_kzalloc(dev, sizeof(struct fam15h_power_data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
-       data = kzalloc(sizeof(struct fam15h_power_data), GFP_KERNEL);
-       if (!data) {
-               err = -ENOMEM;
-               goto exit;
-       }
        fam15h_power_init_data(pdev, data);
-       dev = &pdev->dev;
 
        dev_set_drvdata(dev, data);
        err = sysfs_create_group(&dev->kobj, &fam15h_power_attr_group);
        if (err)
-               goto exit_free_data;
+               return err;
 
        data->hwmon_dev = hwmon_device_register(dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -236,9 +232,6 @@ static int __devinit fam15h_power_probe(struct pci_dev *pdev,
 
 exit_remove_group:
        sysfs_remove_group(&dev->kobj, &fam15h_power_attr_group);
-exit_free_data:
-       kfree(data);
-exit:
        return err;
 }
 
@@ -251,8 +244,6 @@ static void __devexit fam15h_power_remove(struct pci_dev *pdev)
        data = dev_get_drvdata(dev);
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&dev->kobj, &fam15h_power_attr_group);
-       dev_set_drvdata(dev, NULL);
-       kfree(data);
 }
 
 static DEFINE_PCI_DEVICE_TABLE(fam15h_power_id_table) = {
index ebcd269..8b2106f 100644 (file)
@@ -207,7 +207,8 @@ static int g760a_probe(struct i2c_client *client,
                                     I2C_FUNC_SMBUS_BYTE_DATA))
                return -EIO;
 
-       data = kzalloc(sizeof(struct g760a_data), GFP_KERNEL);
+       data = devm_kzalloc(&client->dev, sizeof(struct g760a_data),
+                           GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
@@ -223,7 +224,7 @@ static int g760a_probe(struct i2c_client *client,
        /* Register sysfs hooks */
        err = sysfs_create_group(&client->dev.kobj, &g760a_group);
        if (err)
-               goto error_sysfs_create_group;
+               return err;
 
        data->hwmon_dev = hwmon_device_register(&client->dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -235,9 +236,6 @@ static int g760a_probe(struct i2c_client *client,
 
 error_hwmon_device_register:
        sysfs_remove_group(&client->dev.kobj, &g760a_group);
-error_sysfs_create_group:
-       kfree(data);
-
        return err;
 }
 
@@ -246,8 +244,6 @@ 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);
-       kfree(data);
-
        return 0;
 }
 
index 6021482..70717d4 100644 (file)
@@ -5,10 +5,18 @@
  * Zero Drift Bi-Directional Current/Power Monitor with I2C Interface
  * Datasheet: http://www.ti.com/product/ina219
  *
+ * INA220:
+ * Bi-Directional Current/Power Monitor with I2C Interface
+ * Datasheet: http://www.ti.com/product/ina220
+ *
  * INA226:
  * Bi-Directional Current/Power Monitor with I2C Interface
  * Datasheet: http://www.ti.com/product/ina226
  *
+ * INA230:
+ * Bi-directional Current/Power Monitor with I2C Interface
+ * Datasheet: http://www.ti.com/product/ina230
+ *
  * Copyright (C) 2012 Lothar Felten <l-felten@ti.com>
  * Thanks to Jan Volkering
  *
 
 enum ina2xx_ids { ina219, ina226 };
 
+struct ina2xx_config {
+       u16 config_default;
+       int calibration_factor;
+       int registers;
+       int shunt_div;
+       int bus_voltage_shift;
+       int bus_voltage_lsb;    /* uV */
+       int power_lsb;          /* uW */
+};
+
 struct ina2xx_data {
        struct device *hwmon_dev;
+       const struct ina2xx_config *config;
 
        struct mutex update_lock;
        bool valid;
        unsigned long last_updated;
 
        int kind;
-       int registers;
        u16 regs[INA2XX_MAX_REGISTERS];
 };
 
+static const struct ina2xx_config ina2xx_config[] = {
+       [ina219] = {
+               .config_default = INA219_CONFIG_DEFAULT,
+               .calibration_factor = 40960000,
+               .registers = INA219_REGISTERS,
+               .shunt_div = 100,
+               .bus_voltage_shift = 3,
+               .bus_voltage_lsb = 4000,
+               .power_lsb = 20000,
+       },
+       [ina226] = {
+               .config_default = INA226_CONFIG_DEFAULT,
+               .calibration_factor = 5120000,
+               .registers = INA226_REGISTERS,
+               .shunt_div = 400,
+               .bus_voltage_shift = 0,
+               .bus_voltage_lsb = 1250,
+               .power_lsb = 25000,
+       },
+};
+
 static struct ina2xx_data *ina2xx_update_device(struct device *dev)
 {
        struct i2c_client *client = to_i2c_client(dev);
@@ -85,7 +124,7 @@ static struct ina2xx_data *ina2xx_update_device(struct device *dev)
                dev_dbg(&client->dev, "Starting ina2xx update\n");
 
                /* Read all registers */
-               for (i = 0; i < data->registers; i++) {
+               for (i = 0; i < data->config->registers; i++) {
                        int rv = i2c_smbus_read_word_swapped(client, i);
                        if (rv < 0) {
                                ret = ERR_PTR(rv);
@@ -101,73 +140,26 @@ abort:
        return ret;
 }
 
-static int ina219_get_value(struct ina2xx_data *data, u8 reg)
+static int ina2xx_get_value(struct ina2xx_data *data, u8 reg)
 {
-       /*
-        * calculate exact value for the given register
-        * we assume default power-on reset settings:
-        * bus voltage range 32V
-        * gain = /8
-        * adc 1 & 2 -> conversion time 532uS
-        * mode is continuous shunt and bus
-        * calibration value is INA219_CALIBRATION_VALUE
-        */
-       int val = data->regs[reg];
+       int val;
 
        switch (reg) {
        case INA2XX_SHUNT_VOLTAGE:
-               /* LSB=10uV. Convert to mV. */
-               val = DIV_ROUND_CLOSEST(val, 100);
+               val = DIV_ROUND_CLOSEST(data->regs[reg],
+                                       data->config->shunt_div);
                break;
        case INA2XX_BUS_VOLTAGE:
-               /* LSB=4mV. Register is not right aligned, convert to mV. */
-               val = (val >> 3) * 4;
+               val = (data->regs[reg] >> data->config->bus_voltage_shift)
+                 * data->config->bus_voltage_lsb;
+               val = DIV_ROUND_CLOSEST(val, 1000);
                break;
        case INA2XX_POWER:
-               /* LSB=20mW. Convert to uW */
-               val = val * 20 * 1000;
-               break;
-       case INA2XX_CURRENT:
-               /* LSB=1mA (selected). Is in mA */
-               break;
-       default:
-               /* programmer goofed */
-               WARN_ON_ONCE(1);
-               val = 0;
-               break;
-       }
-
-       return val;
-}
-
-static int ina226_get_value(struct ina2xx_data *data, u8 reg)
-{
-       /*
-        * calculate exact value for the given register
-        * we assume default power-on reset settings:
-        * bus voltage range 32V
-        * gain = /8
-        * adc 1 & 2 -> conversion time 532uS
-        * mode is continuous shunt and bus
-        * calibration value is INA226_CALIBRATION_VALUE
-        */
-       int val = data->regs[reg];
-
-       switch (reg) {
-       case INA2XX_SHUNT_VOLTAGE:
-               /* LSB=2.5uV. Convert to mV. */
-               val = DIV_ROUND_CLOSEST(val, 400);
-               break;
-       case INA2XX_BUS_VOLTAGE:
-               /* LSB=1.25mV. Convert to mV. */
-               val = val + DIV_ROUND_CLOSEST(val, 4);
-               break;
-       case INA2XX_POWER:
-               /* LSB=25mW. Convert to uW */
-               val = val * 25 * 1000;
+               val = data->regs[reg] * data->config->power_lsb;
                break;
        case INA2XX_CURRENT:
                /* LSB=1mA (selected). Is in mA */
+               val = data->regs[reg];
                break;
        default:
                /* programmer goofed */
@@ -184,23 +176,12 @@ static ssize_t ina2xx_show_value(struct device *dev,
 {
        struct sensor_device_attribute *attr = to_sensor_dev_attr(da);
        struct ina2xx_data *data = ina2xx_update_device(dev);
-       int value = 0;
 
        if (IS_ERR(data))
                return PTR_ERR(data);
 
-       switch (data->kind) {
-       case ina219:
-               value = ina219_get_value(data, attr->index);
-               break;
-       case ina226:
-               value = ina226_get_value(data, attr->index);
-               break;
-       default:
-               WARN_ON_ONCE(1);
-               break;
-       }
-       return snprintf(buf, PAGE_SIZE, "%d\n", value);
+       return snprintf(buf, PAGE_SIZE, "%d\n",
+                       ina2xx_get_value(data, attr->index));
 }
 
 /* shunt voltage */
@@ -238,7 +219,7 @@ static int ina2xx_probe(struct i2c_client *client,
        struct i2c_adapter *adapter = client->adapter;
        struct ina2xx_data *data;
        struct ina2xx_platform_data *pdata;
-       int ret = 0;
+       int ret;
        long shunt = 10000; /* default shunt value 10mOhms */
 
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_WORD_DATA))
@@ -259,38 +240,15 @@ static int ina2xx_probe(struct i2c_client *client,
 
        /* set the device type */
        data->kind = id->driver_data;
+       data->config = &ina2xx_config[data->kind];
 
-       switch (data->kind) {
-       case ina219:
-               /* device configuration */
-               i2c_smbus_write_word_swapped(client, INA2XX_CONFIG,
-                                            INA219_CONFIG_DEFAULT);
-
-               /* set current LSB to 1mA, shunt is in uOhms */
-               /* (equation 13 in datasheet) */
-               i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION,
-                                            40960000 / shunt);
-               dev_info(&client->dev,
-                        "power monitor INA219 (Rshunt = %li uOhm)\n", shunt);
-               data->registers = INA219_REGISTERS;
-               break;
-       case ina226:
-               /* device configuration */
-               i2c_smbus_write_word_swapped(client, INA2XX_CONFIG,
-                                            INA226_CONFIG_DEFAULT);
-
-               /* set current LSB to 1mA, shunt is in uOhms */
-               /* (equation 1 in datasheet)*/
-               i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION,
-                                            5120000 / shunt);
-               dev_info(&client->dev,
-                        "power monitor INA226 (Rshunt = %li uOhm)\n", shunt);
-               data->registers = INA226_REGISTERS;
-               break;
-       default:
-               /* unknown device id */
-               return -ENODEV;
-       }
+       /* device configuration */
+       i2c_smbus_write_word_swapped(client, INA2XX_CONFIG,
+                                    data->config->config_default);
+       /* set current LSB to 1mA, shunt is in uOhms */
+       /* (equation 13 in datasheet) */
+       i2c_smbus_write_word_swapped(client, INA2XX_CALIBRATION,
+                                    data->config->calibration_factor / shunt);
 
        i2c_set_clientdata(client, data);
        mutex_init(&data->update_lock);
@@ -305,6 +263,9 @@ static int ina2xx_probe(struct i2c_client *client,
                goto out_err_hwmon;
        }
 
+       dev_info(&client->dev, "power monitor %s (Rshunt = %li uOhm)\n",
+                id->name, shunt);
+
        return 0;
 
 out_err_hwmon:
@@ -324,7 +285,9 @@ static int ina2xx_remove(struct i2c_client *client)
 
 static const struct i2c_device_id ina2xx_id[] = {
        { "ina219", ina219 },
+       { "ina220", ina219 },
        { "ina226", ina226 },
+       { "ina230", ina226 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, ina2xx_id);
index 5253d23..dee9eec 100644 (file)
@@ -20,6 +20,7 @@
 #include <linux/mutex.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
+#include <linux/io.h>
 
 #include <linux/completion.h>
 #include <linux/mfd/core.h>
@@ -106,42 +107,37 @@ static int __devinit jz4740_hwmon_probe(struct platform_device *pdev)
        int ret;
        struct jz4740_hwmon *hwmon;
 
-       hwmon = kmalloc(sizeof(*hwmon), GFP_KERNEL);
-       if (!hwmon) {
-               dev_err(&pdev->dev, "Failed to allocate driver structure\n");
+       hwmon = devm_kzalloc(&pdev->dev, sizeof(*hwmon), GFP_KERNEL);
+       if (!hwmon)
                return -ENOMEM;
-       }
 
        hwmon->cell = mfd_get_cell(pdev);
 
        hwmon->irq = platform_get_irq(pdev, 0);
        if (hwmon->irq < 0) {
-               ret = hwmon->irq;
-               dev_err(&pdev->dev, "Failed to get platform irq: %d\n", ret);
-               goto err_free;
+               dev_err(&pdev->dev, "Failed to get platform irq: %d\n",
+                       hwmon->irq);
+               return hwmon->irq;
        }
 
        hwmon->mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
        if (!hwmon->mem) {
-               ret = -ENOENT;
                dev_err(&pdev->dev, "Failed to get platform mmio resource\n");
-               goto err_free;
+               return -ENOENT;
        }
 
-       hwmon->mem = request_mem_region(hwmon->mem->start,
+       hwmon->mem = devm_request_mem_region(&pdev->dev, hwmon->mem->start,
                        resource_size(hwmon->mem), pdev->name);
        if (!hwmon->mem) {
-               ret = -EBUSY;
                dev_err(&pdev->dev, "Failed to request mmio memory region\n");
-               goto err_free;
+               return -EBUSY;
        }
 
-       hwmon->base = ioremap_nocache(hwmon->mem->start,
-                       resource_size(hwmon->mem));
+       hwmon->base = devm_ioremap_nocache(&pdev->dev, hwmon->mem->start,
+                                          resource_size(hwmon->mem));
        if (!hwmon->base) {
-               ret = -EBUSY;
                dev_err(&pdev->dev, "Failed to ioremap mmio memory\n");
-               goto err_release_mem_region;
+               return -EBUSY;
        }
 
        init_completion(&hwmon->read_completion);
@@ -149,17 +145,18 @@ static int __devinit jz4740_hwmon_probe(struct platform_device *pdev)
 
        platform_set_drvdata(pdev, hwmon);
 
-       ret = request_irq(hwmon->irq, jz4740_hwmon_irq, 0, pdev->name, hwmon);
+       ret = devm_request_irq(&pdev->dev, hwmon->irq, jz4740_hwmon_irq, 0,
+                              pdev->name, hwmon);
        if (ret) {
                dev_err(&pdev->dev, "Failed to request irq: %d\n", ret);
-               goto err_iounmap;
+               return ret;
        }
        disable_irq(hwmon->irq);
 
        ret = sysfs_create_group(&pdev->dev.kobj, &jz4740_hwmon_attr_group);
        if (ret) {
                dev_err(&pdev->dev, "Failed to create sysfs group: %d\n", ret);
-               goto err_free_irq;
+               return ret;
        }
 
        hwmon->hwmon = hwmon_device_register(&pdev->dev);
@@ -172,16 +169,6 @@ static int __devinit jz4740_hwmon_probe(struct platform_device *pdev)
 
 err_remove_file:
        sysfs_remove_group(&pdev->dev.kobj, &jz4740_hwmon_attr_group);
-err_free_irq:
-       free_irq(hwmon->irq, hwmon);
-err_iounmap:
-       platform_set_drvdata(pdev, NULL);
-       iounmap(hwmon->base);
-err_release_mem_region:
-       release_mem_region(hwmon->mem->start, resource_size(hwmon->mem));
-err_free:
-       kfree(hwmon);
-
        return ret;
 }
 
@@ -192,14 +179,6 @@ static int __devexit jz4740_hwmon_remove(struct platform_device *pdev)
        hwmon_device_unregister(hwmon->hwmon);
        sysfs_remove_group(&pdev->dev.kobj, &jz4740_hwmon_attr_group);
 
-       free_irq(hwmon->irq, hwmon);
-
-       iounmap(hwmon->base);
-       release_mem_region(hwmon->mem->start, resource_size(hwmon->mem));
-
-       platform_set_drvdata(pdev, NULL);
-       kfree(hwmon);
-
        return 0;
 }
 
index 472f795..2d1777a 100644 (file)
@@ -43,6 +43,8 @@
 
 #define LM70_CHIP_LM70         0       /* original NS LM70 */
 #define LM70_CHIP_TMP121       1       /* TI TMP121/TMP123 */
+#define LM70_CHIP_LM71         2       /* NS LM71 */
+#define LM70_CHIP_LM74         3       /* NS LM74 */
 
 struct lm70 {
        struct device *hwmon_dev;
@@ -88,9 +90,13 @@ static ssize_t lm70_sense_temp(struct device *dev,
         * Celsius.
         * So it's equivalent to multiplying by 0.25 * 1000 = 250.
         *
-        * TMP121/TMP123:
+        * LM74 and TMP121/TMP123:
         * 13 bits of 2's complement data, discard LSB 3 bits,
         * resolution 0.0625 degrees celsius.
+        *
+        * LM71:
+        * 14 bits of 2's complement data, discard LSB 2 bits,
+        * resolution 0.0312 degrees celsius.
         */
        switch (p_lm70->chip) {
        case LM70_CHIP_LM70:
@@ -98,8 +104,13 @@ static ssize_t lm70_sense_temp(struct device *dev,
                break;
 
        case LM70_CHIP_TMP121:
+       case LM70_CHIP_LM74:
                val = ((int)raw / 8) * 625 / 10;
                break;
+
+       case LM70_CHIP_LM71:
+               val = ((int)raw / 4) * 3125 / 100;
+               break;
        }
 
        status = sprintf(buf, "%d\n", val); /* millidegrees Celsius */
@@ -113,20 +124,7 @@ static DEVICE_ATTR(temp1_input, S_IRUGO, lm70_sense_temp, NULL);
 static ssize_t lm70_show_name(struct device *dev, struct device_attribute
                              *devattr, char *buf)
 {
-       struct lm70 *p_lm70 = dev_get_drvdata(dev);
-       int ret;
-
-       switch (p_lm70->chip) {
-       case LM70_CHIP_LM70:
-               ret = sprintf(buf, "lm70\n");
-               break;
-       case LM70_CHIP_TMP121:
-               ret = sprintf(buf, "tmp121\n");
-               break;
-       default:
-               ret = -EINVAL;
-       }
-       return ret;
+       return sprintf(buf, "%s\n", to_spi_device(dev)->modalias);
 }
 
 static DEVICE_ATTR(name, S_IRUGO, lm70_show_name, NULL);
@@ -139,17 +137,13 @@ static int __devinit lm70_probe(struct spi_device *spi)
        struct lm70 *p_lm70;
        int status;
 
-       /* signaling is SPI_MODE_0 for both LM70 and TMP121 */
+       /* signaling is SPI_MODE_0 */
        if (spi->mode & (SPI_CPOL | SPI_CPHA))
                return -EINVAL;
 
-       /* 3-wire link (shared SI/SO) for LM70 */
-       if (chip == LM70_CHIP_LM70 && !(spi->mode & SPI_3WIRE))
-               return -EINVAL;
-
        /* NOTE:  we assume 8-bit words, and convert to 16 bits manually */
 
-       p_lm70 = kzalloc(sizeof *p_lm70, GFP_KERNEL);
+       p_lm70 = devm_kzalloc(&spi->dev, sizeof(*p_lm70), GFP_KERNEL);
        if (!p_lm70)
                return -ENOMEM;
 
@@ -181,7 +175,6 @@ out_dev_create_file_failed:
        device_remove_file(&spi->dev, &dev_attr_temp1_input);
 out_dev_create_temp_file_failed:
        spi_set_drvdata(spi, NULL);
-       kfree(p_lm70);
        return status;
 }
 
@@ -193,7 +186,6 @@ static int __devexit lm70_remove(struct spi_device *spi)
        device_remove_file(&spi->dev, &dev_attr_temp1_input);
        device_remove_file(&spi->dev, &dev_attr_name);
        spi_set_drvdata(spi, NULL);
-       kfree(p_lm70);
 
        return 0;
 }
@@ -202,6 +194,8 @@ static int __devexit lm70_remove(struct spi_device *spi)
 static const struct spi_device_id lm70_ids[] = {
        { "lm70",   LM70_CHIP_LM70 },
        { "tmp121", LM70_CHIP_TMP121 },
+       { "lm71",   LM70_CHIP_LM71 },
+       { "lm74",   LM70_CHIP_LM74 },
        { },
 };
 MODULE_DEVICE_TABLE(spi, lm70_ids);
@@ -219,5 +213,5 @@ static struct spi_driver lm70_driver = {
 module_spi_driver(lm70_driver);
 
 MODULE_AUTHOR("Kaiwan N Billimoria");
-MODULE_DESCRIPTION("NS LM70 / TI TMP121/TMP123 Linux driver");
+MODULE_DESCRIPTION("NS LM70 and compatibles Linux driver");
 MODULE_LICENSE("GPL");
index bf94618..c3d4255 100644 (file)
@@ -1830,7 +1830,7 @@ static ssize_t store_fan_smart_tach(struct device *dev,
 
        mutex_lock(&data->update_lock);
        /* sanity test, ignore the write otherwise */
-       if (0 <= val && val <= 2) {
+       if (val <= 2) {
                /* can't enable if pwm freq is 22.5KHz */
                if (val) {
                        u8 ctl4 = lm93_read_byte(client,
index bd8cdb7..4b68fb2 100644 (file)
@@ -391,11 +391,10 @@ static int lm95241_probe(struct i2c_client *new_client,
        struct lm95241_data *data;
        int err;
 
-       data = kzalloc(sizeof(struct lm95241_data), GFP_KERNEL);
-       if (!data) {
-               err = -ENOMEM;
-               goto exit;
-       }
+       data = devm_kzalloc(&new_client->dev, sizeof(struct lm95241_data),
+                           GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        i2c_set_clientdata(new_client, data);
        mutex_init(&data->update_lock);
@@ -406,7 +405,7 @@ static int lm95241_probe(struct i2c_client *new_client,
        /* Register sysfs hooks */
        err = sysfs_create_group(&new_client->dev.kobj, &lm95241_group);
        if (err)
-               goto exit_free;
+               return err;
 
        data->hwmon_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -418,9 +417,6 @@ static int lm95241_probe(struct i2c_client *new_client,
 
 exit_remove_files:
        sysfs_remove_group(&new_client->dev.kobj, &lm95241_group);
-exit_free:
-       kfree(data);
-exit:
        return err;
 }
 
@@ -431,7 +427,6 @@ static int lm95241_remove(struct i2c_client *client)
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &lm95241_group);
 
-       kfree(data);
        return 0;
 }
 
index 9a46c10..2915fd9 100644 (file)
@@ -462,11 +462,10 @@ static int lm95245_probe(struct i2c_client *new_client,
        struct lm95245_data *data;
        int err;
 
-       data = kzalloc(sizeof(struct lm95245_data), GFP_KERNEL);
-       if (!data) {
-               err = -ENOMEM;
-               goto exit;
-       }
+       data = devm_kzalloc(&new_client->dev, sizeof(struct lm95245_data),
+                           GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        i2c_set_clientdata(new_client, data);
        mutex_init(&data->update_lock);
@@ -477,7 +476,7 @@ static int lm95245_probe(struct i2c_client *new_client,
        /* Register sysfs hooks */
        err = sysfs_create_group(&new_client->dev.kobj, &lm95245_group);
        if (err)
-               goto exit_free;
+               return err;
 
        data->hwmon_dev = hwmon_device_register(&new_client->dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -489,9 +488,6 @@ static int lm95245_probe(struct i2c_client *new_client,
 
 exit_remove_files:
        sysfs_remove_group(&new_client->dev.kobj, &lm95245_group);
-exit_free:
-       kfree(data);
-exit:
        return err;
 }
 
@@ -502,7 +498,6 @@ static int lm95245_remove(struct i2c_client *client)
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &lm95245_group);
 
-       kfree(data);
        return 0;
 }
 
index 4d005b2..8496baa 100644 (file)
@@ -181,11 +181,9 @@ static int ltc4151_probe(struct i2c_client *client,
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
                return -ENODEV;
 
-       data = kzalloc(sizeof(*data), GFP_KERNEL);
-       if (!data) {
-               ret = -ENOMEM;
-               goto out_kzalloc;
-       }
+       data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        i2c_set_clientdata(client, data);
        mutex_init(&data->update_lock);
@@ -193,7 +191,7 @@ static int ltc4151_probe(struct i2c_client *client,
        /* Register sysfs hooks */
        ret = sysfs_create_group(&client->dev.kobj, &ltc4151_group);
        if (ret)
-               goto out_sysfs_create_group;
+               return ret;
 
        data->hwmon_dev = hwmon_device_register(&client->dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -205,9 +203,6 @@ static int ltc4151_probe(struct i2c_client *client,
 
 out_hwmon_device_register:
        sysfs_remove_group(&client->dev.kobj, &ltc4151_group);
-out_sysfs_create_group:
-       kfree(data);
-out_kzalloc:
        return ret;
 }
 
@@ -218,8 +213,6 @@ static int ltc4151_remove(struct i2c_client *client)
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &ltc4151_group);
 
-       kfree(data);
-
        return 0;
 }
 
index 429c5b2..98b3d04 100644 (file)
@@ -253,11 +253,9 @@ static int ltc4215_probe(struct i2c_client *client,
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
                return -ENODEV;
 
-       data = kzalloc(sizeof(*data), GFP_KERNEL);
-       if (!data) {
-               ret = -ENOMEM;
-               goto out_kzalloc;
-       }
+       data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        i2c_set_clientdata(client, data);
        mutex_init(&data->update_lock);
@@ -268,7 +266,7 @@ static int ltc4215_probe(struct i2c_client *client,
        /* Register sysfs hooks */
        ret = sysfs_create_group(&client->dev.kobj, &ltc4215_group);
        if (ret)
-               goto out_sysfs_create_group;
+               return ret;
 
        data->hwmon_dev = hwmon_device_register(&client->dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -280,9 +278,6 @@ static int ltc4215_probe(struct i2c_client *client,
 
 out_hwmon_device_register:
        sysfs_remove_group(&client->dev.kobj, &ltc4215_group);
-out_sysfs_create_group:
-       kfree(data);
-out_kzalloc:
        return ret;
 }
 
@@ -293,8 +288,6 @@ static int ltc4215_remove(struct i2c_client *client)
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &ltc4215_group);
 
-       kfree(data);
-
        return 0;
 }
 
index b99b45b..5207591 100644 (file)
@@ -519,11 +519,9 @@ static int ltc4245_probe(struct i2c_client *client,
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
                return -ENODEV;
 
-       data = kzalloc(sizeof(*data), GFP_KERNEL);
-       if (!data) {
-               ret = -ENOMEM;
-               goto out_kzalloc;
-       }
+       data = devm_kzalloc(&client->dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        i2c_set_clientdata(client, data);
        mutex_init(&data->update_lock);
@@ -536,7 +534,7 @@ static int ltc4245_probe(struct i2c_client *client,
        /* Register sysfs hooks */
        ret = ltc4245_sysfs_create_groups(client);
        if (ret)
-               goto out_sysfs_create_groups;
+               return ret;
 
        data->hwmon_dev = hwmon_device_register(&client->dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -548,9 +546,6 @@ static int ltc4245_probe(struct i2c_client *client,
 
 out_hwmon_device_register:
        ltc4245_sysfs_remove_groups(client);
-out_sysfs_create_groups:
-       kfree(data);
-out_kzalloc:
        return ret;
 }
 
@@ -560,7 +555,6 @@ static int ltc4245_remove(struct i2c_client *client)
 
        hwmon_device_unregister(data->hwmon_dev);
        ltc4245_sysfs_remove_groups(client);
-       kfree(data);
 
        return 0;
 }
index f3978a4..b4eb088 100644 (file)
@@ -22,6 +22,8 @@
 #include <linux/spi/spi.h>
 #include <linux/slab.h>
 
+enum chips { max1110, max1111, max1112, max1113 };
+
 #define MAX1111_TX_BUF_SIZE    1
 #define MAX1111_RX_BUF_SIZE    2
 
@@ -30,6 +32,7 @@
 #define MAX1111_CTRL_PD1      (1u << 1)
 #define MAX1111_CTRL_SGL      (1u << 2)
 #define MAX1111_CTRL_UNI      (1u << 3)
+#define MAX1110_CTRL_SEL_SH   (4)
 #define MAX1111_CTRL_SEL_SH   (5)      /* NOTE: bit 4 is ignored */
 #define MAX1111_CTRL_STR      (1u << 7)
 
@@ -42,6 +45,8 @@ struct max1111_data {
        uint8_t rx_buf[MAX1111_RX_BUF_SIZE];
        struct mutex            drvdata_lock;
        /* protect msg, xfer and buffers from multiple access */
+       int                     sel_sh;
+       int                     lsb;
 };
 
 static int max1111_read(struct device *dev, int channel)
@@ -53,7 +58,7 @@ static int max1111_read(struct device *dev, int channel)
        /* writing to drvdata struct is not thread safe, wait on mutex */
        mutex_lock(&data->drvdata_lock);
 
-       data->tx_buf[0] = (channel << MAX1111_CTRL_SEL_SH) |
+       data->tx_buf[0] = (channel << data->sel_sh) |
                MAX1111_CTRL_PD0 | MAX1111_CTRL_PD1 |
                MAX1111_CTRL_SGL | MAX1111_CTRL_UNI | MAX1111_CTRL_STR;
 
@@ -93,12 +98,13 @@ EXPORT_SYMBOL(max1111_read_channel);
 static ssize_t show_name(struct device *dev,
                         struct device_attribute *attr, char *buf)
 {
-       return sprintf(buf, "max1111\n");
+       return sprintf(buf, "%s\n", to_spi_device(dev)->modalias);
 }
 
 static ssize_t show_adc(struct device *dev,
                        struct device_attribute *attr, char *buf)
 {
+       struct max1111_data *data = dev_get_drvdata(dev);
        int channel = to_sensor_dev_attr(attr)->index;
        int ret;
 
@@ -107,10 +113,10 @@ static ssize_t show_adc(struct device *dev,
                return ret;
 
        /*
-        * assume the reference voltage to be 2.048V, with an 8-bit sample,
-        * the LSB weight is 8mV
+        * Assume the reference voltage to be 2.048V or 4.096V, with an 8-bit
+        * sample. The LSB weight is 8mV or 16mV depending on the chip type.
         */
-       return sprintf(buf, "%d\n", ret * 8);
+       return sprintf(buf, "%d\n", ret * data->lsb);
 }
 
 #define MAX1111_ADC_ATTR(_id)          \
@@ -121,6 +127,10 @@ static MAX1111_ADC_ATTR(0);
 static MAX1111_ADC_ATTR(1);
 static MAX1111_ADC_ATTR(2);
 static MAX1111_ADC_ATTR(3);
+static MAX1111_ADC_ATTR(4);
+static MAX1111_ADC_ATTR(5);
+static MAX1111_ADC_ATTR(6);
+static MAX1111_ADC_ATTR(7);
 
 static struct attribute *max1111_attributes[] = {
        &dev_attr_name.attr,
@@ -135,6 +145,18 @@ static const struct attribute_group max1111_attr_group = {
        .attrs  = max1111_attributes,
 };
 
+static struct attribute *max1110_attributes[] = {
+       &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,
+       NULL,
+};
+
+static const struct attribute_group max1110_attr_group = {
+       .attrs  = max1110_attributes,
+};
+
 static int __devinit setup_transfer(struct max1111_data *data)
 {
        struct spi_message *m;
@@ -159,6 +181,7 @@ static int __devinit setup_transfer(struct max1111_data *data)
 
 static int __devinit max1111_probe(struct spi_device *spi)
 {
+       enum chips chip = spi_get_device_id(spi)->driver_data;
        struct max1111_data *data;
        int err;
 
@@ -174,6 +197,24 @@ static int __devinit max1111_probe(struct spi_device *spi)
                return -ENOMEM;
        }
 
+       switch (chip) {
+       case max1110:
+               data->lsb = 8;
+               data->sel_sh = MAX1110_CTRL_SEL_SH;
+               break;
+       case max1111:
+               data->lsb = 8;
+               data->sel_sh = MAX1111_CTRL_SEL_SH;
+               break;
+       case max1112:
+               data->lsb = 16;
+               data->sel_sh = MAX1110_CTRL_SEL_SH;
+               break;
+       case max1113:
+               data->lsb = 16;
+               data->sel_sh = MAX1111_CTRL_SEL_SH;
+               break;
+       }
        err = setup_transfer(data);
        if (err)
                return err;
@@ -188,6 +229,14 @@ static int __devinit max1111_probe(struct spi_device *spi)
                dev_err(&spi->dev, "failed to create attribute group\n");
                return err;
        }
+       if (chip == max1110 || chip == max1112) {
+               err = sysfs_create_group(&spi->dev.kobj, &max1110_attr_group);
+               if (err) {
+                       dev_err(&spi->dev,
+                               "failed to create extended attribute group\n");
+                       goto err_remove;
+               }
+       }
 
        data->hwmon_dev = hwmon_device_register(&spi->dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -202,6 +251,7 @@ static int __devinit max1111_probe(struct spi_device *spi)
        return 0;
 
 err_remove:
+       sysfs_remove_group(&spi->dev.kobj, &max1110_attr_group);
        sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group);
        return err;
 }
@@ -211,16 +261,27 @@ static int __devexit max1111_remove(struct spi_device *spi)
        struct max1111_data *data = spi_get_drvdata(spi);
 
        hwmon_device_unregister(data->hwmon_dev);
+       sysfs_remove_group(&spi->dev.kobj, &max1110_attr_group);
        sysfs_remove_group(&spi->dev.kobj, &max1111_attr_group);
        mutex_destroy(&data->drvdata_lock);
        return 0;
 }
 
+static const struct spi_device_id max1111_ids[] = {
+       { "max1110", max1110 },
+       { "max1111", max1111 },
+       { "max1112", max1112 },
+       { "max1113", max1113 },
+       { },
+};
+MODULE_DEVICE_TABLE(spi, max1111_ids);
+
 static struct spi_driver max1111_driver = {
        .driver         = {
                .name   = "max1111",
                .owner  = THIS_MODULE,
        },
+       .id_table       = max1111_ids,
        .probe          = max1111_probe,
        .remove         = __devexit_p(max1111_remove),
 };
@@ -228,6 +289,5 @@ static struct spi_driver max1111_driver = {
 module_spi_driver(max1111_driver);
 
 MODULE_AUTHOR("Eric Miao <eric.miao@marvell.com>");
-MODULE_DESCRIPTION("MAX1111 ADC Driver");
+MODULE_DESCRIPTION("MAX1110/MAX1111/MAX1112/MAX1113 ADC Driver");
 MODULE_LICENSE("GPL");
-MODULE_ALIAS("spi:max1111");
index 335b183..666d9f6 100644 (file)
@@ -411,7 +411,8 @@ static int max1668_probe(struct i2c_client *client,
        if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
                return -ENODEV;
 
-       data = kzalloc(sizeof(struct max1668_data), GFP_KERNEL);
+       data = devm_kzalloc(&client->dev, sizeof(struct max1668_data),
+                           GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
@@ -422,7 +423,7 @@ static int max1668_probe(struct i2c_client *client,
        /* Register sysfs hooks */
        err = sysfs_create_group(&client->dev.kobj, &max1668_group_common);
        if (err)
-               goto error_free;
+               return err;
 
        if (data->type == max1668 || data->type == max1989) {
                err = sysfs_create_group(&client->dev.kobj,
@@ -444,8 +445,6 @@ error_sysrem1:
                sysfs_remove_group(&client->dev.kobj, &max1668_group_unique);
 error_sysrem0:
        sysfs_remove_group(&client->dev.kobj, &max1668_group_common);
-error_free:
-       kfree(data);
        return err;
 }
 
@@ -459,7 +458,6 @@ static int max1668_remove(struct i2c_client *client)
 
        sysfs_remove_group(&client->dev.kobj, &max1668_group_common);
 
-       kfree(data);
        return 0;
 }
 
diff --git a/drivers/hwmon/max197.c b/drivers/hwmon/max197.c
new file mode 100644 (file)
index 0000000..6304f26
--- /dev/null
@@ -0,0 +1,349 @@
+/*
+ * Maxim MAX197 A/D Converter driver
+ *
+ * Copyright (c) 2012 Savoir-faire Linux Inc.
+ *          Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * For further information, see the Documentation/hwmon/max197 file.
+ */
+
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/mutex.h>
+#include <linux/device.h>
+#include <linux/sysfs.h>
+#include <linux/hwmon.h>
+#include <linux/hwmon-sysfs.h>
+#include <linux/platform_device.h>
+#include <linux/platform_data/max197.h>
+
+#define MAX199_LIMIT   4000            /* 4V */
+#define MAX197_LIMIT   10000           /* 10V */
+
+#define MAX197_NUM_CH  8               /* 8 Analog Input Channels */
+
+/* Control byte format */
+#define MAX197_BIP     (1 << 3)        /* Bipolarity */
+#define MAX197_RNG     (1 << 4)        /* Full range */
+
+#define MAX197_SCALE   12207           /* Scale coefficient for raw data */
+
+/* List of supported chips */
+enum max197_chips { max197, max199 };
+
+/**
+ * struct max197_data - device instance specific data
+ * @pdata:             Platform data.
+ * @hwmon_dev:         The hwmon device.
+ * @lock:              Read/Write mutex.
+ * @limit:             Max range value (10V for MAX197, 4V for MAX199).
+ * @scale:             Need to scale.
+ * @ctrl_bytes:                Channels control byte.
+ */
+struct max197_data {
+       struct max197_platform_data *pdata;
+       struct device *hwmon_dev;
+       struct mutex lock;
+       int limit;
+       bool scale;
+       u8 ctrl_bytes[MAX197_NUM_CH];
+};
+
+static inline void max197_set_unipolarity(struct max197_data *data, int channel)
+{
+       data->ctrl_bytes[channel] &= ~MAX197_BIP;
+}
+
+static inline void max197_set_bipolarity(struct max197_data *data, int channel)
+{
+       data->ctrl_bytes[channel] |= MAX197_BIP;
+}
+
+static inline void max197_set_half_range(struct max197_data *data, int channel)
+{
+       data->ctrl_bytes[channel] &= ~MAX197_RNG;
+}
+
+static inline void max197_set_full_range(struct max197_data *data, int channel)
+{
+       data->ctrl_bytes[channel] |= MAX197_RNG;
+}
+
+static inline bool max197_is_bipolar(struct max197_data *data, int channel)
+{
+       return data->ctrl_bytes[channel] & MAX197_BIP;
+}
+
+static inline bool max197_is_full_range(struct max197_data *data, int channel)
+{
+       return data->ctrl_bytes[channel] & MAX197_RNG;
+}
+
+/* Function called on read access on in{0,1,2,3,4,5,6,7}_{min,max} */
+static ssize_t max197_show_range(struct device *dev,
+                                struct device_attribute *devattr, char *buf)
+{
+       struct max197_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+       int channel = attr->index;
+       bool is_min = attr->nr;
+       int range;
+
+       if (mutex_lock_interruptible(&data->lock))
+               return -ERESTARTSYS;
+
+       range = max197_is_full_range(data, channel) ?
+               data->limit : data->limit / 2;
+       if (is_min) {
+               if (max197_is_bipolar(data, channel))
+                       range = -range;
+               else
+                       range = 0;
+       }
+
+       mutex_unlock(&data->lock);
+
+       return sprintf(buf, "%d\n", range);
+}
+
+/* Function called on write access on in{0,1,2,3,4,5,6,7}_{min,max} */
+static ssize_t max197_store_range(struct device *dev,
+                                 struct device_attribute *devattr,
+                                 const char *buf, size_t count)
+{
+       struct max197_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute_2 *attr = to_sensor_dev_attr_2(devattr);
+       int channel = attr->index;
+       bool is_min = attr->nr;
+       long value;
+       int half = data->limit / 2;
+       int full = data->limit;
+
+       if (kstrtol(buf, 10, &value))
+               return -EINVAL;
+
+       if (is_min) {
+               if (value <= -full)
+                       value = -full;
+               else if (value < 0)
+                       value = -half;
+               else
+                       value = 0;
+       } else {
+               if (value >= full)
+                       value = full;
+               else
+                       value = half;
+       }
+
+       if (mutex_lock_interruptible(&data->lock))
+               return -ERESTARTSYS;
+
+       if (value == 0) {
+               /* We can deduce only the polarity */
+               max197_set_unipolarity(data, channel);
+       } else if (value == -half) {
+               max197_set_bipolarity(data, channel);
+               max197_set_half_range(data, channel);
+       } else if (value == -full) {
+               max197_set_bipolarity(data, channel);
+               max197_set_full_range(data, channel);
+       } else if (value == half) {
+               /* We can deduce only the range */
+               max197_set_half_range(data, channel);
+       } else if (value == full) {
+               /* We can deduce only the range */
+               max197_set_full_range(data, channel);
+       }
+
+       mutex_unlock(&data->lock);
+
+       return count;
+}
+
+/* Function called on read access on in{0,1,2,3,4,5,6,7}_input */
+static ssize_t max197_show_input(struct device *dev,
+                                struct device_attribute *devattr,
+                                char *buf)
+{
+       struct max197_data *data = dev_get_drvdata(dev);
+       struct sensor_device_attribute *attr = to_sensor_dev_attr(devattr);
+       int channel = attr->index;
+       s32 value;
+       int ret;
+
+       if (mutex_lock_interruptible(&data->lock))
+               return -ERESTARTSYS;
+
+       ret = data->pdata->convert(data->ctrl_bytes[channel]);
+       if (ret < 0) {
+               dev_err(dev, "conversion failed\n");
+               goto unlock;
+       }
+       value = ret;
+
+       /*
+        * Coefficient to apply on raw value.
+        * See Table 1. Full Scale and Zero Scale in the MAX197 datasheet.
+        */
+       if (data->scale) {
+               value *= MAX197_SCALE;
+               if (max197_is_full_range(data, channel))
+                       value *= 2;
+               value /= 10000;
+       }
+
+       ret = sprintf(buf, "%d\n", value);
+
+unlock:
+       mutex_unlock(&data->lock);
+       return ret;
+}
+
+static ssize_t max197_show_name(struct device *dev,
+                               struct device_attribute *attr, char *buf)
+{
+       struct platform_device *pdev = to_platform_device(dev);
+       return sprintf(buf, "%s\n", pdev->name);
+}
+
+#define MAX197_SENSOR_DEVICE_ATTR_CH(chan)                             \
+       static SENSOR_DEVICE_ATTR(in##chan##_input, S_IRUGO,            \
+                                 max197_show_input, NULL, chan);       \
+       static SENSOR_DEVICE_ATTR_2(in##chan##_min, S_IRUGO | S_IWUSR,  \
+                                   max197_show_range,                  \
+                                   max197_store_range,                 \
+                                   true, chan);                        \
+       static SENSOR_DEVICE_ATTR_2(in##chan##_max, S_IRUGO | S_IWUSR,  \
+                                   max197_show_range,                  \
+                                   max197_store_range,                 \
+                                   false, chan)
+
+#define MAX197_SENSOR_DEV_ATTR_IN(chan)                                        \
+       &sensor_dev_attr_in##chan##_input.dev_attr.attr,                \
+       &sensor_dev_attr_in##chan##_max.dev_attr.attr,                  \
+       &sensor_dev_attr_in##chan##_min.dev_attr.attr
+
+static DEVICE_ATTR(name, S_IRUGO, max197_show_name, NULL);
+
+MAX197_SENSOR_DEVICE_ATTR_CH(0);
+MAX197_SENSOR_DEVICE_ATTR_CH(1);
+MAX197_SENSOR_DEVICE_ATTR_CH(2);
+MAX197_SENSOR_DEVICE_ATTR_CH(3);
+MAX197_SENSOR_DEVICE_ATTR_CH(4);
+MAX197_SENSOR_DEVICE_ATTR_CH(5);
+MAX197_SENSOR_DEVICE_ATTR_CH(6);
+MAX197_SENSOR_DEVICE_ATTR_CH(7);
+
+static const struct attribute_group max197_sysfs_group = {
+       .attrs = (struct attribute *[]) {
+               &dev_attr_name.attr,
+               MAX197_SENSOR_DEV_ATTR_IN(0),
+               MAX197_SENSOR_DEV_ATTR_IN(1),
+               MAX197_SENSOR_DEV_ATTR_IN(2),
+               MAX197_SENSOR_DEV_ATTR_IN(3),
+               MAX197_SENSOR_DEV_ATTR_IN(4),
+               MAX197_SENSOR_DEV_ATTR_IN(5),
+               MAX197_SENSOR_DEV_ATTR_IN(6),
+               MAX197_SENSOR_DEV_ATTR_IN(7),
+               NULL
+       },
+};
+
+static int __devinit max197_probe(struct platform_device *pdev)
+{
+       int ch, ret;
+       struct max197_data *data;
+       struct max197_platform_data *pdata = pdev->dev.platform_data;
+       enum max197_chips chip = platform_get_device_id(pdev)->driver_data;
+
+       if (pdata == NULL) {
+               dev_err(&pdev->dev, "no platform data supplied\n");
+               return -EINVAL;
+       }
+
+       if (pdata->convert == NULL) {
+               dev_err(&pdev->dev, "no convert function supplied\n");
+               return -EINVAL;
+       }
+
+       data = devm_kzalloc(&pdev->dev, sizeof(struct max197_data), GFP_KERNEL);
+       if (!data) {
+               dev_err(&pdev->dev, "devm_kzalloc failed\n");
+               return -ENOMEM;
+       }
+
+       data->pdata = pdata;
+       mutex_init(&data->lock);
+
+       if (chip == max197) {
+               data->limit = MAX197_LIMIT;
+               data->scale = true;
+       } else {
+               data->limit = MAX199_LIMIT;
+               data->scale = false;
+       }
+
+       for (ch = 0; ch < MAX197_NUM_CH; ch++)
+               data->ctrl_bytes[ch] = (u8) ch;
+
+       platform_set_drvdata(pdev, data);
+
+       ret = sysfs_create_group(&pdev->dev.kobj, &max197_sysfs_group);
+       if (ret) {
+               dev_err(&pdev->dev, "sysfs create group failed\n");
+               return ret;
+       }
+
+       data->hwmon_dev = hwmon_device_register(&pdev->dev);
+       if (IS_ERR(data->hwmon_dev)) {
+               ret = PTR_ERR(data->hwmon_dev);
+               dev_err(&pdev->dev, "hwmon device register failed\n");
+               goto error;
+       }
+
+       return 0;
+
+error:
+       sysfs_remove_group(&pdev->dev.kobj, &max197_sysfs_group);
+       return ret;
+}
+
+static int __devexit max197_remove(struct platform_device *pdev)
+{
+       struct max197_data *data = platform_get_drvdata(pdev);
+
+       hwmon_device_unregister(data->hwmon_dev);
+       sysfs_remove_group(&pdev->dev.kobj, &max197_sysfs_group);
+
+       return 0;
+}
+
+static struct platform_device_id max197_device_ids[] = {
+       { "max197", max197 },
+       { "max199", max199 },
+       { }
+};
+MODULE_DEVICE_TABLE(platform, max197_device_ids);
+
+static struct platform_driver max197_driver = {
+       .driver = {
+               .name = "max197",
+               .owner = THIS_MODULE,
+       },
+       .probe = max197_probe,
+       .remove = __devexit_p(max197_remove),
+       .id_table = max197_device_ids,
+};
+module_platform_driver(max197_driver);
+
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("Savoir-faire Linux Inc. <kernel@savoirfairelinux.com>");
+MODULE_DESCRIPTION("Maxim MAX197 A/D Converter driver");
index d0afc0c..eedb322 100644 (file)
@@ -1,8 +1,9 @@
 /*
- * mcp3021.c - driver for the Microchip MCP3021 chip
+ * mcp3021.c - driver for Microchip MCP3021 and MCP3221
  *
  * Copyright (C) 2008-2009, 2012 Freescale Semiconductor, Inc.
  * Author: Mingkai Hu <Mingkai.hu@freescale.com>
+ * Reworked by Sven Schuchmann <schuchmann@schleissheimer.de>
  *
  * This driver export the value of analog input voltage to sysfs, the
  * voltage unit is mV. Through the sysfs interface, lm-sensors tool
 #define MCP3021_OUTPUT_RES     10      /* 10-bit resolution */
 #define MCP3021_OUTPUT_SCALE   4
 
+#define MCP3221_SAR_SHIFT      0
+#define MCP3221_SAR_MASK       0xfff
+#define MCP3221_OUTPUT_RES     12      /* 12-bit resolution */
+#define MCP3221_OUTPUT_SCALE   1
+
+enum chips {
+       mcp3021,
+       mcp3221
+};
+
 /*
  * Client data (each client gets its own)
  */
 struct mcp3021_data {
        struct device *hwmon_dev;
        u32 vdd;        /* device power supply */
+       u16 sar_shift;
+       u16 sar_mask;
+       u8 output_res;
+       u8 output_scale;
 };
 
 static int mcp3021_read16(struct i2c_client *client)
 {
+       struct mcp3021_data *data = i2c_get_clientdata(client);
        int ret;
        u16 reg;
        __be16 buf;
@@ -61,20 +77,20 @@ static int mcp3021_read16(struct i2c_client *client)
         * The ten-bit output code is composed of the lower 4-bit of the
         * first byte and the upper 6-bit of the second byte.
         */
-       reg = (reg >> MCP3021_SAR_SHIFT) & MCP3021_SAR_MASK;
+       reg = (reg >> data->sar_shift) & data->sar_mask;
 
        return reg;
 }
 
-static inline u16 volts_from_reg(u16 vdd, u16 val)
+static inline u16 volts_from_reg(struct mcp3021_data *data, u16 val)
 {
        if (val == 0)
                return 0;
 
-       val = val * MCP3021_OUTPUT_SCALE - MCP3021_OUTPUT_SCALE / 2;
+       val = val * data->output_scale - data->output_scale / 2;
 
-       return val * DIV_ROUND_CLOSEST(vdd,
-                       (1 << MCP3021_OUTPUT_RES) * MCP3021_OUTPUT_SCALE);
+       return val * DIV_ROUND_CLOSEST(data->vdd,
+                       (1 << data->output_res) * data->output_scale);
 }
 
 static ssize_t show_in_input(struct device *dev, struct device_attribute *attr,
@@ -88,7 +104,8 @@ static ssize_t show_in_input(struct device *dev, struct device_attribute *attr,
        if (reg < 0)
                return reg;
 
-       in_input = volts_from_reg(data->vdd, reg);
+       in_input = volts_from_reg(data, reg);
+
        return sprintf(buf, "%d\n", in_input);
 }
 
@@ -103,25 +120,39 @@ static int mcp3021_probe(struct i2c_client *client,
        if (!i2c_check_functionality(client->adapter, I2C_FUNC_I2C))
                return -ENODEV;
 
-       data = kzalloc(sizeof(struct mcp3021_data), GFP_KERNEL);
+       data = devm_kzalloc(&client->dev, sizeof(struct mcp3021_data),
+                           GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
        i2c_set_clientdata(client, data);
 
+       switch (id->driver_data) {
+       case mcp3021:
+               data->sar_shift = MCP3021_SAR_SHIFT;
+               data->sar_mask = MCP3021_SAR_MASK;
+               data->output_res = MCP3021_OUTPUT_RES;
+               data->output_scale = MCP3021_OUTPUT_SCALE;
+               break;
+
+       case mcp3221:
+               data->sar_shift = MCP3221_SAR_SHIFT;
+               data->sar_mask = MCP3221_SAR_MASK;
+               data->output_res = MCP3221_OUTPUT_RES;
+               data->output_scale = MCP3221_OUTPUT_SCALE;
+               break;
+       }
+
        if (client->dev.platform_data) {
                data->vdd = *(u32 *)client->dev.platform_data;
-               if (data->vdd > MCP3021_VDD_MAX ||
-                               data->vdd < MCP3021_VDD_MIN) {
-                       err = -EINVAL;
-                       goto exit_free;
-               }
+               if (data->vdd > MCP3021_VDD_MAX || data->vdd < MCP3021_VDD_MIN)
+                       return -EINVAL;
        } else
                data->vdd = MCP3021_VDD_REF;
 
        err = sysfs_create_file(&client->dev.kobj, &dev_attr_in0_input.attr);
        if (err)
-               goto exit_free;
+               return err;
 
        data->hwmon_dev = hwmon_device_register(&client->dev);
        if (IS_ERR(data->hwmon_dev)) {
@@ -133,8 +164,6 @@ static int mcp3021_probe(struct i2c_client *client,
 
 exit_remove:
        sysfs_remove_file(&client->dev.kobj, &dev_attr_in0_input.attr);
-exit_free:
-       kfree(data);
        return err;
 }
 
@@ -144,13 +173,13 @@ static int mcp3021_remove(struct i2c_client *client)
 
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_file(&client->dev.kobj, &dev_attr_in0_input.attr);
-       kfree(data);
 
        return 0;
 }
 
 static const struct i2c_device_id mcp3021_id[] = {
-       { "mcp3021", 0 },
+       { "mcp3021", mcp3021 },
+       { "mcp3221", mcp3221 },
        { }
 };
 MODULE_DEVICE_TABLE(i2c, mcp3021_id);
@@ -167,5 +196,5 @@ static struct i2c_driver mcp3021_driver = {
 module_i2c_driver(mcp3021_driver);
 
 MODULE_AUTHOR("Mingkai Hu <Mingkai.hu@freescale.com>");
-MODULE_DESCRIPTION("Microchip MCP3021 driver");
+MODULE_DESCRIPTION("Microchip MCP3021/MCP3221 driver");
 MODULE_LICENSE("GPL");
index 8342275..49f6230 100644 (file)
@@ -461,8 +461,6 @@ static int sch5627_remove(struct platform_device *pdev)
                hwmon_device_unregister(data->hwmon_dev);
 
        sysfs_remove_group(&pdev->dev.kobj, &sch5627_group);
-       platform_set_drvdata(pdev, NULL);
-       kfree(data);
 
        return 0;
 }
@@ -472,7 +470,8 @@ static int __devinit sch5627_probe(struct platform_device *pdev)
        struct sch5627_data *data;
        int err, build_code, build_id, hwmon_rev, val;
 
-       data = kzalloc(sizeof(struct sch5627_data), GFP_KERNEL);
+       data = devm_kzalloc(&pdev->dev, sizeof(struct sch5627_data),
+                           GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
index 96a7e68..5171180 100644 (file)
@@ -402,9 +402,6 @@ static int sch5636_remove(struct platform_device *pdev)
                device_remove_file(&pdev->dev,
                                   &sch5636_fan_attr[i].dev_attr);
 
-       platform_set_drvdata(pdev, NULL);
-       kfree(data);
-
        return 0;
 }
 
@@ -414,7 +411,8 @@ static int __devinit sch5636_probe(struct platform_device *pdev)
        int i, err, val, revision[2];
        char id[4];
 
-       data = kzalloc(sizeof(struct sch5636_data), GFP_KERNEL);
+       data = devm_kzalloc(&pdev->dev, sizeof(struct sch5636_data),
+                           GFP_KERNEL);
        if (!data)
                return -ENOMEM;
 
index 4380f5d..d00b30a 100644 (file)
@@ -503,10 +503,10 @@ EXPORT_SYMBOL(sch56xx_watchdog_unregister);
  * platform dev find, add and remove functions
  */
 
-static int __init sch56xx_find(int sioaddr, unsigned short *address,
-                              const char **name)
+static int __init sch56xx_find(int sioaddr, const char **name)
 {
        u8 devid;
+       unsigned short address;
        int err;
 
        err = superio_enter(sioaddr);
@@ -540,20 +540,21 @@ static int __init sch56xx_find(int sioaddr, unsigned short *address,
         * Warning the order of the low / high byte is the other way around
         * as on most other superio devices!!
         */
-       *address = superio_inb(sioaddr, SIO_REG_ADDR) |
+       address = superio_inb(sioaddr, SIO_REG_ADDR) |
                   superio_inb(sioaddr, SIO_REG_ADDR + 1) << 8;
-       if (*address == 0) {
+       if (address == 0) {
                pr_warn("Base address not set\n");
                err = -ENODEV;
                goto exit;
        }
+       err = address;
 
 exit:
        superio_exit(sioaddr);
        return err;
 }
 
-static int __init sch56xx_device_add(unsigned short address, const char *name)
+static int __init sch56xx_device_add(int address, const char *name)
 {
        struct resource res = {
                .start  = address,
@@ -593,15 +594,14 @@ exit_device_put:
 
 static int __init sch56xx_init(void)
 {
-       int err;
-       unsigned short address;
-       const char *name;
-
-       err = sch56xx_find(0x4e, &address, &name);
-       if (err)
-               err = sch56xx_find(0x2e, &address, &name);
-       if (err)
-               return err;
+       int address;
+       const char *name = NULL;
+
+       address = sch56xx_find(0x4e, &name);
+       if (address < 0)
+               address = sch56xx_find(0x2e, &name);
+       if (address < 0)
+               return address;
 
        return sch56xx_device_add(address, name);
 }
index 8b011d0..07a0c1a 100644 (file)
@@ -1,7 +1,7 @@
 /*
  * sht15.c - support for the SHT15 Temperature and Humidity Sensor
  *
- * Portions Copyright (c) 2010-2011 Savoir-faire Linux Inc.
+ * Portions Copyright (c) 2010-2012 Savoir-faire Linux Inc.
  *          Jerome Oufella <jerome.oufella@savoirfairelinux.com>
  *          Vivien Didelot <vivien.didelot@savoirfairelinux.com>
  *
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/mutex.h>
+#include <linux/platform_data/sht15.h>
 #include <linux/platform_device.h>
 #include <linux/sched.h>
 #include <linux/delay.h>
 #include <linux/jiffies.h>
 #include <linux/err.h>
-#include <linux/sht15.h>
 #include <linux/regulator/consumer.h>
 #include <linux/slab.h>
 #include <linux/atomic.h>
@@ -53,6 +53,9 @@
 #define SHT15_STATUS_HEATER            0x04
 #define SHT15_STATUS_LOW_BATTERY       0x40
 
+/* List of supported chips */
+enum sht15_chips { sht10, sht11, sht15, sht71, sht75 };
+
 /* Actions the driver may be doing */
 enum sht15_state {
        SHT15_READING_NOTHING,
@@ -884,14 +887,12 @@ static int sht15_invalidate_voltage(struct notifier_block *nb,
 static int __devinit sht15_probe(struct platform_device *pdev)
 {
        int ret;
-       struct sht15_data *data = kzalloc(sizeof(*data), GFP_KERNEL);
+       struct sht15_data *data;
        u8 status = 0;
 
-       if (!data) {
-               ret = -ENOMEM;
-               dev_err(&pdev->dev, "kzalloc failed\n");
-               goto error_ret;
-       }
+       data = devm_kzalloc(&pdev->dev, sizeof(*data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        INIT_WORK(&data->read_work, sht15_bh_read_data);
        INIT_WORK(&data->update_supply_work, sht15_update_voltage);
@@ -901,9 +902,8 @@ static int __devinit sht15_probe(struct platform_device *pdev)
        init_waitqueue_head(&data->wait_queue);
 
        if (pdev->dev.platform_data == NULL) {
-               ret = -EINVAL;
                dev_err(&pdev->dev, "no platform data supplied\n");
-               goto err_free_data;
+               return -EINVAL;
        }
        data->pdata = pdev->dev.platform_data;
        data->supply_uV = data->pdata->supply_mv * 1000;
@@ -918,7 +918,7 @@ static int __devinit sht15_probe(struct platform_device *pdev)
         * If a regulator is available,
         * query what the supply voltage actually is!
         */
-       data->reg = regulator_get(data->dev, "vcc");
+       data->reg = devm_regulator_get(data->dev, "vcc");
        if (!IS_ERR(data->reg)) {
                int voltage;
 
@@ -937,51 +937,51 @@ static int __devinit sht15_probe(struct platform_device *pdev)
                        dev_err(&pdev->dev,
                                "regulator notifier request failed\n");
                        regulator_disable(data->reg);
-                       regulator_put(data->reg);
-                       goto err_free_data;
+                       return ret;
                }
        }
 
        /* Try requesting the GPIOs */
-       ret = gpio_request(data->pdata->gpio_sck, "SHT15 sck");
+       ret = devm_gpio_request(&pdev->dev, data->pdata->gpio_sck, "SHT15 sck");
        if (ret) {
                dev_err(&pdev->dev, "gpio request failed\n");
                goto err_release_reg;
        }
        gpio_direction_output(data->pdata->gpio_sck, 0);
 
-       ret = gpio_request(data->pdata->gpio_data, "SHT15 data");
+       ret = devm_gpio_request(&pdev->dev, data->pdata->gpio_data,
+                               "SHT15 data");
        if (ret) {
                dev_err(&pdev->dev, "gpio request failed\n");
-               goto err_release_gpio_sck;
+               goto err_release_reg;
        }
 
-       ret = request_irq(gpio_to_irq(data->pdata->gpio_data),
-                         sht15_interrupt_fired,
-                         IRQF_TRIGGER_FALLING,
-                         "sht15 data",
-                         data);
+       ret = devm_request_irq(&pdev->dev, gpio_to_irq(data->pdata->gpio_data),
+                              sht15_interrupt_fired,
+                              IRQF_TRIGGER_FALLING,
+                              "sht15 data",
+                              data);
        if (ret) {
                dev_err(&pdev->dev, "failed to get irq for data line\n");
-               goto err_release_gpio_data;
+               goto err_release_reg;
        }
        disable_irq_nosync(gpio_to_irq(data->pdata->gpio_data));
        sht15_connection_reset(data);
        ret = sht15_soft_reset(data);
        if (ret)
-               goto err_release_irq;
+               goto err_release_reg;
 
        /* write status with platform data options */
        if (status) {
                ret = sht15_send_status(data, status);
                if (ret)
-                       goto err_release_irq;
+                       goto err_release_reg;
        }
 
        ret = sysfs_create_group(&pdev->dev.kobj, &sht15_attr_group);
        if (ret) {
                dev_err(&pdev->dev, "sysfs create failed\n");
-               goto err_release_irq;
+               goto err_release_reg;
        }
 
        data->hwmon_dev = hwmon_device_register(data->dev);
@@ -994,21 +994,11 @@ static int __devinit sht15_probe(struct platform_device *pdev)
 
 err_release_sysfs_group:
        sysfs_remove_group(&pdev->dev.kobj, &sht15_attr_group);
-err_release_irq:
-       free_irq(gpio_to_irq(data->pdata->gpio_data), data);
-err_release_gpio_data:
-       gpio_free(data->pdata->gpio_data);
-err_release_gpio_sck:
-       gpio_free(data->pdata->gpio_sck);
 err_release_reg:
        if (!IS_ERR(data->reg)) {
                regulator_unregister_notifier(data->reg, &data->nb);
                regulator_disable(data->reg);
-               regulator_put(data->reg);
        }
-err_free_data:
-       kfree(data);
-error_ret:
        return ret;
 }
 
@@ -1030,89 +1020,33 @@ static int __devexit sht15_remove(struct platform_device *pdev)
        if (!IS_ERR(data->reg)) {
                regulator_unregister_notifier(data->reg, &data->nb);
                regulator_disable(data->reg);
-               regulator_put(data->reg);
        }
 
-       free_irq(gpio_to_irq(data->pdata->gpio_data), data);
-       gpio_free(data->pdata->gpio_data);
-       gpio_free(data->pdata->gpio_sck);
        mutex_unlock(&data->read_lock);
-       kfree(data);
 
        return 0;
 }
 
-/*
- * sht_drivers simultaneously refers to __devinit and __devexit function
- * which causes spurious section mismatch warning. So use __refdata to
- * get rid from this.
- */
-static struct platform_driver __refdata sht_drivers[] = {
-       {
-               .driver = {
-                       .name = "sht10",
-                       .owner = THIS_MODULE,
-               },
-               .probe = sht15_probe,
-               .remove = __devexit_p(sht15_remove),
-       }, {
-               .driver = {
-                       .name = "sht11",
-                       .owner = THIS_MODULE,
-               },
-               .probe = sht15_probe,
-               .remove = __devexit_p(sht15_remove),
-       }, {
-               .driver = {
-                       .name = "sht15",
-                       .owner = THIS_MODULE,
-               },
-               .probe = sht15_probe,
-               .remove = __devexit_p(sht15_remove),
-       }, {
-               .driver = {
-                       .name = "sht71",
-                       .owner = THIS_MODULE,
-               },
-               .probe = sht15_probe,
-               .remove = __devexit_p(sht15_remove),
-       }, {
-               .driver = {
-                       .name = "sht75",
-                       .owner = THIS_MODULE,
-               },
-               .probe = sht15_probe,
-               .remove = __devexit_p(sht15_remove),
-       },
+static struct platform_device_id sht15_device_ids[] = {
+       { "sht10", sht10 },
+       { "sht11", sht11 },
+       { "sht15", sht15 },
+       { "sht71", sht71 },
+       { "sht75", sht75 },
+       { }
 };
+MODULE_DEVICE_TABLE(platform, sht15_device_ids);
 
-static int __init sht15_init(void)
-{
-       int ret;
-       int i;
-
-       for (i = 0; i < ARRAY_SIZE(sht_drivers); i++) {
-               ret = platform_driver_register(&sht_drivers[i]);
-               if (ret)
-                       goto error_unreg;
-       }
-
-       return 0;
-
-error_unreg:
-       while (--i >= 0)
-               platform_driver_unregister(&sht_drivers[i]);
-
-       return ret;
-}
-module_init(sht15_init);
-
-static void __exit sht15_exit(void)
-{
-       int i;
-       for (i = ARRAY_SIZE(sht_drivers) - 1; i >= 0; i--)
-               platform_driver_unregister(&sht_drivers[i]);
-}
-module_exit(sht15_exit);
+static struct platform_driver sht15_driver = {
+       .driver = {
+               .name = "sht15",
+               .owner = THIS_MODULE,
+       },
+       .probe = sht15_probe,
+       .remove = __devexit_p(sht15_remove),
+       .id_table = sht15_device_ids,
+};
+module_platform_driver(sht15_driver);
 
 MODULE_LICENSE("GPL");
+MODULE_DESCRIPTION("Sensirion SHT15 temperature and humidity sensor driver");
index 6c2dede..c2565d0 100644 (file)
@@ -199,11 +199,10 @@ static int __devinit sht21_probe(struct i2c_client *client,
                return -ENODEV;
        }
 
-       sht21 = kzalloc(sizeof(*sht21), GFP_KERNEL);
-       if (!sht21) {
-               dev_dbg(&client->dev, "kzalloc failed\n");
+       sht21 = devm_kzalloc(&client->dev, sizeof(*sht21), GFP_KERNEL);
+       if (!sht21)
                return -ENOMEM;
-       }
+
        i2c_set_clientdata(client, sht21);
 
        mutex_init(&sht21->lock);
@@ -211,7 +210,7 @@ static int __devinit sht21_probe(struct i2c_client *client,
        err = sysfs_create_group(&client->dev.kobj, &sht21_attr_group);
        if (err) {
                dev_dbg(&client->dev, "could not create sysfs files\n");
-               goto fail_free;
+               return err;
        }
        sht21->hwmon_dev = hwmon_device_register(&client->dev);
        if (IS_ERR(sht21->hwmon_dev)) {
@@ -226,9 +225,6 @@ static int __devinit sht21_probe(struct i2c_client *client,
 
 fail_remove_sysfs:
        sysfs_remove_group(&client->dev.kobj, &sht21_attr_group);
-fail_free:
-       kfree(sht21);
-
        return err;
 }
 
@@ -242,7 +238,6 @@ static int __devexit sht21_remove(struct i2c_client *client)
 
        hwmon_device_unregister(sht21->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &sht21_attr_group);
-       kfree(sht21);
 
        return 0;
 }
index 2e56c6c..4cddee0 100644 (file)
@@ -128,12 +128,10 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev)
        int err;
        u32 eax, edx;
 
-       data = kzalloc(sizeof(struct via_cputemp_data), GFP_KERNEL);
-       if (!data) {
-               err = -ENOMEM;
-               dev_err(&pdev->dev, "Out of memory\n");
-               goto exit;
-       }
+       data = devm_kzalloc(&pdev->dev, sizeof(struct via_cputemp_data),
+                           GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        data->id = pdev->id;
        data->name = "via_cputemp";
@@ -151,8 +149,7 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev)
                data->msr_temp = 0x1423;
                break;
        default:
-               err = -ENODEV;
-               goto exit_free;
+               return -ENODEV;
        }
 
        /* test if we can access the TEMPERATURE MSR */
@@ -160,14 +157,14 @@ static int __devinit via_cputemp_probe(struct platform_device *pdev)
        if (err) {
                dev_err(&pdev->dev,
                        "Unable to access TEMPERATURE MSR, giving up\n");
-               goto exit_free;
+               return err;
        }
 
        platform_set_drvdata(pdev, data);
 
        err = sysfs_create_group(&pdev->dev.kobj, &via_cputemp_group);
        if (err)
-               goto exit_free;
+               return err;
 
        if (data->msr_vid)
                data->vrm = vid_which_vrm();
@@ -192,10 +189,6 @@ exit_remove:
        if (data->vrm)
                device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
        sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group);
-exit_free:
-       platform_set_drvdata(pdev, NULL);
-       kfree(data);
-exit:
        return err;
 }
 
@@ -207,8 +200,6 @@ static int __devexit via_cputemp_remove(struct platform_device *pdev)
        if (data->vrm)
                device_remove_file(&pdev->dev, &dev_attr_cpu0_vid);
        sysfs_remove_group(&pdev->dev.kobj, &via_cputemp_group);
-       platform_set_drvdata(pdev, NULL);
-       kfree(data);
        return 0;
 }
 
index 386a845..84e3dc5 100644 (file)
@@ -789,18 +789,16 @@ static int vt8231_probe(struct platform_device *pdev)
 
        /* Reserve the ISA region */
        res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-       if (!request_region(res->start, VT8231_EXTENT,
-                           vt8231_driver.driver.name)) {
+       if (!devm_request_region(&pdev->dev, res->start, VT8231_EXTENT,
+                                vt8231_driver.driver.name)) {
                dev_err(&pdev->dev, "Region 0x%lx-0x%lx already in use!\n",
                        (unsigned long)res->start, (unsigned long)res->end);
                return -ENODEV;
        }
 
-       data = kzalloc(sizeof(struct vt8231_data), GFP_KERNEL);
-       if (!data) {
-               err = -ENOMEM;
-               goto exit_release;
-       }
+       data = devm_kzalloc(&pdev->dev, sizeof(struct vt8231_data), GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        platform_set_drvdata(pdev, data);
        data->addr = res->start;
@@ -812,7 +810,7 @@ static int vt8231_probe(struct platform_device *pdev)
        /* Register sysfs hooks */
        err = sysfs_create_group(&pdev->dev.kobj, &vt8231_group);
        if (err)
-               goto exit_free;
+               return err;
 
        /* Must update device information to find out the config field */
        data->uch_config = vt8231_read_value(data, VT8231_REG_UCH_CONFIG);
@@ -850,13 +848,6 @@ exit_remove_files:
                sysfs_remove_group(&pdev->dev.kobj, &vt8231_group_temps[i]);
 
        sysfs_remove_group(&pdev->dev.kobj, &vt8231_group);
-
-exit_free:
-       platform_set_drvdata(pdev, NULL);
-       kfree(data);
-
-exit_release:
-       release_region(res->start, VT8231_EXTENT);
        return err;
 }
 
@@ -875,9 +866,6 @@ static int __devexit vt8231_remove(struct platform_device *pdev)
 
        sysfs_remove_group(&pdev->dev.kobj, &vt8231_group);
 
-       release_region(data->addr, VT8231_EXTENT);
-       platform_set_drvdata(pdev, NULL);
-       kfree(data);
        return 0;
 }
 
index 9ade4d4..93ea81a 100644 (file)
@@ -259,8 +259,7 @@ static u8 fan_to_reg(long rpm, int div)
                                        ((val) + 500) / 1000)
 
 /* for thermal cruise temp tolerance, 4-bits, LSB = 1 degree Celsius */
-#define TOL_TEMP_TO_REG(val)           ((val) < 0 ? 0 : \
-                                       (val) >= 15000 ? 15 : \
+#define TOL_TEMP_TO_REG(val)           ((val) >= 15000 ? 15 : \
                                        ((val) + 500) / 1000)
 
 #define BEEP_MASK_TO_REG(val)          ((val) & 0xffffff)
@@ -848,10 +847,10 @@ static ssize_t store_temp_target(struct device *dev,
        struct i2c_client *client = to_i2c_client(dev);
        struct w83791d_data *data = i2c_get_clientdata(client);
        int nr = sensor_attr->index;
-       unsigned long val;
+       long val;
        u8 target_mask;
 
-       if (kstrtoul(buf, 10, &val))
+       if (kstrtol(buf, 10, &val))
                return -EINVAL;
 
        mutex_lock(&data->update_lock);
index 0ba5a2b..06d6f56 100644 (file)
@@ -296,7 +296,6 @@ struct w83792d_data {
        u8 pwmenable[3];
        u32 alarms;             /* realtime status register encoding,combined */
        u8 chassis;             /* Chassis status */
-       u8 chassis_clear;       /* CLR_CHS, clear chassis intrusion detection */
        u8 thermal_cruise[3];   /* Smart FanI: Fan1,2,3 target value */
        u8 tolerance[3];        /* Fan1,2,3 tolerance(Smart Fan I/II) */
        u8 sf2_points[3][4];    /* Smart FanII: Fan1,2,3 temperature points */
@@ -739,7 +738,7 @@ store_pwm_mode(struct device *dev, struct device_attribute *attr,
 }
 
 static ssize_t
-show_chassis(struct device *dev, struct device_attribute *attr,
+show_chassis_clear(struct device *dev, struct device_attribute *attr,
                        char *buf)
 {
        struct w83792d_data *data = w83792d_update_device(dev);
@@ -747,52 +746,6 @@ show_chassis(struct device *dev, struct device_attribute *attr,
 }
 
 static ssize_t
-show_regs_chassis(struct device *dev, struct device_attribute *attr,
-                       char *buf)
-{
-       dev_warn(dev,
-                "Attribute %s is deprecated, use intrusion0_alarm instead\n",
-                "chassis");
-       return show_chassis(dev, attr, buf);
-}
-
-static ssize_t
-show_chassis_clear(struct device *dev, struct device_attribute *attr, char *buf)
-{
-       struct w83792d_data *data = w83792d_update_device(dev);
-       return sprintf(buf, "%d\n", data->chassis_clear);
-}
-
-static ssize_t
-store_chassis_clear_legacy(struct device *dev, struct device_attribute *attr,
-                       const char *buf, size_t count)
-{
-       struct i2c_client *client = to_i2c_client(dev);
-       struct w83792d_data *data = i2c_get_clientdata(client);
-       unsigned long val;
-       int err;
-       u8 temp1 = 0, temp2 = 0;
-
-       dev_warn(dev,
-                "Attribute %s is deprecated, use intrusion0_alarm instead\n",
-                "chassis_clear");
-
-       err = kstrtoul(buf, 10, &val);
-       if (err)
-               return err;
-
-       mutex_lock(&data->update_lock);
-       data->chassis_clear = SENSORS_LIMIT(val, 0, 1);
-       temp1 = ((data->chassis_clear) << 7) & 0x80;
-       temp2 = w83792d_read_value(client,
-               W83792D_REG_CHASSIS_CLR) & 0x7f;
-       w83792d_write_value(client, W83792D_REG_CHASSIS_CLR, temp1 | temp2);
-       mutex_unlock(&data->update_lock);
-
-       return count;
-}
-
-static ssize_t
 store_chassis_clear(struct device *dev, struct device_attribute *attr,
                        const char *buf, size_t count)
 {
@@ -1116,11 +1069,8 @@ static SENSOR_DEVICE_ATTR(in8_alarm, S_IRUGO, show_alarm, NULL, 20);
 static SENSOR_DEVICE_ATTR(fan4_alarm, S_IRUGO, show_alarm, NULL, 21);
 static SENSOR_DEVICE_ATTR(fan5_alarm, S_IRUGO, show_alarm, NULL, 22);
 static SENSOR_DEVICE_ATTR(fan6_alarm, S_IRUGO, show_alarm, NULL, 23);
-static DEVICE_ATTR(chassis, S_IRUGO, show_regs_chassis, NULL);
-static DEVICE_ATTR(chassis_clear, S_IRUGO | S_IWUSR,
-                       show_chassis_clear, store_chassis_clear_legacy);
 static DEVICE_ATTR(intrusion0_alarm, S_IRUGO | S_IWUSR,
-                       show_chassis, store_chassis_clear);
+                       show_chassis_clear, store_chassis_clear);
 static SENSOR_DEVICE_ATTR(pwm1, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 0);
 static SENSOR_DEVICE_ATTR(pwm2, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 1);
 static SENSOR_DEVICE_ATTR(pwm3, S_IWUSR | S_IRUGO, show_pwm, store_pwm, 2);
@@ -1320,8 +1270,6 @@ static struct attribute *w83792d_attributes[] = {
        &sensor_dev_attr_pwm3_mode.dev_attr.attr,
        &sensor_dev_attr_pwm3_enable.dev_attr.attr,
        &dev_attr_alarms.attr,
-       &dev_attr_chassis.attr,
-       &dev_attr_chassis_clear.attr,
        &dev_attr_intrusion0_alarm.attr,
        &sensor_dev_attr_tolerance1.dev_attr.attr,
        &sensor_dev_attr_thermal_cruise1.dev_attr.attr,
@@ -1627,8 +1575,6 @@ static struct w83792d_data *w83792d_update_device(struct device *dev)
                /* Update CaseOpen status and it's CLR_CHS. */
                data->chassis = (w83792d_read_value(client,
                        W83792D_REG_CHASSIS) >> 5) & 0x01;
-               data->chassis_clear = (w83792d_read_value(client,
-                       W83792D_REG_CHASSIS_CLR) >> 7) & 0x01;
 
                /* Update Thermal Cruise/Smart Fan I target value */
                for (i = 0; i < 3; i++) {
index d6b0bdd..4fc47e0 100644 (file)
@@ -442,27 +442,6 @@ store_beep_enable(struct device *dev, struct device_attribute *attr,
        return count;
 }
 
-/* Write any value to clear chassis alarm */
-static ssize_t
-store_chassis_clear_legacy(struct device *dev,
-                          struct device_attribute *attr, const char *buf,
-                          size_t count)
-{
-       struct i2c_client *client = to_i2c_client(dev);
-       struct w83793_data *data = i2c_get_clientdata(client);
-       u8 val;
-
-       dev_warn(dev, "Attribute chassis is deprecated, "
-                "use intrusion0_alarm instead\n");
-
-       mutex_lock(&data->update_lock);
-       val = w83793_read_value(client, W83793_REG_CLR_CHASSIS);
-       val |= 0x80;
-       w83793_write_value(client, W83793_REG_CLR_CHASSIS, val);
-       mutex_unlock(&data->update_lock);
-       return count;
-}
-
 /* Write 0 to clear chassis alarm */
 static ssize_t
 store_chassis_clear(struct device *dev,
@@ -1189,8 +1168,6 @@ static struct sensor_device_attribute_2 w83793_vid[] = {
 static DEVICE_ATTR(vrm, S_IWUSR | S_IRUGO, show_vrm, store_vrm);
 
 static struct sensor_device_attribute_2 sda_single_files[] = {
-       SENSOR_ATTR_2(chassis, S_IWUSR | S_IRUGO, show_alarm_beep,
-                     store_chassis_clear_legacy, ALARM_STATUS, 30),
        SENSOR_ATTR_2(intrusion0_alarm, S_IWUSR | S_IRUGO, show_alarm_beep,
                      store_chassis_clear, ALARM_STATUS, 30),
        SENSOR_ATTR_2(beep_enable, S_IWUSR | S_IRUGO, show_beep_enable,
index 5850b77..c99c8a0 100644 (file)
@@ -668,11 +668,10 @@ w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id)
        int i, err = 0;
        u8 reg_tmp;
 
-       data = kzalloc(sizeof(struct w83l786ng_data), GFP_KERNEL);
-       if (!data) {
-               err = -ENOMEM;
-               goto exit;
-       }
+       data = devm_kzalloc(&client->dev, sizeof(struct w83l786ng_data),
+                           GFP_KERNEL);
+       if (!data)
+               return -ENOMEM;
 
        i2c_set_clientdata(client, data);
        mutex_init(&data->update_lock);
@@ -708,8 +707,6 @@ w83l786ng_probe(struct i2c_client *client, const struct i2c_device_id *id)
 
 exit_remove:
        sysfs_remove_group(&client->dev.kobj, &w83l786ng_group);
-       kfree(data);
-exit:
        return err;
 }
 
@@ -721,8 +718,6 @@ w83l786ng_remove(struct i2c_client *client)
        hwmon_device_unregister(data->hwmon_dev);
        sysfs_remove_group(&client->dev.kobj, &w83l786ng_group);
 
-       kfree(data);
-
        return 0;
 }
 
diff --git a/include/linux/platform_data/max197.h b/include/linux/platform_data/max197.h
new file mode 100644 (file)
index 0000000..e2a41dd
--- /dev/null
@@ -0,0 +1,21 @@
+/*
+ * Maxim MAX197 A/D Converter Driver
+ *
+ * Copyright (c) 2012 Savoir-faire Linux Inc.
+ *          Vivien Didelot <vivien.didelot@savoirfairelinux.com>
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 as
+ * published by the Free Software Foundation.
+ *
+ * For further information, see the Documentation/hwmon/max197 file.
+ */
+
+/**
+ * struct max197_platform_data - MAX197 connectivity info
+ * @convert:   Function used to start a conversion with control byte ctrl.
+ *             It must return the raw data, or a negative error code.
+ */
+struct max197_platform_data {
+       int (*convert)(u8 ctrl);
+};
similarity index 99%
rename from include/linux/sht15.h
rename to include/linux/platform_data/sht15.h
index f85c7c5..33e0fd2 100644 (file)
@@ -31,4 +31,3 @@ struct sht15_platform_data {
        bool no_otp_reload;
        bool low_resolution;
 };
-