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

* 'hwmon-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jdelvare/staging:
  hwmon: (lm85) Don't bind to Winbond/Nuvoton WPCD377I
  hwmon: (pcf8591) Documentation clean-ups
  hwmon: Clearly mark ACPI drivers as such
  hwmon: Use resource_size
  hwmon: Include <linux/io.h> instead of <asm/io.h>
  hwmon: (tmp421) Add documentation
  hwmon: Add driver for Texas Instruments TMP421/422/423 sensor chips
  hwmon-vid: Ignore 6th VID pin of AMD family 0Fh processors
  hwmon: (asus_atk0110) Add maintainer information
  hwmon: (abituguru3) Support multiple DMI strings per chip ID
diff --git a/Documentation/hwmon/pcf8591 b/Documentation/hwmon/pcf8591
index 5628fcf..e76a789 100644
--- a/Documentation/hwmon/pcf8591
+++ b/Documentation/hwmon/pcf8591
@@ -2,11 +2,11 @@
 =====================
 
 Supported chips:
-  * Philips PCF8591
+  * Philips/NXP PCF8591
     Prefix: 'pcf8591'
     Addresses scanned: I2C 0x48 - 0x4f
-    Datasheet: Publicly available at the Philips Semiconductor website
-               http://www.semiconductors.philips.com/pip/PCF8591P.html
+    Datasheet: Publicly available at the NXP website
+               http://www.nxp.com/pip/PCF8591_6.html
 
 Authors:
         Aurelien Jarno <aurelien@aurel32.net>
@@ -16,9 +16,10 @@
 
 Description
 -----------
+
 The PCF8591 is an 8-bit A/D and D/A converter (4 analog inputs and one
-analog output) for the I2C bus produced by Philips Semiconductors. It
-is designed to provide a byte I2C interface to up to 4 separate devices.
+analog output) for the I2C bus produced by Philips Semiconductors (now NXP).
+It is designed to provide a byte I2C interface to up to 4 separate devices.
 
 The PCF8591 has 4 analog inputs programmable as single-ended or
 differential inputs :
@@ -58,8 +59,8 @@
 -------------------------------------
 
 ! Be careful !
-The PCF8591 is plainly impossible to detect ! Stupid chip.
-So every chip with address in the interval [48..4f] is
+The PCF8591 is plainly impossible to detect! Stupid chip.
+So every chip with address in the interval [0x48..0x4f] is
 detected as PCF8591. If you have other chips in this address
 range, the workaround is to load this module after the one
 for your others chips.
@@ -67,19 +68,20 @@
 On detection (i.e. insmod, modprobe et al.), directories are being
 created for each detected PCF8591:
 
-/sys/bus/devices/<0>-<1>/
+/sys/bus/i2c/devices/<0>-<1>/
 where <0> is the bus the chip was detected on (e. g. i2c-0)
 and <1> the chip address ([48..4f])
 
 Inside these directories, there are such files:
-in0, in1, in2, in3, out0_enable, out0_output, name
+in0_input, in1_input, in2_input, in3_input, out0_enable, out0_output, name
 
 Name contains chip name.
 
-The in0, in1, in2 and in3 files are RO. Reading gives the value of the
-corresponding channel. Depending on the current analog inputs configuration,
-files in2 and/or in3 do not exist. Values range are from 0 to 255 for single
-ended inputs and -128 to +127 for differential inputs (8-bit ADC).
+The in0_input, in1_input, in2_input and in3_input files are RO. Reading gives
+the value of the corresponding channel. Depending on the current analog inputs
+configuration, files in2_input and in3_input may not exist. Values range
+from 0 to 255 for single ended inputs and -128 to +127 for differential inputs
+(8-bit ADC).
 
 The out0_enable file is RW. Reading gives "1" for analog output enabled and
 "0" for analog output disabled. Writing accepts "0" and "1" accordingly.
diff --git a/Documentation/hwmon/tmp421 b/Documentation/hwmon/tmp421
new file mode 100644
index 0000000..0cf07f8
--- /dev/null
+++ b/Documentation/hwmon/tmp421
@@ -0,0 +1,36 @@
+Kernel driver tmp421
+====================
+
+Supported chips:
+  * Texas Instruments TMP421
+    Prefix: 'tmp421'
+    Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
+    Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
+  * Texas Instruments TMP422
+    Prefix: 'tmp422'
+    Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
+    Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
+  * Texas Instruments TMP423
+    Prefix: 'tmp423'
+    Addresses scanned: I2C 0x2a, 0x4c, 0x4d, 0x4e and 0x4f
+    Datasheet: http://focus.ti.com/docs/prod/folders/print/tmp421.html
+
+Authors:
+	Andre Prendel <andre.prendel@gmx.de>
+
+Description
+-----------
+
+This driver implements support for Texas Instruments TMP421, TMP422
+and TMP423 temperature sensor chips. These chips implement one local
+and up to one (TMP421), up to two (TMP422) or up to three (TMP423)
+remote sensors. Temperature is measured in degrees Celsius. The chips
+are wired over I2C/SMBus and specified over a temperature range of -40
+to +125 degrees Celsius. Resolution for both the local and remote
+channels is 0.0625 degree C.
+
+The chips support only temperature measurement. The driver exports
+the temperature values via the following sysfs files:
+
+temp[1-4]_input
+temp[2-4]_fault
diff --git a/MAINTAINERS b/MAINTAINERS
index 9117b65..c5f312b 100644
--- a/MAINTAINERS
+++ b/MAINTAINERS
@@ -931,6 +931,12 @@
 S:	Maintained
 F:	drivers/net/wireless/ath/ar9170/
 
+ATK0110 HWMON DRIVER
+M:	Luca Tettamanti <kronos.it@gmail.com>
+L:	lm-sensors@lm-sensors.org
+S:	Maintained
+F:	drivers/hwmon/asus_atk0110.c
+
 ATI_REMOTE2 DRIVER
 M:	Ville Syrjala <syrjala@sci.fi>
 S:	Maintained
diff --git a/drivers/hwmon/Kconfig b/drivers/hwmon/Kconfig
index 2e25b7a..461abb1 100644
--- a/drivers/hwmon/Kconfig
+++ b/drivers/hwmon/Kconfig
@@ -28,6 +28,17 @@
 	tristate
 	default n
 
+config HWMON_DEBUG_CHIP
+	bool "Hardware Monitoring Chip debugging messages"
+	default n
+	help
+	  Say Y here if you want the I2C chip drivers to produce a bunch of
+	  debug messages to the system log.  Select this if you are having
+	  a problem with I2C support and want to see more of what is going
+	  on.
+
+comment "Native drivers"
+
 config SENSORS_ABITUGURU
 	tristate "Abit uGuru (rev 1 & 2)"
 	depends on X86 && EXPERIMENTAL
@@ -248,18 +259,6 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called asb100.
 
-config SENSORS_ATK0110
-	tristate "ASUS ATK0110 ACPI hwmon"
-	depends on X86 && ACPI && EXPERIMENTAL
-	help
-	  If you say yes here you get support for the ACPI hardware
-	  monitoring interface found in many ASUS motherboards. This
-	  driver will provide readings of fans, voltages and temperatures
-	  through the system firmware.
-
-	  This driver can also be built as a module. If so, the module
-	  will be called asus_atk0110.
-
 config SENSORS_ATXP1
 	tristate "Attansic ATXP1 VID controller"
 	depends on I2C && EXPERIMENTAL
@@ -814,6 +813,16 @@
 	  This driver can also be built as a module.  If so, the module
 	  will be called tmp401.
 
+config SENSORS_TMP421
+	tristate "Texas Instruments TMP421 and compatible"
+	depends on I2C && EXPERIMENTAL
+	help
+	  If you say yes here you get support for Texas Instruments TMP421,
+	  TMP422 and TMP423 temperature sensor chips.
+
+	  This driver can also be built as a module.  If so, the module
+	  will be called tmp421.
+
 config SENSORS_VIA686A
 	tristate "VIA686A"
 	depends on PCI
@@ -964,34 +973,6 @@
 	  Say Y here if you have an applicable laptop and want to experience
 	  the awesome power of hdaps.
 
-config SENSORS_LIS3LV02D
-	tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer"
-	depends on ACPI && INPUT
-	select INPUT_POLLDEV
-	select NEW_LEDS
-	select LEDS_CLASS
-	default n
-	help
-	  This driver provides support for the LIS3LV02Dx accelerometer. In
-	  particular, it can be found in a number of HP laptops, which have the
-	  "Mobile Data Protection System 3D" or "3D DriveGuard" feature. On such
-	  systems the driver should load automatically (via ACPI). The
-	  accelerometer might also be found in other systems, connected via SPI
-	  or I2C.  The accelerometer data is readable via
-	  /sys/devices/platform/lis3lv02d.
-
-	  This driver also provides an absolute input class device, allowing
-	  the laptop to act as a pinball machine-esque joystick. On HP laptops,
-	  if the led infrastructure is activated, support for a led indicating
-	  disk protection will be provided as hp:red:hddprotection.
-
-	  This driver can also be built as modules.  If so, the core module
-	  will be called lis3lv02d and a specific module for HP laptops will be
-	  called hp_accel.
-
-	  Say Y here if you have an applicable laptop and want to experience
-	  the awesome power of lis3lv02d.
-
 config SENSORS_LIS3_SPI
 	tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer (SPI)"
 	depends on !ACPI && SPI_MASTER && INPUT
@@ -1034,13 +1015,50 @@
 	  Say Y here if you have an applicable laptop and want to experience
 	  the awesome power of applesmc.
 
-config HWMON_DEBUG_CHIP
-	bool "Hardware Monitoring Chip debugging messages"
+if ACPI
+
+comment "ACPI drivers"
+
+config SENSORS_ATK0110
+	tristate "ASUS ATK0110"
+	depends on X86 && EXPERIMENTAL
+	help
+	  If you say yes here you get support for the ACPI hardware
+	  monitoring interface found in many ASUS motherboards. This
+	  driver will provide readings of fans, voltages and temperatures
+	  through the system firmware.
+
+	  This driver can also be built as a module. If so, the module
+	  will be called asus_atk0110.
+
+config SENSORS_LIS3LV02D
+	tristate "STMicroeletronics LIS3LV02Dx three-axis digital accelerometer"
+	depends on INPUT
+	select INPUT_POLLDEV
+	select NEW_LEDS
+	select LEDS_CLASS
 	default n
 	help
-	  Say Y here if you want the I2C chip drivers to produce a bunch of
-	  debug messages to the system log.  Select this if you are having
-	  a problem with I2C support and want to see more of what is going
-	  on.
+	  This driver provides support for the LIS3LV02Dx accelerometer. In
+	  particular, it can be found in a number of HP laptops, which have the
+	  "Mobile Data Protection System 3D" or "3D DriveGuard" feature. On such
+	  systems the driver should load automatically (via ACPI). The
+	  accelerometer might also be found in other systems, connected via SPI
+	  or I2C.  The accelerometer data is readable via
+	  /sys/devices/platform/lis3lv02d.
+
+	  This driver also provides an absolute input class device, allowing
+	  the laptop to act as a pinball machine-esque joystick. On HP laptops,
+	  if the led infrastructure is activated, support for a led indicating
+	  disk protection will be provided as hp:red:hddprotection.
+
+	  This driver can also be built as modules.  If so, the core module
+	  will be called lis3lv02d and a specific module for HP laptops will be
+	  called hp_accel.
+
+	  Say Y here if you have an applicable laptop and want to experience
+	  the awesome power of lis3lv02d.
+
+endif # ACPI
 
 endif # HWMON
diff --git a/drivers/hwmon/Makefile b/drivers/hwmon/Makefile
index 7f239a2..2e54788 100644
--- a/drivers/hwmon/Makefile
+++ b/drivers/hwmon/Makefile
@@ -5,6 +5,10 @@
 obj-$(CONFIG_HWMON)		+= hwmon.o
 obj-$(CONFIG_HWMON_VID)		+= hwmon-vid.o
 
+# APCI drivers
+obj-$(CONFIG_SENSORS_ATK0110)	+= asus_atk0110.o
+
+# Native drivers
 # asb100, then w83781d go first, as they can override other drivers' addresses.
 obj-$(CONFIG_SENSORS_ASB100)	+= asb100.o
 obj-$(CONFIG_SENSORS_W83627HF)	+= w83627hf.o
@@ -29,10 +33,8 @@
 obj-$(CONFIG_SENSORS_ADT7470)	+= adt7470.o
 obj-$(CONFIG_SENSORS_ADT7473)	+= adt7473.o
 obj-$(CONFIG_SENSORS_ADT7475)	+= adt7475.o
-
 obj-$(CONFIG_SENSORS_APPLESMC)	+= applesmc.o
 obj-$(CONFIG_SENSORS_AMS)	+= ams/
-obj-$(CONFIG_SENSORS_ATK0110)	+= asus_atk0110.o
 obj-$(CONFIG_SENSORS_ATXP1)	+= atxp1.o
 obj-$(CONFIG_SENSORS_CORETEMP)	+= coretemp.o
 obj-$(CONFIG_SENSORS_DME1737)	+= dme1737.o
@@ -84,6 +86,7 @@
 obj-$(CONFIG_SENSORS_SMSC47M192)+= smsc47m192.o
 obj-$(CONFIG_SENSORS_THMC50)	+= thmc50.o
 obj-$(CONFIG_SENSORS_TMP401)	+= tmp401.o
+obj-$(CONFIG_SENSORS_TMP421)	+= tmp421.o
 obj-$(CONFIG_SENSORS_VIA686A)	+= via686a.o
 obj-$(CONFIG_SENSORS_VT1211)	+= vt1211.o
 obj-$(CONFIG_SENSORS_VT8231)	+= vt8231.o
diff --git a/drivers/hwmon/abituguru.c b/drivers/hwmon/abituguru.c
index 4dbdb81..03694cc 100644
--- a/drivers/hwmon/abituguru.c
+++ b/drivers/hwmon/abituguru.c
@@ -32,7 +32,7 @@
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/dmi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* Banks */
 #define ABIT_UGURU_ALARM_BANK			0x20 /* 1x 3 bytes */
diff --git a/drivers/hwmon/abituguru3.c b/drivers/hwmon/abituguru3.c
index 7d3f15d..3cf28af 100644
--- a/drivers/hwmon/abituguru3.c
+++ b/drivers/hwmon/abituguru3.c
@@ -34,7 +34,7 @@
 #include <linux/hwmon.h>
 #include <linux/hwmon-sysfs.h>
 #include <linux/dmi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* uGuru3 bank addresses */
 #define ABIT_UGURU3_SETTINGS_BANK		0x01
@@ -117,9 +117,12 @@
 	int offset;
 };
 
+/* Avoid use of flexible array members */
+#define ABIT_UGURU3_MAX_DMI_NAMES 2
+
 struct abituguru3_motherboard_info {
 	u16 id;
-	const char *dmi_name;
+	const char *dmi_name[ABIT_UGURU3_MAX_DMI_NAMES + 1];
 	/* + 1 -> end of sensors indicated by a sensor with name == NULL */
 	struct abituguru3_sensor_info sensors[ABIT_UGURU3_MAX_NO_SENSORS + 1];
 };
@@ -164,7 +167,7 @@
 
 /* Constants */
 static const struct abituguru3_motherboard_info abituguru3_motherboards[] = {
-	{ 0x000C, NULL /* Unknown, need DMI string */, {
+	{ 0x000C, { NULL } /* Unknown, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 10, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -186,7 +189,7 @@
 		{ "AUX1 Fan",		35, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x000D, NULL /* Abit AW8, need DMI string */, {
+	{ 0x000D, { NULL } /* Abit AW8, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 10, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -215,7 +218,7 @@
 		{ "AUX5 Fan",		39, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x000E, NULL /* AL-8, need DMI string */, {
+	{ 0x000E, { NULL } /* AL-8, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 10, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -236,7 +239,8 @@
 		{ "SYS Fan",		34, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x000F, NULL /* Unknown, need DMI string */, {
+	{ 0x000F, { NULL } /* Unknown, need DMI string */, {
+
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 10, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -257,7 +261,7 @@
 		{ "SYS Fan",		34, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0010, NULL /* Abit NI8 SLI GR, need DMI string */, {
+	{ 0x0010, { NULL } /* Abit NI8 SLI GR, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 10, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -279,7 +283,7 @@
 		{ "OTES1 Fan",		36, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0011, "AT8 32X", {
+	{ 0x0011, { "AT8 32X", NULL }, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 20, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -306,7 +310,7 @@
 		{ "AUX3 Fan",		37, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0012, NULL /* Abit AN8 32X, need DMI string */, {
+	{ 0x0012, { NULL } /* Abit AN8 32X, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 20, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -328,7 +332,7 @@
 		{ "AUX1 Fan",		36, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0013, NULL /* Abit AW8D, need DMI string */, {
+	{ 0x0013, { NULL } /* Abit AW8D, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 10, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -357,7 +361,7 @@
 		{ "AUX5 Fan",		39, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0014, "AB9", /* + AB9 Pro */ {
+	{ 0x0014, { "AB9", "AB9 Pro", NULL }, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 10, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -378,7 +382,7 @@
 		{ "SYS Fan",		34, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0015, NULL /* Unknown, need DMI string */, {
+	{ 0x0015, { NULL } /* Unknown, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR",		 1, 0, 20, 1, 0 },
 		{ "DDR VTT",		 2, 0, 10, 1, 0 },
@@ -402,7 +406,7 @@
 		{ "AUX3 Fan",		36, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0016, "AW9D-MAX", {
+	{ 0x0016, { "AW9D-MAX", NULL }, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR2",		 1, 0, 20, 1, 0 },
 		{ "DDR2 VTT",		 2, 0, 10, 1, 0 },
@@ -430,7 +434,7 @@
 		{ "OTES1 Fan",		38, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0017, NULL /* Unknown, need DMI string */, {
+	{ 0x0017, { NULL } /* Unknown, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR2",		 1, 0, 20, 1, 0 },
 		{ "DDR2 VTT",		 2, 0, 10, 1, 0 },
@@ -455,7 +459,7 @@
 		{ "AUX3 FAN",		37, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0018, "AB9 QuadGT", {
+	{ 0x0018, { "AB9 QuadGT", NULL }, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR2",		 1, 0, 20, 1, 0 },
 		{ "DDR2 VTT",		 2, 0, 10, 1, 0 },
@@ -482,7 +486,7 @@
 		{ "AUX3 Fan",		36, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0019, "IN9 32X MAX", {
+	{ 0x0019, { "IN9 32X MAX", NULL }, {
 		{ "CPU Core",		 7, 0, 10, 1, 0 },
 		{ "DDR2",		13, 0, 20, 1, 0 },
 		{ "DDR2 VTT",		14, 0, 10, 1, 0 },
@@ -509,7 +513,7 @@
 		{ "AUX3 FAN",		36, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x001A, "IP35 Pro", {
+	{ 0x001A, { "IP35 Pro", "IP35 Pro XE", NULL }, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR2",		 1, 0, 20, 1, 0 },
 		{ "DDR2 VTT",		 2, 0, 10, 1, 0 },
@@ -537,7 +541,7 @@
 		{ "AUX4 Fan",		37, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x001B, NULL /* Unknown, need DMI string */, {
+	{ 0x001B, { NULL } /* Unknown, need DMI string */, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR3",		 1, 0, 20, 1, 0 },
 		{ "DDR3 VTT",		 2, 0, 10, 1, 0 },
@@ -564,7 +568,7 @@
 		{ "AUX3 Fan",		36, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x001C, "IX38 QuadGT", {
+	{ 0x001C, { "IX38 QuadGT", NULL }, {
 		{ "CPU Core",		 0, 0, 10, 1, 0 },
 		{ "DDR2",		 1, 0, 20, 1, 0 },
 		{ "DDR2 VTT",		 2, 0, 10, 1, 0 },
@@ -591,7 +595,7 @@
 		{ "AUX3 Fan",		36, 2, 60, 1, 0 },
 		{ NULL, 0, 0, 0, 0, 0 } }
 	},
-	{ 0x0000, NULL, { { NULL, 0, 0, 0, 0, 0 } } }
+	{ 0x0000, { NULL }, { { NULL, 0, 0, 0, 0, 0 } } }
 };
 
 
@@ -946,15 +950,6 @@
 	printk(KERN_INFO ABIT_UGURU3_NAME ": found Abit uGuru3, motherboard "
 		"ID: %04X\n", (unsigned int)id);
 
-#ifdef CONFIG_DMI
-	if (!abituguru3_motherboards[i].dmi_name) {
-		printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was "
-			"not detected using DMI. Please send the output of "
-			"\"dmidecode\" to the abituguru3 maintainer "
-			"(see MAINTAINERS)\n");
-	}
-#endif
-
 	/* Fill the sysfs attr array */
 	sysfs_attr_i = 0;
 	sysfs_filename = data->sysfs_names;
@@ -1131,6 +1126,7 @@
 {
 	const char *board_vendor, *board_name;
 	int i, err = (force) ? 1 : -ENODEV;
+	const char *const *dmi_name;
 	size_t sublen;
 
 	board_vendor = dmi_get_system_info(DMI_BOARD_VENDOR);
@@ -1151,17 +1147,17 @@
 		sublen--;
 
 	for (i = 0; abituguru3_motherboards[i].id; i++) {
-		const char *dmi_name = abituguru3_motherboards[i].dmi_name;
-		if (!dmi_name || strlen(dmi_name) != sublen)
-			continue;
-		if (!strncasecmp(board_name, dmi_name, sublen))
-			break;
+		dmi_name = abituguru3_motherboards[i].dmi_name;
+		for ( ; *dmi_name; dmi_name++) {
+			if (strlen(*dmi_name) != sublen)
+				continue;
+			if (!strncasecmp(board_name, *dmi_name, sublen))
+				return 0;
+		}
 	}
 
-	if (!abituguru3_motherboards[i].id)
-		return 1;
-
-	return 0;
+	/* No match found */
+	return 1;
 }
 
 #else /* !CONFIG_DMI */
@@ -1221,6 +1217,13 @@
 		err = abituguru3_detect();
 		if (err)
 			return err;
+
+#ifdef CONFIG_DMI
+		printk(KERN_WARNING ABIT_UGURU3_NAME ": this motherboard was "
+			"not detected using DMI. Please send the output of "
+			"\"dmidecode\" to the abituguru3 maintainer "
+			"(see MAINTAINERS)\n");
+#endif
 	}
 
 	err = platform_driver_register(&abituguru3_driver);
diff --git a/drivers/hwmon/applesmc.c b/drivers/hwmon/applesmc.c
index 678e34b..753b348 100644
--- a/drivers/hwmon/applesmc.c
+++ b/drivers/hwmon/applesmc.c
@@ -35,7 +35,7 @@
 #include <linux/dmi.h>
 #include <linux/mutex.h>
 #include <linux/hwmon-sysfs.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include <linux/leds.h>
 #include <linux/hwmon.h>
 #include <linux/workqueue.h>
diff --git a/drivers/hwmon/dme1737.c b/drivers/hwmon/dme1737.c
index 3df202a..9814d51 100644
--- a/drivers/hwmon/dme1737.c
+++ b/drivers/hwmon/dme1737.c
@@ -35,7 +35,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* ISA device, if found */
 static struct platform_device *pdev;
diff --git a/drivers/hwmon/f71805f.c b/drivers/hwmon/f71805f.c
index 89987657..525a00b 100644
--- a/drivers/hwmon/f71805f.c
+++ b/drivers/hwmon/f71805f.c
@@ -40,7 +40,7 @@
 #include <linux/sysfs.h>
 #include <linux/ioport.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static unsigned short force_id;
 module_param(force_id, ushort, 0);
diff --git a/drivers/hwmon/hdaps.c b/drivers/hwmon/hdaps.c
index d3612a1..be2d131 100644
--- a/drivers/hwmon/hdaps.c
+++ b/drivers/hwmon/hdaps.c
@@ -35,8 +35,7 @@
 #include <linux/timer.h>
 #include <linux/dmi.h>
 #include <linux/jiffies.h>
-
-#include <asm/io.h>
+#include <linux/io.h>
 
 #define HDAPS_LOW_PORT		0x1600	/* first port used by hdaps */
 #define HDAPS_NR_PORTS		0x30	/* number of ports: 0x1600 - 0x162f */
diff --git a/drivers/hwmon/hwmon-vid.c b/drivers/hwmon/hwmon-vid.c
index bfc2961..bf0862a 100644
--- a/drivers/hwmon/hwmon-vid.c
+++ b/drivers/hwmon/hwmon-vid.c
@@ -179,8 +179,14 @@
 static struct vrm_model vrm_models[] = {
 	{X86_VENDOR_AMD, 0x6, ANY, ANY, 90},		/* Athlon Duron etc */
 	{X86_VENDOR_AMD, 0xF, 0x3F, ANY, 24},		/* Athlon 64, Opteron */
-	{X86_VENDOR_AMD, 0xF, ANY, ANY, 25},		/* NPT family 0Fh */
+	/* In theory, all NPT family 0Fh processors have 6 VID pins and should
+	   thus use vrm 25, however in practice not all mainboards route the
+	   6th VID pin because it is never needed. So we use the 5 VID pin
+	   variant (vrm 24) for the models which exist today. */
+	{X86_VENDOR_AMD, 0xF, 0x7F, ANY, 24},		/* NPT family 0Fh */
+	{X86_VENDOR_AMD, 0xF, ANY, ANY, 25},		/* future fam. 0Fh */
 	{X86_VENDOR_AMD, 0x10, ANY, ANY, 25},		/* NPT family 10h */
+
 	{X86_VENDOR_INTEL, 0x6, 0x9, ANY, 13},		/* Pentium M (130 nm) */
 	{X86_VENDOR_INTEL, 0x6, 0xB, ANY, 85},		/* Tualatin */
 	{X86_VENDOR_INTEL, 0x6, 0xD, ANY, 13},		/* Pentium M (90 nm) */
@@ -191,12 +197,14 @@
 	{X86_VENDOR_INTEL, 0xF, 0x1, ANY, 90},		/* P4 Willamette */
 	{X86_VENDOR_INTEL, 0xF, 0x2, ANY, 90},		/* P4 Northwood */
 	{X86_VENDOR_INTEL, 0xF, ANY, ANY, 100},		/* Prescott and above assume VRD 10 */
+
 	{X86_VENDOR_CENTAUR, 0x6, 0x7, ANY, 85},	/* Eden ESP/Ezra */
 	{X86_VENDOR_CENTAUR, 0x6, 0x8, 0x7, 85},	/* Ezra T */
 	{X86_VENDOR_CENTAUR, 0x6, 0x9, 0x7, 85},	/* Nemiah */
 	{X86_VENDOR_CENTAUR, 0x6, 0x9, ANY, 17},	/* C3-M, Eden-N */
 	{X86_VENDOR_CENTAUR, 0x6, 0xA, 0x7, 0},		/* No information */
 	{X86_VENDOR_CENTAUR, 0x6, 0xA, ANY, 13},	/* C7, Esther */
+
 	{X86_VENDOR_UNKNOWN, ANY, ANY, ANY, 0}		/* stop here */
 };
 
diff --git a/drivers/hwmon/it87.c b/drivers/hwmon/it87.c
index 9157247..ffeb2a1 100644
--- a/drivers/hwmon/it87.c
+++ b/drivers/hwmon/it87.c
@@ -50,7 +50,7 @@
 #include <linux/string.h>
 #include <linux/dmi.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 #define DRVNAME "it87"
 
diff --git a/drivers/hwmon/lm78.c b/drivers/hwmon/lm78.c
index a1787fd..f7e7016 100644
--- a/drivers/hwmon/lm78.c
+++ b/drivers/hwmon/lm78.c
@@ -31,7 +31,7 @@
 #include <linux/hwmon-sysfs.h>
 #include <linux/err.h>
 #include <linux/mutex.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 /* ISA device, if found */
 static struct platform_device *pdev;
diff --git a/drivers/hwmon/lm85.c b/drivers/hwmon/lm85.c
index b251d86..6c53d98 100644
--- a/drivers/hwmon/lm85.c
+++ b/drivers/hwmon/lm85.c
@@ -75,6 +75,8 @@
 #define	LM85_VERSTEP_GENERIC2		0x70
 #define	LM85_VERSTEP_LM85C		0x60
 #define	LM85_VERSTEP_LM85B		0x62
+#define	LM85_VERSTEP_LM96000_1		0x68
+#define	LM85_VERSTEP_LM96000_2		0x69
 #define	LM85_VERSTEP_ADM1027		0x60
 #define	LM85_VERSTEP_ADT7463		0x62
 #define	LM85_VERSTEP_ADT7463C		0x6A
@@ -1133,6 +1135,26 @@
 		dev_warn(&client->dev, "Device is not ready\n");
 }
 
+static int lm85_is_fake(struct i2c_client *client)
+{
+	/*
+	 * Differenciate between real LM96000 and Winbond WPCD377I. The latter
+	 * emulate the former except that it has no hardware monitoring function
+	 * so the readings are always 0.
+	 */
+	int i;
+	u8 in_temp, fan;
+
+	for (i = 0; i < 8; i++) {
+		in_temp = i2c_smbus_read_byte_data(client, 0x20 + i);
+		fan = i2c_smbus_read_byte_data(client, 0x28 + i);
+		if (in_temp != 0x00 || fan != 0xff)
+			return 0;
+	}
+
+	return 1;
+}
+
 /* Return 0 if detection is successful, -ENODEV otherwise */
 static int lm85_detect(struct i2c_client *client, int kind,
 		       struct i2c_board_info *info)
@@ -1173,6 +1195,16 @@
 			case LM85_VERSTEP_LM85B:
 				kind = lm85b;
 				break;
+			case LM85_VERSTEP_LM96000_1:
+			case LM85_VERSTEP_LM96000_2:
+				/* Check for Winbond WPCD377I */
+				if (lm85_is_fake(client)) {
+					dev_dbg(&adapter->dev,
+						"Found Winbond WPCD377I, "
+						"ignoring\n");
+					return -ENODEV;
+				}
+				break;
 			}
 		} else if (company == LM85_COMPANY_ANALOG_DEV) {
 			switch (verstep) {
diff --git a/drivers/hwmon/pc87360.c b/drivers/hwmon/pc87360.c
index fb052fe..4a64b85 100644
--- a/drivers/hwmon/pc87360.c
+++ b/drivers/hwmon/pc87360.c
@@ -44,7 +44,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static u8 devid;
 static struct platform_device *pdev;
diff --git a/drivers/hwmon/pc87427.c b/drivers/hwmon/pc87427.c
index 3a8a0f7..3170b26 100644
--- a/drivers/hwmon/pc87427.c
+++ b/drivers/hwmon/pc87427.c
@@ -33,7 +33,7 @@
 #include <linux/sysfs.h>
 #include <linux/ioport.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static unsigned short force_id;
 module_param(force_id, ushort, 0);
@@ -435,7 +435,7 @@
 	/* This will need to be revisited when we add support for
 	   temperature and voltage monitoring. */
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) {
+	if (!request_region(res->start, resource_size(res), DRVNAME)) {
 		err = -EBUSY;
 		dev_err(&pdev->dev, "Failed to request region 0x%lx-0x%lx\n",
 			(unsigned long)res->start, (unsigned long)res->end);
@@ -475,7 +475,7 @@
 		sysfs_remove_group(&pdev->dev.kobj, &pc87427_group_fan[i]);
 	}
 exit_release_region:
-	release_region(res->start, res->end - res->start + 1);
+	release_region(res->start, resource_size(res));
 exit_kfree:
 	platform_set_drvdata(pdev, NULL);
 	kfree(data);
@@ -500,7 +500,7 @@
 	kfree(data);
 
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	release_region(res->start, res->end - res->start + 1);
+	release_region(res->start, resource_size(res));
 
 	return 0;
 }
diff --git a/drivers/hwmon/sis5595.c b/drivers/hwmon/sis5595.c
index aa2e831..12f2e70 100644
--- a/drivers/hwmon/sis5595.c
+++ b/drivers/hwmon/sis5595.c
@@ -63,7 +63,7 @@
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 
 /* If force_addr is set to anything different from 0, we forcibly enable
diff --git a/drivers/hwmon/smsc47b397.c b/drivers/hwmon/smsc47b397.c
index 6f6d52b..f46d936 100644
--- a/drivers/hwmon/smsc47b397.c
+++ b/drivers/hwmon/smsc47b397.c
@@ -37,7 +37,7 @@
 #include <linux/init.h>
 #include <linux/mutex.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static unsigned short force_id;
 module_param(force_id, ushort, 0);
diff --git a/drivers/hwmon/smsc47m1.c b/drivers/hwmon/smsc47m1.c
index ba75bfc..8ad50fd 100644
--- a/drivers/hwmon/smsc47m1.c
+++ b/drivers/hwmon/smsc47m1.c
@@ -38,7 +38,7 @@
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static unsigned short force_id;
 module_param(force_id, ushort, 0);
diff --git a/drivers/hwmon/tmp421.c b/drivers/hwmon/tmp421.c
new file mode 100644
index 0000000..2092434
--- /dev/null
+++ b/drivers/hwmon/tmp421.c
@@ -0,0 +1,347 @@
+/* tmp421.c
+ *
+ * Copyright (C) 2009 Andre Prendel <andre.prendel@gmx.de>
+ * Preliminary support by:
+ * Melvin Rook, Raymond Ng
+ *
+ * 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.
+ */
+
+/*
+ * Driver for the Texas Instruments TMP421 SMBus temperature sensor IC.
+ * Supported models: TMP421, TMP422, TMP423
+ */
+
+#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/sysfs.h>
+
+/* Addresses to scan */
+static unsigned short normal_i2c[] = { 0x2a, 0x4c, 0x4d, 0x4e, 0x4f,
+				       I2C_CLIENT_END };
+
+/* Insmod parameters */
+I2C_CLIENT_INSMOD_3(tmp421, tmp422, tmp423);
+
+/* The TMP421 registers */
+#define TMP421_CONFIG_REG_1			0x09
+#define TMP421_CONVERSION_RATE_REG		0x0B
+#define TMP421_MANUFACTURER_ID_REG		0xFE
+#define TMP421_DEVICE_ID_REG			0xFF
+
+static const u8 TMP421_TEMP_MSB[4]		= { 0x00, 0x01, 0x02, 0x03 };
+static const u8 TMP421_TEMP_LSB[4]		= { 0x10, 0x11, 0x12, 0x13 };
+
+/* Flags */
+#define TMP421_CONFIG_SHUTDOWN			0x40
+#define TMP421_CONFIG_RANGE			0x04
+
+/* Manufacturer / Device ID's */
+#define TMP421_MANUFACTURER_ID			0x55
+#define TMP421_DEVICE_ID			0x21
+#define TMP422_DEVICE_ID			0x22
+#define TMP423_DEVICE_ID			0x23
+
+static const struct i2c_device_id tmp421_id[] = {
+	{ "tmp421", tmp421 },
+	{ "tmp422", tmp422 },
+	{ "tmp423", tmp423 },
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, tmp421_id);
+
+struct tmp421_data {
+	struct device *hwmon_dev;
+	struct mutex update_lock;
+	char valid;
+	unsigned long last_updated;
+	int kind;
+	u8 config;
+	s16 temp[4];
+};
+
+static int temp_from_s16(s16 reg)
+{
+	int temp = reg;
+
+	return (temp * 1000 + 128) / 256;
+}
+
+static int temp_from_u16(u16 reg)
+{
+	int temp = reg;
+
+	/* Add offset for extended temperature range. */
+	temp -= 64 * 256;
+
+	return (temp * 1000 + 128) / 256;
+}
+
+static struct tmp421_data *tmp421_update_device(struct device *dev)
+{
+	struct i2c_client *client = to_i2c_client(dev);
+	struct tmp421_data *data = i2c_get_clientdata(client);
+	int i;
+
+	mutex_lock(&data->update_lock);
+
+	if (time_after(jiffies, data->last_updated + 2 * HZ) || !data->valid) {
+		data->config = i2c_smbus_read_byte_data(client,
+			TMP421_CONFIG_REG_1);
+
+		for (i = 0; i <= data->kind; i++) {
+			data->temp[i] = i2c_smbus_read_byte_data(client,
+				TMP421_TEMP_MSB[i]) << 8;
+			data->temp[i] |= i2c_smbus_read_byte_data(client,
+				TMP421_TEMP_LSB[i]);
+		}
+		data->last_updated = jiffies;
+		data->valid = 1;
+	}
+
+	mutex_unlock(&data->update_lock);
+
+	return data;
+}
+
+static ssize_t show_temp_value(struct device *dev,
+			       struct device_attribute *devattr, char *buf)
+{
+	int index = to_sensor_dev_attr(devattr)->index;
+	struct tmp421_data *data = tmp421_update_device(dev);
+	int temp;
+
+	mutex_lock(&data->update_lock);
+	if (data->config & TMP421_CONFIG_RANGE)
+		temp = temp_from_u16(data->temp[index]);
+	else
+		temp = temp_from_s16(data->temp[index]);
+	mutex_unlock(&data->update_lock);
+
+	return sprintf(buf, "%d\n", temp);
+}
+
+static ssize_t show_fault(struct device *dev,
+			  struct device_attribute *devattr, char *buf)
+{
+	int index = to_sensor_dev_attr(devattr)->index;
+	struct tmp421_data *data = tmp421_update_device(dev);
+
+	/*
+	 * The OPEN bit signals a fault. This is bit 0 of the temperature
+	 * register (low byte).
+	 */
+	if (data->temp[index] & 0x01)
+		return sprintf(buf, "1\n");
+	else
+		return sprintf(buf, "0\n");
+}
+
+static mode_t tmp421_is_visible(struct kobject *kobj, struct attribute *a,
+				int n)
+{
+	struct device *dev = container_of(kobj, struct device, kobj);
+	struct tmp421_data *data = dev_get_drvdata(dev);
+	struct device_attribute *devattr;
+	unsigned int index;
+
+	devattr = container_of(a, struct device_attribute, attr);
+	index = to_sensor_dev_attr(devattr)->index;
+
+	if (data->kind > index)
+		return a->mode;
+
+	return 0;
+}
+
+static SENSOR_DEVICE_ATTR(temp1_input, S_IRUGO, show_temp_value, NULL, 0);
+static SENSOR_DEVICE_ATTR(temp2_input, S_IRUGO, show_temp_value, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp2_fault, S_IRUGO, show_fault, NULL, 1);
+static SENSOR_DEVICE_ATTR(temp3_input, S_IRUGO, show_temp_value, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp3_fault, S_IRUGO, show_fault, NULL, 2);
+static SENSOR_DEVICE_ATTR(temp4_input, S_IRUGO, show_temp_value, NULL, 3);
+static SENSOR_DEVICE_ATTR(temp4_fault, S_IRUGO, show_fault, NULL, 3);
+
+static struct attribute *tmp421_attr[] = {
+	&sensor_dev_attr_temp1_input.dev_attr.attr,
+	&sensor_dev_attr_temp2_input.dev_attr.attr,
+	&sensor_dev_attr_temp2_fault.dev_attr.attr,
+	&sensor_dev_attr_temp3_input.dev_attr.attr,
+	&sensor_dev_attr_temp3_fault.dev_attr.attr,
+	&sensor_dev_attr_temp4_input.dev_attr.attr,
+	&sensor_dev_attr_temp4_fault.dev_attr.attr,
+	NULL
+};
+
+static const struct attribute_group tmp421_group = {
+	.attrs = tmp421_attr,
+	.is_visible = tmp421_is_visible,
+};
+
+static int tmp421_init_client(struct i2c_client *client)
+{
+	int config, config_orig;
+
+	/* Set the conversion rate to 2 Hz */
+	i2c_smbus_write_byte_data(client, TMP421_CONVERSION_RATE_REG, 0x05);
+
+	/* Start conversions (disable shutdown if necessary) */
+	config = i2c_smbus_read_byte_data(client, TMP421_CONFIG_REG_1);
+	if (config < 0) {
+		dev_err(&client->dev, "Could not read configuration"
+			 " register (%d)\n", config);
+		return -ENODEV;
+	}
+
+	config_orig = config;
+	config &= ~TMP421_CONFIG_SHUTDOWN;
+
+	if (config != config_orig) {
+		dev_info(&client->dev, "Enable monitoring chip\n");
+		i2c_smbus_write_byte_data(client, TMP421_CONFIG_REG_1, config);
+	}
+
+	return 0;
+}
+
+static int tmp421_detect(struct i2c_client *client, int kind,
+			 struct i2c_board_info *info)
+{
+	struct i2c_adapter *adapter = client->adapter;
+	const char *names[] = { "TMP421", "TMP422", "TMP423" };
+
+	if (!i2c_check_functionality(adapter, I2C_FUNC_SMBUS_BYTE_DATA))
+		return -ENODEV;
+
+	if (kind <= 0) {
+		u8 reg;
+
+		reg = i2c_smbus_read_byte_data(client,
+					       TMP421_MANUFACTURER_ID_REG);
+		if (reg != TMP421_MANUFACTURER_ID)
+			return -ENODEV;
+
+		reg = i2c_smbus_read_byte_data(client,
+					       TMP421_DEVICE_ID_REG);
+		switch (reg) {
+		case TMP421_DEVICE_ID:
+			kind = tmp421;
+			break;
+		case TMP422_DEVICE_ID:
+			kind = tmp422;
+			break;
+		case TMP423_DEVICE_ID:
+			kind = tmp423;
+			break;
+		default:
+			return -ENODEV;
+		}
+	}
+	strlcpy(info->type, tmp421_id[kind - 1].name, I2C_NAME_SIZE);
+	dev_info(&adapter->dev, "Detected TI %s chip at 0x%02x\n",
+		 names[kind - 1], client->addr);
+
+	return 0;
+}
+
+static int tmp421_probe(struct i2c_client *client,
+			const struct i2c_device_id *id)
+{
+	struct tmp421_data *data;
+	int err;
+
+	data = kzalloc(sizeof(struct tmp421_data), GFP_KERNEL);
+	if (!data)
+		return -ENOMEM;
+
+	i2c_set_clientdata(client, data);
+	mutex_init(&data->update_lock);
+	data->kind = id->driver_data;
+
+	err = tmp421_init_client(client);
+	if (err)
+		goto exit_free;
+
+	err = sysfs_create_group(&client->dev.kobj, &tmp421_group);
+	if (err)
+		goto exit_free;
+
+	data->hwmon_dev = hwmon_device_register(&client->dev);
+	if (IS_ERR(data->hwmon_dev)) {
+		err = PTR_ERR(data->hwmon_dev);
+		data->hwmon_dev = NULL;
+		goto exit_remove;
+	}
+	return 0;
+
+exit_remove:
+	sysfs_remove_group(&client->dev.kobj, &tmp421_group);
+
+exit_free:
+	i2c_set_clientdata(client, NULL);
+	kfree(data);
+
+	return err;
+}
+
+static int tmp421_remove(struct i2c_client *client)
+{
+	struct tmp421_data *data = i2c_get_clientdata(client);
+
+	hwmon_device_unregister(data->hwmon_dev);
+	sysfs_remove_group(&client->dev.kobj, &tmp421_group);
+
+	i2c_set_clientdata(client, NULL);
+	kfree(data);
+
+	return 0;
+}
+
+static struct i2c_driver tmp421_driver = {
+	.class = I2C_CLASS_HWMON,
+	.driver = {
+		.name	= "tmp421",
+	},
+	.probe = tmp421_probe,
+	.remove = tmp421_remove,
+	.id_table = tmp421_id,
+	.detect = tmp421_detect,
+	.address_data = &addr_data,
+};
+
+static int __init tmp421_init(void)
+{
+	return i2c_add_driver(&tmp421_driver);
+}
+
+static void __exit tmp421_exit(void)
+{
+	i2c_del_driver(&tmp421_driver);
+}
+
+MODULE_AUTHOR("Andre Prendel <andre.prendel@gmx.de>");
+MODULE_DESCRIPTION("Texas Instruments TMP421/422/423 temperature sensor"
+		   " driver");
+MODULE_LICENSE("GPL");
+
+module_init(tmp421_init);
+module_exit(tmp421_exit);
diff --git a/drivers/hwmon/via686a.c b/drivers/hwmon/via686a.c
index a022aed..39e82a4 100644
--- a/drivers/hwmon/via686a.c
+++ b/drivers/hwmon/via686a.c
@@ -42,7 +42,7 @@
 #include <linux/mutex.h>
 #include <linux/sysfs.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 
 /* If force_addr is set to anything different from 0, we forcibly enable
diff --git a/drivers/hwmon/vt1211.c b/drivers/hwmon/vt1211.c
index 73f77a9..ae33bbb 100644
--- a/drivers/hwmon/vt1211.c
+++ b/drivers/hwmon/vt1211.c
@@ -33,7 +33,7 @@
 #include <linux/mutex.h>
 #include <linux/ioport.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static int uch_config = -1;
 module_param(uch_config, int, 0);
@@ -1136,7 +1136,7 @@
 	}
 
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	if (!request_region(res->start, res->end - res->start + 1, DRVNAME)) {
+	if (!request_region(res->start, resource_size(res), DRVNAME)) {
 		err = -EBUSY;
 		dev_err(dev, "Failed to request region 0x%lx-0x%lx\n",
 			(unsigned long)res->start, (unsigned long)res->end);
@@ -1209,7 +1209,7 @@
 	dev_err(dev, "Sysfs interface creation failed (%d)\n", err);
 EXIT_DEV_REMOVE_SILENT:
 	vt1211_remove_sysfs(pdev);
-	release_region(res->start, res->end - res->start + 1);
+	release_region(res->start, resource_size(res));
 EXIT_KFREE:
 	platform_set_drvdata(pdev, NULL);
 	kfree(data);
@@ -1228,7 +1228,7 @@
 	kfree(data);
 
 	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	release_region(res->start, res->end - res->start + 1);
+	release_region(res->start, resource_size(res));
 
 	return 0;
 }
diff --git a/drivers/hwmon/vt8231.c b/drivers/hwmon/vt8231.c
index 9982b45..470a122 100644
--- a/drivers/hwmon/vt8231.c
+++ b/drivers/hwmon/vt8231.c
@@ -36,7 +36,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 
 static int force_addr;
 module_param(force_addr, int, 0);
diff --git a/drivers/hwmon/w83627ehf.c b/drivers/hwmon/w83627ehf.c
index 0e97469..bb5e787 100644
--- a/drivers/hwmon/w83627ehf.c
+++ b/drivers/hwmon/w83627ehf.c
@@ -51,7 +51,7 @@
 #include <linux/err.h>
 #include <linux/mutex.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include "lm75.h"
 
 enum kinds { w83627ehf, w83627dhg, w83627dhg_p, w83667hg };
diff --git a/drivers/hwmon/w83627hf.c b/drivers/hwmon/w83627hf.c
index 389150b..2be28ac 100644
--- a/drivers/hwmon/w83627hf.c
+++ b/drivers/hwmon/w83627hf.c
@@ -51,7 +51,7 @@
 #include <linux/mutex.h>
 #include <linux/ioport.h>
 #include <linux/acpi.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #include "lm75.h"
 
 static struct platform_device *pdev;
diff --git a/drivers/hwmon/w83781d.c b/drivers/hwmon/w83781d.c
index 0bdab95..d27ed1b 100644
--- a/drivers/hwmon/w83781d.c
+++ b/drivers/hwmon/w83781d.c
@@ -48,7 +48,7 @@
 #ifdef CONFIG_ISA
 #include <linux/platform_device.h>
 #include <linux/ioport.h>
-#include <asm/io.h>
+#include <linux/io.h>
 #endif
 
 #include "lm75.h"