Merge tag 'mfd-3.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6

Pull MFD changes from Samuel Ortiz:
 "MFD bits for the 3.7 merge window.

  As usual we have a few new drivers:

   - TI LP8788
   - TI OMAP USB TLL
   - Maxim MAX8907
   - SMSC ECE1099
   - Dialog Semiconductor DA9055
   - A simpler syscon driver that allow us to get rid of the anatop one.

  Drivers are also gradually getting Device Tree and IRQ domain support.

  The following drivers got DT support:
   - palmas, 88pm860x, tc3589x and twl4030-audio

  And those ones now use the IRQ domain APIs:
   - 88pm860x, tc3589x, db8500_prcmu

  Also some other interesting changes:
   - Intel's ICH LPC now supports Lynx Point
   - TI's twl4030-audio added a GPO child
   - tps6527 enabled its backlight subdevice
   - The twl6030 pwm driver moved to the new PWM subsystem

  And finally a bunch of cleanup and casual fixes for mc13xxx, 88pm860x,
  palmas, ab8500, wm8994, wm5110, max8907 and the tps65xxx family."

Fix up various annoying conflicts: the DT and IRQ domain support came in
twice and was already in 3.6. And then it was apparently rebased.

Guys, DON'T REBASE!

* tag 'mfd-3.7-1' of git://git.kernel.org/pub/scm/linux/kernel/git/sameo/mfd-2.6: (89 commits)
  ARM: dts: Enable 88pm860x pmic
  mfd: 88pm860x: Move gpadc init into touch
  mfd: 88pm860x: Device tree support
  mfd: 88pm860x: Use irqdomain
  mfd: smsc: Add support for smsc gpio io/keypad driver
  backlight: tps65217_bl: Add missing platform_set_drvdata in tps65217_bl_probe
  mfd: DA9055 core driver
  mfd: tps65910: Add alarm interrupt of TPS65910 RTC to mfd device list
  mfd: wm5110: Add register patches for revision B
  mfd: wm5110: Disable control interface error report for WM5110 rev B
  mfd: max8907: Remove regulator-compatible from DT docs
  backlight: Add TPS65217 WLED driver
  mfd: Add backlight as subdevice to the tps65217
  mfd: Provide the PRCMU with its own IRQ domain
  mfd: Fix max8907 sparse warning
  mfd: Add lp8788 mfd driver
  mfd: dbx500: Provide a more accurate smp_twd clock
  mfd: rc5t583: Fix warning messages
  regulator: palmas: Add DT support
  mfd: palmas: Change regulator defns to better suite DT
  ...
diff --git a/Documentation/devicetree/bindings/mfd/88pm860x.txt b/Documentation/devicetree/bindings/mfd/88pm860x.txt
new file mode 100644
index 0000000..63f3ee3
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/88pm860x.txt
@@ -0,0 +1,85 @@
+* Marvell 88PM860x Power Management IC
+
+Required parent device properties:
+- compatible : "marvell,88pm860x"
+- reg : the I2C slave address for the 88pm860x chip
+- interrupts : IRQ line for the 88pm860x chip
+- interrupt-controller: describes the 88pm860x as an interrupt controller (has its own domain)
+- #interrupt-cells : should be 1.
+		- The cell is the 88pm860x local IRQ number
+
+Optional parent device properties:
+- marvell,88pm860x-irq-read-clr: inicates whether interrupt status is cleared by read
+- marvell,88pm860x-slave-addr: 88pm860x are two chips solution. <reg> stores the I2C address
+				of one chip, and this property stores the I2C address of
+				another chip.
+
+88pm860x consists of a large and varied group of sub-devices:
+
+Device			 Supply Names	 Description
+------			 ------------	 -----------
+88pm860x-onkey		:		: On key
+88pm860x-rtc		:		: RTC
+88pm8607		:		: Regulators
+88pm860x-backlight	:		: Backlight
+88pm860x-led		:		: Led
+88pm860x-touch		:		: Touchscreen
+
+Example:
+
+	pmic: 88pm860x@34 {
+		compatible = "marvell,88pm860x";
+		reg = <0x34>;
+		interrupts = <4>;
+		interrupt-parent = <&intc>;
+		interrupt-controller;
+		#interrupt-cells = <1>;
+
+		marvell,88pm860x-irq-read-clr;
+		marvell,88pm860x-slave-addr = <0x11>;
+
+		regulators {
+			BUCK1 {
+				regulator-min-microvolt = <1000000>;
+				regulator-max-microvolt = <1500000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+			LDO1 {
+				regulator-min-microvolt = <1200000>;
+				regulator-max-microvolt = <2800000>;
+				regulator-boot-on;
+				regulator-always-on;
+			};
+		};
+		rtc {
+			marvell,88pm860x-vrtc = <1>;
+		};
+		touch {
+			marvell,88pm860x-gpadc-prebias = <1>;
+			marvell,88pm860x-gpadc-slot-cycle = <1>;
+			marvell,88pm860x-tsi-prebias = <6>;
+			marvell,88pm860x-pen-prebias = <16>;
+			marvell,88pm860x-pen-prechg = <2>;
+			marvell,88pm860x-resistor-X = <300>;
+		};
+		backlights {
+			backlight-0 {
+				marvell,88pm860x-iset = <4>;
+				marvell,88pm860x-pwm = <3>;
+			};
+			backlight-2 {
+			};
+		};
+		leds {
+			led0-red {
+				marvell,88pm860x-iset = <12>;
+			};
+			led0-green {
+				marvell,88pm860x-iset = <12>;
+			};
+			led0-blue {
+				marvell,88pm860x-iset = <12>;
+			};
+		};
+	};
diff --git a/Documentation/devicetree/bindings/mfd/syscon.txt b/Documentation/devicetree/bindings/mfd/syscon.txt
new file mode 100644
index 0000000..fe8150b
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/syscon.txt
@@ -0,0 +1,20 @@
+* System Controller Registers R/W driver
+
+System controller node represents a register region containing a set
+of miscellaneous registers. The registers are not cohesive enough to
+represent as any specific type of device. The typical use-case is for
+some other node's driver, or platform-specific code, to acquire a
+reference to the syscon node (e.g. by phandle, node path, or search
+using a specific compatible value), interrogate the node (or associated
+OS driver) to determine the location of the registers, and access the
+registers directly.
+
+Required properties:
+- compatible: Should contain "syscon".
+- reg: the register region can be accessed from syscon
+
+Examples:
+gpr: iomuxc-gpr@020e0000 {
+	compatible = "fsl,imx6q-iomuxc-gpr", "syscon";
+	reg = <0x020e0000 0x38>;
+};
diff --git a/Documentation/devicetree/bindings/mfd/tps65910.txt b/Documentation/devicetree/bindings/mfd/tps65910.txt
index db03599..2e33048 100644
--- a/Documentation/devicetree/bindings/mfd/tps65910.txt
+++ b/Documentation/devicetree/bindings/mfd/tps65910.txt
@@ -59,6 +59,8 @@
   in TPS6591X datasheet)
 - ti,en-gpio-sleep: enable sleep control for gpios
   There should be 9 entries here, one for each gpio.
+- ti,system-power-controller: Telling whether or not this pmic is controlling
+  the system power.
 
 Regulator Optional properties:
 - ti,regulator-ext-sleep-control: enable external sleep
@@ -79,6 +81,8 @@
 		#interrupt-cells = <2>;
 		interrupt-controller;
 
+		ti,system-power-controller;
+
 		ti,vmbch-threshold = 0;
 		ti,vmbch2-threshold = 0;
 		ti,en-ck32k-xtal;
diff --git a/Documentation/devicetree/bindings/mfd/twl4030-audio.txt b/Documentation/devicetree/bindings/mfd/twl4030-audio.txt
new file mode 100644
index 0000000..414d2ae
--- /dev/null
+++ b/Documentation/devicetree/bindings/mfd/twl4030-audio.txt
@@ -0,0 +1,46 @@
+Texas Instruments TWL family (twl4030) audio module
+
+The audio module inside the TWL family consist of an audio codec and a vibra
+driver.
+
+Required properties:
+- compatible : must be "ti,twl4030-audio"
+
+Optional properties, nodes:
+
+Audio functionality:
+- codec { }: Need to be present if the audio functionality is used. Within this
+	     section the following options can be used:
+- ti,digimic_delay: Delay need after enabling the digimic to reduce artifacts
+		    from the start of the recorded sample (in ms)
+-ti,ramp_delay_value: HS ramp delay configuration to reduce pop noise
+-ti,hs_extmute: Use external mute for HS pop reduction
+-ti,hs_extmute_gpio: Use external GPIO to control the external mute
+-ti,offset_cncl_path: Offset cancellation path selection, refer to TRM for the
+		      valid values.
+
+Vibra functionality
+- ti,enable-vibra: Need to be set to <1> if the vibra functionality is used. if
+		   missing or it is 0, the vibra functionality is disabled.
+
+Example:
+&i2c1 {
+	clock-frequency = <2600000>;
+
+	twl: twl@48 {
+		reg = <0x48>;
+		interrupts = <7>; /* SYS_NIRQ cascaded to intc */
+		interrupt-parent = <&intc>;
+
+		twl_audio: audio {
+			compatible = "ti,twl4030-audio";
+
+			ti,enable-vibra = <1>;
+
+			codec {
+				ti,ramp_delay_value = <3>;
+			};
+
+		};
+	};
+};
diff --git a/Documentation/devicetree/bindings/mfd/twl6040.txt b/Documentation/devicetree/bindings/mfd/twl6040.txt
index c855240..0f5dd70 100644
--- a/Documentation/devicetree/bindings/mfd/twl6040.txt
+++ b/Documentation/devicetree/bindings/mfd/twl6040.txt
@@ -1,7 +1,7 @@
 Texas Instruments TWL6040 family
 
-The TWL6040s are 8-channel high quality low-power audio codecs providing audio
-and vibra functionality on OMAP4+ platforms.
+The TWL6040s are 8-channel high quality low-power audio codecs providing audio,
+vibra and GPO functionality on OMAP4+ platforms.
 They are connected ot the host processor via i2c for commands, McPDM for audio
 data and commands.
 
@@ -10,6 +10,8 @@
 - reg: must be 0x4b for i2c address
 - interrupts: twl6040 has one interrupt line connecteded to the main SoC
 - interrupt-parent: The parent interrupt controller
+- gpio-controller:
+- #gpio-cells = <1>: twl6040 provides GPO lines.
 - twl6040,audpwron-gpio: Power on GPIO line for the twl6040
 
 - vio-supply: Regulator for the twl6040 VIO supply
@@ -37,7 +39,6 @@
 &i2c1 {
 	twl6040: twl@4b {
 		compatible = "ti,twl6040";
-		reg = <0x4b>;
 
 		interrupts = <0 119 4>;
 		interrupt-parent = <&gic>;
@@ -60,3 +61,5 @@
 		};
 	};
 };
+
+/include/ "twl6040.dtsi"
diff --git a/Documentation/devicetree/bindings/regulator/88pm860x.txt b/Documentation/devicetree/bindings/regulator/88pm860x.txt
new file mode 100644
index 0000000..1267b3e
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/88pm860x.txt
@@ -0,0 +1,30 @@
+Marvell 88PM860x regulator
+
+Required properties:
+- compatible: "marvell,88pm860x"
+- reg: I2C slave address
+- regulators: A node that houses a sub-node for each regulator within the
+  device. Each sub-node is identified using the regulator-compatible
+  property, with valid values listed below.
+
+Example:
+
+	pmic: 88pm860x@34 {
+		compatible = "marvell,88pm860x";
+		reg = <0x34>;
+
+		regulators {
+			BUCK1 {
+			        regulator-min-microvolt = <1000000>;
+			        regulator-max-microvolt = <1500000>;
+			        regulator-boot-on;
+			        regulator-always-on;
+			};
+			BUCK3 {
+			        regulator-min-microvolt = <1000000>;
+			        regulator-max-microvolt = <3000000>;
+			        regulator-boot-on;
+			        regulator-always-on;
+			};
+		};
+	};
diff --git a/Documentation/devicetree/bindings/regulator/max8907.txt b/Documentation/devicetree/bindings/regulator/max8907.txt
new file mode 100644
index 0000000..371eccd
--- /dev/null
+++ b/Documentation/devicetree/bindings/regulator/max8907.txt
@@ -0,0 +1,69 @@
+MAX8907 regulator
+
+Required properties:
+- compatible: "maxim,max8907"
+- reg: I2C slave address
+- interrupts: The interrupt output of the controller
+- mbatt-supply: The input supply for MBATT, BBAT, SDBY, VRTC.
+- in-v1-supply: The input supply for SD1.
+- in-v2-supply: The input supply for SD2.
+- in-v3-supply: The input supply for SD3.
+- in1-supply: The input supply for LDO1.
+...
+- in20-supply: The input supply for LDO20.
+- regulators: A node that houses a sub-node for each regulator within the
+  device. Each sub-node is identified using the node's name (or the deprecated
+  regulator-compatible property if present), with valid values listed below.
+  The content of each sub-node is defined by the standard binding for
+  regulators; see regulator.txt.
+
+Optional properties:
+- maxim,system-power-controller: Boolean property indicating that the PMIC
+  controls the overall system power.
+
+The valid names for regulators are:
+
+  sd1, sd2, sd3, ldo1, ldo2, ldo3, ldo4, ldo5, ldo6, ldo7, ldo8, ldo9, ldo10,
+  ldo11, ldo12, ldo13, ldo14, ldo15, ldo16, ldo17, ldo18, ldo19, ldo20, out5v,
+  out33v, bbat, sdby, vrtc.
+
+Example:
+
+		max8907@3c {
+			compatible = "maxim,max8907";
+			reg = <0x3c>;
+			interrupts = <0 86 0x4>;
+
+			maxim,system-power-controller;
+
+			mbatt-supply = <&some_reg>;
+			in-v1-supply = <&mbatt_reg>;
+			...
+			in1-supply = <&mbatt_reg>;
+			...
+
+			regulators {
+				mbatt_reg: mbatt {
+					regulator-name = "vbat_pmu";
+					regulator-min-microvolt = <5000000>;
+					regulator-max-microvolt = <5000000>;
+					regulator-always-on;
+				};
+
+				sd1 {
+					regulator-name = "nvvdd_sv1,vdd_cpu_pmu";
+					regulator-min-microvolt = <1000000>;
+					regulator-max-microvolt = <1000000>;
+					regulator-always-on;
+				};
+
+				sd2 {
+					regulator-name = "nvvdd_sv2,vdd_core";
+					regulator-min-microvolt = <1200000>;
+					regulator-max-microvolt = <1200000>;
+					regulator-always-on;
+				};
+...
+			};
+		};
+	};
diff --git a/Documentation/devicetree/bindings/regulator/tps6586x.txt b/Documentation/devicetree/bindings/regulator/tps6586x.txt
index 07b9ef6..8b40cac 100644
--- a/Documentation/devicetree/bindings/regulator/tps6586x.txt
+++ b/Documentation/devicetree/bindings/regulator/tps6586x.txt
@@ -22,6 +22,10 @@
 - vinldo678-supply: The input supply for the LDO6, LDO7 and LDO8
 - vinldo9-supply: The input supply for the LDO9
 
+Optional properties:
+- ti,system-power-controller: Telling whether or not this pmic is controlling
+  the system power.
+
 Each regulator is defined using the standard binding for regulators.
 
 Note: LDO5 and LDO_RTC is supplied by SYS regulator internally and driver
@@ -37,6 +41,8 @@
 		#gpio-cells = <2>;
 		gpio-controller;
 
+		ti,system-power-controller;
+
 		sys-supply = <&some_reg>;
 		vin-sm0-supply = <&some_reg>;
 		vin-sm1-supply = <&some_reg>;
diff --git a/Documentation/devicetree/bindings/video/backlight/88pm860x.txt b/Documentation/devicetree/bindings/video/backlight/88pm860x.txt
new file mode 100644
index 0000000..261df27
--- /dev/null
+++ b/Documentation/devicetree/bindings/video/backlight/88pm860x.txt
@@ -0,0 +1,15 @@
+88pm860x-backlight bindings
+
+Optional properties:
+  - marvell,88pm860x-iset: Current supplies on backlight device.
+  - marvell,88pm860x-pwm: PWM frequency on backlight device.
+
+Example:
+
+	backlights {
+		backlight-0 {
+			marvell,88pm860x-iset = <4>;
+			marvell,88pm860x-pwm = <3>;
+		};
+		backlight-2 {
+		};
diff --git a/Documentation/smsc_ece1099.txt b/Documentation/smsc_ece1099.txt
new file mode 100644
index 0000000..6b492e8
--- /dev/null
+++ b/Documentation/smsc_ece1099.txt
@@ -0,0 +1,56 @@
+What is smsc-ece1099?
+----------------------
+
+The ECE1099 is a 40-Pin 3.3V Keyboard Scan Expansion
+or GPIO Expansion device. The device supports a keyboard
+scan matrix of 23x8. The device is connected to a Master
+via the SMSC BC-Link interface or via the SMBus.
+Keypad scan Input(KSI) and Keypad Scan Output(KSO) signals
+are multiplexed with GPIOs.
+
+Interrupt generation
+--------------------
+
+Interrupts can be generated by an edge detection on a GPIO
+pin or an edge detection on one of the bus interface pins.
+Interrupts can also be detected on the keyboard scan interface.
+The bus interrupt pin (BC_INT# or SMBUS_INT#) is asserted if
+any bit in one of the Interrupt Status registers is 1 and
+the corresponding Interrupt Mask bit is also 1.
+
+In order for software to determine which device is the source
+of an interrupt, it should first read the Group Interrupt Status Register
+to determine which Status register group is a source for the interrupt.
+Software should read both the Status register and the associated Mask register,
+then AND the two values together. Bits that are 1 in the result of the AND
+are active interrupts. Software clears an interrupt by writing a 1 to the
+corresponding bit in the Status register.
+
+Communication Protocol
+----------------------
+
+- SMbus slave Interface
+	The host processor communicates with the ECE1099 device
+	through a series of read/write registers via the SMBus
+	interface. SMBus is a serial communication protocol between
+	a computer host and its peripheral devices. The SMBus data
+	rate is 10KHz minimum to 400 KHz maximum
+
+- Slave Bus Interface
+	The ECE1099 device SMBus implementation is a subset of the
+	SMBus interface to the host. The device is a slave-only SMBus device.
+	The implementation in the device is a subset of SMBus since it
+	only supports four protocols.
+
+	The Write Byte, Read Byte, Send Byte, and Receive Byte protocols are the
+	only valid SMBus protocols for the device.
+
+- BC-LinkTM Interface
+	The BC-Link is a proprietary bus that allows communication
+	between a Master device and a Companion device. The Master
+	device uses this serial bus to read and write registers
+	located on the Companion device. The bus comprises three signals,
+	BC_CLK, BC_DAT and BC_INT#. The Master device always provides the
+	clock, BC_CLK, and the Companion device is the source for an
+	independent asynchronous interrupt signal, BC_INT#. The ECE1099
+	supports BC-Link speeds up to 24MHz.
diff --git a/arch/arm/boot/dts/imx6q.dtsi b/arch/arm/boot/dts/imx6q.dtsi
index 35e5895..f3990b0 100644
--- a/arch/arm/boot/dts/imx6q.dtsi
+++ b/arch/arm/boot/dts/imx6q.dtsi
@@ -400,8 +400,8 @@
 				#clock-cells = <1>;
 			};
 
-			anatop@020c8000 {
-				compatible = "fsl,imx6q-anatop";
+			anatop: anatop@020c8000 {
+				compatible = "fsl,imx6q-anatop", "syscon", "simple-bus";
 				reg = <0x020c8000 0x1000>;
 				interrupts = <0 49 0x04 0 54 0x04 0 127 0x04>;
 
@@ -531,6 +531,11 @@
 				interrupts = <0 89 0x04 0 90 0x04>;
 			};
 
+			gpr: iomuxc-gpr@020e0000 {
+				compatible = "fsl,imx6q-iomuxc-gpr", "syscon";
+				reg = <0x020e0000 0x38>;
+			};
+
 			iomuxc@020e0000 {
 				compatible = "fsl,imx6q-iomuxc";
 				reg = <0x020e0000 0x4000>;
diff --git a/arch/arm/boot/dts/pxa910-dkb.dts b/arch/arm/boot/dts/pxa910-dkb.dts
index e92be5a..595492a 100644
--- a/arch/arm/boot/dts/pxa910-dkb.dts
+++ b/arch/arm/boot/dts/pxa910-dkb.dts
@@ -29,6 +29,143 @@
 			};
 			twsi1: i2c@d4011000 {
 				status = "okay";
+
+				pmic: 88pm860x@34 {
+					compatible = "marvell,88pm860x";
+					reg = <0x34>;
+					interrupts = <4>;
+					interrupt-parent = <&intc>;
+					interrupt-controller;
+					#interrupt-cells = <1>;
+
+					marvell,88pm860x-irq-read-clr;
+					marvell,88pm860x-slave-addr = <0x11>;
+
+					regulators {
+						BUCK1 {
+							regulator-min-microvolt = <1000000>;
+							regulator-max-microvolt = <1500000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						BUCK2 {
+							regulator-min-microvolt = <1000000>;
+							regulator-max-microvolt = <1500000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						BUCK3 {
+							regulator-min-microvolt = <1000000>;
+							regulator-max-microvolt = <3000000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO1 {
+							regulator-min-microvolt = <1200000>;
+							regulator-max-microvolt = <2800000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO2 {
+							regulator-min-microvolt = <1800000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO3 {
+							regulator-min-microvolt = <1800000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO4 {
+							regulator-min-microvolt = <1800000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-always-on;
+						};
+						LDO5 {
+							regulator-min-microvolt = <2900000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO6 {
+							regulator-min-microvolt = <1800000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO7 {
+							regulator-min-microvolt = <1800000>;
+							regulator-max-microvolt = <2900000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO8 {
+							regulator-min-microvolt = <1800000>;
+							regulator-max-microvolt = <2900000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO9 {
+							regulator-min-microvolt = <1800000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO10 {
+							regulator-min-microvolt = <1200000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-boot-on;
+							regulator-always-on;
+						};
+						LDO12 {
+							regulator-min-microvolt = <1200000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-always-on;
+						};
+						LDO13 {
+							regulator-min-microvolt = <1200000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-always-on;
+						};
+						LDO14 {
+							regulator-min-microvolt = <1800000>;
+							regulator-max-microvolt = <3300000>;
+							regulator-always-on;
+						};
+					};
+					rtc {
+						marvell,88pm860x-vrtc = <1>;
+					};
+					touch {
+						marvell,88pm860x-gpadc-prebias = <1>;
+						marvell,88pm860x-gpadc-slot-cycle = <1>;
+						marvell,88pm860x-tsi-prebias = <6>;
+						marvell,88pm860x-pen-prebias = <16>;
+						marvell,88pm860x-pen-prechg = <2>;
+						marvell,88pm860x-resistor-X = <300>;
+					};
+					backlights {
+						backlight-0 {
+							marvell,88pm860x-iset = <4>;
+							marvell,88pm860x-pwm = <3>;
+						};
+						backlight-2 {
+						};
+					};
+					leds {
+						led0-red {
+							marvell,88pm860x-iset = <12>;
+						};
+						led0-green {
+							marvell,88pm860x-iset = <12>;
+						};
+						led0-blue {
+							marvell,88pm860x-iset = <12>;
+						};
+					};
+				};
 			};
 			rtc: rtc@d4010000 {
 				status = "okay";
diff --git a/arch/arm/boot/dts/pxa910.dtsi b/arch/arm/boot/dts/pxa910.dtsi
index a3be44d8..825aaca 100644
--- a/arch/arm/boot/dts/pxa910.dtsi
+++ b/arch/arm/boot/dts/pxa910.dtsi
@@ -120,6 +120,8 @@
 
 			twsi1: i2c@d4011000 {
 				compatible = "mrvl,mmp-twsi";
+				#address-cells = <1>;
+				#size-cells = <0>;
 				reg = <0xd4011000 0x1000>;
 				interrupts = <7>;
 				mrvl,i2c-fast-mode;
@@ -128,6 +130,8 @@
 
 			twsi2: i2c@d4037000 {
 				compatible = "mrvl,mmp-twsi";
+				#address-cells = <1>;
+				#size-cells = <0>;
 				reg = <0xd4037000 0x1000>;
 				interrupts = <54>;
 				status = "disabled";
diff --git a/arch/arm/mach-imx/Kconfig b/arch/arm/mach-imx/Kconfig
index 3a2042f..32197c1 100644
--- a/arch/arm/mach-imx/Kconfig
+++ b/arch/arm/mach-imx/Kconfig
@@ -758,7 +758,7 @@
 	select HAVE_IMX_MMDC
 	select HAVE_IMX_SRC
 	select HAVE_SMP
-	select MFD_ANATOP
+	select MFD_SYSCON
 	select PINCTRL
 	select PINCTRL_IMX6Q
 
diff --git a/arch/arm/mach-imx/mach-imx6q.c b/arch/arm/mach-imx/mach-imx6q.c
index 36979d3..47c91f7 100644
--- a/arch/arm/mach-imx/mach-imx6q.c
+++ b/arch/arm/mach-imx/mach-imx6q.c
@@ -23,8 +23,9 @@
 #include <linux/of_irq.h>
 #include <linux/of_platform.h>
 #include <linux/phy.h>
+#include <linux/regmap.h>
 #include <linux/micrel_phy.h>
-#include <linux/mfd/anatop.h>
+#include <linux/mfd/syscon.h>
 #include <asm/cpuidle.h>
 #include <asm/smp_twd.h>
 #include <asm/hardware/cache-l2x0.h>
@@ -118,20 +119,7 @@
 
 static void __init imx6q_usb_init(void)
 {
-	struct device_node *np;
-	struct platform_device *pdev = NULL;
-	struct anatop *adata = NULL;
-
-	np = of_find_compatible_node(NULL, NULL, "fsl,imx6q-anatop");
-	if (np)
-		pdev = of_find_device_by_node(np);
-	if (pdev)
-		adata = platform_get_drvdata(pdev);
-	if (!adata) {
-		if (np)
-			of_node_put(np);
-		return;
-	}
+	struct regmap *anatop;
 
 #define HW_ANADIG_USB1_CHRG_DETECT		0x000001b0
 #define HW_ANADIG_USB2_CHRG_DETECT		0x00000210
@@ -139,20 +127,21 @@
 #define BM_ANADIG_USB_CHRG_DETECT_EN_B		0x00100000
 #define BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B	0x00080000
 
-	/*
-	 * The external charger detector needs to be disabled,
-	 * or the signal at DP will be poor
-	 */
-	anatop_write_reg(adata, HW_ANADIG_USB1_CHRG_DETECT,
-			BM_ANADIG_USB_CHRG_DETECT_EN_B
-			| BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B,
-			~0);
-	anatop_write_reg(adata, HW_ANADIG_USB2_CHRG_DETECT,
-			BM_ANADIG_USB_CHRG_DETECT_EN_B |
-			BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B,
-			~0);
-
-	of_node_put(np);
+	anatop = syscon_regmap_lookup_by_compatible("fsl,imx6q-anatop");
+	if (!IS_ERR(anatop)) {
+		/*
+		 * The external charger detector needs to be disabled,
+		 * or the signal at DP will be poor
+		 */
+		regmap_write(anatop, HW_ANADIG_USB1_CHRG_DETECT,
+				BM_ANADIG_USB_CHRG_DETECT_EN_B
+				| BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
+		regmap_write(anatop, HW_ANADIG_USB2_CHRG_DETECT,
+				BM_ANADIG_USB_CHRG_DETECT_EN_B |
+				BM_ANADIG_USB_CHRG_DETECT_CHK_CHRG_B);
+	} else {
+		pr_warn("failed to find fsl,imx6q-anatop regmap\n");
+	}
 }
 
 static void __init imx6q_init_machine(void)
diff --git a/arch/arm/mach-omap2/usb-host.c b/arch/arm/mach-omap2/usb-host.c
index ac95daa..3c43449 100644
--- a/arch/arm/mach-omap2/usb-host.c
+++ b/arch/arm/mach-omap2/usb-host.c
@@ -33,10 +33,12 @@
 #ifdef CONFIG_MFD_OMAP_USB_HOST
 
 #define OMAP_USBHS_DEVICE	"usbhs_omap"
+#define OMAP_USBTLL_DEVICE	"usbhs_tll"
 #define	USBHS_UHH_HWMODNAME	"usb_host_hs"
 #define USBHS_TLL_HWMODNAME	"usb_tll_hs"
 
 static struct usbhs_omap_platform_data		usbhs_data;
+static struct usbtll_omap_platform_data		usbtll_data;
 static struct ehci_hcd_omap_platform_data	ehci_data;
 static struct ohci_hcd_omap_platform_data	ohci_data;
 
@@ -485,13 +487,14 @@
 
 void __init usbhs_init(const struct usbhs_omap_board_data *pdata)
 {
-	struct omap_hwmod	*oh[2];
+	struct omap_hwmod	*uhh_hwm, *tll_hwm;
 	struct platform_device	*pdev;
 	int			bus_id = -1;
 	int			i;
 
 	for (i = 0; i < OMAP3_HS_USB_PORTS; i++) {
 		usbhs_data.port_mode[i] = pdata->port_mode[i];
+		usbtll_data.port_mode[i] = pdata->port_mode[i];
 		ohci_data.port_mode[i] = pdata->port_mode[i];
 		ehci_data.port_mode[i] = pdata->port_mode[i];
 		ehci_data.reset_gpio_port[i] = pdata->reset_gpio_port[i];
@@ -510,25 +513,35 @@
 		setup_4430ohci_io_mux(pdata->port_mode);
 	}
 
-	oh[0] = omap_hwmod_lookup(USBHS_UHH_HWMODNAME);
-	if (!oh[0]) {
+	uhh_hwm = omap_hwmod_lookup(USBHS_UHH_HWMODNAME);
+	if (!uhh_hwm) {
 		pr_err("Could not look up %s\n", USBHS_UHH_HWMODNAME);
 		return;
 	}
 
-	oh[1] = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
-	if (!oh[1]) {
+	tll_hwm = omap_hwmod_lookup(USBHS_TLL_HWMODNAME);
+	if (!tll_hwm) {
 		pr_err("Could not look up %s\n", USBHS_TLL_HWMODNAME);
 		return;
 	}
 
-	pdev = omap_device_build_ss(OMAP_USBHS_DEVICE, bus_id, oh, 2,
-				(void *)&usbhs_data, sizeof(usbhs_data),
+	pdev = omap_device_build(OMAP_USBTLL_DEVICE, bus_id, tll_hwm,
+				&usbtll_data, sizeof(usbtll_data),
 				omap_uhhtll_latency,
 				ARRAY_SIZE(omap_uhhtll_latency), false);
 	if (IS_ERR(pdev)) {
-		pr_err("Could not build hwmod devices %s,%s\n",
-			USBHS_UHH_HWMODNAME, USBHS_TLL_HWMODNAME);
+		pr_err("Could not build hwmod device %s\n",
+		       USBHS_TLL_HWMODNAME);
+		return;
+	}
+
+	pdev = omap_device_build(OMAP_USBHS_DEVICE, bus_id, uhh_hwm,
+				&usbhs_data, sizeof(usbhs_data),
+				omap_uhhtll_latency,
+				ARRAY_SIZE(omap_uhhtll_latency), false);
+	if (IS_ERR(pdev)) {
+		pr_err("Could not build hwmod devices %s\n",
+		       USBHS_UHH_HWMODNAME);
 		return;
 	}
 }
diff --git a/arch/arm/mach-u300/i2c.c b/arch/arm/mach-u300/i2c.c
index 0d4620e..96800aa 100644
--- a/arch/arm/mach-u300/i2c.c
+++ b/arch/arm/mach-u300/i2c.c
@@ -9,7 +9,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/i2c.h>
-#include <linux/mfd/abx500.h>
+#include <linux/mfd/ab3100.h>
 #include <linux/regulator/machine.h>
 #include <linux/amba/bus.h>
 #include <mach/irqs.h>
diff --git a/arch/arm/plat-omap/include/plat/usb.h b/arch/arm/plat-omap/include/plat/usb.h
index bd20588..87ee140 100644
--- a/arch/arm/plat-omap/include/plat/usb.h
+++ b/arch/arm/plat-omap/include/plat/usb.h
@@ -4,6 +4,7 @@
 #define	__ASM_ARCH_OMAP_USB_H
 
 #include <linux/io.h>
+#include <linux/platform_device.h>
 #include <linux/usb/musb.h>
 
 #define OMAP3_HS_USB_PORTS	3
@@ -63,6 +64,10 @@
 	struct ehci_hcd_omap_platform_data	*ehci_data;
 	struct ohci_hcd_omap_platform_data	*ohci_data;
 };
+
+struct usbtll_omap_platform_data {
+	enum usbhs_omap_port_mode		port_mode[OMAP3_HS_USB_PORTS];
+};
 /*-------------------------------------------------------------------------*/
 
 struct omap_musb_board_data {
@@ -81,6 +86,8 @@
 extern void usb_musb_init(struct omap_musb_board_data *board_data);
 
 extern void usbhs_init(const struct usbhs_omap_board_data *pdata);
+extern int omap_tll_enable(void);
+extern int omap_tll_disable(void);
 
 extern int omap4430_phy_power(struct device *dev, int ID, int on);
 extern int omap4430_phy_set_clk(struct device *dev, int on);
diff --git a/drivers/gpio/Kconfig b/drivers/gpio/Kconfig
index 8382dc8..aa73ef3 100644
--- a/drivers/gpio/Kconfig
+++ b/drivers/gpio/Kconfig
@@ -409,6 +409,13 @@
 	  Say yes here to access the GPIO signals of various multi-function
 	  power management chips from Texas Instruments.
 
+config GPIO_TWL6040
+	tristate "TWL6040 GPO"
+	depends on TWL6040_CORE
+	help
+	  Say yes here to access the GPO signals of twl6040
+	  audio chip from Texas Instruments.
+
 config GPIO_WM831X
 	tristate "WM831x GPIOs"
 	depends on MFD_WM831X
diff --git a/drivers/gpio/Makefile b/drivers/gpio/Makefile
index 0ffaa84..b2c109d 100644
--- a/drivers/gpio/Makefile
+++ b/drivers/gpio/Makefile
@@ -68,6 +68,7 @@
 obj-$(CONFIG_GPIO_TPS65910)	+= gpio-tps65910.o
 obj-$(CONFIG_GPIO_TPS65912)	+= gpio-tps65912.o
 obj-$(CONFIG_GPIO_TWL4030)	+= gpio-twl4030.o
+obj-$(CONFIG_GPIO_TWL6040)	+= gpio-twl6040.o
 obj-$(CONFIG_GPIO_UCB1400)	+= gpio-ucb1400.o
 obj-$(CONFIG_GPIO_VR41XX)	+= gpio-vr41xx.o
 obj-$(CONFIG_GPIO_VT8500)	+= gpio-vt8500.o
diff --git a/drivers/gpio/gpio-ich.c b/drivers/gpio/gpio-ich.c
index b7c0651..d4d6179 100644
--- a/drivers/gpio/gpio-ich.c
+++ b/drivers/gpio/gpio-ich.c
@@ -49,6 +49,10 @@
 	{0x0c, 0x38, 0x48},	/* LVL[1-3] offsets */
 };
 
+static const u8 ichx_reglen[3] = {
+	0x30, 0x10, 0x10,
+};
+
 #define ICHX_WRITE(val, reg, base_res)	outl(val, (reg) + (base_res)->start)
 #define ICHX_READ(reg, base_res)	inl((reg) + (base_res)->start)
 
@@ -75,6 +79,7 @@
 	struct resource *pm_base;	/* Power Mangagment IO base */
 	struct ichx_desc *desc;	/* Pointer to chipset-specific description */
 	u32 orig_gpio_ctrl;	/* Orig CTRL value, used to restore on exit */
+	u8 use_gpio;		/* Which GPIO groups are usable */
 } ichx_priv;
 
 static int modparam_gpiobase = -1;	/* dynamic */
@@ -123,8 +128,16 @@
 	return data & (1 << bit) ? 1 : 0;
 }
 
+static int ichx_gpio_check_available(struct gpio_chip *gpio, unsigned nr)
+{
+	return (ichx_priv.use_gpio & (1 << (nr / 32))) ? 0 : -ENXIO;
+}
+
 static int ichx_gpio_direction_input(struct gpio_chip *gpio, unsigned nr)
 {
+	if (!ichx_gpio_check_available(gpio, nr))
+		return -ENXIO;
+
 	/*
 	 * Try setting pin as an input and verify it worked since many pins
 	 * are output-only.
@@ -138,6 +151,9 @@
 static int ichx_gpio_direction_output(struct gpio_chip *gpio, unsigned nr,
 					int val)
 {
+	if (!ichx_gpio_check_available(gpio, nr))
+		return -ENXIO;
+
 	/* Set GPIO output value. */
 	ichx_write_bit(GPIO_LVL, nr, val, 0);
 
@@ -153,6 +169,9 @@
 
 static int ichx_gpio_get(struct gpio_chip *chip, unsigned nr)
 {
+	if (!ichx_gpio_check_available(chip, nr))
+		return -ENXIO;
+
 	return ichx_read_bit(GPIO_LVL, nr);
 }
 
@@ -161,6 +180,9 @@
 	unsigned long flags;
 	u32 data;
 
+	if (!ichx_gpio_check_available(chip, nr))
+		return -ENXIO;
+
 	/*
 	 * GPI 0 - 15 need to be read from the power management registers on
 	 * a ICH6/3100 bridge.
@@ -291,6 +313,46 @@
 	.ngpio = 76,
 };
 
+static int __devinit ichx_gpio_request_regions(struct resource *res_base,
+						const char *name, u8 use_gpio)
+{
+	int i;
+
+	if (!res_base || !res_base->start || !res_base->end)
+		return -ENODEV;
+
+	for (i = 0; i < ARRAY_SIZE(ichx_regs[0]); i++) {
+		if (!(use_gpio & (1 << i)))
+			continue;
+		if (!request_region(res_base->start + ichx_regs[0][i],
+				    ichx_reglen[i], name))
+			goto request_err;
+	}
+	return 0;
+
+request_err:
+	/* Clean up: release already requested regions, if any */
+	for (i--; i >= 0; i--) {
+		if (!(use_gpio & (1 << i)))
+			continue;
+		release_region(res_base->start + ichx_regs[0][i],
+			       ichx_reglen[i]);
+	}
+	return -EBUSY;
+}
+
+static void ichx_gpio_release_regions(struct resource *res_base, u8 use_gpio)
+{
+	int i;
+
+	for (i = 0; i < ARRAY_SIZE(ichx_regs[0]); i++) {
+		if (!(use_gpio & (1 << i)))
+			continue;
+		release_region(res_base->start + ichx_regs[0][i],
+			       ichx_reglen[i]);
+	}
+}
+
 static int __devinit ichx_gpio_probe(struct platform_device *pdev)
 {
 	struct resource *res_base, *res_pm;
@@ -329,12 +391,11 @@
 	}
 
 	res_base = platform_get_resource(pdev, IORESOURCE_IO, ICH_RES_GPIO);
-	if (!res_base || !res_base->start || !res_base->end)
-		return -ENODEV;
-
-	if (!request_region(res_base->start, resource_size(res_base),
-				pdev->name))
-		return -EBUSY;
+	ichx_priv.use_gpio = ich_info->use_gpio;
+	err = ichx_gpio_request_regions(res_base, pdev->name,
+					ichx_priv.use_gpio);
+	if (err)
+		return err;
 
 	ichx_priv.gpio_base = res_base;
 
@@ -374,8 +435,7 @@
 	return 0;
 
 add_err:
-	release_region(ichx_priv.gpio_base->start,
-			resource_size(ichx_priv.gpio_base));
+	ichx_gpio_release_regions(ichx_priv.gpio_base, ichx_priv.use_gpio);
 	if (ichx_priv.pm_base)
 		release_region(ichx_priv.pm_base->start,
 				resource_size(ichx_priv.pm_base));
@@ -393,8 +453,7 @@
 		return err;
 	}
 
-	release_region(ichx_priv.gpio_base->start,
-				resource_size(ichx_priv.gpio_base));
+	ichx_gpio_release_regions(ichx_priv.gpio_base, ichx_priv.use_gpio);
 	if (ichx_priv.pm_base)
 		release_region(ichx_priv.pm_base->start,
 				resource_size(ichx_priv.pm_base));
diff --git a/drivers/gpio/gpio-twl6040.c b/drivers/gpio/gpio-twl6040.c
new file mode 100644
index 0000000..dd58e8b
--- /dev/null
+++ b/drivers/gpio/gpio-twl6040.c
@@ -0,0 +1,137 @@
+/*
+ * Access to GPOs on TWL6040 chip
+ *
+ * Copyright (C) 2012 Texas Instruments, Inc.
+ *
+ * Authors:
+ *	Sergio Aguirre <saaguirre@ti.com>
+ *	Peter Ujfalusi <peter.ujfalusi@ti.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., 59 Temple Place, Suite 330, Boston, MA  02111-1307 USA
+ */
+
+#include <linux/module.h>
+#include <linux/init.h>
+#include <linux/kthread.h>
+#include <linux/irq.h>
+#include <linux/gpio.h>
+#include <linux/platform_device.h>
+#include <linux/of.h>
+
+#include <linux/mfd/twl6040.h>
+
+static struct gpio_chip twl6040gpo_chip;
+
+static int twl6040gpo_get(struct gpio_chip *chip, unsigned offset)
+{
+	struct twl6040 *twl6040 = dev_get_drvdata(chip->dev->parent);
+	int ret = 0;
+
+	ret = twl6040_reg_read(twl6040, TWL6040_REG_GPOCTL);
+	if (ret < 0)
+		return ret;
+
+	return (ret >> offset) & 1;
+}
+
+static int twl6040gpo_direction_out(struct gpio_chip *chip, unsigned offset,
+				    int value)
+{
+	/* This only drives GPOs, and can't change direction */
+	return 0;
+}
+
+static void twl6040gpo_set(struct gpio_chip *chip, unsigned offset, int value)
+{
+	struct twl6040 *twl6040 = dev_get_drvdata(chip->dev->parent);
+	int ret;
+	u8 gpoctl;
+
+	ret = twl6040_reg_read(twl6040, TWL6040_REG_GPOCTL);
+	if (ret < 0)
+		return;
+
+	if (value)
+		gpoctl = ret | (1 << offset);
+	else
+		gpoctl = ret & ~(1 << offset);
+
+	twl6040_reg_write(twl6040, TWL6040_REG_GPOCTL, gpoctl);
+}
+
+static struct gpio_chip twl6040gpo_chip = {
+	.label			= "twl6040",
+	.owner			= THIS_MODULE,
+	.get			= twl6040gpo_get,
+	.direction_output	= twl6040gpo_direction_out,
+	.set			= twl6040gpo_set,
+	.can_sleep		= 1,
+};
+
+/*----------------------------------------------------------------------*/
+
+static int __devinit gpo_twl6040_probe(struct platform_device *pdev)
+{
+	struct twl6040_gpo_data *pdata = pdev->dev.platform_data;
+	struct device *twl6040_core_dev = pdev->dev.parent;
+	struct twl6040 *twl6040 = dev_get_drvdata(twl6040_core_dev);
+	int ret;
+
+	if (pdata)
+		twl6040gpo_chip.base = pdata->gpio_base;
+	else
+		twl6040gpo_chip.base = -1;
+
+	if (twl6040_get_revid(twl6040) < TWL6041_REV_ES2_0)
+		twl6040gpo_chip.ngpio = 3; /* twl6040 have 3 GPO */
+	else
+		twl6040gpo_chip.ngpio = 1; /* twl6041 have 1 GPO */
+
+	twl6040gpo_chip.dev = &pdev->dev;
+#ifdef CONFIG_OF_GPIO
+	twl6040gpo_chip.of_node = twl6040_core_dev->of_node;
+#endif
+
+	ret = gpiochip_add(&twl6040gpo_chip);
+	if (ret < 0) {
+		dev_err(&pdev->dev, "could not register gpiochip, %d\n", ret);
+		twl6040gpo_chip.ngpio = 0;
+	}
+
+	return ret;
+}
+
+static int __devexit gpo_twl6040_remove(struct platform_device *pdev)
+{
+	return gpiochip_remove(&twl6040gpo_chip);
+}
+
+/* Note:  this hardware lives inside an I2C-based multi-function device. */
+MODULE_ALIAS("platform:twl6040-gpo");
+
+static struct platform_driver gpo_twl6040_driver = {
+	.driver = {
+		.name	= "twl6040-gpo",
+		.owner	= THIS_MODULE,
+	},
+	.probe		= gpo_twl6040_probe,
+	.remove		= gpo_twl6040_remove,
+};
+
+module_platform_driver(gpo_twl6040_driver);
+
+MODULE_AUTHOR("Texas Instruments, Inc.");
+MODULE_DESCRIPTION("GPO interface for TWL6040");
+MODULE_LICENSE("GPL");
diff --git a/drivers/input/misc/twl4030-vibra.c b/drivers/input/misc/twl4030-vibra.c
index fc0ed9b..2194a3c 100644
--- a/drivers/input/misc/twl4030-vibra.c
+++ b/drivers/input/misc/twl4030-vibra.c
@@ -26,6 +26,7 @@
 #include <linux/module.h>
 #include <linux/jiffies.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
 #include <linux/workqueue.h>
 #include <linux/i2c/twl.h>
 #include <linux/mfd/twl4030-audio.h>
@@ -194,13 +195,26 @@
 static SIMPLE_DEV_PM_OPS(twl4030_vibra_pm_ops,
 			 twl4030_vibra_suspend, twl4030_vibra_resume);
 
+static bool twl4030_vibra_check_coexist(struct twl4030_vibra_data *pdata,
+			      struct device_node *node)
+{
+	if (pdata && pdata->coexist)
+		return true;
+
+	if (of_find_node_by_name(node, "codec"))
+		return true;
+
+	return false;
+}
+
 static int __devinit twl4030_vibra_probe(struct platform_device *pdev)
 {
 	struct twl4030_vibra_data *pdata = pdev->dev.platform_data;
+	struct device_node *twl4030_core_node = pdev->dev.parent->of_node;
 	struct vibra_info *info;
 	int ret;
 
-	if (!pdata) {
+	if (!pdata && !twl4030_core_node) {
 		dev_dbg(&pdev->dev, "platform_data not available\n");
 		return -EINVAL;
 	}
@@ -210,7 +224,7 @@
 		return -ENOMEM;
 
 	info->dev = &pdev->dev;
-	info->coexist = pdata->coexist;
+	info->coexist = twl4030_vibra_check_coexist(pdata, twl4030_core_node);
 	INIT_WORK(&info->play_work, vibra_play_work);
 
 	info->input_dev = input_allocate_device();
diff --git a/drivers/input/touchscreen/88pm860x-ts.c b/drivers/input/touchscreen/88pm860x-ts.c
index 05f30b7..326218d 100644
--- a/drivers/input/touchscreen/88pm860x-ts.c
+++ b/drivers/input/touchscreen/88pm860x-ts.c
@@ -10,6 +10,7 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
@@ -113,14 +114,69 @@
 	pm860x_set_bits(touch->i2c, MEAS_EN3, data, 0);
 }
 
+#ifdef CONFIG_OF
+static int __devinit pm860x_touch_dt_init(struct platform_device *pdev,
+					  struct pm860x_chip *chip,
+					  int *res_x)
+{
+	struct device_node *np = pdev->dev.parent->of_node;
+	struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
+				 : chip->companion;
+	int data, n, ret;
+	if (!np)
+		return -ENODEV;
+	np = of_find_node_by_name(np, "touch");
+	if (!np) {
+		dev_err(&pdev->dev, "Can't find touch node\n");
+		return -EINVAL;
+	}
+	/* set GPADC MISC1 register */
+	data = 0;
+	if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-prebias", &n))
+		data |= (n << 1) & PM8607_GPADC_PREBIAS_MASK;
+	if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-slot-cycle", &n))
+		data |= (n << 3) & PM8607_GPADC_SLOT_CYCLE_MASK;
+	if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-off-scale", &n))
+		data |= (n << 5) & PM8607_GPADC_OFF_SCALE_MASK;
+	if (!of_property_read_u32(np, "marvell,88pm860x-gpadc-sw-cal", &n))
+		data |= (n << 7) & PM8607_GPADC_SW_CAL_MASK;
+	if (data) {
+		ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data);
+		if (ret < 0)
+			return -EINVAL;
+	}
+	/* set tsi prebias time */
+	if (!of_property_read_u32(np, "marvell,88pm860x-tsi-prebias", &data)) {
+		ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data);
+		if (ret < 0)
+			return -EINVAL;
+	}
+	/* set prebias & prechg time of pen detect */
+	data = 0;
+	if (!of_property_read_u32(np, "marvell,88pm860x-pen-prebias", &n))
+		data |= n & PM8607_PD_PREBIAS_MASK;
+	if (!of_property_read_u32(np, "marvell,88pm860x-pen-prechg", &n))
+		data |= n & PM8607_PD_PRECHG_MASK;
+	if (data) {
+		ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data);
+		if (ret < 0)
+			return -EINVAL;
+	}
+	of_property_read_u32(np, "marvell,88pm860x-resistor-X", res_x);
+	return 0;
+}
+#else
+#define pm860x_touch_dt_init(x, y, z)	(-1)
+#endif
+
 static int __devinit pm860x_touch_probe(struct platform_device *pdev)
 {
 	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
-	struct pm860x_platform_data *pm860x_pdata =		\
-				pdev->dev.parent->platform_data;
-	struct pm860x_touch_pdata *pdata = NULL;
+	struct pm860x_touch_pdata *pdata = pdev->dev.platform_data;
 	struct pm860x_touch *touch;
-	int irq, ret;
+	struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
+				 : chip->companion;
+	int irq, ret, res_x = 0, data = 0;
 
 	irq = platform_get_irq(pdev, 0);
 	if (irq < 0) {
@@ -128,16 +184,55 @@
 		return -EINVAL;
 	}
 
-	if (!pm860x_pdata) {
-		dev_err(&pdev->dev, "platform data is missing\n");
-		return -EINVAL;
+	if (pm860x_touch_dt_init(pdev, chip, &res_x)) {
+		if (pdata) {
+			/* set GPADC MISC1 register */
+			data = 0;
+			data |= (pdata->gpadc_prebias << 1)
+				& PM8607_GPADC_PREBIAS_MASK;
+			data |= (pdata->slot_cycle << 3)
+				& PM8607_GPADC_SLOT_CYCLE_MASK;
+			data |= (pdata->off_scale << 5)
+				& PM8607_GPADC_OFF_SCALE_MASK;
+			data |= (pdata->sw_cal << 7)
+				& PM8607_GPADC_SW_CAL_MASK;
+			if (data) {
+				ret = pm860x_reg_write(i2c,
+					PM8607_GPADC_MISC1, data);
+				if (ret < 0)
+					return -EINVAL;
+			}
+			/* set tsi prebias time */
+			if (pdata->tsi_prebias) {
+				data = pdata->tsi_prebias;
+				ret = pm860x_reg_write(i2c,
+					PM8607_TSI_PREBIAS, data);
+				if (ret < 0)
+					return -EINVAL;
+			}
+			/* set prebias & prechg time of pen detect */
+			data = 0;
+			data |= pdata->pen_prebias
+				& PM8607_PD_PREBIAS_MASK;
+			data |= (pdata->pen_prechg << 5)
+				& PM8607_PD_PRECHG_MASK;
+			if (data) {
+				ret = pm860x_reg_write(i2c,
+					PM8607_PD_PREBIAS, data);
+				if (ret < 0)
+					return -EINVAL;
+			}
+			res_x = pdata->res_x;
+		} else {
+			dev_err(&pdev->dev, "failed to get platform data\n");
+			return -EINVAL;
+		}
 	}
-
-	pdata = pm860x_pdata->touch;
-	if (!pdata) {
-		dev_err(&pdev->dev, "touchscreen data is missing\n");
-		return -EINVAL;
-	}
+	/* enable GPADC */
+	ret = pm860x_set_bits(i2c, PM8607_GPADC_MISC1, PM8607_GPADC_EN,
+			      PM8607_GPADC_EN);
+	if (ret)
+		return ret;
 
 	touch = kzalloc(sizeof(struct pm860x_touch), GFP_KERNEL);
 	if (touch == NULL)
@@ -158,9 +253,9 @@
 	touch->idev->open = pm860x_touch_open;
 	touch->idev->close = pm860x_touch_close;
 	touch->chip = chip;
-	touch->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
-	touch->irq = irq + chip->irq_base;
-	touch->res_x = pdata->res_x;
+	touch->i2c = i2c;
+	touch->irq = irq;
+	touch->res_x = res_x;
 	input_set_drvdata(touch->idev, touch);
 
 	ret = request_threaded_irq(touch->irq, NULL, pm860x_touch_handler,
diff --git a/drivers/leds/leds-88pm860x.c b/drivers/leds/leds-88pm860x.c
index 61897cf..b7e8cc0 100644
--- a/drivers/leds/leds-88pm860x.c
+++ b/drivers/leds/leds-88pm860x.c
@@ -12,6 +12,7 @@
 
 #include <linux/kernel.h>
 #include <linux/init.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/i2c.h>
 #include <linux/leds.h>
@@ -20,18 +21,12 @@
 #include <linux/mfd/88pm860x.h>
 #include <linux/module.h>
 
-#define LED_PWM_SHIFT		(3)
 #define LED_PWM_MASK		(0x1F)
 #define LED_CURRENT_MASK	(0x07 << 5)
 
-#define LED_BLINK_ON_MASK	(0x07)
 #define LED_BLINK_MASK		(0x7F)
 
-#define LED_BLINK_ON(x)		((x & 0x7) * 66 + 66)
-#define LED_BLINK_ON_MIN	LED_BLINK_ON(0)
-#define LED_BLINK_ON_MAX	LED_BLINK_ON(0x7)
 #define LED_ON_CONTINUOUS	(0x0F << 3)
-#define LED_TO_ON(x)		((x - 66) / 66)
 
 #define LED1_BLINK_EN		(1 << 1)
 #define LED2_BLINK_EN		(1 << 2)
@@ -49,85 +44,25 @@
 	unsigned char brightness;
 	unsigned char current_brightness;
 
-	int blink_data;
-	int blink_time;
-	int blink_on;
-	int blink_off;
+	int reg_control;
+	int reg_blink;
+	int blink_mask;
 };
 
-/* return offset of color register */
-static inline int __led_off(int port)
-{
-	int ret = -EINVAL;
-
-	switch (port) {
-	case PM8606_LED1_RED:
-	case PM8606_LED1_GREEN:
-	case PM8606_LED1_BLUE:
-		ret = port - PM8606_LED1_RED + PM8606_RGB1B;
-		break;
-	case PM8606_LED2_RED:
-	case PM8606_LED2_GREEN:
-	case PM8606_LED2_BLUE:
-		ret = port - PM8606_LED2_RED + PM8606_RGB2B;
-		break;
-	}
-	return ret;
-}
-
-/* return offset of blink register */
-static inline int __blink_off(int port)
-{
-	int ret = -EINVAL;
-
-	switch (port) {
-	case PM8606_LED1_RED:
-	case PM8606_LED1_GREEN:
-	case PM8606_LED1_BLUE:
-		ret = PM8606_RGB1A;
-		break;
-	case PM8606_LED2_RED:
-	case PM8606_LED2_GREEN:
-	case PM8606_LED2_BLUE:
-		ret = PM8606_RGB2A;
-		break;
-	}
-	return ret;
-}
-
-static inline int __blink_ctl_mask(int port)
-{
-	int ret = -EINVAL;
-
-	switch (port) {
-	case PM8606_LED1_RED:
-	case PM8606_LED1_GREEN:
-	case PM8606_LED1_BLUE:
-		ret = LED1_BLINK_EN;
-		break;
-	case PM8606_LED2_RED:
-	case PM8606_LED2_GREEN:
-	case PM8606_LED2_BLUE:
-		ret = LED2_BLINK_EN;
-		break;
-	}
-	return ret;
-}
-
 static int led_power_set(struct pm860x_chip *chip, int port, int on)
 {
 	int ret = -EINVAL;
 
 	switch (port) {
-	case PM8606_LED1_RED:
-	case PM8606_LED1_GREEN:
-	case PM8606_LED1_BLUE:
+	case 0:
+	case 1:
+	case 2:
 		ret = on ? pm8606_osc_enable(chip, RGB1_ENABLE) :
 			pm8606_osc_disable(chip, RGB1_ENABLE);
 		break;
-	case PM8606_LED2_RED:
-	case PM8606_LED2_GREEN:
-	case PM8606_LED2_BLUE:
+	case 3:
+	case 4:
+	case 5:
 		ret = on ? pm8606_osc_enable(chip, RGB2_ENABLE) :
 			pm8606_osc_disable(chip, RGB2_ENABLE);
 		break;
@@ -141,7 +76,7 @@
 	struct pm860x_led *led;
 	struct pm860x_chip *chip;
 	unsigned char buf[3];
-	int mask, ret;
+	int ret;
 
 	led = container_of(work, struct pm860x_led, work);
 	chip = led->chip;
@@ -149,34 +84,34 @@
 	if ((led->current_brightness == 0) && led->brightness) {
 		led_power_set(chip, led->port, 1);
 		if (led->iset) {
-			pm860x_set_bits(led->i2c, __led_off(led->port),
+			pm860x_set_bits(led->i2c, led->reg_control,
 					LED_CURRENT_MASK, led->iset);
 		}
-		pm860x_set_bits(led->i2c, __blink_off(led->port),
+		pm860x_set_bits(led->i2c, led->reg_blink,
 				LED_BLINK_MASK, LED_ON_CONTINUOUS);
-		mask = __blink_ctl_mask(led->port);
-		pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, mask);
+		pm860x_set_bits(led->i2c, PM8606_WLED3B, led->blink_mask,
+				led->blink_mask);
 	}
-	pm860x_set_bits(led->i2c, __led_off(led->port), LED_PWM_MASK,
+	pm860x_set_bits(led->i2c, led->reg_control, LED_PWM_MASK,
 			led->brightness);
 
 	if (led->brightness == 0) {
-		pm860x_bulk_read(led->i2c, __led_off(led->port), 3, buf);
+		pm860x_bulk_read(led->i2c, led->reg_control, 3, buf);
 		ret = buf[0] & LED_PWM_MASK;
 		ret |= buf[1] & LED_PWM_MASK;
 		ret |= buf[2] & LED_PWM_MASK;
 		if (ret == 0) {
 			/* unset current since no led is lighting */
-			pm860x_set_bits(led->i2c, __led_off(led->port),
+			pm860x_set_bits(led->i2c, led->reg_control,
 					LED_CURRENT_MASK, 0);
-			mask = __blink_ctl_mask(led->port);
-			pm860x_set_bits(led->i2c, PM8606_WLED3B, mask, 0);
+			pm860x_set_bits(led->i2c, PM8606_WLED3B,
+					led->blink_mask, 0);
 			led_power_set(chip, led->port, 0);
 		}
 	}
 	led->current_brightness = led->brightness;
 	dev_dbg(chip->dev, "Update LED. (reg:%d, brightness:%d)\n",
-		__led_off(led->port), led->brightness);
+		led->reg_control, led->brightness);
 	mutex_unlock(&led->lock);
 }
 
@@ -189,39 +124,92 @@
 	schedule_work(&data->work);
 }
 
+#ifdef CONFIG_OF
+static int pm860x_led_dt_init(struct platform_device *pdev,
+			      struct pm860x_led *data)
+{
+	struct device_node *nproot = pdev->dev.parent->of_node, *np;
+	int iset = 0;
+	if (!nproot)
+		return -ENODEV;
+	nproot = of_find_node_by_name(nproot, "leds");
+	if (!nproot) {
+		dev_err(&pdev->dev, "failed to find leds node\n");
+		return -ENODEV;
+	}
+	for_each_child_of_node(nproot, np) {
+		if (!of_node_cmp(np->name, data->name)) {
+			of_property_read_u32(np, "marvell,88pm860x-iset",
+					     &iset);
+			data->iset = PM8606_LED_CURRENT(iset);
+			break;
+		}
+	}
+	return 0;
+}
+#else
+#define pm860x_led_dt_init(x, y)	(-1)
+#endif
+
 static int pm860x_led_probe(struct platform_device *pdev)
 {
 	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
-	struct pm860x_led_pdata *pdata;
+	struct pm860x_led_pdata *pdata = pdev->dev.platform_data;
 	struct pm860x_led *data;
 	struct resource *res;
-	int ret;
-
-	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "No I/O resource!\n");
-		return -EINVAL;
-	}
-
-	pdata = pdev->dev.platform_data;
-	if (pdata == NULL) {
-		dev_err(&pdev->dev, "No platform data!\n");
-		return -EINVAL;
-	}
+	int ret = 0;
 
 	data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_led), GFP_KERNEL);
 	if (data == NULL)
 		return -ENOMEM;
-	strncpy(data->name, res->name, MFD_NAME_SIZE - 1);
+	res = platform_get_resource_byname(pdev, IORESOURCE_REG, "control");
+	if (!res) {
+		dev_err(&pdev->dev, "No REG resource for control\n");
+		ret = -ENXIO;
+		goto out;
+	}
+	data->reg_control = res->start;
+	res = platform_get_resource_byname(pdev, IORESOURCE_REG, "blink");
+	if (!res) {
+		dev_err(&pdev->dev, "No REG resource for blink\n");
+		ret = -ENXIO;
+		goto out;
+	}
+	data->reg_blink = res->start;
+	memset(data->name, 0, MFD_NAME_SIZE);
+	switch (pdev->id) {
+	case 0:
+		data->blink_mask = LED1_BLINK_EN;
+		sprintf(data->name, "led0-red");
+		break;
+	case 1:
+		data->blink_mask = LED1_BLINK_EN;
+		sprintf(data->name, "led0-green");
+		break;
+	case 2:
+		data->blink_mask = LED1_BLINK_EN;
+		sprintf(data->name, "led0-blue");
+		break;
+	case 3:
+		data->blink_mask = LED2_BLINK_EN;
+		sprintf(data->name, "led1-red");
+		break;
+	case 4:
+		data->blink_mask = LED2_BLINK_EN;
+		sprintf(data->name, "led1-green");
+		break;
+	case 5:
+		data->blink_mask = LED2_BLINK_EN;
+		sprintf(data->name, "led1-blue");
+		break;
+	}
 	dev_set_drvdata(&pdev->dev, data);
 	data->chip = chip;
 	data->i2c = (chip->id == CHIP_PM8606) ? chip->client : chip->companion;
-	data->iset = pdata->iset;
-	data->port = pdata->flags;
-	if (data->port < 0) {
-		dev_err(&pdev->dev, "check device failed\n");
-		return -EINVAL;
-	}
+	data->port = pdev->id;
+	if (pm860x_led_dt_init(pdev, data))
+		if (pdata)
+			data->iset = pdata->iset;
 
 	data->current_brightness = 0;
 	data->cdev.name = data->name;
@@ -236,6 +224,9 @@
 	}
 	pm860x_led_set(&data->cdev, 0);
 	return 0;
+out:
+	devm_kfree(&pdev->dev, data);
+	return ret;
 }
 
 static int pm860x_led_remove(struct platform_device *pdev)
diff --git a/drivers/mfd/88pm860x-core.c b/drivers/mfd/88pm860x-core.c
index b73f033..59d117e 100644
--- a/drivers/mfd/88pm860x-core.c
+++ b/drivers/mfd/88pm860x-core.c
@@ -11,50 +11,116 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/err.h>
 #include <linux/i2c.h>
 #include <linux/irq.h>
 #include <linux/interrupt.h>
+#include <linux/irqdomain.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/platform_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/88pm860x.h>
 #include <linux/regulator/machine.h>
 
 #define INT_STATUS_NUM			3
 
-static struct resource bk_resources[] __devinitdata = {
-	{PM8606_BACKLIGHT1, PM8606_BACKLIGHT1, "backlight-0", IORESOURCE_IO,},
-	{PM8606_BACKLIGHT2, PM8606_BACKLIGHT2, "backlight-1", IORESOURCE_IO,},
-	{PM8606_BACKLIGHT3, PM8606_BACKLIGHT3, "backlight-2", IORESOURCE_IO,},
+static struct resource bk0_resources[] __devinitdata = {
+	{2, 2, "duty cycle", IORESOURCE_REG, },
+	{3, 3, "always on",  IORESOURCE_REG, },
+	{3, 3, "current",    IORESOURCE_REG, },
+};
+static struct resource bk1_resources[] __devinitdata = {
+	{4, 4, "duty cycle", IORESOURCE_REG, },
+	{5, 5, "always on",  IORESOURCE_REG, },
+	{5, 5, "current",    IORESOURCE_REG, },
+};
+static struct resource bk2_resources[] __devinitdata = {
+	{6, 6, "duty cycle", IORESOURCE_REG, },
+	{7, 7, "always on",  IORESOURCE_REG, },
+	{5, 5, "current",    IORESOURCE_REG, },
 };
 
-static struct resource led_resources[] __devinitdata = {
-	{PM8606_LED1_RED,   PM8606_LED1_RED,   "led0-red",   IORESOURCE_IO,},
-	{PM8606_LED1_GREEN, PM8606_LED1_GREEN, "led0-green", IORESOURCE_IO,},
-	{PM8606_LED1_BLUE,  PM8606_LED1_BLUE,  "led0-blue",  IORESOURCE_IO,},
-	{PM8606_LED2_RED,   PM8606_LED2_RED,   "led1-red",   IORESOURCE_IO,},
-	{PM8606_LED2_GREEN, PM8606_LED2_GREEN, "led1-green", IORESOURCE_IO,},
-	{PM8606_LED2_BLUE,  PM8606_LED2_BLUE,  "led1-blue",  IORESOURCE_IO,},
+static struct resource led0_resources[] __devinitdata = {
+	/* RGB1 Red LED */
+	{0xd, 0xd, "control", IORESOURCE_REG, },
+	{0xc, 0xc, "blink",   IORESOURCE_REG, },
+};
+static struct resource led1_resources[] __devinitdata = {
+	/* RGB1 Green LED */
+	{0xe, 0xe, "control", IORESOURCE_REG, },
+	{0xc, 0xc, "blink",   IORESOURCE_REG, },
+};
+static struct resource led2_resources[] __devinitdata = {
+	/* RGB1 Blue LED */
+	{0xf, 0xf, "control", IORESOURCE_REG, },
+	{0xc, 0xc, "blink",   IORESOURCE_REG, },
+};
+static struct resource led3_resources[] __devinitdata = {
+	/* RGB2 Red LED */
+	{0x9, 0x9, "control", IORESOURCE_REG, },
+	{0x8, 0x8, "blink",   IORESOURCE_REG, },
+};
+static struct resource led4_resources[] __devinitdata = {
+	/* RGB2 Green LED */
+	{0xa, 0xa, "control", IORESOURCE_REG, },
+	{0x8, 0x8, "blink",   IORESOURCE_REG, },
+};
+static struct resource led5_resources[] __devinitdata = {
+	/* RGB2 Blue LED */
+	{0xb, 0xb, "control", IORESOURCE_REG, },
+	{0x8, 0x8, "blink",   IORESOURCE_REG, },
 };
 
-static struct resource regulator_resources[] __devinitdata = {
-	{PM8607_ID_BUCK1, PM8607_ID_BUCK1, "buck-1", IORESOURCE_IO,},
-	{PM8607_ID_BUCK2, PM8607_ID_BUCK2, "buck-2", IORESOURCE_IO,},
-	{PM8607_ID_BUCK3, PM8607_ID_BUCK3, "buck-3", IORESOURCE_IO,},
-	{PM8607_ID_LDO1,  PM8607_ID_LDO1,  "ldo-01", IORESOURCE_IO,},
-	{PM8607_ID_LDO2,  PM8607_ID_LDO2,  "ldo-02", IORESOURCE_IO,},
-	{PM8607_ID_LDO3,  PM8607_ID_LDO3,  "ldo-03", IORESOURCE_IO,},
-	{PM8607_ID_LDO4,  PM8607_ID_LDO4,  "ldo-04", IORESOURCE_IO,},
-	{PM8607_ID_LDO5,  PM8607_ID_LDO5,  "ldo-05", IORESOURCE_IO,},
-	{PM8607_ID_LDO6,  PM8607_ID_LDO6,  "ldo-06", IORESOURCE_IO,},
-	{PM8607_ID_LDO7,  PM8607_ID_LDO7,  "ldo-07", IORESOURCE_IO,},
-	{PM8607_ID_LDO8,  PM8607_ID_LDO8,  "ldo-08", IORESOURCE_IO,},
-	{PM8607_ID_LDO9,  PM8607_ID_LDO9,  "ldo-09", IORESOURCE_IO,},
-	{PM8607_ID_LDO10, PM8607_ID_LDO10, "ldo-10", IORESOURCE_IO,},
-	{PM8607_ID_LDO11, PM8607_ID_LDO11, "ldo-11", IORESOURCE_IO,},
-	{PM8607_ID_LDO12, PM8607_ID_LDO12, "ldo-12", IORESOURCE_IO,},
-	{PM8607_ID_LDO13, PM8607_ID_LDO13, "ldo-13", IORESOURCE_IO,},
-	{PM8607_ID_LDO14, PM8607_ID_LDO14, "ldo-14", IORESOURCE_IO,},
-	{PM8607_ID_LDO15, PM8607_ID_LDO15, "ldo-15", IORESOURCE_IO,},
+static struct resource buck1_resources[] __devinitdata = {
+	{0x24, 0x24, "buck set", IORESOURCE_REG, },
+};
+static struct resource buck2_resources[] __devinitdata = {
+	{0x25, 0x25, "buck set", IORESOURCE_REG, },
+};
+static struct resource buck3_resources[] __devinitdata = {
+	{0x26, 0x26, "buck set", IORESOURCE_REG, },
+};
+static struct resource ldo1_resources[] __devinitdata = {
+	{0x10, 0x10, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo2_resources[] __devinitdata = {
+	{0x11, 0x11, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo3_resources[] __devinitdata = {
+	{0x12, 0x12, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo4_resources[] __devinitdata = {
+	{0x13, 0x13, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo5_resources[] __devinitdata = {
+	{0x14, 0x14, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo6_resources[] __devinitdata = {
+	{0x15, 0x15, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo7_resources[] __devinitdata = {
+	{0x16, 0x16, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo8_resources[] __devinitdata = {
+	{0x17, 0x17, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo9_resources[] __devinitdata = {
+	{0x18, 0x18, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo10_resources[] __devinitdata = {
+	{0x19, 0x19, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo12_resources[] __devinitdata = {
+	{0x1a, 0x1a, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo_vibrator_resources[] __devinitdata = {
+	{0x28, 0x28, "ldo set", IORESOURCE_REG, },
+};
+static struct resource ldo14_resources[] __devinitdata = {
+	{0x1b, 0x1b, "ldo set", IORESOURCE_REG, },
 };
 
 static struct resource touch_resources[] __devinitdata = {
@@ -90,48 +156,145 @@
 	{PM8607_IRQ_VCHG, PM8607_IRQ_VCHG, "vchg voltage",    IORESOURCE_IRQ,},
 };
 
-static struct resource preg_resources[] __devinitdata = {
-	{PM8606_ID_PREG,  PM8606_ID_PREG,  "preg",   IORESOURCE_IO,},
-};
-
 static struct resource rtc_resources[] __devinitdata = {
 	{PM8607_IRQ_RTC, PM8607_IRQ_RTC, "rtc", IORESOURCE_IRQ,},
 };
 
-static struct mfd_cell bk_devs[] = {
-	{"88pm860x-backlight", 0,},
-	{"88pm860x-backlight", 1,},
-	{"88pm860x-backlight", 2,},
+static struct mfd_cell bk_devs[] __devinitdata = {
+	{
+		.name = "88pm860x-backlight",
+		.id = 0,
+		.num_resources = ARRAY_SIZE(bk0_resources),
+		.resources = bk0_resources,
+	}, {
+		.name = "88pm860x-backlight",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(bk1_resources),
+		.resources = bk1_resources,
+	}, {
+		.name = "88pm860x-backlight",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(bk2_resources),
+		.resources = bk2_resources,
+	},
 };
 
-static struct mfd_cell led_devs[] = {
-	{"88pm860x-led", 0,},
-	{"88pm860x-led", 1,},
-	{"88pm860x-led", 2,},
-	{"88pm860x-led", 3,},
-	{"88pm860x-led", 4,},
-	{"88pm860x-led", 5,},
+static struct mfd_cell led_devs[] __devinitdata = {
+	{
+		.name = "88pm860x-led",
+		.id = 0,
+		.num_resources = ARRAY_SIZE(led0_resources),
+		.resources = led0_resources,
+	}, {
+		.name = "88pm860x-led",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(led1_resources),
+		.resources = led1_resources,
+	}, {
+		.name = "88pm860x-led",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(led2_resources),
+		.resources = led2_resources,
+	}, {
+		.name = "88pm860x-led",
+		.id = 3,
+		.num_resources = ARRAY_SIZE(led3_resources),
+		.resources = led3_resources,
+	}, {
+		.name = "88pm860x-led",
+		.id = 4,
+		.num_resources = ARRAY_SIZE(led4_resources),
+		.resources = led4_resources,
+	}, {
+		.name = "88pm860x-led",
+		.id = 5,
+		.num_resources = ARRAY_SIZE(led5_resources),
+		.resources = led5_resources,
+	},
 };
 
-static struct mfd_cell regulator_devs[] = {
-	{"88pm860x-regulator", 0,},
-	{"88pm860x-regulator", 1,},
-	{"88pm860x-regulator", 2,},
-	{"88pm860x-regulator", 3,},
-	{"88pm860x-regulator", 4,},
-	{"88pm860x-regulator", 5,},
-	{"88pm860x-regulator", 6,},
-	{"88pm860x-regulator", 7,},
-	{"88pm860x-regulator", 8,},
-	{"88pm860x-regulator", 9,},
-	{"88pm860x-regulator", 10,},
-	{"88pm860x-regulator", 11,},
-	{"88pm860x-regulator", 12,},
-	{"88pm860x-regulator", 13,},
-	{"88pm860x-regulator", 14,},
-	{"88pm860x-regulator", 15,},
-	{"88pm860x-regulator", 16,},
-	{"88pm860x-regulator", 17,},
+static struct mfd_cell reg_devs[] __devinitdata = {
+	{
+		.name = "88pm860x-regulator",
+		.id = 0,
+		.num_resources = ARRAY_SIZE(buck1_resources),
+		.resources = buck1_resources,
+	}, {
+		.name = "88pm860x-regulator",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(buck2_resources),
+		.resources = buck2_resources,
+	}, {
+		.name = "88pm860x-regulator",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(buck3_resources),
+		.resources = buck3_resources,
+	}, {
+		.name = "88pm860x-regulator",
+		.id = 3,
+		.num_resources = ARRAY_SIZE(ldo1_resources),
+		.resources = ldo1_resources,
+	}, {
+		.name = "88pm860x-regulator",
+		.id = 4,
+		.num_resources = ARRAY_SIZE(ldo2_resources),
+		.resources = ldo2_resources,
+	}, {
+		.name = "88pm860x-regulator",
+		.id = 5,
+		.num_resources = ARRAY_SIZE(ldo3_resources),
+		.resources = ldo3_resources,
+	}, {
+		.name = "88pm860x-regulator",
+		.id = 6,
+		.num_resources = ARRAY_SIZE(ldo4_resources),
+		.resources = ldo4_resources,
+	}, {
+		.name = "88pm860x-regulator",
+		.id = 7,
+		.num_resources = ARRAY_SIZE(ldo5_resources),
+		.resources = ldo5_resources,
+	}, {
+		.name = "88pm860x-regulator",
+		.id = 8,
+		.num_resources = ARRAY_SIZE(ldo6_resources),
+		.resources = ldo6_resources,
+	}, {
+		.name = "88pm860x-regulator",
+		.id = 9,
+		.num_resources = ARRAY_SIZE(ldo7_resources),
+		.resources = ldo7_resources,
+	}, {
+		.name = "88pm860x-regulator",
+		.id = 10,
+		.num_resources = ARRAY_SIZE(ldo8_resources),
+		.resources = ldo8_resources,
+	}, {
+		.name = "88pm860x-regulator",
+		.id = 11,
+		.num_resources = ARRAY_SIZE(ldo9_resources),
+		.resources = ldo9_resources,
+	}, {
+		.name = "88pm860x-regulator",
+		.id = 12,
+		.num_resources = ARRAY_SIZE(ldo10_resources),
+		.resources = ldo10_resources,
+	}, {
+		.name = "88pm860x-regulator",
+		.id = 13,
+		.num_resources = ARRAY_SIZE(ldo12_resources),
+		.resources = ldo12_resources,
+	}, {
+		.name = "88pm860x-regulator",
+		.id = 14,
+		.num_resources = ARRAY_SIZE(ldo_vibrator_resources),
+		.resources = ldo_vibrator_resources,
+	}, {
+		.name = "88pm860x-regulator",
+		.id = 15,
+		.num_resources = ARRAY_SIZE(ldo14_resources),
+		.resources = ldo14_resources,
+	},
 };
 
 static struct mfd_cell touch_devs[] = {
@@ -360,15 +523,12 @@
 
 static void pm860x_irq_enable(struct irq_data *data)
 {
-	struct pm860x_chip *chip = irq_data_get_irq_chip_data(data);
-	pm860x_irqs[data->irq - chip->irq_base].enable
-		= pm860x_irqs[data->irq - chip->irq_base].offs;
+	pm860x_irqs[data->hwirq].enable = pm860x_irqs[data->hwirq].offs;
 }
 
 static void pm860x_irq_disable(struct irq_data *data)
 {
-	struct pm860x_chip *chip = irq_data_get_irq_chip_data(data);
-	pm860x_irqs[data->irq - chip->irq_base].enable = 0;
+	pm860x_irqs[data->hwirq].enable = 0;
 }
 
 static struct irq_chip pm860x_irq_chip = {
@@ -379,53 +539,25 @@
 	.irq_disable	= pm860x_irq_disable,
 };
 
-static int __devinit device_gpadc_init(struct pm860x_chip *chip,
-				       struct pm860x_platform_data *pdata)
+static int pm860x_irq_domain_map(struct irq_domain *d, unsigned int virq,
+				 irq_hw_number_t hw)
 {
-	struct i2c_client *i2c = (chip->id == CHIP_PM8607) ? chip->client \
-				: chip->companion;
-	int data;
-	int ret;
-
-	/* initialize GPADC without activating it */
-
-	if (!pdata || !pdata->touch)
-		return -EINVAL;
-
-	/* set GPADC MISC1 register */
-	data = 0;
-	data |= (pdata->touch->gpadc_prebias << 1) & PM8607_GPADC_PREBIAS_MASK;
-	data |= (pdata->touch->slot_cycle << 3) & PM8607_GPADC_SLOT_CYCLE_MASK;
-	data |= (pdata->touch->off_scale << 5) & PM8607_GPADC_OFF_SCALE_MASK;
-	data |= (pdata->touch->sw_cal << 7) & PM8607_GPADC_SW_CAL_MASK;
-	if (data) {
-		ret = pm860x_reg_write(i2c, PM8607_GPADC_MISC1, data);
-		if (ret < 0)
-			goto out;
-	}
-	/* set tsi prebias time */
-	if (pdata->touch->tsi_prebias) {
-		data = pdata->touch->tsi_prebias;
-		ret = pm860x_reg_write(i2c, PM8607_TSI_PREBIAS, data);
-		if (ret < 0)
-			goto out;
-	}
-	/* set prebias & prechg time of pen detect */
-	data = 0;
-	data |= pdata->touch->pen_prebias & PM8607_PD_PREBIAS_MASK;
-	data |= (pdata->touch->pen_prechg << 5) & PM8607_PD_PRECHG_MASK;
-	if (data) {
-		ret = pm860x_reg_write(i2c, PM8607_PD_PREBIAS, data);
-		if (ret < 0)
-			goto out;
-	}
-
-	ret = pm860x_set_bits(i2c, PM8607_GPADC_MISC1,
-			      PM8607_GPADC_EN, PM8607_GPADC_EN);
-out:
-	return ret;
+	irq_set_chip_data(virq, d->host_data);
+	irq_set_chip_and_handler(virq, &pm860x_irq_chip, handle_edge_irq);
+	irq_set_nested_thread(virq, 1);
+#ifdef CONFIG_ARM
+	set_irq_flags(virq, IRQF_VALID);
+#else
+	irq_set_noprobe(virq);
+#endif
+	return 0;
 }
 
+static struct irq_domain_ops pm860x_irq_domain_ops = {
+	.map	= pm860x_irq_domain_map,
+	.xlate	= irq_domain_xlate_onetwocell,
+};
+
 static int __devinit device_irq_init(struct pm860x_chip *chip,
 				     struct pm860x_platform_data *pdata)
 {
@@ -433,13 +565,9 @@
 				: chip->companion;
 	unsigned char status_buf[INT_STATUS_NUM];
 	unsigned long flags = IRQF_TRIGGER_FALLING | IRQF_ONESHOT;
-	int i, data, mask, ret = -EINVAL;
-	int __irq;
-
-	if (!pdata || !pdata->irq_base) {
-		dev_warn(chip->dev, "No interrupt support on IRQ base\n");
-		return -EINVAL;
-	}
+	int data, mask, ret = -EINVAL;
+	int nr_irqs, irq_base = -1;
+	struct device_node *node = i2c->dev.of_node;
 
 	mask = PM8607_B0_MISC1_INV_INT | PM8607_B0_MISC1_INT_CLEAR
 		| PM8607_B0_MISC1_INT_MASK;
@@ -479,26 +607,24 @@
 		goto out;
 
 	mutex_init(&chip->irq_lock);
-	chip->irq_base = pdata->irq_base;
+
+	if (pdata && pdata->irq_base)
+		irq_base = pdata->irq_base;
+	nr_irqs = ARRAY_SIZE(pm860x_irqs);
+	chip->irq_base = irq_alloc_descs(irq_base, 0, nr_irqs, 0);
+	if (chip->irq_base < 0) {
+		dev_err(&i2c->dev, "Failed to allocate interrupts, ret:%d\n",
+			chip->irq_base);
+		ret = -EBUSY;
+		goto out;
+	}
+	irq_domain_add_legacy(node, nr_irqs, chip->irq_base, 0,
+			      &pm860x_irq_domain_ops, chip);
 	chip->core_irq = i2c->irq;
 	if (!chip->core_irq)
 		goto out;
 
-	/* register IRQ by genirq */
-	for (i = 0; i < ARRAY_SIZE(pm860x_irqs); i++) {
-		__irq = i + chip->irq_base;
-		irq_set_chip_data(__irq, chip);
-		irq_set_chip_and_handler(__irq, &pm860x_irq_chip,
-					 handle_edge_irq);
-		irq_set_nested_thread(__irq, 1);
-#ifdef CONFIG_ARM
-		set_irq_flags(__irq, IRQF_VALID);
-#else
-		irq_set_noprobe(__irq);
-#endif
-	}
-
-	ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags,
+	ret = request_threaded_irq(chip->core_irq, NULL, pm860x_irq, flags | IRQF_ONESHOT,
 				   "88pm860x", chip);
 	if (ret) {
 		dev_err(chip->dev, "Failed to request IRQ: %d\n", ret);
@@ -615,108 +741,122 @@
 static void __devinit device_bk_init(struct pm860x_chip *chip,
 				     struct pm860x_platform_data *pdata)
 {
-	int ret;
-	int i, j, id;
+	int ret, i;
 
-	if ((pdata == NULL) || (pdata->backlight == NULL))
-		return;
-
-	if (pdata->num_backlights > ARRAY_SIZE(bk_devs))
-		pdata->num_backlights = ARRAY_SIZE(bk_devs);
-
-	for (i = 0; i < pdata->num_backlights; i++) {
-		bk_devs[i].platform_data = &pdata->backlight[i];
-		bk_devs[i].pdata_size = sizeof(struct pm860x_backlight_pdata);
-
-		for (j = 0; j < ARRAY_SIZE(bk_devs); j++) {
-			id = bk_resources[j].start;
-			if (pdata->backlight[i].flags != id)
-				continue;
-
-			bk_devs[i].num_resources = 1;
-			bk_devs[i].resources = &bk_resources[j];
-			ret = mfd_add_devices(chip->dev, 0,
-					      &bk_devs[i], 1,
-					      &bk_resources[j], 0, NULL);
-			if (ret < 0) {
-				dev_err(chip->dev, "Failed to add "
-					"backlight subdev\n");
-				return;
-			}
+	if (pdata && pdata->backlight) {
+		if (pdata->num_backlights > ARRAY_SIZE(bk_devs))
+			pdata->num_backlights = ARRAY_SIZE(bk_devs);
+		for (i = 0; i < pdata->num_backlights; i++) {
+			bk_devs[i].platform_data = &pdata->backlight[i];
+			bk_devs[i].pdata_size =
+				sizeof(struct pm860x_backlight_pdata);
 		}
 	}
+	ret = mfd_add_devices(chip->dev, 0, bk_devs,
+			      ARRAY_SIZE(bk_devs), NULL, 0, NULL);
+	if (ret < 0)
+		dev_err(chip->dev, "Failed to add backlight subdev\n");
 }
 
 static void __devinit device_led_init(struct pm860x_chip *chip,
 				      struct pm860x_platform_data *pdata)
 {
-	int ret;
-	int i, j, id;
+	int ret, i;
 
-	if ((pdata == NULL) || (pdata->led == NULL))
-		return;
-
-	if (pdata->num_leds > ARRAY_SIZE(led_devs))
-		pdata->num_leds = ARRAY_SIZE(led_devs);
-
-	for (i = 0; i < pdata->num_leds; i++) {
-		led_devs[i].platform_data = &pdata->led[i];
-		led_devs[i].pdata_size = sizeof(struct pm860x_led_pdata);
-
-		for (j = 0; j < ARRAY_SIZE(led_devs); j++) {
-			id = led_resources[j].start;
-			if (pdata->led[i].flags != id)
-				continue;
-
-			led_devs[i].num_resources = 1;
-			led_devs[i].resources = &led_resources[j],
-			ret = mfd_add_devices(chip->dev, 0,
-					      &led_devs[i], 1,
-					      &led_resources[j], 0, NULL);
-			if (ret < 0) {
-				dev_err(chip->dev, "Failed to add "
-					"led subdev\n");
-				return;
-			}
+	if (pdata && pdata->led) {
+		if (pdata->num_leds > ARRAY_SIZE(led_devs))
+			pdata->num_leds = ARRAY_SIZE(led_devs);
+		for (i = 0; i < pdata->num_leds; i++) {
+			led_devs[i].platform_data = &pdata->led[i];
+			led_devs[i].pdata_size =
+				sizeof(struct pm860x_led_pdata);
 		}
 	}
+	ret = mfd_add_devices(chip->dev, 0, led_devs,
+			      ARRAY_SIZE(led_devs), NULL, 0, NULL);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to add led subdev\n");
+		return;
+	}
 }
 
 static void __devinit device_regulator_init(struct pm860x_chip *chip,
 					    struct pm860x_platform_data *pdata)
 {
-	struct regulator_init_data *initdata;
 	int ret;
-	int i, seq;
 
-	if ((pdata == NULL) || (pdata->regulator == NULL))
+	if (pdata == NULL)
 		return;
-
-	if (pdata->num_regulators > ARRAY_SIZE(regulator_devs))
-		pdata->num_regulators = ARRAY_SIZE(regulator_devs);
-
-	for (i = 0, seq = -1; i < pdata->num_regulators; i++) {
-		initdata = &pdata->regulator[i];
-		seq = *(unsigned int *)initdata->driver_data;
-		if ((seq < 0) || (seq > PM8607_ID_RG_MAX)) {
-			dev_err(chip->dev, "Wrong ID(%d) on regulator(%s)\n",
-				seq, initdata->constraints.name);
-			goto out;
-		}
-		regulator_devs[i].platform_data = &pdata->regulator[i];
-		regulator_devs[i].pdata_size = sizeof(struct regulator_init_data);
-		regulator_devs[i].num_resources = 1;
-		regulator_devs[i].resources = &regulator_resources[seq];
-
-		ret = mfd_add_devices(chip->dev, 0, &regulator_devs[i], 1,
-				      &regulator_resources[seq], 0, NULL);
-		if (ret < 0) {
-			dev_err(chip->dev, "Failed to add regulator subdev\n");
-			goto out;
-		}
+	if (pdata->buck1) {
+		reg_devs[0].platform_data = pdata->buck1;
+		reg_devs[0].pdata_size = sizeof(struct regulator_init_data);
 	}
-out:
-	return;
+	if (pdata->buck2) {
+		reg_devs[1].platform_data = pdata->buck2;
+		reg_devs[1].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->buck3) {
+		reg_devs[2].platform_data = pdata->buck3;
+		reg_devs[2].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo1) {
+		reg_devs[3].platform_data = pdata->ldo1;
+		reg_devs[3].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo2) {
+		reg_devs[4].platform_data = pdata->ldo2;
+		reg_devs[4].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo3) {
+		reg_devs[5].platform_data = pdata->ldo3;
+		reg_devs[5].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo4) {
+		reg_devs[6].platform_data = pdata->ldo4;
+		reg_devs[6].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo5) {
+		reg_devs[7].platform_data = pdata->ldo5;
+		reg_devs[7].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo6) {
+		reg_devs[8].platform_data = pdata->ldo6;
+		reg_devs[8].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo7) {
+		reg_devs[9].platform_data = pdata->ldo7;
+		reg_devs[9].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo8) {
+		reg_devs[10].platform_data = pdata->ldo8;
+		reg_devs[10].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo9) {
+		reg_devs[11].platform_data = pdata->ldo9;
+		reg_devs[11].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo10) {
+		reg_devs[12].platform_data = pdata->ldo10;
+		reg_devs[12].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo12) {
+		reg_devs[13].platform_data = pdata->ldo12;
+		reg_devs[13].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo_vibrator) {
+		reg_devs[14].platform_data = pdata->ldo_vibrator;
+		reg_devs[14].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo14) {
+		reg_devs[15].platform_data = pdata->ldo14;
+		reg_devs[15].pdata_size = sizeof(struct regulator_init_data);
+	}
+	ret = mfd_add_devices(chip->dev, 0, reg_devs,
+			      ARRAY_SIZE(reg_devs), NULL, 0, NULL);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to add regulator subdev\n");
+		return;
+	}
 }
 
 static void __devinit device_rtc_init(struct pm860x_chip *chip,
@@ -785,10 +925,8 @@
 
 	power_devs[2].platform_data = &preg_init_data;
 	power_devs[2].pdata_size = sizeof(struct regulator_init_data);
-	power_devs[2].num_resources = ARRAY_SIZE(preg_resources);
-	power_devs[2].resources = &preg_resources[0],
 	ret = mfd_add_devices(chip->dev, 0, &power_devs[2], 1,
-			      &preg_resources[0], chip->irq_base, NULL);
+			      NULL, chip->irq_base, NULL);
 	if (ret < 0)
 		dev_err(chip->dev, "Failed to add preg subdev\n");
 }
@@ -868,10 +1006,6 @@
 		goto out;
 	}
 
-	ret = device_gpadc_init(chip, pdata);
-	if (ret < 0)
-		goto out;
-
 	ret = device_irq_init(chip, pdata);
 	if (ret < 0)
 		goto out;
@@ -895,8 +1029,8 @@
 	device_led_init(chip, pdata);
 }
 
-int __devinit pm860x_device_init(struct pm860x_chip *chip,
-		       struct pm860x_platform_data *pdata)
+static int __devinit pm860x_device_init(struct pm860x_chip *chip,
+					struct pm860x_platform_data *pdata)
 {
 	chip->core_irq = 0;
 
@@ -923,12 +1057,207 @@
 	return 0;
 }
 
-void __devexit pm860x_device_exit(struct pm860x_chip *chip)
+static void __devexit pm860x_device_exit(struct pm860x_chip *chip)
 {
 	device_irq_exit(chip);
 	mfd_remove_devices(chip->dev);
 }
 
+static int verify_addr(struct i2c_client *i2c)
+{
+	unsigned short addr_8607[] = {0x30, 0x34};
+	unsigned short addr_8606[] = {0x10, 0x11};
+	int size, i;
+
+	if (i2c == NULL)
+		return 0;
+	size = ARRAY_SIZE(addr_8606);
+	for (i = 0; i < size; i++) {
+		if (i2c->addr == *(addr_8606 + i))
+			return CHIP_PM8606;
+	}
+	size = ARRAY_SIZE(addr_8607);
+	for (i = 0; i < size; i++) {
+		if (i2c->addr == *(addr_8607 + i))
+			return CHIP_PM8607;
+	}
+	return 0;
+}
+
+static struct regmap_config pm860x_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+};
+
+static int __devinit pm860x_dt_init(struct device_node *np,
+				    struct device *dev,
+				    struct pm860x_platform_data *pdata)
+{
+	int ret;
+
+	if (of_get_property(np, "marvell,88pm860x-irq-read-clr", NULL))
+		pdata->irq_mode = 1;
+	ret = of_property_read_u32(np, "marvell,88pm860x-slave-addr",
+				   &pdata->companion_addr);
+	if (ret) {
+		dev_err(dev, "Not found \"marvell,88pm860x-slave-addr\" "
+			"property\n");
+		pdata->companion_addr = 0;
+	}
+	return 0;
+}
+
+static int __devinit pm860x_probe(struct i2c_client *client,
+				  const struct i2c_device_id *id)
+{
+	struct pm860x_platform_data *pdata = client->dev.platform_data;
+	struct device_node *node = client->dev.of_node;
+	struct pm860x_chip *chip;
+	int ret;
+
+	if (node && !pdata) {
+		/* parse DT to get platform data */
+		pdata = devm_kzalloc(&client->dev,
+				     sizeof(struct pm860x_platform_data),
+				     GFP_KERNEL);
+		if (!pdata)
+			return -ENOMEM;
+		ret = pm860x_dt_init(node, &client->dev, pdata);
+		if (ret)
+			goto err;
+	} else if (!pdata) {
+		pr_info("No platform data in %s!\n", __func__);
+		return -EINVAL;
+	}
+
+	chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
+	if (chip == NULL) {
+		ret = -ENOMEM;
+		goto err;
+	}
+
+	chip->id = verify_addr(client);
+	chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config);
+	if (IS_ERR(chip->regmap)) {
+		ret = PTR_ERR(chip->regmap);
+		dev_err(&client->dev, "Failed to allocate register map: %d\n",
+				ret);
+		kfree(chip);
+		return ret;
+	}
+	chip->client = client;
+	i2c_set_clientdata(client, chip);
+	chip->dev = &client->dev;
+	dev_set_drvdata(chip->dev, chip);
+
+	/*
+	 * Both client and companion client shares same platform driver.
+	 * Driver distinguishes them by pdata->companion_addr.
+	 * pdata->companion_addr is only assigned if companion chip exists.
+	 * At the same time, the companion_addr shouldn't equal to client
+	 * address.
+	 */
+	if (pdata->companion_addr && (pdata->companion_addr != client->addr)) {
+		chip->companion_addr = pdata->companion_addr;
+		chip->companion = i2c_new_dummy(chip->client->adapter,
+						chip->companion_addr);
+		chip->regmap_companion = regmap_init_i2c(chip->companion,
+							&pm860x_regmap_config);
+		if (IS_ERR(chip->regmap_companion)) {
+			ret = PTR_ERR(chip->regmap_companion);
+			dev_err(&chip->companion->dev,
+				"Failed to allocate register map: %d\n", ret);
+			return ret;
+		}
+		i2c_set_clientdata(chip->companion, chip);
+	}
+
+	pm860x_device_init(chip, pdata);
+	return 0;
+err:
+	if (node)
+		devm_kfree(&client->dev, pdata);
+	return ret;
+}
+
+static int __devexit pm860x_remove(struct i2c_client *client)
+{
+	struct pm860x_chip *chip = i2c_get_clientdata(client);
+
+	pm860x_device_exit(chip);
+	if (chip->companion) {
+		regmap_exit(chip->regmap_companion);
+		i2c_unregister_device(chip->companion);
+	}
+	regmap_exit(chip->regmap);
+	kfree(chip);
+	return 0;
+}
+
+#ifdef CONFIG_PM_SLEEP
+static int pm860x_suspend(struct device *dev)
+{
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+	struct pm860x_chip *chip = i2c_get_clientdata(client);
+
+	if (device_may_wakeup(dev) && chip->wakeup_flag)
+		enable_irq_wake(chip->core_irq);
+	return 0;
+}
+
+static int pm860x_resume(struct device *dev)
+{
+	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
+	struct pm860x_chip *chip = i2c_get_clientdata(client);
+
+	if (device_may_wakeup(dev) && chip->wakeup_flag)
+		disable_irq_wake(chip->core_irq);
+	return 0;
+}
+#endif
+
+static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume);
+
+static const struct i2c_device_id pm860x_id_table[] = {
+	{ "88PM860x", 0 },
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
+
+static const struct of_device_id pm860x_dt_ids[] = {
+	{ .compatible = "marvell,88pm860x", },
+	{},
+};
+MODULE_DEVICE_TABLE(of, pm860x_dt_ids);
+
+static struct i2c_driver pm860x_driver = {
+	.driver	= {
+		.name	= "88PM860x",
+		.owner	= THIS_MODULE,
+		.pm     = &pm860x_pm_ops,
+		.of_match_table	= of_match_ptr(pm860x_dt_ids),
+	},
+	.probe		= pm860x_probe,
+	.remove		= __devexit_p(pm860x_remove),
+	.id_table	= pm860x_id_table,
+};
+
+static int __init pm860x_i2c_init(void)
+{
+	int ret;
+	ret = i2c_add_driver(&pm860x_driver);
+	if (ret != 0)
+		pr_err("Failed to register 88PM860x I2C driver: %d\n", ret);
+	return ret;
+}
+subsys_initcall(pm860x_i2c_init);
+
+static void __exit pm860x_i2c_exit(void)
+{
+	i2c_del_driver(&pm860x_driver);
+}
+module_exit(pm860x_i2c_exit);
+
 MODULE_DESCRIPTION("PMIC Driver for Marvell 88PM860x");
 MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
 MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/88pm860x-i2c.c b/drivers/mfd/88pm860x-i2c.c
index b2cfdc4..ff8f803 100644
--- a/drivers/mfd/88pm860x-i2c.c
+++ b/drivers/mfd/88pm860x-i2c.c
@@ -10,12 +10,9 @@
  */
 #include <linux/kernel.h>
 #include <linux/module.h>
-#include <linux/platform_device.h>
 #include <linux/i2c.h>
-#include <linux/err.h>
 #include <linux/regmap.h>
 #include <linux/mfd/88pm860x.h>
-#include <linux/slab.h>
 
 int pm860x_reg_read(struct i2c_client *i2c, int reg)
 {
@@ -91,8 +88,18 @@
 	unsigned char msgbuf0[I2C_SMBUS_BLOCK_MAX + 3];
 	unsigned char msgbuf1[I2C_SMBUS_BLOCK_MAX + 2];
 	struct i2c_adapter *adap = i2c->adapter;
-	struct i2c_msg msg[2] = {{i2c->addr, 0, 1, msgbuf0},
-				 {i2c->addr, I2C_M_RD, 0, msgbuf1},
+	struct i2c_msg msg[2] = {
+					{
+						.addr = i2c->addr,
+						.flags = 0,
+						.len = 1,
+						.buf = msgbuf0
+					},
+					{	.addr = i2c->addr,
+						.flags = I2C_M_RD,
+						.len = 0,
+						.buf = msgbuf1
+					},
 				};
 	int num = 1, ret = 0;
 
@@ -231,160 +238,3 @@
 	return ret;
 }
 EXPORT_SYMBOL(pm860x_page_set_bits);
-
-static const struct i2c_device_id pm860x_id_table[] = {
-	{ "88PM860x", 0 },
-	{}
-};
-MODULE_DEVICE_TABLE(i2c, pm860x_id_table);
-
-static int verify_addr(struct i2c_client *i2c)
-{
-	unsigned short addr_8607[] = {0x30, 0x34};
-	unsigned short addr_8606[] = {0x10, 0x11};
-	int size, i;
-
-	if (i2c == NULL)
-		return 0;
-	size = ARRAY_SIZE(addr_8606);
-	for (i = 0; i < size; i++) {
-		if (i2c->addr == *(addr_8606 + i))
-			return CHIP_PM8606;
-	}
-	size = ARRAY_SIZE(addr_8607);
-	for (i = 0; i < size; i++) {
-		if (i2c->addr == *(addr_8607 + i))
-			return CHIP_PM8607;
-	}
-	return 0;
-}
-
-static struct regmap_config pm860x_regmap_config = {
-	.reg_bits = 8,
-	.val_bits = 8,
-};
-
-static int __devinit pm860x_probe(struct i2c_client *client,
-				  const struct i2c_device_id *id)
-{
-	struct pm860x_platform_data *pdata = client->dev.platform_data;
-	struct pm860x_chip *chip;
-	int ret;
-
-	if (!pdata) {
-		pr_info("No platform data in %s!\n", __func__);
-		return -EINVAL;
-	}
-
-	chip = kzalloc(sizeof(struct pm860x_chip), GFP_KERNEL);
-	if (chip == NULL)
-		return -ENOMEM;
-
-	chip->id = verify_addr(client);
-	chip->regmap = regmap_init_i2c(client, &pm860x_regmap_config);
-	if (IS_ERR(chip->regmap)) {
-		ret = PTR_ERR(chip->regmap);
-		dev_err(&client->dev, "Failed to allocate register map: %d\n",
-				ret);
-		kfree(chip);
-		return ret;
-	}
-	chip->client = client;
-	i2c_set_clientdata(client, chip);
-	chip->dev = &client->dev;
-	dev_set_drvdata(chip->dev, chip);
-
-	/*
-	 * Both client and companion client shares same platform driver.
-	 * Driver distinguishes them by pdata->companion_addr.
-	 * pdata->companion_addr is only assigned if companion chip exists.
-	 * At the same time, the companion_addr shouldn't equal to client
-	 * address.
-	 */
-	if (pdata->companion_addr && (pdata->companion_addr != client->addr)) {
-		chip->companion_addr = pdata->companion_addr;
-		chip->companion = i2c_new_dummy(chip->client->adapter,
-						chip->companion_addr);
-		chip->regmap_companion = regmap_init_i2c(chip->companion,
-							&pm860x_regmap_config);
-		if (IS_ERR(chip->regmap_companion)) {
-			ret = PTR_ERR(chip->regmap_companion);
-			dev_err(&chip->companion->dev,
-				"Failed to allocate register map: %d\n", ret);
-			return ret;
-		}
-		i2c_set_clientdata(chip->companion, chip);
-	}
-
-	pm860x_device_init(chip, pdata);
-	return 0;
-}
-
-static int __devexit pm860x_remove(struct i2c_client *client)
-{
-	struct pm860x_chip *chip = i2c_get_clientdata(client);
-
-	pm860x_device_exit(chip);
-	if (chip->companion) {
-		regmap_exit(chip->regmap_companion);
-		i2c_unregister_device(chip->companion);
-	}
-	regmap_exit(chip->regmap);
-	kfree(chip);
-	return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int pm860x_suspend(struct device *dev)
-{
-	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
-	struct pm860x_chip *chip = i2c_get_clientdata(client);
-
-	if (device_may_wakeup(dev) && chip->wakeup_flag)
-		enable_irq_wake(chip->core_irq);
-	return 0;
-}
-
-static int pm860x_resume(struct device *dev)
-{
-	struct i2c_client *client = container_of(dev, struct i2c_client, dev);
-	struct pm860x_chip *chip = i2c_get_clientdata(client);
-
-	if (device_may_wakeup(dev) && chip->wakeup_flag)
-		disable_irq_wake(chip->core_irq);
-	return 0;
-}
-#endif
-
-static SIMPLE_DEV_PM_OPS(pm860x_pm_ops, pm860x_suspend, pm860x_resume);
-
-static struct i2c_driver pm860x_driver = {
-	.driver	= {
-		.name	= "88PM860x",
-		.owner	= THIS_MODULE,
-		.pm     = &pm860x_pm_ops,
-	},
-	.probe		= pm860x_probe,
-	.remove		= __devexit_p(pm860x_remove),
-	.id_table	= pm860x_id_table,
-};
-
-static int __init pm860x_i2c_init(void)
-{
-	int ret;
-	ret = i2c_add_driver(&pm860x_driver);
-	if (ret != 0)
-		pr_err("Failed to register 88PM860x I2C driver: %d\n", ret);
-	return ret;
-}
-subsys_initcall(pm860x_i2c_init);
-
-static void __exit pm860x_i2c_exit(void)
-{
-	i2c_del_driver(&pm860x_driver);
-}
-module_exit(pm860x_i2c_exit);
-
-MODULE_DESCRIPTION("I2C Driver for Marvell 88PM860x");
-MODULE_AUTHOR("Haojian Zhuang <haojian.zhuang@marvell.com>");
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index b1a1462..acab3ef 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -298,16 +298,6 @@
 	select MFD_CORE
 	default n
 
-config TWL6030_PWM
-	tristate "TWL6030 PWM (Pulse Width Modulator) Support"
-	depends on TWL4030_CORE
-	select HAVE_PWM
-	depends on !PWM
-	default n
-	help
-	  Say yes here if you want support for TWL6030 PWM.
-	  This is used to control charging LED brightness.
-
 config TWL6040_CORE
 	bool "Support for TWL6040 audio codec"
 	depends on I2C=y && GENERIC_HARDIRQS
@@ -385,6 +375,18 @@
 	help
 	  Support for Toshiba Mobile IO Controller T7L66XB
 
+config MFD_SMSC
+       bool "Support for the SMSC ECE1099 series chips"
+       depends on I2C=y
+       select MFD_CORE
+       select REGMAP_I2C
+       help
+        If you say yes here you get support for the
+        ece1099 chips from SMSC.
+
+        To compile this driver as a module, choose M here: the
+        module will be called smsc.
+
 config MFD_TC6387XB
 	bool "Support Toshiba TC6387XB"
 	depends on ARM && HAVE_CLK
@@ -441,6 +443,23 @@
 	  for accessing the device, additional drivers must be enabled in
 	  order to use the functionality of the device.
 
+config MFD_DA9055
+	bool "Dialog Semiconductor DA9055 PMIC Support"
+	select REGMAP_I2C
+	select REGMAP_IRQ
+	select PMIC_DA9055
+	select MFD_CORE
+	depends on I2C=y
+	help
+	  Say yes here for support of Dialog Semiconductor DA9055. This is
+	  a Power Management IC. This driver provides common support for
+	  accessing the device as well as the I2C interface to the chip itself.
+	  Additional drivers must be enabled in order to use the functionality
+	  of the device.
+
+	  This driver can be built as a module. If built as a module it will be
+	  called "da9055"
+
 config PMIC_ADP5520
 	bool "Analog Devices ADP5520/01 MFD PMIC Core Support"
 	depends on I2C=y
@@ -451,6 +470,16 @@
 	  individual components like LCD backlight, LEDs, GPIOs and Kepad
 	  under the corresponding menus.
 
+config MFD_LP8788
+	bool "Texas Instruments LP8788 Power Management Unit Driver"
+	depends on I2C=y
+	select MFD_CORE
+	select REGMAP_I2C
+	select IRQ_DOMAIN
+	help
+	  TI LP8788 PMU supports regulators, battery charger, RTC,
+	  ADC, backlight driver and current sinks.
+
 config MFD_MAX77686
 	bool "Maxim Semiconductor MAX77686 PMIC Support"
 	depends on I2C=y && GENERIC_HARDIRQS
@@ -477,6 +506,18 @@
 	  additional drivers must be enabled in order to use the functionality
 	  of the device.
 
+config MFD_MAX8907
+	tristate "Maxim Semiconductor MAX8907 PMIC Support"
+	select MFD_CORE
+	depends on I2C=y && GENERIC_HARDIRQS
+	select REGMAP_I2C
+	select REGMAP_IRQ
+	help
+	  Say yes here to support for Maxim Semiconductor MAX8907. This is
+	  a Power Management IC. This driver provides common support for
+	  accessing the device; additional drivers must be enabled in order
+	  to use the functionality of the device.
+
 config MFD_MAX8925
 	bool "Maxim Semiconductor MAX8925 PMIC Support"
 	depends on I2C=y && GENERIC_HARDIRQS
@@ -896,7 +937,7 @@
 	  audio codec.
 
 config MFD_OMAP_USB_HOST
-	bool "Support OMAP USBHS core driver"
+	bool "Support OMAP USBHS core and TLL driver"
 	depends on USB_EHCI_HCD_OMAP || USB_OHCI_HCD_OMAP3
 	default y
 	help
@@ -985,13 +1026,13 @@
 	depends on STA2X11
 	select MFD_CORE
 
-config MFD_ANATOP
-	bool "Support for Freescale i.MX on-chip ANATOP controller"
-	depends on SOC_IMX6Q
+config MFD_SYSCON
+	bool "System Controller Register R/W Based on Regmap"
+	depends on OF
+	select REGMAP_MMIO
 	help
-	  Select this option to enable Freescale i.MX on-chip ANATOP
-	  MFD controller. This controller embeds regulator and
-	  thermal devices for Freescale i.MX platforms.
+	  Select this option to enable accessing system control registers
+	  via regmap.
 
 config MFD_PALMAS
 	bool "Support for the TI Palmas series chips"
diff --git a/drivers/mfd/Makefile b/drivers/mfd/Makefile
index 79dd22d..d8ccb63 100644
--- a/drivers/mfd/Makefile
+++ b/drivers/mfd/Makefile
@@ -63,7 +63,6 @@
 obj-$(CONFIG_TWL4030_MADC)      += twl4030-madc.o
 obj-$(CONFIG_TWL4030_POWER)    += twl4030-power.o
 obj-$(CONFIG_MFD_TWL4030_AUDIO)	+= twl4030-audio.o
-obj-$(CONFIG_TWL6030_PWM)	+= twl6030-pwm.o
 obj-$(CONFIG_TWL6040_CORE)	+= twl6040-core.o twl6040-irq.o
 
 obj-$(CONFIG_MFD_MC13XXX)	+= mc13xxx-core.o
@@ -77,6 +76,7 @@
 obj-$(CONFIG_MCP)		+= mcp-core.o
 obj-$(CONFIG_MCP_SA11X0)	+= mcp-sa11x0.o
 obj-$(CONFIG_MCP_UCB1200)	+= ucb1x00-core.o
+obj-$(CONFIG_MFD_SMSC)        += smsc-ece1099.o
 obj-$(CONFIG_MCP_UCB1200_TS)	+= ucb1x00-ts.o
 
 ifeq ($(CONFIG_SA1100_ASSABET),y)
@@ -90,8 +90,14 @@
 obj-$(CONFIG_MFD_DA9052_SPI)	+= da9052-spi.o
 obj-$(CONFIG_MFD_DA9052_I2C)	+= da9052-i2c.o
 
+obj-$(CONFIG_MFD_LP8788)	+= lp8788.o lp8788-irq.o
+
+da9055-objs			:= da9055-core.o da9055-i2c.o
+obj-$(CONFIG_MFD_DA9055)	+= da9055.o
+
 obj-$(CONFIG_MFD_MAX77686)	+= max77686.o max77686-irq.o
 obj-$(CONFIG_MFD_MAX77693)	+= max77693.o max77693-irq.o
+obj-$(CONFIG_MFD_MAX8907)	+= max8907.o
 max8925-objs			:= max8925-core.o max8925-i2c.o
 obj-$(CONFIG_MFD_MAX8925)	+= max8925.o
 obj-$(CONFIG_MFD_MAX8997)	+= max8997.o max8997-irq.o
@@ -120,7 +126,7 @@
 obj-$(CONFIG_MFD_VX855)		+= vx855.o
 obj-$(CONFIG_MFD_WL1273_CORE)	+= wl1273-core.o
 obj-$(CONFIG_MFD_CS5535)	+= cs5535-mfd.o
-obj-$(CONFIG_MFD_OMAP_USB_HOST)	+= omap-usb-host.o
+obj-$(CONFIG_MFD_OMAP_USB_HOST)	+= omap-usb-host.o omap-usb-tll.o
 obj-$(CONFIG_MFD_PM8921_CORE) 	+= pm8921-core.o
 obj-$(CONFIG_MFD_PM8XXX_IRQ) 	+= pm8xxx-irq.o
 obj-$(CONFIG_TPS65911_COMPARATOR)	+= tps65911-comparator.o
@@ -130,5 +136,5 @@
 obj-$(CONFIG_MFD_PALMAS)	+= palmas.o
 obj-$(CONFIG_MFD_RC5T583)	+= rc5t583.o rc5t583-irq.o
 obj-$(CONFIG_MFD_SEC_CORE)	+= sec-core.o sec-irq.o
-obj-$(CONFIG_MFD_ANATOP)	+= anatop-mfd.o
+obj-$(CONFIG_MFD_SYSCON)	+= syscon.o
 obj-$(CONFIG_MFD_LM3533)	+= lm3533-core.o lm3533-ctrlbank.o
diff --git a/drivers/mfd/ab3100-core.c b/drivers/mfd/ab3100-core.c
index 01781ae..2b3dde5 100644
--- a/drivers/mfd/ab3100-core.c
+++ b/drivers/mfd/ab3100-core.c
@@ -21,6 +21,7 @@
 #include <linux/seq_file.h>
 #include <linux/uaccess.h>
 #include <linux/mfd/core.h>
+#include <linux/mfd/ab3100.h>
 #include <linux/mfd/abx500.h>
 
 /* These are the only registers inside AB3100 used in this main file */
diff --git a/drivers/mfd/ab8500-core.c b/drivers/mfd/ab8500-core.c
index 47adf80..1667c77 100644
--- a/drivers/mfd/ab8500-core.c
+++ b/drivers/mfd/ab8500-core.c
@@ -472,6 +472,22 @@
 	return IRQ_HANDLED;
 }
 
+/**
+ * ab8500_irq_get_virq(): Map an interrupt on a chip to a virtual IRQ
+ *
+ * @ab8500: ab8500_irq controller to operate on.
+ * @irq: index of the interrupt requested in the chip IRQs
+ *
+ * Useful for drivers to request their own IRQs.
+ */
+static int ab8500_irq_get_virq(struct ab8500 *ab8500, int irq)
+{
+	if (!ab8500)
+		return -EINVAL;
+
+	return irq_create_mapping(ab8500->domain, irq);
+}
+
 static irqreturn_t ab8500_irq(int irq, void *dev)
 {
 	struct ab8500 *ab8500 = dev;
@@ -501,8 +517,9 @@
 		do {
 			int bit = __ffs(value);
 			int line = i * 8 + bit;
+			int virq = ab8500_irq_get_virq(ab8500, line);
 
-			handle_nested_irq(ab8500->irq_base + line);
+			handle_nested_irq(virq);
 			value &= ~(1 << bit);
 
 		} while (value);
@@ -511,23 +528,6 @@
 	return IRQ_HANDLED;
 }
 
-/**
- * ab8500_irq_get_virq(): Map an interrupt on a chip to a virtual IRQ
- *
- * @ab8500: ab8500_irq controller to operate on.
- * @irq: index of the interrupt requested in the chip IRQs
- *
- * Useful for drivers to request their own IRQs.
- */
-int ab8500_irq_get_virq(struct ab8500 *ab8500, int irq)
-{
-	if (!ab8500)
-		return -EINVAL;
-
-	return irq_create_mapping(ab8500->domain, irq);
-}
-EXPORT_SYMBOL_GPL(ab8500_irq_get_virq);
-
 static int ab8500_irq_map(struct irq_domain *d, unsigned int virq,
 				irq_hw_number_t hwirq)
 {
@@ -1076,6 +1076,7 @@
 	},
 	{
 		.name = "ab8500-codec",
+		.of_compatible = "stericsson,ab8500-codec",
 	},
 };
 
diff --git a/drivers/mfd/anatop-mfd.c b/drivers/mfd/anatop-mfd.c
deleted file mode 100644
index 5576e07..0000000
--- a/drivers/mfd/anatop-mfd.c
+++ /dev/null
@@ -1,124 +0,0 @@
-/*
- * Anatop MFD driver
- *
- * Copyright (C) 2012 Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
- * Copyright (C) 2012 Linaro
- *
- *  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.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *  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.,
- *  51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
- *
- */
-
-#include <linux/io.h>
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/of.h>
-#include <linux/of_platform.h>
-#include <linux/of_address.h>
-#include <linux/mfd/anatop.h>
-
-u32 anatop_read_reg(struct anatop *adata, u32 addr)
-{
-	return readl(adata->ioreg + addr);
-}
-EXPORT_SYMBOL_GPL(anatop_read_reg);
-
-void anatop_write_reg(struct anatop *adata, u32 addr, u32 data, u32 mask)
-{
-	u32 val;
-
-	data &= mask;
-
-	spin_lock(&adata->reglock);
-	val = readl(adata->ioreg + addr);
-	val &= ~mask;
-	val |= data;
-	writel(val, adata->ioreg + addr);
-	spin_unlock(&adata->reglock);
-}
-EXPORT_SYMBOL_GPL(anatop_write_reg);
-
-static const struct of_device_id of_anatop_match[] = {
-	{ .compatible = "fsl,imx6q-anatop", },
-	{ },
-};
-
-static int __devinit of_anatop_probe(struct platform_device *pdev)
-{
-	struct device *dev = &pdev->dev;
-	struct device_node *np = dev->of_node;
-	void *ioreg;
-	struct anatop *drvdata;
-
-	ioreg = of_iomap(np, 0);
-	if (!ioreg)
-		return -EADDRNOTAVAIL;
-	drvdata = devm_kzalloc(dev, sizeof(*drvdata), GFP_KERNEL);
-	if (!drvdata)
-		return -ENOMEM;
-	drvdata->ioreg = ioreg;
-	spin_lock_init(&drvdata->reglock);
-	platform_set_drvdata(pdev, drvdata);
-	of_platform_populate(np, NULL, NULL, dev);
-
-	return 0;
-}
-
-static int __devexit of_anatop_remove(struct platform_device *pdev)
-{
-	struct anatop *drvdata;
-	drvdata = platform_get_drvdata(pdev);
-	iounmap(drvdata->ioreg);
-
-	return 0;
-}
-
-static struct platform_driver anatop_of_driver = {
-	.driver = {
-		.name = "anatop-mfd",
-		.owner = THIS_MODULE,
-		.of_match_table = of_anatop_match,
-	},
-	.probe		= of_anatop_probe,
-	.remove		= of_anatop_remove,
-};
-
-static int __init anatop_init(void)
-{
-	return platform_driver_register(&anatop_of_driver);
-}
-postcore_initcall(anatop_init);
-
-static void __exit anatop_exit(void)
-{
-	platform_driver_unregister(&anatop_of_driver);
-}
-module_exit(anatop_exit);
-
-MODULE_AUTHOR("Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>");
-MODULE_DESCRIPTION("ANATOP MFD driver");
-MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/arizona-irq.c b/drivers/mfd/arizona-irq.c
index 98ac345..ef0f2d00 100644
--- a/drivers/mfd/arizona-irq.c
+++ b/drivers/mfd/arizona-irq.c
@@ -94,7 +94,8 @@
 static irqreturn_t arizona_irq_thread(int irq, void *data)
 {
 	struct arizona *arizona = data;
-	int i, ret;
+	unsigned int val;
+	int ret;
 
 	ret = pm_runtime_get_sync(arizona->dev);
 	if (ret < 0) {
@@ -102,9 +103,20 @@
 		return IRQ_NONE;
 	}
 
-	/* Check both domains */
-	for (i = 0; i < 2; i++)
-		handle_nested_irq(irq_find_mapping(arizona->virq, i));
+	/* Always handle the AoD domain */
+	handle_nested_irq(irq_find_mapping(arizona->virq, 0));
+
+	/*
+	 * Check if one of the main interrupts is asserted and only
+	 * check that domain if it is.
+	 */
+	ret = regmap_read(arizona->regmap, ARIZONA_IRQ_PIN_STATUS, &val);
+	if (ret == 0 && val & ARIZONA_IRQ1_STS) {
+		handle_nested_irq(irq_find_mapping(arizona->virq, 1));
+	} else if (ret != 0) {
+		dev_err(arizona->dev, "Failed to read main IRQ status: %d\n",
+			ret);
+	}
 
 	pm_runtime_mark_last_busy(arizona->dev);
 	pm_runtime_put_autosuspend(arizona->dev);
@@ -156,18 +168,36 @@
 	int flags = IRQF_ONESHOT;
 	int ret, i;
 	const struct regmap_irq_chip *aod, *irq;
+	bool ctrlif_error = true;
 
 	switch (arizona->type) {
 #ifdef CONFIG_MFD_WM5102
 	case WM5102:
 		aod = &wm5102_aod;
 		irq = &wm5102_irq;
+
+		switch (arizona->rev) {
+		case 0:
+			ctrlif_error = false;
+			break;
+		default:
+			break;
+		}
 		break;
 #endif
 #ifdef CONFIG_MFD_WM5110
 	case WM5110:
 		aod = &wm5110_aod;
 		irq = &wm5110_irq;
+
+		switch (arizona->rev) {
+		case 0:
+		case 1:
+			ctrlif_error = false;
+			break;
+		default:
+			break;
+		}
 		break;
 #endif
 	default:
@@ -226,13 +256,17 @@
 	}
 
 	/* Handle control interface errors in the core */
-	i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR);
-	ret = request_threaded_irq(i, NULL, arizona_ctrlif_err, IRQF_ONESHOT,
-				   "Control interface error", arizona);
-	if (ret != 0) {
-		dev_err(arizona->dev, "Failed to request boot done %d: %d\n",
-			arizona->irq, ret);
-		goto err_ctrlif;
+	if (ctrlif_error) {
+		i = arizona_map_irq(arizona, ARIZONA_IRQ_CTRLIF_ERR);
+		ret = request_threaded_irq(i, NULL, arizona_ctrlif_err,
+					   IRQF_ONESHOT,
+					   "Control interface error", arizona);
+		if (ret != 0) {
+			dev_err(arizona->dev,
+				"Failed to request CTRLIF_ERR %d: %d\n",
+				arizona->irq, ret);
+			goto err_ctrlif;
+		}
 	}
 
 	ret = request_threaded_irq(arizona->irq, NULL, arizona_irq_thread,
diff --git a/drivers/mfd/da9055-core.c b/drivers/mfd/da9055-core.c
new file mode 100644
index 0000000..ff6c77f3
--- /dev/null
+++ b/drivers/mfd/da9055-core.c
@@ -0,0 +1,423 @@
+/*
+ * Device access for Dialog DA9055 PMICs.
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: David Dajun Chen <dchen@diasemi.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.
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/input.h>
+#include <linux/irq.h>
+#include <linux/mutex.h>
+
+#include <linux/mfd/core.h>
+#include <linux/mfd/da9055/core.h>
+#include <linux/mfd/da9055/pdata.h>
+#include <linux/mfd/da9055/reg.h>
+
+#define DA9055_IRQ_NONKEY_MASK		0x01
+#define DA9055_IRQ_ALM_MASK		0x02
+#define DA9055_IRQ_TICK_MASK		0x04
+#define DA9055_IRQ_ADC_MASK		0x08
+#define DA9055_IRQ_BUCK_ILIM_MASK	0x08
+
+static bool da9055_register_readable(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case DA9055_REG_STATUS_A:
+	case DA9055_REG_STATUS_B:
+	case DA9055_REG_EVENT_A:
+	case DA9055_REG_EVENT_B:
+	case DA9055_REG_EVENT_C:
+	case DA9055_REG_IRQ_MASK_A:
+	case DA9055_REG_IRQ_MASK_B:
+	case DA9055_REG_IRQ_MASK_C:
+
+	case DA9055_REG_CONTROL_A:
+	case DA9055_REG_CONTROL_B:
+	case DA9055_REG_CONTROL_C:
+	case DA9055_REG_CONTROL_D:
+	case DA9055_REG_CONTROL_E:
+
+	case DA9055_REG_ADC_MAN:
+	case DA9055_REG_ADC_CONT:
+	case DA9055_REG_VSYS_MON:
+	case DA9055_REG_ADC_RES_L:
+	case DA9055_REG_ADC_RES_H:
+	case DA9055_REG_VSYS_RES:
+	case DA9055_REG_ADCIN1_RES:
+	case DA9055_REG_ADCIN2_RES:
+	case DA9055_REG_ADCIN3_RES:
+
+	case DA9055_REG_COUNT_S:
+	case DA9055_REG_COUNT_MI:
+	case DA9055_REG_COUNT_H:
+	case DA9055_REG_COUNT_D:
+	case DA9055_REG_COUNT_MO:
+	case DA9055_REG_COUNT_Y:
+	case DA9055_REG_ALARM_H:
+	case DA9055_REG_ALARM_D:
+	case DA9055_REG_ALARM_MI:
+	case DA9055_REG_ALARM_MO:
+	case DA9055_REG_ALARM_Y:
+
+	case DA9055_REG_GPIO0_1:
+	case DA9055_REG_GPIO2:
+	case DA9055_REG_GPIO_MODE0_2:
+
+	case DA9055_REG_BCORE_CONT:
+	case DA9055_REG_BMEM_CONT:
+	case DA9055_REG_LDO1_CONT:
+	case DA9055_REG_LDO2_CONT:
+	case DA9055_REG_LDO3_CONT:
+	case DA9055_REG_LDO4_CONT:
+	case DA9055_REG_LDO5_CONT:
+	case DA9055_REG_LDO6_CONT:
+	case DA9055_REG_BUCK_LIM:
+	case DA9055_REG_BCORE_MODE:
+	case DA9055_REG_VBCORE_A:
+	case DA9055_REG_VBMEM_A:
+	case DA9055_REG_VLDO1_A:
+	case DA9055_REG_VLDO2_A:
+	case DA9055_REG_VLDO3_A:
+	case DA9055_REG_VLDO4_A:
+	case DA9055_REG_VLDO5_A:
+	case DA9055_REG_VLDO6_A:
+	case DA9055_REG_VBCORE_B:
+	case DA9055_REG_VBMEM_B:
+	case DA9055_REG_VLDO1_B:
+	case DA9055_REG_VLDO2_B:
+	case DA9055_REG_VLDO3_B:
+	case DA9055_REG_VLDO4_B:
+	case DA9055_REG_VLDO5_B:
+	case DA9055_REG_VLDO6_B:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool da9055_register_writeable(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case DA9055_REG_STATUS_A:
+	case DA9055_REG_STATUS_B:
+	case DA9055_REG_EVENT_A:
+	case DA9055_REG_EVENT_B:
+	case DA9055_REG_EVENT_C:
+	case DA9055_REG_IRQ_MASK_A:
+	case DA9055_REG_IRQ_MASK_B:
+	case DA9055_REG_IRQ_MASK_C:
+
+	case DA9055_REG_CONTROL_A:
+	case DA9055_REG_CONTROL_B:
+	case DA9055_REG_CONTROL_C:
+	case DA9055_REG_CONTROL_D:
+	case DA9055_REG_CONTROL_E:
+
+	case DA9055_REG_ADC_MAN:
+	case DA9055_REG_ADC_CONT:
+	case DA9055_REG_VSYS_MON:
+	case DA9055_REG_ADC_RES_L:
+	case DA9055_REG_ADC_RES_H:
+	case DA9055_REG_VSYS_RES:
+	case DA9055_REG_ADCIN1_RES:
+	case DA9055_REG_ADCIN2_RES:
+	case DA9055_REG_ADCIN3_RES:
+
+	case DA9055_REG_COUNT_S:
+	case DA9055_REG_COUNT_MI:
+	case DA9055_REG_COUNT_H:
+	case DA9055_REG_COUNT_D:
+	case DA9055_REG_COUNT_MO:
+	case DA9055_REG_COUNT_Y:
+	case DA9055_REG_ALARM_H:
+	case DA9055_REG_ALARM_D:
+	case DA9055_REG_ALARM_MI:
+	case DA9055_REG_ALARM_MO:
+	case DA9055_REG_ALARM_Y:
+
+	case DA9055_REG_GPIO0_1:
+	case DA9055_REG_GPIO2:
+	case DA9055_REG_GPIO_MODE0_2:
+
+	case DA9055_REG_BCORE_CONT:
+	case DA9055_REG_BMEM_CONT:
+	case DA9055_REG_LDO1_CONT:
+	case DA9055_REG_LDO2_CONT:
+	case DA9055_REG_LDO3_CONT:
+	case DA9055_REG_LDO4_CONT:
+	case DA9055_REG_LDO5_CONT:
+	case DA9055_REG_LDO6_CONT:
+	case DA9055_REG_BUCK_LIM:
+	case DA9055_REG_BCORE_MODE:
+	case DA9055_REG_VBCORE_A:
+	case DA9055_REG_VBMEM_A:
+	case DA9055_REG_VLDO1_A:
+	case DA9055_REG_VLDO2_A:
+	case DA9055_REG_VLDO3_A:
+	case DA9055_REG_VLDO4_A:
+	case DA9055_REG_VLDO5_A:
+	case DA9055_REG_VLDO6_A:
+	case DA9055_REG_VBCORE_B:
+	case DA9055_REG_VBMEM_B:
+	case DA9055_REG_VLDO1_B:
+	case DA9055_REG_VLDO2_B:
+	case DA9055_REG_VLDO3_B:
+	case DA9055_REG_VLDO4_B:
+	case DA9055_REG_VLDO5_B:
+	case DA9055_REG_VLDO6_B:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool da9055_register_volatile(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case DA9055_REG_STATUS_A:
+	case DA9055_REG_STATUS_B:
+	case DA9055_REG_EVENT_A:
+	case DA9055_REG_EVENT_B:
+	case DA9055_REG_EVENT_C:
+
+	case DA9055_REG_CONTROL_A:
+	case DA9055_REG_CONTROL_E:
+
+	case DA9055_REG_ADC_MAN:
+	case DA9055_REG_ADC_RES_L:
+	case DA9055_REG_ADC_RES_H:
+	case DA9055_REG_VSYS_RES:
+	case DA9055_REG_ADCIN1_RES:
+	case DA9055_REG_ADCIN2_RES:
+	case DA9055_REG_ADCIN3_RES:
+
+	case DA9055_REG_COUNT_S:
+	case DA9055_REG_COUNT_MI:
+	case DA9055_REG_COUNT_H:
+	case DA9055_REG_COUNT_D:
+	case DA9055_REG_COUNT_MO:
+	case DA9055_REG_COUNT_Y:
+	case DA9055_REG_ALARM_MI:
+
+	case DA9055_REG_BCORE_CONT:
+	case DA9055_REG_BMEM_CONT:
+	case DA9055_REG_LDO1_CONT:
+	case DA9055_REG_LDO2_CONT:
+	case DA9055_REG_LDO3_CONT:
+	case DA9055_REG_LDO4_CONT:
+	case DA9055_REG_LDO5_CONT:
+	case DA9055_REG_LDO6_CONT:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static struct regmap_irq da9055_irqs[] = {
+	[DA9055_IRQ_NONKEY] = {
+		.reg_offset = 0,
+		.mask = DA9055_IRQ_NONKEY_MASK,
+	},
+	[DA9055_IRQ_ALARM] = {
+		.reg_offset = 0,
+		.mask = DA9055_IRQ_ALM_MASK,
+	},
+	[DA9055_IRQ_TICK] = {
+		.reg_offset = 0,
+		.mask = DA9055_IRQ_TICK_MASK,
+	},
+	[DA9055_IRQ_HWMON] = {
+		.reg_offset = 0,
+		.mask = DA9055_IRQ_ADC_MASK,
+	},
+	[DA9055_IRQ_REGULATOR] = {
+		.reg_offset = 1,
+		.mask = DA9055_IRQ_BUCK_ILIM_MASK,
+	},
+};
+
+struct regmap_config da9055_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+
+	.cache_type = REGCACHE_RBTREE,
+
+	.max_register = DA9055_MAX_REGISTER_CNT,
+	.readable_reg = da9055_register_readable,
+	.writeable_reg = da9055_register_writeable,
+	.volatile_reg = da9055_register_volatile,
+};
+EXPORT_SYMBOL_GPL(da9055_regmap_config);
+
+static struct resource da9055_onkey_resource = {
+	.name = "ONKEY",
+	.start = DA9055_IRQ_NONKEY,
+	.end   = DA9055_IRQ_NONKEY,
+	.flags = IORESOURCE_IRQ,
+};
+
+static struct resource da9055_rtc_resource[] = {
+	{
+		.name = "ALM",
+		.start = DA9055_IRQ_ALARM,
+		.end   = DA9055_IRQ_ALARM,
+		.flags = IORESOURCE_IRQ,
+	},
+	{
+		.name = "TICK",
+		.start = DA9055_IRQ_TICK,
+		.end   = DA9055_IRQ_TICK,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource da9055_hwmon_resource = {
+	.name = "HWMON",
+	.start = DA9055_IRQ_HWMON,
+	.end   = DA9055_IRQ_HWMON,
+	.flags = IORESOURCE_IRQ,
+};
+
+static struct resource da9055_ld05_6_resource = {
+	.name = "REGULATOR",
+	.start = DA9055_IRQ_REGULATOR,
+	.end   = DA9055_IRQ_REGULATOR,
+	.flags = IORESOURCE_IRQ,
+};
+
+static struct mfd_cell da9055_devs[] = {
+	{
+		.of_compatible = "dialog,da9055-gpio",
+		.name = "da9055-gpio",
+	},
+	{
+		.of_compatible = "dialog,da9055-regulator",
+		.name = "da9055-regulator",
+		.id = 1,
+	},
+	{
+		.of_compatible = "dialog,da9055-regulator",
+		.name = "da9055-regulator",
+		.id = 2,
+	},
+	{
+		.of_compatible = "dialog,da9055-regulator",
+		.name = "da9055-regulator",
+		.id = 3,
+	},
+	{
+		.of_compatible = "dialog,da9055-regulator",
+		.name = "da9055-regulator",
+		.id = 4,
+	},
+	{
+		.of_compatible = "dialog,da9055-regulator",
+		.name = "da9055-regulator",
+		.id = 5,
+	},
+	{
+		.of_compatible = "dialog,da9055-regulator",
+		.name = "da9055-regulator",
+		.id = 6,
+	},
+	{
+		.of_compatible = "dialog,da9055-regulator",
+		.name = "da9055-regulator",
+		.id = 7,
+		.resources = &da9055_ld05_6_resource,
+		.num_resources = 1,
+	},
+	{
+		.of_compatible = "dialog,da9055-regulator",
+		.name = "da9055-regulator",
+		.resources = &da9055_ld05_6_resource,
+		.num_resources = 1,
+		.id = 8,
+	},
+	{
+		.of_compatible = "dialog,da9055-onkey",
+		.name = "da9055-onkey",
+		.resources = &da9055_onkey_resource,
+		.num_resources = 1,
+	},
+	{
+		.of_compatible = "dialog,da9055-rtc",
+		.name = "da9055-rtc",
+		.resources = da9055_rtc_resource,
+		.num_resources = ARRAY_SIZE(da9055_rtc_resource),
+	},
+	{
+		.of_compatible = "dialog,da9055-hwmon",
+		.name = "da9055-hwmon",
+		.resources = &da9055_hwmon_resource,
+		.num_resources = 1,
+	},
+	{
+		.of_compatible = "dialog,da9055-watchdog",
+		.name = "da9055-watchdog",
+	},
+};
+
+static struct regmap_irq_chip da9055_regmap_irq_chip = {
+	.name = "da9055_irq",
+	.status_base = DA9055_REG_EVENT_A,
+	.mask_base = DA9055_REG_IRQ_MASK_A,
+	.ack_base = DA9055_REG_EVENT_A,
+	.num_regs = 3,
+	.irqs = da9055_irqs,
+	.num_irqs = ARRAY_SIZE(da9055_irqs),
+};
+
+int __devinit da9055_device_init(struct da9055 *da9055)
+{
+	struct da9055_pdata *pdata = da9055->dev->platform_data;
+	int ret;
+
+	if (pdata && pdata->init != NULL)
+		pdata->init(da9055);
+
+	if (!pdata || !pdata->irq_base)
+		da9055->irq_base = -1;
+	else
+		da9055->irq_base = pdata->irq_base;
+
+	ret = regmap_add_irq_chip(da9055->regmap, da9055->chip_irq,
+				  IRQF_TRIGGER_HIGH | IRQF_ONESHOT,
+				  da9055->irq_base, &da9055_regmap_irq_chip,
+				  &da9055->irq_data);
+	if (ret < 0)
+		return ret;
+
+	da9055->irq_base = regmap_irq_chip_get_base(da9055->irq_data);
+
+	ret = mfd_add_devices(da9055->dev, -1,
+			      da9055_devs, ARRAY_SIZE(da9055_devs),
+			      NULL, da9055->irq_base, NULL);
+	if (ret)
+		goto err;
+
+	return 0;
+
+err:
+	mfd_remove_devices(da9055->dev);
+	return ret;
+}
+
+void __devexit da9055_device_exit(struct da9055 *da9055)
+{
+	regmap_del_irq_chip(da9055->chip_irq, da9055->irq_data);
+	mfd_remove_devices(da9055->dev);
+}
+
+MODULE_DESCRIPTION("Core support for the DA9055 PMIC");
+MODULE_LICENSE("GPL");
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
diff --git a/drivers/mfd/da9055-i2c.c b/drivers/mfd/da9055-i2c.c
new file mode 100644
index 0000000..88f6dca
--- /dev/null
+++ b/drivers/mfd/da9055-i2c.c
@@ -0,0 +1,93 @@
+ /* I2C access for DA9055 PMICs.
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: David Dajun Chen <dchen@diasemi.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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/device.h>
+#include <linux/i2c.h>
+#include <linux/err.h>
+
+#include <linux/mfd/da9055/core.h>
+
+static int __devinit da9055_i2c_probe(struct i2c_client *i2c,
+				      const struct i2c_device_id *id)
+{
+	struct da9055 *da9055;
+	int ret;
+
+	da9055 = devm_kzalloc(&i2c->dev, sizeof(struct da9055), GFP_KERNEL);
+	if (!da9055)
+		return -ENOMEM;
+
+	da9055->regmap = devm_regmap_init_i2c(i2c, &da9055_regmap_config);
+	if (IS_ERR(da9055->regmap)) {
+		ret = PTR_ERR(da9055->regmap);
+		dev_err(&i2c->dev, "Failed to allocate register map: %d\n",
+			ret);
+		return ret;
+	}
+
+	da9055->dev = &i2c->dev;
+	da9055->chip_irq = i2c->irq;
+
+	i2c_set_clientdata(i2c, da9055);
+
+	return da9055_device_init(da9055);
+}
+
+static int __devexit da9055_i2c_remove(struct i2c_client *i2c)
+{
+	struct da9055 *da9055 = i2c_get_clientdata(i2c);
+
+	da9055_device_exit(da9055);
+
+	return 0;
+}
+
+static struct i2c_device_id da9055_i2c_id[] = {
+	{"da9055-pmic", 0},
+	{ }
+};
+
+static struct i2c_driver da9055_i2c_driver = {
+	.probe = da9055_i2c_probe,
+	.remove = __devexit_p(da9055_i2c_remove),
+	.id_table = da9055_i2c_id,
+	.driver = {
+		.name = "da9055",
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init da9055_i2c_init(void)
+{
+	int ret;
+
+	ret = i2c_add_driver(&da9055_i2c_driver);
+	if (ret != 0) {
+		pr_err("DA9055 I2C registration failed %d\n", ret);
+		return ret;
+	}
+
+	return 0;
+}
+subsys_initcall(da9055_i2c_init);
+
+static void __exit da9055_i2c_exit(void)
+{
+	i2c_del_driver(&da9055_i2c_driver);
+}
+module_exit(da9055_i2c_exit);
+
+MODULE_AUTHOR("David Dajun Chen <dchen@diasemi.com>");
+MODULE_DESCRIPTION("I2C driver for Dialog DA9055 PMIC");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/db8500-prcmu.c b/drivers/mfd/db8500-prcmu.c
index 6b67edb..00b8b0f 100644
--- a/drivers/mfd/db8500-prcmu.c
+++ b/drivers/mfd/db8500-prcmu.c
@@ -270,6 +270,8 @@
 	struct prcmu_fw_version version;
 } fw_info;
 
+static struct irq_domain *db8500_irq_domain;
+
 /*
  * This vector maps irq numbers to the bits in the bit field used in
  * communication with the PRCMU firmware.
@@ -2624,7 +2626,7 @@
 
 	spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags);
 
-	mb0_transfer.req.dbb_irqs &= ~prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE];
+	mb0_transfer.req.dbb_irqs &= ~prcmu_irq_bit[d->hwirq];
 
 	spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags);
 
@@ -2638,7 +2640,7 @@
 
 	spin_lock_irqsave(&mb0_transfer.dbb_irqs_lock, flags);
 
-	mb0_transfer.req.dbb_irqs |= prcmu_irq_bit[d->irq - IRQ_PRCMU_BASE];
+	mb0_transfer.req.dbb_irqs |= prcmu_irq_bit[d->hwirq];
 
 	spin_unlock_irqrestore(&mb0_transfer.dbb_irqs_lock, flags);
 
@@ -2678,9 +2680,37 @@
 	}
 }
 
+static int db8500_irq_map(struct irq_domain *d, unsigned int virq,
+				irq_hw_number_t hwirq)
+{
+	irq_set_chip_and_handler(virq, &prcmu_irq_chip,
+				handle_simple_irq);
+	set_irq_flags(virq, IRQF_VALID);
+
+	return 0;
+}
+
+static struct irq_domain_ops db8500_irq_ops = {
+        .map    = db8500_irq_map,
+        .xlate  = irq_domain_xlate_twocell,
+};
+
+static int db8500_irq_init(struct device_node *np)
+{
+	db8500_irq_domain = irq_domain_add_legacy(
+		np, NUM_PRCMU_WAKEUPS, IRQ_PRCMU_BASE,
+		0, &db8500_irq_ops, NULL);
+
+	if (!db8500_irq_domain) {
+		pr_err("Failed to create irqdomain\n");
+		return -ENOSYS;
+	}
+
+	return 0;
+}
+
 void __init db8500_prcmu_early_init(void)
 {
-	unsigned int i;
 	if (cpu_is_u8500v2()) {
 		void *tcpm_base = ioremap_nocache(U8500_PRCMU_TCPM_BASE, SZ_4K);
 
@@ -2725,15 +2755,6 @@
 
 	INIT_WORK(&mb0_transfer.mask_work, prcmu_mask_work);
 
-	/* Initalize irqs. */
-	for (i = 0; i < NUM_PRCMU_WAKEUPS; i++) {
-		unsigned int irq;
-
-		irq = IRQ_PRCMU_BASE + i;
-		irq_set_chip_and_handler(irq, &prcmu_irq_chip,
-					 handle_simple_irq);
-		set_irq_flags(irq, IRQF_VALID);
-	}
 	compute_armss_rate();
 }
 
@@ -3041,6 +3062,8 @@
 		goto no_irq_return;
 	}
 
+	db8500_irq_init(np);
+
 	for (i = 0; i < ARRAY_SIZE(db8500_prcmu_devs); i++) {
 		if (!strcmp(db8500_prcmu_devs[i].name, "ab8500-core")) {
 			db8500_prcmu_devs[i].platform_data = ab8500_platdata;
diff --git a/drivers/mfd/lp8788-irq.c b/drivers/mfd/lp8788-irq.c
new file mode 100644
index 0000000..c84ded5
--- /dev/null
+++ b/drivers/mfd/lp8788-irq.c
@@ -0,0 +1,198 @@
+/*
+ * TI LP8788 MFD - interrupt handler
+ *
+ * Copyright 2012 Texas Instruments
+ *
+ * Author: Milo(Woogyom) Kim <milo.kim@ti.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.
+ *
+ */
+
+#include <linux/delay.h>
+#include <linux/err.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/irqdomain.h>
+#include <linux/device.h>
+#include <linux/mfd/lp8788.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+/* register address */
+#define LP8788_INT_1			0x00
+#define LP8788_INTEN_1			0x03
+
+#define BASE_INTEN_ADDR			LP8788_INTEN_1
+#define SIZE_REG			8
+#define NUM_REGS			3
+
+/*
+ * struct lp8788_irq_data
+ * @lp               : used for accessing to lp8788 registers
+ * @irq_lock         : mutex for enabling/disabling the interrupt
+ * @domain           : IRQ domain for handling nested interrupt
+ * @enabled          : status of enabled interrupt
+ */
+struct lp8788_irq_data {
+	struct lp8788 *lp;
+	struct mutex irq_lock;
+	struct irq_domain *domain;
+	int enabled[LP8788_INT_MAX];
+};
+
+static inline u8 _irq_to_addr(enum lp8788_int_id id)
+{
+	return id / SIZE_REG;
+}
+
+static inline u8 _irq_to_enable_addr(enum lp8788_int_id id)
+{
+	return _irq_to_addr(id) + BASE_INTEN_ADDR;
+}
+
+static inline u8 _irq_to_mask(enum lp8788_int_id id)
+{
+	return 1 << (id % SIZE_REG);
+}
+
+static inline u8 _irq_to_val(enum lp8788_int_id id, int enable)
+{
+	return enable << (id % SIZE_REG);
+}
+
+static void lp8788_irq_enable(struct irq_data *data)
+{
+	struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
+	irqd->enabled[data->hwirq] = 1;
+}
+
+static void lp8788_irq_disable(struct irq_data *data)
+{
+	struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
+	irqd->enabled[data->hwirq] = 0;
+}
+
+static void lp8788_irq_bus_lock(struct irq_data *data)
+{
+	struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
+
+	mutex_lock(&irqd->irq_lock);
+}
+
+static void lp8788_irq_bus_sync_unlock(struct irq_data *data)
+{
+	struct lp8788_irq_data *irqd = irq_data_get_irq_chip_data(data);
+	enum lp8788_int_id irq = data->hwirq;
+	u8 addr, mask, val;
+
+	addr = _irq_to_enable_addr(irq);
+	mask = _irq_to_mask(irq);
+	val = _irq_to_val(irq, irqd->enabled[irq]);
+
+	lp8788_update_bits(irqd->lp, addr, mask, val);
+
+	mutex_unlock(&irqd->irq_lock);
+}
+
+static struct irq_chip lp8788_irq_chip = {
+	.name			= "lp8788",
+	.irq_enable		= lp8788_irq_enable,
+	.irq_disable		= lp8788_irq_disable,
+	.irq_bus_lock		= lp8788_irq_bus_lock,
+	.irq_bus_sync_unlock	= lp8788_irq_bus_sync_unlock,
+};
+
+static irqreturn_t lp8788_irq_handler(int irq, void *ptr)
+{
+	struct lp8788_irq_data *irqd = ptr;
+	struct lp8788 *lp = irqd->lp;
+	u8 status[NUM_REGS], addr, mask;
+	bool handled;
+	int i;
+
+	if (lp8788_read_multi_bytes(lp, LP8788_INT_1, status, NUM_REGS))
+		return IRQ_NONE;
+
+	for (i = 0 ; i < LP8788_INT_MAX ; i++) {
+		addr = _irq_to_addr(i);
+		mask = _irq_to_mask(i);
+
+		/* reporting only if the irq is enabled */
+		if (status[addr] & mask) {
+			handle_nested_irq(irq_find_mapping(irqd->domain, i));
+			handled = true;
+		}
+	}
+
+	return handled ? IRQ_HANDLED : IRQ_NONE;
+}
+
+static int lp8788_irq_map(struct irq_domain *d, unsigned int virq,
+			irq_hw_number_t hwirq)
+{
+	struct lp8788_irq_data *irqd = d->host_data;
+	struct irq_chip *chip = &lp8788_irq_chip;
+
+	irq_set_chip_data(virq, irqd);
+	irq_set_chip_and_handler(virq, chip, handle_edge_irq);
+	irq_set_nested_thread(virq, 1);
+
+#ifdef CONFIG_ARM
+	set_irq_flags(virq, IRQF_VALID);
+#else
+	irq_set_noprobe(virq);
+#endif
+
+	return 0;
+}
+
+static struct irq_domain_ops lp8788_domain_ops = {
+	.map = lp8788_irq_map,
+};
+
+int lp8788_irq_init(struct lp8788 *lp, int irq)
+{
+	struct lp8788_irq_data *irqd;
+	int ret;
+
+	if (irq <= 0) {
+		dev_warn(lp->dev, "invalid irq number: %d\n", irq);
+		return 0;
+	}
+
+	irqd = devm_kzalloc(lp->dev, sizeof(*irqd), GFP_KERNEL);
+	if (!irqd)
+		return -ENOMEM;
+
+	irqd->lp = lp;
+	irqd->domain = irq_domain_add_linear(lp->dev->of_node, LP8788_INT_MAX,
+					&lp8788_domain_ops, irqd);
+	if (!irqd->domain) {
+		dev_err(lp->dev, "failed to add irq domain err\n");
+		return -EINVAL;
+	}
+
+	lp->irqdm = irqd->domain;
+	mutex_init(&irqd->irq_lock);
+
+	ret = request_threaded_irq(irq, NULL, lp8788_irq_handler,
+				IRQF_TRIGGER_FALLING | IRQF_ONESHOT,
+				"lp8788-irq", irqd);
+	if (ret) {
+		dev_err(lp->dev, "failed to create a thread for IRQ_N\n");
+		return ret;
+	}
+
+	lp->irq = irq;
+
+	return 0;
+}
+
+void lp8788_irq_exit(struct lp8788 *lp)
+{
+	if (lp->irq)
+		free_irq(lp->irq, lp->irqdm);
+}
diff --git a/drivers/mfd/lp8788.c b/drivers/mfd/lp8788.c
new file mode 100644
index 0000000..3e94a69
--- /dev/null
+++ b/drivers/mfd/lp8788.c
@@ -0,0 +1,245 @@
+/*
+ * TI LP8788 MFD - core interface
+ *
+ * Copyright 2012 Texas Instruments
+ *
+ * Author: Milo(Woogyom) Kim <milo.kim@ti.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.
+ *
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/lp8788.h>
+#include <linux/module.h>
+#include <linux/slab.h>
+
+#define MAX_LP8788_REGISTERS		0xA2
+
+#define MFD_DEV_SIMPLE(_name)					\
+{								\
+	.name = LP8788_DEV_##_name,				\
+}
+
+#define MFD_DEV_WITH_ID(_name, _id)				\
+{								\
+	.name = LP8788_DEV_##_name,				\
+	.id = _id,						\
+}
+
+#define MFD_DEV_WITH_RESOURCE(_name, _resource, num_resource)	\
+{								\
+	.name = LP8788_DEV_##_name,				\
+	.resources = _resource,					\
+	.num_resources = num_resource,				\
+}
+
+static struct resource chg_irqs[] = {
+	/* Charger Interrupts */
+	{
+		.start = LP8788_INT_CHG_INPUT_STATE,
+		.end   = LP8788_INT_PRECHG_TIMEOUT,
+		.name  = LP8788_CHG_IRQ,
+		.flags = IORESOURCE_IRQ,
+	},
+	/* Power Routing Switch Interrupts */
+	{
+		.start = LP8788_INT_ENTER_SYS_SUPPORT,
+		.end   = LP8788_INT_EXIT_SYS_SUPPORT,
+		.name  = LP8788_PRSW_IRQ,
+		.flags = IORESOURCE_IRQ,
+	},
+	/* Battery Interrupts */
+	{
+		.start = LP8788_INT_BATT_LOW,
+		.end   = LP8788_INT_NO_BATT,
+		.name  = LP8788_BATT_IRQ,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct resource rtc_irqs[] = {
+	{
+		.start = LP8788_INT_RTC_ALARM1,
+		.end   = LP8788_INT_RTC_ALARM2,
+		.name  = LP8788_ALM_IRQ,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct mfd_cell lp8788_devs[] = {
+	/* 4 bucks */
+	MFD_DEV_WITH_ID(BUCK, 1),
+	MFD_DEV_WITH_ID(BUCK, 2),
+	MFD_DEV_WITH_ID(BUCK, 3),
+	MFD_DEV_WITH_ID(BUCK, 4),
+
+	/* 12 digital ldos */
+	MFD_DEV_WITH_ID(DLDO, 1),
+	MFD_DEV_WITH_ID(DLDO, 2),
+	MFD_DEV_WITH_ID(DLDO, 3),
+	MFD_DEV_WITH_ID(DLDO, 4),
+	MFD_DEV_WITH_ID(DLDO, 5),
+	MFD_DEV_WITH_ID(DLDO, 6),
+	MFD_DEV_WITH_ID(DLDO, 7),
+	MFD_DEV_WITH_ID(DLDO, 8),
+	MFD_DEV_WITH_ID(DLDO, 9),
+	MFD_DEV_WITH_ID(DLDO, 10),
+	MFD_DEV_WITH_ID(DLDO, 11),
+	MFD_DEV_WITH_ID(DLDO, 12),
+
+	/* 10 analog ldos */
+	MFD_DEV_WITH_ID(ALDO, 1),
+	MFD_DEV_WITH_ID(ALDO, 2),
+	MFD_DEV_WITH_ID(ALDO, 3),
+	MFD_DEV_WITH_ID(ALDO, 4),
+	MFD_DEV_WITH_ID(ALDO, 5),
+	MFD_DEV_WITH_ID(ALDO, 6),
+	MFD_DEV_WITH_ID(ALDO, 7),
+	MFD_DEV_WITH_ID(ALDO, 8),
+	MFD_DEV_WITH_ID(ALDO, 9),
+	MFD_DEV_WITH_ID(ALDO, 10),
+
+	/* ADC */
+	MFD_DEV_SIMPLE(ADC),
+
+	/* battery charger */
+	MFD_DEV_WITH_RESOURCE(CHARGER, chg_irqs, ARRAY_SIZE(chg_irqs)),
+
+	/* rtc */
+	MFD_DEV_WITH_RESOURCE(RTC, rtc_irqs, ARRAY_SIZE(rtc_irqs)),
+
+	/* backlight */
+	MFD_DEV_SIMPLE(BACKLIGHT),
+
+	/* current sink for vibrator */
+	MFD_DEV_SIMPLE(VIBRATOR),
+
+	/* current sink for keypad LED */
+	MFD_DEV_SIMPLE(KEYLED),
+};
+
+int lp8788_read_byte(struct lp8788 *lp, u8 reg, u8 *data)
+{
+	int ret;
+	unsigned int val;
+
+	ret = regmap_read(lp->regmap, reg, &val);
+	if (ret < 0) {
+		dev_err(lp->dev, "failed to read 0x%.2x\n", reg);
+		return ret;
+	}
+
+	*data = (u8)val;
+	return 0;
+}
+EXPORT_SYMBOL_GPL(lp8788_read_byte);
+
+int lp8788_read_multi_bytes(struct lp8788 *lp, u8 reg, u8 *data, size_t count)
+{
+	return regmap_bulk_read(lp->regmap, reg, data, count);
+}
+EXPORT_SYMBOL_GPL(lp8788_read_multi_bytes);
+
+int lp8788_write_byte(struct lp8788 *lp, u8 reg, u8 data)
+{
+	return regmap_write(lp->regmap, reg, data);
+}
+EXPORT_SYMBOL_GPL(lp8788_write_byte);
+
+int lp8788_update_bits(struct lp8788 *lp, u8 reg, u8 mask, u8 data)
+{
+	return regmap_update_bits(lp->regmap, reg, mask, data);
+}
+EXPORT_SYMBOL_GPL(lp8788_update_bits);
+
+static int lp8788_platform_init(struct lp8788 *lp)
+{
+	struct lp8788_platform_data *pdata = lp->pdata;
+
+	return (pdata && pdata->init_func) ? pdata->init_func(lp) : 0;
+}
+
+static const struct regmap_config lp8788_regmap_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.max_register = MAX_LP8788_REGISTERS,
+};
+
+static int lp8788_probe(struct i2c_client *cl, const struct i2c_device_id *id)
+{
+	struct lp8788 *lp;
+	struct lp8788_platform_data *pdata = cl->dev.platform_data;
+	int ret;
+
+	lp = devm_kzalloc(&cl->dev, sizeof(struct lp8788), GFP_KERNEL);
+	if (!lp)
+		return -ENOMEM;
+
+	lp->regmap = devm_regmap_init_i2c(cl, &lp8788_regmap_config);
+	if (IS_ERR(lp->regmap)) {
+		ret = PTR_ERR(lp->regmap);
+		dev_err(&cl->dev, "regmap init i2c err: %d\n", ret);
+		return ret;
+	}
+
+	lp->pdata = pdata;
+	lp->dev = &cl->dev;
+	i2c_set_clientdata(cl, lp);
+
+	ret = lp8788_platform_init(lp);
+	if (ret)
+		return ret;
+
+	ret = lp8788_irq_init(lp, cl->irq);
+	if (ret)
+		return ret;
+
+	return mfd_add_devices(lp->dev, -1, lp8788_devs,
+			       ARRAY_SIZE(lp8788_devs), NULL, 0, NULL);
+}
+
+static int __devexit lp8788_remove(struct i2c_client *cl)
+{
+	struct lp8788 *lp = i2c_get_clientdata(cl);
+
+	mfd_remove_devices(lp->dev);
+	lp8788_irq_exit(lp);
+	return 0;
+}
+
+static const struct i2c_device_id lp8788_ids[] = {
+	{"lp8788", 0},
+	{ }
+};
+MODULE_DEVICE_TABLE(i2c, lp8788_ids);
+
+static struct i2c_driver lp8788_driver = {
+	.driver = {
+		.name = "lp8788",
+		.owner = THIS_MODULE,
+	},
+	.probe = lp8788_probe,
+	.remove = __devexit_p(lp8788_remove),
+	.id_table = lp8788_ids,
+};
+
+static int __init lp8788_init(void)
+{
+	return i2c_add_driver(&lp8788_driver);
+}
+subsys_initcall(lp8788_init);
+
+static void __exit lp8788_exit(void)
+{
+	i2c_del_driver(&lp8788_driver);
+}
+module_exit(lp8788_exit);
+
+MODULE_DESCRIPTION("TI LP8788 MFD Driver");
+MODULE_AUTHOR("Milo Kim");
+MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/lpc_ich.c b/drivers/mfd/lpc_ich.c
index 092ad4b..a22544f 100644
--- a/drivers/mfd/lpc_ich.c
+++ b/drivers/mfd/lpc_ich.c
@@ -49,6 +49,7 @@
  *	document number TBD : DH89xxCC
  *	document number TBD : Panther Point
  *	document number TBD : Lynx Point
+ *	document number TBD : Lynx Point-LP
  */
 
 #define pr_fmt(fmt) KBUILD_MODNAME ": " fmt
@@ -192,6 +193,7 @@
 	LPC_DH89XXCC,	/* DH89xxCC */
 	LPC_PPT,	/* Panther Point */
 	LPC_LPT,	/* Lynx Point */
+	LPC_LPT_LP,	/* Lynx Point-LP */
 };
 
 struct lpc_ich_info lpc_chipset_info[] __devinitdata = {
@@ -468,6 +470,10 @@
 		.name = "Lynx Point",
 		.iTCO_version = 2,
 	},
+	[LPC_LPT_LP] = {
+		.name = "Lynx Point_LP",
+		.iTCO_version = 2,
+	},
 };
 
 /*
@@ -641,6 +647,14 @@
 	{ PCI_VDEVICE(INTEL, 0x8c5d), LPC_LPT},
 	{ PCI_VDEVICE(INTEL, 0x8c5e), LPC_LPT},
 	{ PCI_VDEVICE(INTEL, 0x8c5f), LPC_LPT},
+	{ PCI_VDEVICE(INTEL, 0x9c40), LPC_LPT_LP},
+	{ PCI_VDEVICE(INTEL, 0x9c41), LPC_LPT_LP},
+	{ PCI_VDEVICE(INTEL, 0x9c42), LPC_LPT_LP},
+	{ PCI_VDEVICE(INTEL, 0x9c43), LPC_LPT_LP},
+	{ PCI_VDEVICE(INTEL, 0x9c44), LPC_LPT_LP},
+	{ PCI_VDEVICE(INTEL, 0x9c45), LPC_LPT_LP},
+	{ PCI_VDEVICE(INTEL, 0x9c46), LPC_LPT_LP},
+	{ PCI_VDEVICE(INTEL, 0x9c47), LPC_LPT_LP},
 	{ 0, },			/* End of list */
 };
 MODULE_DEVICE_TABLE(pci, lpc_ich_ids);
@@ -683,6 +697,30 @@
 	cell->pdata_size = sizeof(struct lpc_ich_info);
 }
 
+/*
+ * We don't check for resource conflict globally. There are 2 or 3 independent
+ * GPIO groups and it's enough to have access to one of these to instantiate
+ * the device.
+ */
+static int __devinit lpc_ich_check_conflict_gpio(struct resource *res)
+{
+	int ret;
+	u8 use_gpio = 0;
+
+	if (resource_size(res) >= 0x50 &&
+	    !acpi_check_region(res->start + 0x40, 0x10, "LPC ICH GPIO3"))
+		use_gpio |= 1 << 2;
+
+	if (!acpi_check_region(res->start + 0x30, 0x10, "LPC ICH GPIO2"))
+		use_gpio |= 1 << 1;
+
+	ret = acpi_check_region(res->start + 0x00, 0x30, "LPC ICH GPIO1");
+	if (!ret)
+		use_gpio |= 1 << 0;
+
+	return use_gpio ? use_gpio : ret;
+}
+
 static int __devinit lpc_ich_init_gpio(struct pci_dev *dev,
 				const struct pci_device_id *id)
 {
@@ -740,12 +778,13 @@
 		break;
 	}
 
-	ret = acpi_check_resource_conflict(res);
-	if (ret) {
+	ret = lpc_ich_check_conflict_gpio(res);
+	if (ret < 0) {
 		/* this isn't necessarily fatal for the GPIO */
 		acpi_conflict = true;
 		goto gpio_done;
 	}
+	lpc_chipset_info[id->driver_data].use_gpio = ret;
 	lpc_ich_enable_gpio_space(dev);
 
 	lpc_ich_finalize_cell(&lpc_ich_cells[LPC_GPIO], id);
diff --git a/drivers/mfd/max8907.c b/drivers/mfd/max8907.c
new file mode 100644
index 0000000..17f2593
--- /dev/null
+++ b/drivers/mfd/max8907.c
@@ -0,0 +1,351 @@
+/*
+ * max8907.c - mfd driver for MAX8907
+ *
+ * Copyright (C) 2010 Gyungoh Yoo <jack.yoo@maxim-ic.com>
+ * Copyright (C) 2010-2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * 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.
+ */
+
+#include <linux/err.h>
+#include <linux/i2c.h>
+#include <linux/init.h>
+#include <linux/interrupt.h>
+#include <linux/irq.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/max8907.h>
+#include <linux/module.h>
+#include <linux/of_device.h>
+#include <linux/regmap.h>
+#include <linux/slab.h>
+
+static struct mfd_cell max8907_cells[] = {
+	{ .name = "max8907-regulator", },
+	{ .name = "max8907-rtc", },
+};
+
+static bool max8907_gen_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case MAX8907_REG_ON_OFF_IRQ1:
+	case MAX8907_REG_ON_OFF_STAT:
+	case MAX8907_REG_ON_OFF_IRQ2:
+	case MAX8907_REG_CHG_IRQ1:
+	case MAX8907_REG_CHG_IRQ2:
+	case MAX8907_REG_CHG_STAT:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool max8907_gen_is_precious_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case MAX8907_REG_ON_OFF_IRQ1:
+	case MAX8907_REG_ON_OFF_IRQ2:
+	case MAX8907_REG_CHG_IRQ1:
+	case MAX8907_REG_CHG_IRQ2:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool max8907_gen_is_writeable_reg(struct device *dev, unsigned int reg)
+{
+	return !max8907_gen_is_volatile_reg(dev, reg);
+}
+
+static const struct regmap_config max8907_regmap_gen_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.volatile_reg = max8907_gen_is_volatile_reg,
+	.precious_reg = max8907_gen_is_precious_reg,
+	.writeable_reg = max8907_gen_is_writeable_reg,
+	.max_register = MAX8907_REG_LDO20VOUT,
+	.cache_type = REGCACHE_RBTREE,
+};
+
+static bool max8907_rtc_is_volatile_reg(struct device *dev, unsigned int reg)
+{
+	if (reg <= MAX8907_REG_RTC_YEAR2)
+		return true;
+
+	switch (reg) {
+	case MAX8907_REG_RTC_STATUS:
+	case MAX8907_REG_RTC_IRQ:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool max8907_rtc_is_precious_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case MAX8907_REG_RTC_IRQ:
+		return true;
+	default:
+		return false;
+	}
+}
+
+static bool max8907_rtc_is_writeable_reg(struct device *dev, unsigned int reg)
+{
+	switch (reg) {
+	case MAX8907_REG_RTC_STATUS:
+	case MAX8907_REG_RTC_IRQ:
+		return false;
+	default:
+		return true;
+	}
+}
+
+static const struct regmap_config max8907_regmap_rtc_config = {
+	.reg_bits = 8,
+	.val_bits = 8,
+	.volatile_reg = max8907_rtc_is_volatile_reg,
+	.precious_reg = max8907_rtc_is_precious_reg,
+	.writeable_reg = max8907_rtc_is_writeable_reg,
+	.max_register = MAX8907_REG_MPL_CNTL,
+	.cache_type = REGCACHE_RBTREE,
+};
+
+static const struct regmap_irq max8907_chg_irqs[] = {
+	{ .reg_offset = 0, .mask = 1 << 0, },
+	{ .reg_offset = 0, .mask = 1 << 1, },
+	{ .reg_offset = 0, .mask = 1 << 2, },
+	{ .reg_offset = 1, .mask = 1 << 0, },
+	{ .reg_offset = 1, .mask = 1 << 1, },
+	{ .reg_offset = 1, .mask = 1 << 2, },
+	{ .reg_offset = 1, .mask = 1 << 3, },
+	{ .reg_offset = 1, .mask = 1 << 4, },
+	{ .reg_offset = 1, .mask = 1 << 5, },
+	{ .reg_offset = 1, .mask = 1 << 6, },
+	{ .reg_offset = 1, .mask = 1 << 7, },
+};
+
+static const struct regmap_irq_chip max8907_chg_irq_chip = {
+	.name = "max8907 chg",
+	.status_base = MAX8907_REG_CHG_IRQ1,
+	.mask_base = MAX8907_REG_CHG_IRQ1_MASK,
+	.wake_base = MAX8907_REG_CHG_IRQ1_MASK,
+	.irq_reg_stride = MAX8907_REG_CHG_IRQ2 - MAX8907_REG_CHG_IRQ1,
+	.num_regs = 2,
+	.irqs = max8907_chg_irqs,
+	.num_irqs = ARRAY_SIZE(max8907_chg_irqs),
+};
+
+static const struct regmap_irq max8907_on_off_irqs[] = {
+	{ .reg_offset = 0, .mask = 1 << 0, },
+	{ .reg_offset = 0, .mask = 1 << 1, },
+	{ .reg_offset = 0, .mask = 1 << 2, },
+	{ .reg_offset = 0, .mask = 1 << 3, },
+	{ .reg_offset = 0, .mask = 1 << 4, },
+	{ .reg_offset = 0, .mask = 1 << 5, },
+	{ .reg_offset = 0, .mask = 1 << 6, },
+	{ .reg_offset = 0, .mask = 1 << 7, },
+	{ .reg_offset = 1, .mask = 1 << 0, },
+	{ .reg_offset = 1, .mask = 1 << 1, },
+};
+
+static const struct regmap_irq_chip max8907_on_off_irq_chip = {
+	.name = "max8907 on_off",
+	.status_base = MAX8907_REG_ON_OFF_IRQ1,
+	.mask_base = MAX8907_REG_ON_OFF_IRQ1_MASK,
+	.irq_reg_stride = MAX8907_REG_ON_OFF_IRQ2 - MAX8907_REG_ON_OFF_IRQ1,
+	.num_regs = 2,
+	.irqs = max8907_on_off_irqs,
+	.num_irqs = ARRAY_SIZE(max8907_on_off_irqs),
+};
+
+static const struct regmap_irq max8907_rtc_irqs[] = {
+	{ .reg_offset = 0, .mask = 1 << 2, },
+	{ .reg_offset = 0, .mask = 1 << 3, },
+};
+
+static const struct regmap_irq_chip max8907_rtc_irq_chip = {
+	.name = "max8907 rtc",
+	.status_base = MAX8907_REG_RTC_IRQ,
+	.mask_base = MAX8907_REG_RTC_IRQ_MASK,
+	.num_regs = 1,
+	.irqs = max8907_rtc_irqs,
+	.num_irqs = ARRAY_SIZE(max8907_rtc_irqs),
+};
+
+static struct max8907 *max8907_pm_off;
+static void max8907_power_off(void)
+{
+	regmap_update_bits(max8907_pm_off->regmap_gen, MAX8907_REG_RESET_CNFG,
+			MAX8907_MASK_POWER_OFF, MAX8907_MASK_POWER_OFF);
+}
+
+static __devinit int max8907_i2c_probe(struct i2c_client *i2c,
+				       const struct i2c_device_id *id)
+{
+	struct max8907 *max8907;
+	int ret;
+	struct max8907_platform_data *pdata = dev_get_platdata(&i2c->dev);
+	bool pm_off = false;
+
+	if (pdata)
+		pm_off = pdata->pm_off;
+	else if (i2c->dev.of_node)
+		pm_off = of_property_read_bool(i2c->dev.of_node,
+					"maxim,system-power-controller");
+
+	max8907 = devm_kzalloc(&i2c->dev, sizeof(struct max8907), GFP_KERNEL);
+	if (!max8907) {
+		ret = -ENOMEM;
+		goto err_alloc_drvdata;
+	}
+
+	max8907->dev = &i2c->dev;
+	dev_set_drvdata(max8907->dev, max8907);
+
+	max8907->i2c_gen = i2c;
+	i2c_set_clientdata(i2c, max8907);
+	max8907->regmap_gen = devm_regmap_init_i2c(i2c,
+						&max8907_regmap_gen_config);
+	if (IS_ERR(max8907->regmap_gen)) {
+		ret = PTR_ERR(max8907->regmap_gen);
+		dev_err(&i2c->dev, "gen regmap init failed: %d\n", ret);
+		goto err_regmap_gen;
+	}
+
+	max8907->i2c_rtc = i2c_new_dummy(i2c->adapter, MAX8907_RTC_I2C_ADDR);
+	if (!max8907->i2c_rtc) {
+		ret = -ENOMEM;
+		goto err_dummy_rtc;
+	}
+	i2c_set_clientdata(max8907->i2c_rtc, max8907);
+	max8907->regmap_rtc = devm_regmap_init_i2c(max8907->i2c_rtc,
+						&max8907_regmap_rtc_config);
+	if (IS_ERR(max8907->regmap_rtc)) {
+		ret = PTR_ERR(max8907->regmap_rtc);
+		dev_err(&i2c->dev, "rtc regmap init failed: %d\n", ret);
+		goto err_regmap_rtc;
+	}
+
+	irq_set_status_flags(max8907->i2c_gen->irq, IRQ_NOAUTOEN);
+
+	ret = regmap_add_irq_chip(max8907->regmap_gen, max8907->i2c_gen->irq,
+				  IRQF_ONESHOT | IRQF_SHARED, -1,
+				  &max8907_chg_irq_chip,
+				  &max8907->irqc_chg);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "failed to add chg irq chip: %d\n", ret);
+		goto err_irqc_chg;
+	}
+	ret = regmap_add_irq_chip(max8907->regmap_gen, max8907->i2c_gen->irq,
+				  IRQF_ONESHOT | IRQF_SHARED, -1,
+				  &max8907_on_off_irq_chip,
+				  &max8907->irqc_on_off);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "failed to add on off irq chip: %d\n", ret);
+		goto err_irqc_on_off;
+	}
+	ret = regmap_add_irq_chip(max8907->regmap_rtc, max8907->i2c_gen->irq,
+				  IRQF_ONESHOT | IRQF_SHARED, -1,
+				  &max8907_rtc_irq_chip,
+				  &max8907->irqc_rtc);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "failed to add rtc irq chip: %d\n", ret);
+		goto err_irqc_rtc;
+	}
+
+	enable_irq(max8907->i2c_gen->irq);
+
+	ret = mfd_add_devices(max8907->dev, -1, max8907_cells,
+			      ARRAY_SIZE(max8907_cells), NULL, 0, NULL);
+	if (ret != 0) {
+		dev_err(&i2c->dev, "failed to add MFD devices %d\n", ret);
+		goto err_add_devices;
+	}
+
+	if (pm_off && !pm_power_off) {
+		max8907_pm_off = max8907;
+		pm_power_off = max8907_power_off;
+	}
+
+	return 0;
+
+err_add_devices:
+	regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_rtc);
+err_irqc_rtc:
+	regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_on_off);
+err_irqc_on_off:
+	regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_chg);
+err_irqc_chg:
+err_regmap_rtc:
+	i2c_unregister_device(max8907->i2c_rtc);
+err_dummy_rtc:
+err_regmap_gen:
+err_alloc_drvdata:
+	return ret;
+}
+
+static __devexit int max8907_i2c_remove(struct i2c_client *i2c)
+{
+	struct max8907 *max8907 = i2c_get_clientdata(i2c);
+
+	mfd_remove_devices(max8907->dev);
+
+	regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_rtc);
+	regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_on_off);
+	regmap_del_irq_chip(max8907->i2c_gen->irq, max8907->irqc_chg);
+
+	i2c_unregister_device(max8907->i2c_rtc);
+
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static struct of_device_id max8907_of_match[] = {
+	{ .compatible = "maxim,max8907" },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, max8907_of_match);
+#endif
+
+static const struct i2c_device_id max8907_i2c_id[] = {
+	{"max8907", 0},
+	{}
+};
+MODULE_DEVICE_TABLE(i2c, max8907_i2c_id);
+
+static struct i2c_driver max8907_i2c_driver = {
+	.driver = {
+		.name = "max8907",
+		.owner = THIS_MODULE,
+		.of_match_table = of_match_ptr(max8907_of_match),
+	},
+	.probe = max8907_i2c_probe,
+	.remove = max8907_i2c_remove,
+	.id_table = max8907_i2c_id,
+};
+
+static int __init max8907_i2c_init(void)
+{
+	int ret = -ENODEV;
+
+	ret = i2c_add_driver(&max8907_i2c_driver);
+	if (ret != 0)
+		pr_err("Failed to register I2C driver: %d\n", ret);
+
+	return ret;
+}
+subsys_initcall(max8907_i2c_init);
+
+static void __exit max8907_i2c_exit(void)
+{
+	i2c_del_driver(&max8907_i2c_driver);
+}
+module_exit(max8907_i2c_exit);
+
+MODULE_DESCRIPTION("MAX8907 multi-function core driver");
+MODULE_AUTHOR("Gyungoh Yoo <jack.yoo@maxim-ic.com>");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/max8925-core.c b/drivers/mfd/max8925-core.c
index ee53757..9f54c04 100644
--- a/drivers/mfd/max8925-core.c
+++ b/drivers/mfd/max8925-core.c
@@ -15,23 +15,20 @@
 #include <linux/irq.h>
 #include <linux/interrupt.h>
 #include <linux/platform_device.h>
+#include <linux/regulator/machine.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/max8925.h>
 
-static struct resource backlight_resources[] = {
-	{
-		.name	= "max8925-backlight",
-		.start	= MAX8925_WLED_MODE_CNTL,
-		.end	= MAX8925_WLED_CNTL,
-		.flags	= IORESOURCE_IO,
-	},
+static struct resource bk_resources[] __devinitdata = {
+	{ 0x84, 0x84, "mode control", IORESOURCE_REG, },
+	{ 0x85, 0x85, "control",      IORESOURCE_REG, },
 };
 
-static struct mfd_cell backlight_devs[] = {
+static struct mfd_cell bk_devs[] __devinitdata = {
 	{
 		.name		= "max8925-backlight",
-		.num_resources	= 1,
-		.resources	= &backlight_resources[0],
+		.num_resources	= ARRAY_SIZE(bk_resources),
+		.resources	= &bk_resources[0],
 		.id		= -1,
 	},
 };
@@ -41,7 +38,7 @@
 		.name	= "max8925-tsc",
 		.start	= MAX8925_TSC_IRQ,
 		.end	= MAX8925_ADC_RES_END,
-		.flags	= IORESOURCE_IO,
+		.flags	= IORESOURCE_REG,
 	},
 };
 
@@ -59,7 +56,7 @@
 		.name	= "max8925-power",
 		.start	= MAX8925_CHG_IRQ1,
 		.end	= MAX8925_CHG_IRQ1_MASK,
-		.flags	= IORESOURCE_IO,
+		.flags	= IORESOURCE_REG,
 	},
 };
 
@@ -113,71 +110,215 @@
 	},
 };
 
-#define MAX8925_REG_RESOURCE(_start, _end)	\
-{						\
-	.start	= MAX8925_##_start,		\
-	.end	= MAX8925_##_end,		\
-	.flags	= IORESOURCE_IO,		\
-}
-
-static struct resource regulator_resources[] = {
-	MAX8925_REG_RESOURCE(SDCTL1, SDCTL1),
-	MAX8925_REG_RESOURCE(SDCTL2, SDCTL2),
-	MAX8925_REG_RESOURCE(SDCTL3, SDCTL3),
-	MAX8925_REG_RESOURCE(LDOCTL1, LDOCTL1),
-	MAX8925_REG_RESOURCE(LDOCTL2, LDOCTL2),
-	MAX8925_REG_RESOURCE(LDOCTL3, LDOCTL3),
-	MAX8925_REG_RESOURCE(LDOCTL4, LDOCTL4),
-	MAX8925_REG_RESOURCE(LDOCTL5, LDOCTL5),
-	MAX8925_REG_RESOURCE(LDOCTL6, LDOCTL6),
-	MAX8925_REG_RESOURCE(LDOCTL7, LDOCTL7),
-	MAX8925_REG_RESOURCE(LDOCTL8, LDOCTL8),
-	MAX8925_REG_RESOURCE(LDOCTL9, LDOCTL9),
-	MAX8925_REG_RESOURCE(LDOCTL10, LDOCTL10),
-	MAX8925_REG_RESOURCE(LDOCTL11, LDOCTL11),
-	MAX8925_REG_RESOURCE(LDOCTL12, LDOCTL12),
-	MAX8925_REG_RESOURCE(LDOCTL13, LDOCTL13),
-	MAX8925_REG_RESOURCE(LDOCTL14, LDOCTL14),
-	MAX8925_REG_RESOURCE(LDOCTL15, LDOCTL15),
-	MAX8925_REG_RESOURCE(LDOCTL16, LDOCTL16),
-	MAX8925_REG_RESOURCE(LDOCTL17, LDOCTL17),
-	MAX8925_REG_RESOURCE(LDOCTL18, LDOCTL18),
-	MAX8925_REG_RESOURCE(LDOCTL19, LDOCTL19),
-	MAX8925_REG_RESOURCE(LDOCTL20, LDOCTL20),
+static struct resource sd1_resources[] __devinitdata = {
+	{0x06, 0x06, "sdv", IORESOURCE_REG, },
 };
 
-#define MAX8925_REG_DEVS(_id)						\
-{									\
-	.name		= "max8925-regulator",				\
-	.num_resources	= 1,						\
-	.resources	= &regulator_resources[MAX8925_ID_##_id],	\
-	.id		= MAX8925_ID_##_id,				\
-}
+static struct resource sd2_resources[] __devinitdata = {
+	{0x09, 0x09, "sdv", IORESOURCE_REG, },
+};
 
-static struct mfd_cell regulator_devs[] = {
-	MAX8925_REG_DEVS(SD1),
-	MAX8925_REG_DEVS(SD2),
-	MAX8925_REG_DEVS(SD3),
-	MAX8925_REG_DEVS(LDO1),
-	MAX8925_REG_DEVS(LDO2),
-	MAX8925_REG_DEVS(LDO3),
-	MAX8925_REG_DEVS(LDO4),
-	MAX8925_REG_DEVS(LDO5),
-	MAX8925_REG_DEVS(LDO6),
-	MAX8925_REG_DEVS(LDO7),
-	MAX8925_REG_DEVS(LDO8),
-	MAX8925_REG_DEVS(LDO9),
-	MAX8925_REG_DEVS(LDO10),
-	MAX8925_REG_DEVS(LDO11),
-	MAX8925_REG_DEVS(LDO12),
-	MAX8925_REG_DEVS(LDO13),
-	MAX8925_REG_DEVS(LDO14),
-	MAX8925_REG_DEVS(LDO15),
-	MAX8925_REG_DEVS(LDO16),
-	MAX8925_REG_DEVS(LDO17),
-	MAX8925_REG_DEVS(LDO18),
-	MAX8925_REG_DEVS(LDO19),
-	MAX8925_REG_DEVS(LDO20),
+static struct resource sd3_resources[] __devinitdata = {
+	{0x0c, 0x0c, "sdv", IORESOURCE_REG, },
+};
+
+static struct resource ldo1_resources[] __devinitdata = {
+	{0x1a, 0x1a, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo2_resources[] __devinitdata = {
+	{0x1e, 0x1e, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo3_resources[] __devinitdata = {
+	{0x22, 0x22, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo4_resources[] __devinitdata = {
+	{0x26, 0x26, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo5_resources[] __devinitdata = {
+	{0x2a, 0x2a, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo6_resources[] __devinitdata = {
+	{0x2e, 0x2e, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo7_resources[] __devinitdata = {
+	{0x32, 0x32, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo8_resources[] __devinitdata = {
+	{0x36, 0x36, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo9_resources[] __devinitdata = {
+	{0x3a, 0x3a, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo10_resources[] __devinitdata = {
+	{0x3e, 0x3e, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo11_resources[] __devinitdata = {
+	{0x42, 0x42, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo12_resources[] __devinitdata = {
+	{0x46, 0x46, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo13_resources[] __devinitdata = {
+	{0x4a, 0x4a, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo14_resources[] __devinitdata = {
+	{0x4e, 0x4e, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo15_resources[] __devinitdata = {
+	{0x52, 0x52, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo16_resources[] __devinitdata = {
+	{0x12, 0x12, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo17_resources[] __devinitdata = {
+	{0x16, 0x16, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo18_resources[] __devinitdata = {
+	{0x74, 0x74, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo19_resources[] __devinitdata = {
+	{0x5e, 0x5e, "ldov", IORESOURCE_REG, },
+};
+
+static struct resource ldo20_resources[] __devinitdata = {
+	{0x9e, 0x9e, "ldov", IORESOURCE_REG, },
+};
+
+static struct mfd_cell reg_devs[] __devinitdata = {
+	{
+		.name = "max8925-regulator",
+		.id = 0,
+		.num_resources = ARRAY_SIZE(sd1_resources),
+		.resources = sd1_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 1,
+		.num_resources = ARRAY_SIZE(sd2_resources),
+		.resources = sd2_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 2,
+		.num_resources = ARRAY_SIZE(sd3_resources),
+		.resources = sd3_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 3,
+		.num_resources = ARRAY_SIZE(ldo1_resources),
+		.resources = ldo1_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 4,
+		.num_resources = ARRAY_SIZE(ldo2_resources),
+		.resources = ldo2_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 5,
+		.num_resources = ARRAY_SIZE(ldo3_resources),
+		.resources = ldo3_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 6,
+		.num_resources = ARRAY_SIZE(ldo4_resources),
+		.resources = ldo4_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 7,
+		.num_resources = ARRAY_SIZE(ldo5_resources),
+		.resources = ldo5_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 8,
+		.num_resources = ARRAY_SIZE(ldo6_resources),
+		.resources = ldo6_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 9,
+		.num_resources = ARRAY_SIZE(ldo7_resources),
+		.resources = ldo7_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 10,
+		.num_resources = ARRAY_SIZE(ldo8_resources),
+		.resources = ldo8_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 11,
+		.num_resources = ARRAY_SIZE(ldo9_resources),
+		.resources = ldo9_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 12,
+		.num_resources = ARRAY_SIZE(ldo10_resources),
+		.resources = ldo10_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 13,
+		.num_resources = ARRAY_SIZE(ldo11_resources),
+		.resources = ldo11_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 14,
+		.num_resources = ARRAY_SIZE(ldo12_resources),
+		.resources = ldo12_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 15,
+		.num_resources = ARRAY_SIZE(ldo13_resources),
+		.resources = ldo13_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 16,
+		.num_resources = ARRAY_SIZE(ldo14_resources),
+		.resources = ldo14_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 17,
+		.num_resources = ARRAY_SIZE(ldo15_resources),
+		.resources = ldo15_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 18,
+		.num_resources = ARRAY_SIZE(ldo16_resources),
+		.resources = ldo16_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 19,
+		.num_resources = ARRAY_SIZE(ldo17_resources),
+		.resources = ldo17_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 20,
+		.num_resources = ARRAY_SIZE(ldo18_resources),
+		.resources = ldo18_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 21,
+		.num_resources = ARRAY_SIZE(ldo19_resources),
+		.resources = ldo19_resources,
+	}, {
+		.name = "max8925-regulator",
+		.id = 22,
+		.num_resources = ARRAY_SIZE(ldo20_resources),
+		.resources = ldo20_resources,
+	},
 };
 
 enum {
@@ -547,7 +688,7 @@
 		goto tsc_irq;
 	}
 
-	ret = request_threaded_irq(irq, NULL, max8925_irq, flags,
+	ret = request_threaded_irq(irq, NULL, max8925_irq, flags | IRQF_ONESHOT,
 				   "max8925", chip);
 	if (ret) {
 		dev_err(chip->dev, "Failed to request core IRQ: %d\n", ret);
@@ -565,7 +706,7 @@
 	chip->tsc_irq = pdata->tsc_irq;
 
 	ret = request_threaded_irq(chip->tsc_irq, NULL, max8925_tsc_irq,
-				   flags, "max8925-tsc", chip);
+				   flags | IRQF_ONESHOT, "max8925-tsc", chip);
 	if (ret) {
 		dev_err(chip->dev, "Failed to request TSC IRQ: %d\n", ret);
 		chip->tsc_irq = 0;
@@ -573,6 +714,113 @@
 	return 0;
 }
 
+static void __devinit init_regulator(struct max8925_chip *chip,
+				     struct max8925_platform_data *pdata)
+{
+	int ret;
+
+	if (!pdata)
+		return;
+	if (pdata->sd1) {
+		reg_devs[0].platform_data = pdata->sd1;
+		reg_devs[0].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->sd2) {
+		reg_devs[1].platform_data = pdata->sd2;
+		reg_devs[1].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->sd3) {
+		reg_devs[2].platform_data = pdata->sd3;
+		reg_devs[2].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo1) {
+		reg_devs[3].platform_data = pdata->ldo1;
+		reg_devs[3].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo2) {
+		reg_devs[4].platform_data = pdata->ldo2;
+		reg_devs[4].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo3) {
+		reg_devs[5].platform_data = pdata->ldo3;
+		reg_devs[5].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo4) {
+		reg_devs[6].platform_data = pdata->ldo4;
+		reg_devs[6].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo5) {
+		reg_devs[7].platform_data = pdata->ldo5;
+		reg_devs[7].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo6) {
+		reg_devs[8].platform_data = pdata->ldo6;
+		reg_devs[8].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo7) {
+		reg_devs[9].platform_data = pdata->ldo7;
+		reg_devs[9].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo8) {
+		reg_devs[10].platform_data = pdata->ldo8;
+		reg_devs[10].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo9) {
+		reg_devs[11].platform_data = pdata->ldo9;
+		reg_devs[11].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo10) {
+		reg_devs[12].platform_data = pdata->ldo10;
+		reg_devs[12].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo11) {
+		reg_devs[13].platform_data = pdata->ldo11;
+		reg_devs[13].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo12) {
+		reg_devs[14].platform_data = pdata->ldo12;
+		reg_devs[14].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo13) {
+		reg_devs[15].platform_data = pdata->ldo13;
+		reg_devs[15].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo14) {
+		reg_devs[16].platform_data = pdata->ldo14;
+		reg_devs[16].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo15) {
+		reg_devs[17].platform_data = pdata->ldo15;
+		reg_devs[17].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo16) {
+		reg_devs[18].platform_data = pdata->ldo16;
+		reg_devs[18].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo17) {
+		reg_devs[19].platform_data = pdata->ldo17;
+		reg_devs[19].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo18) {
+		reg_devs[20].platform_data = pdata->ldo18;
+		reg_devs[20].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo19) {
+		reg_devs[21].platform_data = pdata->ldo19;
+		reg_devs[21].pdata_size = sizeof(struct regulator_init_data);
+	}
+	if (pdata->ldo20) {
+		reg_devs[22].platform_data = pdata->ldo20;
+		reg_devs[22].pdata_size = sizeof(struct regulator_init_data);
+	}
+	ret = mfd_add_devices(chip->dev, 0, reg_devs, ARRAY_SIZE(reg_devs),
+			      NULL, 0, NULL);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to add regulator subdev\n");
+		return;
+	}
+}
+
 int __devinit max8925_device_init(struct max8925_chip *chip,
 				  struct max8925_platform_data *pdata)
 {
@@ -612,24 +860,17 @@
 		goto out_dev;
 	}
 
-	if (pdata) {
-		ret = mfd_add_devices(chip->dev, 0, &regulator_devs[0],
-				      ARRAY_SIZE(regulator_devs),
-				      &regulator_resources[0], 0, NULL);
-		if (ret < 0) {
-			dev_err(chip->dev, "Failed to add regulator subdev\n");
-			goto out_dev;
-		}
-	}
+	init_regulator(chip, pdata);
 
 	if (pdata && pdata->backlight) {
-		ret = mfd_add_devices(chip->dev, 0, &backlight_devs[0],
-				      ARRAY_SIZE(backlight_devs),
-				      &backlight_resources[0], 0, NULL);
-		if (ret < 0) {
-			dev_err(chip->dev, "Failed to add backlight subdev\n");
-			goto out_dev;
-		}
+		bk_devs[0].platform_data = &pdata->backlight;
+		bk_devs[0].pdata_size = sizeof(struct max8925_backlight_pdata);
+	}
+	ret = mfd_add_devices(chip->dev, 0, bk_devs, ARRAY_SIZE(bk_devs),
+			      NULL, 0, NULL);
+	if (ret < 0) {
+		dev_err(chip->dev, "Failed to add backlight subdev\n");
+		goto out_dev;
 	}
 
 	if (pdata && pdata->power) {
diff --git a/drivers/mfd/mc13xxx-core.c b/drivers/mfd/mc13xxx-core.c
index 1ec79b5..1aba023 100644
--- a/drivers/mfd/mc13xxx-core.c
+++ b/drivers/mfd/mc13xxx-core.c
@@ -676,7 +676,6 @@
 err_mask:
 err_revision:
 		mc13xxx_unlock(mc13xxx);
-		kfree(mc13xxx);
 		return ret;
 	}
 
diff --git a/drivers/mfd/omap-usb-host.c b/drivers/mfd/omap-usb-host.c
index 41088ec..23cec57 100644
--- a/drivers/mfd/omap-usb-host.c
+++ b/drivers/mfd/omap-usb-host.c
@@ -21,7 +21,6 @@
 #include <linux/types.h>
 #include <linux/slab.h>
 #include <linux/delay.h>
-#include <linux/platform_device.h>
 #include <linux/clk.h>
 #include <linux/dma-mapping.h>
 #include <linux/spinlock.h>
@@ -36,63 +35,6 @@
 
 /* OMAP USBHOST Register addresses  */
 
-/* TLL Register Set */
-#define	OMAP_USBTLL_REVISION				(0x00)
-#define	OMAP_USBTLL_SYSCONFIG				(0x10)
-#define	OMAP_USBTLL_SYSCONFIG_CACTIVITY			(1 << 8)
-#define	OMAP_USBTLL_SYSCONFIG_SIDLEMODE			(1 << 3)
-#define	OMAP_USBTLL_SYSCONFIG_ENAWAKEUP			(1 << 2)
-#define	OMAP_USBTLL_SYSCONFIG_SOFTRESET			(1 << 1)
-#define	OMAP_USBTLL_SYSCONFIG_AUTOIDLE			(1 << 0)
-
-#define	OMAP_USBTLL_SYSSTATUS				(0x14)
-#define	OMAP_USBTLL_SYSSTATUS_RESETDONE			(1 << 0)
-
-#define	OMAP_USBTLL_IRQSTATUS				(0x18)
-#define	OMAP_USBTLL_IRQENABLE				(0x1C)
-
-#define	OMAP_TLL_SHARED_CONF				(0x30)
-#define	OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN		(1 << 6)
-#define	OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN		(1 << 5)
-#define	OMAP_TLL_SHARED_CONF_USB_DIVRATION		(1 << 2)
-#define	OMAP_TLL_SHARED_CONF_FCLK_REQ			(1 << 1)
-#define	OMAP_TLL_SHARED_CONF_FCLK_IS_ON			(1 << 0)
-
-#define	OMAP_TLL_CHANNEL_CONF(num)			(0x040 + 0x004 * num)
-#define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT		24
-#define	OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF		(1 << 11)
-#define	OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE		(1 << 10)
-#define	OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE		(1 << 9)
-#define	OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE		(1 << 8)
-#define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS		(1 << 1)
-#define	OMAP_TLL_CHANNEL_CONF_CHANEN			(1 << 0)
-
-#define OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0		0x0
-#define OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM		0x1
-#define OMAP_TLL_FSLSMODE_3PIN_PHY			0x2
-#define OMAP_TLL_FSLSMODE_4PIN_PHY			0x3
-#define OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0		0x4
-#define OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM		0x5
-#define OMAP_TLL_FSLSMODE_3PIN_TLL			0x6
-#define OMAP_TLL_FSLSMODE_4PIN_TLL			0x7
-#define OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0		0xA
-#define OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM		0xB
-
-#define	OMAP_TLL_ULPI_FUNCTION_CTRL(num)		(0x804 + 0x100 * num)
-#define	OMAP_TLL_ULPI_INTERFACE_CTRL(num)		(0x807 + 0x100 * num)
-#define	OMAP_TLL_ULPI_OTG_CTRL(num)			(0x80A + 0x100 * num)
-#define	OMAP_TLL_ULPI_INT_EN_RISE(num)			(0x80D + 0x100 * num)
-#define	OMAP_TLL_ULPI_INT_EN_FALL(num)			(0x810 + 0x100 * num)
-#define	OMAP_TLL_ULPI_INT_STATUS(num)			(0x813 + 0x100 * num)
-#define	OMAP_TLL_ULPI_INT_LATCH(num)			(0x814 + 0x100 * num)
-#define	OMAP_TLL_ULPI_DEBUG(num)			(0x815 + 0x100 * num)
-#define	OMAP_TLL_ULPI_SCRATCH_REGISTER(num)		(0x816 + 0x100 * num)
-
-#define OMAP_TLL_CHANNEL_COUNT				3
-#define OMAP_TLL_CHANNEL_1_EN_MASK			(1 << 0)
-#define OMAP_TLL_CHANNEL_2_EN_MASK			(1 << 1)
-#define OMAP_TLL_CHANNEL_3_EN_MASK			(1 << 2)
-
 /* UHH Register Set */
 #define	OMAP_UHH_REVISION				(0x00)
 #define	OMAP_UHH_SYSCONFIG				(0x10)
@@ -132,8 +74,6 @@
 #define OMAP4_P2_MODE_TLL				(1 << 18)
 #define OMAP4_P2_MODE_HSIC				(3 << 18)
 
-#define OMAP_REV2_TLL_CHANNEL_COUNT			2
-
 #define	OMAP_UHH_DEBUG_CSR				(0x44)
 
 /* Values of UHH_REVISION - Note: these are not given in the TRM */
@@ -153,15 +93,12 @@
 	struct clk			*xclk60mhsp2_ck;
 	struct clk			*utmi_p1_fck;
 	struct clk			*usbhost_p1_fck;
-	struct clk			*usbtll_p1_fck;
 	struct clk			*utmi_p2_fck;
 	struct clk			*usbhost_p2_fck;
-	struct clk			*usbtll_p2_fck;
 	struct clk			*init_60m_fclk;
 	struct clk			*ehci_logic_fck;
 
 	void __iomem			*uhh_base;
-	void __iomem			*tll_base;
 
 	struct usbhs_omap_platform_data	platdata;
 
@@ -336,93 +273,6 @@
 	}
 }
 
-/*
- * convert the port-mode enum to a value we can use in the FSLSMODE
- * field of USBTLL_CHANNEL_CONF
- */
-static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode)
-{
-	switch (mode) {
-	case OMAP_USBHS_PORT_MODE_UNUSED:
-	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
-		return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0;
-
-	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
-		return OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM;
-
-	case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
-		return OMAP_TLL_FSLSMODE_3PIN_PHY;
-
-	case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
-		return OMAP_TLL_FSLSMODE_4PIN_PHY;
-
-	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
-		return OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0;
-
-	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
-		return OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM;
-
-	case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
-		return OMAP_TLL_FSLSMODE_3PIN_TLL;
-
-	case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
-		return OMAP_TLL_FSLSMODE_4PIN_TLL;
-
-	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
-		return OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0;
-
-	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
-		return OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM;
-	default:
-		pr_warning("Invalid port mode, using default\n");
-		return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0;
-	}
-}
-
-static void usbhs_omap_tll_init(struct device *dev, u8 tll_channel_count)
-{
-	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
-	struct usbhs_omap_platform_data	*pdata = dev->platform_data;
-	unsigned			reg;
-	int				i;
-
-	/* Program Common TLL register */
-	reg = usbhs_read(omap->tll_base, OMAP_TLL_SHARED_CONF);
-	reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON
-		| OMAP_TLL_SHARED_CONF_USB_DIVRATION);
-	reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN;
-	reg &= ~OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN;
-
-	usbhs_write(omap->tll_base, OMAP_TLL_SHARED_CONF, reg);
-
-	/* Enable channels now */
-	for (i = 0; i < tll_channel_count; i++) {
-		reg = usbhs_read(omap->tll_base,
-				OMAP_TLL_CHANNEL_CONF(i));
-
-		if (is_ohci_port(pdata->port_mode[i])) {
-			reg |= ohci_omap3_fslsmode(pdata->port_mode[i])
-				<< OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT;
-			reg |= OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS;
-		} else if (pdata->port_mode[i] == OMAP_EHCI_PORT_MODE_TLL) {
-
-			/* Disable AutoIdle, BitStuffing and use SDR Mode */
-			reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE
-				| OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF
-				| OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE);
-
-		} else
-			continue;
-
-		reg |= OMAP_TLL_CHANNEL_CONF_CHANEN;
-		usbhs_write(omap->tll_base,
-				OMAP_TLL_CHANNEL_CONF(i), reg);
-
-		usbhs_writeb(omap->tll_base,
-				OMAP_TLL_ULPI_SCRATCH_REGISTER(i), 0xbe);
-	}
-}
-
 static int usbhs_runtime_resume(struct device *dev)
 {
 	struct usbhs_hcd_omap		*omap = dev_get_drvdata(dev);
@@ -436,19 +286,17 @@
 		return  -ENODEV;
 	}
 
+	omap_tll_enable();
 	spin_lock_irqsave(&omap->lock, flags);
 
 	if (omap->ehci_logic_fck && !IS_ERR(omap->ehci_logic_fck))
 		clk_enable(omap->ehci_logic_fck);
 
-	if (is_ehci_tll_mode(pdata->port_mode[0])) {
+	if (is_ehci_tll_mode(pdata->port_mode[0]))
 		clk_enable(omap->usbhost_p1_fck);
-		clk_enable(omap->usbtll_p1_fck);
-	}
-	if (is_ehci_tll_mode(pdata->port_mode[1])) {
+	if (is_ehci_tll_mode(pdata->port_mode[1]))
 		clk_enable(omap->usbhost_p2_fck);
-		clk_enable(omap->usbtll_p2_fck);
-	}
+
 	clk_enable(omap->utmi_p1_fck);
 	clk_enable(omap->utmi_p2_fck);
 
@@ -472,14 +320,11 @@
 
 	spin_lock_irqsave(&omap->lock, flags);
 
-	if (is_ehci_tll_mode(pdata->port_mode[0])) {
+	if (is_ehci_tll_mode(pdata->port_mode[0]))
 		clk_disable(omap->usbhost_p1_fck);
-		clk_disable(omap->usbtll_p1_fck);
-	}
-	if (is_ehci_tll_mode(pdata->port_mode[1])) {
+	if (is_ehci_tll_mode(pdata->port_mode[1]))
 		clk_disable(omap->usbhost_p2_fck);
-		clk_disable(omap->usbtll_p2_fck);
-	}
+
 	clk_disable(omap->utmi_p2_fck);
 	clk_disable(omap->utmi_p1_fck);
 
@@ -487,6 +332,7 @@
 		clk_disable(omap->ehci_logic_fck);
 
 	spin_unlock_irqrestore(&omap->lock, flags);
+	omap_tll_disable();
 
 	return 0;
 }
@@ -500,8 +346,6 @@
 
 	dev_dbg(dev, "starting TI HSUSB Controller\n");
 
-	pm_runtime_get_sync(dev);
-
 	if (pdata->ehci_data->phy_reset) {
 		if (gpio_is_valid(pdata->ehci_data->reset_gpio_port[0]))
 			gpio_request_one(pdata->ehci_data->reset_gpio_port[0],
@@ -515,6 +359,7 @@
 		udelay(10);
 	}
 
+	pm_runtime_get_sync(dev);
 	spin_lock_irqsave(&omap->lock, flags);
 	omap->usbhs_rev = usbhs_read(omap->uhh_base, OMAP_UHH_REVISION);
 	dev_dbg(dev, "OMAP UHH_REVISION 0x%x\n", omap->usbhs_rev);
@@ -580,22 +425,9 @@
 	usbhs_write(omap->uhh_base, OMAP_UHH_HOSTCONFIG, reg);
 	dev_dbg(dev, "UHH setup done, uhh_hostconfig=%x\n", reg);
 
-	if (is_ehci_tll_mode(pdata->port_mode[0]) ||
-		is_ehci_tll_mode(pdata->port_mode[1]) ||
-		is_ehci_tll_mode(pdata->port_mode[2]) ||
-		(is_ohci_port(pdata->port_mode[0])) ||
-		(is_ohci_port(pdata->port_mode[1])) ||
-		(is_ohci_port(pdata->port_mode[2]))) {
-
-		/* Enable UTMI mode for required TLL channels */
-		if (is_omap_usbhs_rev2(omap))
-			usbhs_omap_tll_init(dev, OMAP_REV2_TLL_CHANNEL_COUNT);
-		else
-			usbhs_omap_tll_init(dev, OMAP_TLL_CHANNEL_COUNT);
-	}
-
 	spin_unlock_irqrestore(&omap->lock, flags);
 
+	pm_runtime_put_sync(dev);
 	if (pdata->ehci_data->phy_reset) {
 		/* Hold the PHY in RESET for enough time till
 		 * PHY is settled and ready
@@ -610,8 +442,6 @@
 			gpio_set_value_cansleep
 				(pdata->ehci_data->reset_gpio_port[1], 1);
 	}
-
-	pm_runtime_put_sync(dev);
 }
 
 static void omap_usbhs_deinit(struct device *dev)
@@ -714,32 +544,18 @@
 		goto err_xclk60mhsp2_ck;
 	}
 
-	omap->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
-	if (IS_ERR(omap->usbtll_p1_fck)) {
-		ret = PTR_ERR(omap->usbtll_p1_fck);
-		dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
-		goto err_usbhost_p1_fck;
-	}
-
 	omap->usbhost_p2_fck = clk_get(dev, "usb_host_hs_utmi_p2_clk");
 	if (IS_ERR(omap->usbhost_p2_fck)) {
 		ret = PTR_ERR(omap->usbhost_p2_fck);
 		dev_err(dev, "usbhost_p2_fck failed error:%d\n", ret);
-		goto err_usbtll_p1_fck;
-	}
-
-	omap->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
-	if (IS_ERR(omap->usbtll_p2_fck)) {
-		ret = PTR_ERR(omap->usbtll_p2_fck);
-		dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
-		goto err_usbhost_p2_fck;
+		goto err_usbhost_p1_fck;
 	}
 
 	omap->init_60m_fclk = clk_get(dev, "init_60m_fclk");
 	if (IS_ERR(omap->init_60m_fclk)) {
 		ret = PTR_ERR(omap->init_60m_fclk);
 		dev_err(dev, "init_60m_fclk failed error:%d\n", ret);
-		goto err_usbtll_p2_fck;
+		goto err_usbhost_p2_fck;
 	}
 
 	if (is_ehci_phy_mode(pdata->port_mode[0])) {
@@ -785,20 +601,6 @@
 		goto err_init_60m_fclk;
 	}
 
-	res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "tll");
-	if (!res) {
-		dev_err(dev, "UHH EHCI get resource failed\n");
-		ret = -ENODEV;
-		goto err_tll;
-	}
-
-	omap->tll_base = ioremap(res->start, resource_size(res));
-	if (!omap->tll_base) {
-		dev_err(dev, "TLL ioremap failed\n");
-		ret = -ENOMEM;
-		goto err_tll;
-	}
-
 	platform_set_drvdata(pdev, omap);
 
 	omap_usbhs_init(dev);
@@ -812,23 +614,14 @@
 
 err_alloc:
 	omap_usbhs_deinit(&pdev->dev);
-	iounmap(omap->tll_base);
-
-err_tll:
 	iounmap(omap->uhh_base);
 
 err_init_60m_fclk:
 	clk_put(omap->init_60m_fclk);
 
-err_usbtll_p2_fck:
-	clk_put(omap->usbtll_p2_fck);
-
 err_usbhost_p2_fck:
 	clk_put(omap->usbhost_p2_fck);
 
-err_usbtll_p1_fck:
-	clk_put(omap->usbtll_p1_fck);
-
 err_usbhost_p1_fck:
 	clk_put(omap->usbhost_p1_fck);
 
@@ -864,12 +657,9 @@
 	struct usbhs_hcd_omap *omap = platform_get_drvdata(pdev);
 
 	omap_usbhs_deinit(&pdev->dev);
-	iounmap(omap->tll_base);
 	iounmap(omap->uhh_base);
 	clk_put(omap->init_60m_fclk);
-	clk_put(omap->usbtll_p2_fck);
 	clk_put(omap->usbhost_p2_fck);
-	clk_put(omap->usbtll_p1_fck);
 	clk_put(omap->usbhost_p1_fck);
 	clk_put(omap->xclk60mhsp2_ck);
 	clk_put(omap->utmi_p2_fck);
@@ -910,8 +700,10 @@
  * init before ehci and ohci drivers;
  * The usbhs core driver should be initialized much before
  * the omap ehci and ohci probe functions are called.
+ * This usbhs core driver should be initialized after
+ * usb tll driver
  */
-fs_initcall(omap_usbhs_drvinit);
+fs_initcall_sync(omap_usbhs_drvinit);
 
 static void __exit omap_usbhs_drvexit(void)
 {
diff --git a/drivers/mfd/omap-usb-tll.c b/drivers/mfd/omap-usb-tll.c
new file mode 100644
index 0000000..4b7757b
--- /dev/null
+++ b/drivers/mfd/omap-usb-tll.c
@@ -0,0 +1,471 @@
+/**
+ * omap-usb-tll.c - The USB TLL driver for OMAP EHCI & OHCI
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
+ * Author: Keshava Munegowda <keshava_mgowda@ti.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  of
+ * the License as published by the Free Software Foundation.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+#include <linux/kernel.h>
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/slab.h>
+#include <linux/spinlock.h>
+#include <linux/platform_device.h>
+#include <linux/clk.h>
+#include <linux/io.h>
+#include <linux/err.h>
+#include <plat/usb.h>
+#include <linux/pm_runtime.h>
+
+#define USBTLL_DRIVER_NAME	"usbhs_tll"
+
+/* TLL Register Set */
+#define	OMAP_USBTLL_REVISION				(0x00)
+#define	OMAP_USBTLL_SYSCONFIG				(0x10)
+#define	OMAP_USBTLL_SYSCONFIG_CACTIVITY			(1 << 8)
+#define	OMAP_USBTLL_SYSCONFIG_SIDLEMODE			(1 << 3)
+#define	OMAP_USBTLL_SYSCONFIG_ENAWAKEUP			(1 << 2)
+#define	OMAP_USBTLL_SYSCONFIG_SOFTRESET			(1 << 1)
+#define	OMAP_USBTLL_SYSCONFIG_AUTOIDLE			(1 << 0)
+
+#define	OMAP_USBTLL_SYSSTATUS				(0x14)
+#define	OMAP_USBTLL_SYSSTATUS_RESETDONE			(1 << 0)
+
+#define	OMAP_USBTLL_IRQSTATUS				(0x18)
+#define	OMAP_USBTLL_IRQENABLE				(0x1C)
+
+#define	OMAP_TLL_SHARED_CONF				(0x30)
+#define	OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN		(1 << 6)
+#define	OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN		(1 << 5)
+#define	OMAP_TLL_SHARED_CONF_USB_DIVRATION		(1 << 2)
+#define	OMAP_TLL_SHARED_CONF_FCLK_REQ			(1 << 1)
+#define	OMAP_TLL_SHARED_CONF_FCLK_IS_ON			(1 << 0)
+
+#define	OMAP_TLL_CHANNEL_CONF(num)			(0x040 + 0x004 * num)
+#define OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT		24
+#define	OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF		(1 << 11)
+#define	OMAP_TLL_CHANNEL_CONF_ULPI_ULPIAUTOIDLE		(1 << 10)
+#define	OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE		(1 << 9)
+#define	OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE		(1 << 8)
+#define OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS		(1 << 1)
+#define	OMAP_TLL_CHANNEL_CONF_CHANEN			(1 << 0)
+
+#define OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0		0x0
+#define OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM		0x1
+#define OMAP_TLL_FSLSMODE_3PIN_PHY			0x2
+#define OMAP_TLL_FSLSMODE_4PIN_PHY			0x3
+#define OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0		0x4
+#define OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM		0x5
+#define OMAP_TLL_FSLSMODE_3PIN_TLL			0x6
+#define OMAP_TLL_FSLSMODE_4PIN_TLL			0x7
+#define OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0		0xA
+#define OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM		0xB
+
+#define	OMAP_TLL_ULPI_FUNCTION_CTRL(num)		(0x804 + 0x100 * num)
+#define	OMAP_TLL_ULPI_INTERFACE_CTRL(num)		(0x807 + 0x100 * num)
+#define	OMAP_TLL_ULPI_OTG_CTRL(num)			(0x80A + 0x100 * num)
+#define	OMAP_TLL_ULPI_INT_EN_RISE(num)			(0x80D + 0x100 * num)
+#define	OMAP_TLL_ULPI_INT_EN_FALL(num)			(0x810 + 0x100 * num)
+#define	OMAP_TLL_ULPI_INT_STATUS(num)			(0x813 + 0x100 * num)
+#define	OMAP_TLL_ULPI_INT_LATCH(num)			(0x814 + 0x100 * num)
+#define	OMAP_TLL_ULPI_DEBUG(num)			(0x815 + 0x100 * num)
+#define	OMAP_TLL_ULPI_SCRATCH_REGISTER(num)		(0x816 + 0x100 * num)
+
+#define OMAP_REV2_TLL_CHANNEL_COUNT			2
+#define OMAP_TLL_CHANNEL_COUNT				3
+#define OMAP_TLL_CHANNEL_1_EN_MASK			(1 << 0)
+#define OMAP_TLL_CHANNEL_2_EN_MASK			(1 << 1)
+#define OMAP_TLL_CHANNEL_3_EN_MASK			(1 << 2)
+
+/* Values of USBTLL_REVISION - Note: these are not given in the TRM */
+#define OMAP_USBTLL_REV1		0x00000015	/* OMAP3 */
+#define OMAP_USBTLL_REV2		0x00000018	/* OMAP 3630 */
+#define OMAP_USBTLL_REV3		0x00000004	/* OMAP4 */
+
+#define is_ehci_tll_mode(x)	(x == OMAP_EHCI_PORT_MODE_TLL)
+
+struct usbtll_omap {
+	struct clk				*usbtll_p1_fck;
+	struct clk				*usbtll_p2_fck;
+	struct usbtll_omap_platform_data	platdata;
+	/* secure the register updates */
+	spinlock_t				lock;
+};
+
+/*-------------------------------------------------------------------------*/
+
+const char usbtll_driver_name[] = USBTLL_DRIVER_NAME;
+struct platform_device	*tll_pdev;
+
+/*-------------------------------------------------------------------------*/
+
+static inline void usbtll_write(void __iomem *base, u32 reg, u32 val)
+{
+	__raw_writel(val, base + reg);
+}
+
+static inline u32 usbtll_read(void __iomem *base, u32 reg)
+{
+	return __raw_readl(base + reg);
+}
+
+static inline void usbtll_writeb(void __iomem *base, u8 reg, u8 val)
+{
+	__raw_writeb(val, base + reg);
+}
+
+static inline u8 usbtll_readb(void __iomem *base, u8 reg)
+{
+	return __raw_readb(base + reg);
+}
+
+/*-------------------------------------------------------------------------*/
+
+static bool is_ohci_port(enum usbhs_omap_port_mode pmode)
+{
+	switch (pmode) {
+	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
+	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
+	case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
+	case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
+	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
+	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
+	case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
+	case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
+	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
+	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
+		return true;
+
+	default:
+		return false;
+	}
+}
+
+/*
+ * convert the port-mode enum to a value we can use in the FSLSMODE
+ * field of USBTLL_CHANNEL_CONF
+ */
+static unsigned ohci_omap3_fslsmode(enum usbhs_omap_port_mode mode)
+{
+	switch (mode) {
+	case OMAP_USBHS_PORT_MODE_UNUSED:
+	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DATSE0:
+		return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0;
+
+	case OMAP_OHCI_PORT_MODE_PHY_6PIN_DPDM:
+		return OMAP_TLL_FSLSMODE_6PIN_PHY_DP_DM;
+
+	case OMAP_OHCI_PORT_MODE_PHY_3PIN_DATSE0:
+		return OMAP_TLL_FSLSMODE_3PIN_PHY;
+
+	case OMAP_OHCI_PORT_MODE_PHY_4PIN_DPDM:
+		return OMAP_TLL_FSLSMODE_4PIN_PHY;
+
+	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DATSE0:
+		return OMAP_TLL_FSLSMODE_6PIN_TLL_DAT_SE0;
+
+	case OMAP_OHCI_PORT_MODE_TLL_6PIN_DPDM:
+		return OMAP_TLL_FSLSMODE_6PIN_TLL_DP_DM;
+
+	case OMAP_OHCI_PORT_MODE_TLL_3PIN_DATSE0:
+		return OMAP_TLL_FSLSMODE_3PIN_TLL;
+
+	case OMAP_OHCI_PORT_MODE_TLL_4PIN_DPDM:
+		return OMAP_TLL_FSLSMODE_4PIN_TLL;
+
+	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DATSE0:
+		return OMAP_TLL_FSLSMODE_2PIN_TLL_DAT_SE0;
+
+	case OMAP_OHCI_PORT_MODE_TLL_2PIN_DPDM:
+		return OMAP_TLL_FSLSMODE_2PIN_DAT_DP_DM;
+	default:
+		pr_warn("Invalid port mode, using default\n");
+		return OMAP_TLL_FSLSMODE_6PIN_PHY_DAT_SE0;
+	}
+}
+
+/**
+ * usbtll_omap_probe - initialize TI-based HCDs
+ *
+ * Allocates basic resources for this USB host controller.
+ */
+static int __devinit usbtll_omap_probe(struct platform_device *pdev)
+{
+	struct device				*dev =  &pdev->dev;
+	struct usbtll_omap_platform_data	*pdata = dev->platform_data;
+	void __iomem				*base;
+	struct resource				*res;
+	struct usbtll_omap			*tll;
+	unsigned				reg;
+	unsigned long				flags;
+	int					ret = 0;
+	int					i, ver, count;
+
+	dev_dbg(dev, "starting TI HSUSB TLL Controller\n");
+
+	tll = kzalloc(sizeof(struct usbtll_omap), GFP_KERNEL);
+	if (!tll) {
+		dev_err(dev, "Memory allocation failed\n");
+		ret = -ENOMEM;
+		goto end;
+	}
+
+	spin_lock_init(&tll->lock);
+
+	for (i = 0; i < OMAP3_HS_USB_PORTS; i++)
+		tll->platdata.port_mode[i] = pdata->port_mode[i];
+
+	tll->usbtll_p1_fck = clk_get(dev, "usb_tll_hs_usb_ch0_clk");
+	if (IS_ERR(tll->usbtll_p1_fck)) {
+		ret = PTR_ERR(tll->usbtll_p1_fck);
+		dev_err(dev, "usbtll_p1_fck failed error:%d\n", ret);
+		goto err_tll;
+	}
+
+	tll->usbtll_p2_fck = clk_get(dev, "usb_tll_hs_usb_ch1_clk");
+	if (IS_ERR(tll->usbtll_p2_fck)) {
+		ret = PTR_ERR(tll->usbtll_p2_fck);
+		dev_err(dev, "usbtll_p2_fck failed error:%d\n", ret);
+		goto err_usbtll_p1_fck;
+	}
+
+	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
+	if (!res) {
+		dev_err(dev, "usb tll get resource failed\n");
+		ret = -ENODEV;
+		goto err_usbtll_p2_fck;
+	}
+
+	base = ioremap(res->start, resource_size(res));
+	if (!base) {
+		dev_err(dev, "TLL ioremap failed\n");
+		ret = -ENOMEM;
+		goto err_usbtll_p2_fck;
+	}
+
+	platform_set_drvdata(pdev, tll);
+	pm_runtime_enable(dev);
+	pm_runtime_get_sync(dev);
+
+	spin_lock_irqsave(&tll->lock, flags);
+
+	ver =  usbtll_read(base, OMAP_USBTLL_REVISION);
+	switch (ver) {
+	case OMAP_USBTLL_REV1:
+	case OMAP_USBTLL_REV2:
+		count = OMAP_TLL_CHANNEL_COUNT;
+		break;
+	case OMAP_USBTLL_REV3:
+		count = OMAP_REV2_TLL_CHANNEL_COUNT;
+		break;
+	default:
+		dev_err(dev, "TLL version failed\n");
+		ret = -ENODEV;
+		goto err_ioremap;
+	}
+
+	if (is_ehci_tll_mode(pdata->port_mode[0]) ||
+	    is_ehci_tll_mode(pdata->port_mode[1]) ||
+	    is_ehci_tll_mode(pdata->port_mode[2]) ||
+	    is_ohci_port(pdata->port_mode[0]) ||
+	    is_ohci_port(pdata->port_mode[1]) ||
+	    is_ohci_port(pdata->port_mode[2])) {
+
+		/* Program Common TLL register */
+		reg = usbtll_read(base, OMAP_TLL_SHARED_CONF);
+		reg |= (OMAP_TLL_SHARED_CONF_FCLK_IS_ON
+			| OMAP_TLL_SHARED_CONF_USB_DIVRATION);
+		reg &= ~OMAP_TLL_SHARED_CONF_USB_90D_DDR_EN;
+		reg &= ~OMAP_TLL_SHARED_CONF_USB_180D_SDR_EN;
+
+		usbtll_write(base, OMAP_TLL_SHARED_CONF, reg);
+
+		/* Enable channels now */
+		for (i = 0; i < count; i++) {
+			reg = usbtll_read(base,	OMAP_TLL_CHANNEL_CONF(i));
+
+			if (is_ohci_port(pdata->port_mode[i])) {
+				reg |= ohci_omap3_fslsmode(pdata->port_mode[i])
+				<< OMAP_TLL_CHANNEL_CONF_FSLSMODE_SHIFT;
+				reg |= OMAP_TLL_CHANNEL_CONF_CHANMODE_FSLS;
+			} else if (pdata->port_mode[i] ==
+					OMAP_EHCI_PORT_MODE_TLL) {
+				/*
+				 * Disable AutoIdle, BitStuffing
+				 * and use SDR Mode
+				 */
+				reg &= ~(OMAP_TLL_CHANNEL_CONF_UTMIAUTOIDLE
+					| OMAP_TLL_CHANNEL_CONF_ULPINOBITSTUFF
+					| OMAP_TLL_CHANNEL_CONF_ULPIDDRMODE);
+			} else {
+				continue;
+			}
+			reg |= OMAP_TLL_CHANNEL_CONF_CHANEN;
+			usbtll_write(base, OMAP_TLL_CHANNEL_CONF(i), reg);
+
+			usbtll_writeb(base,
+				      OMAP_TLL_ULPI_SCRATCH_REGISTER(i),
+				      0xbe);
+		}
+	}
+
+err_ioremap:
+	spin_unlock_irqrestore(&tll->lock, flags);
+	iounmap(base);
+	pm_runtime_put_sync(dev);
+	tll_pdev = pdev;
+	if (!ret)
+		goto end;
+	pm_runtime_disable(dev);
+
+err_usbtll_p2_fck:
+	clk_put(tll->usbtll_p2_fck);
+
+err_usbtll_p1_fck:
+	clk_put(tll->usbtll_p1_fck);
+
+err_tll:
+	kfree(tll);
+
+end:
+	return ret;
+}
+
+/**
+ * usbtll_omap_remove - shutdown processing for UHH & TLL HCDs
+ * @pdev: USB Host Controller being removed
+ *
+ * Reverses the effect of usbtll_omap_probe().
+ */
+static int __devexit usbtll_omap_remove(struct platform_device *pdev)
+{
+	struct usbtll_omap *tll = platform_get_drvdata(pdev);
+
+	clk_put(tll->usbtll_p2_fck);
+	clk_put(tll->usbtll_p1_fck);
+	pm_runtime_disable(&pdev->dev);
+	kfree(tll);
+	return 0;
+}
+
+static int usbtll_runtime_resume(struct device *dev)
+{
+	struct usbtll_omap			*tll = dev_get_drvdata(dev);
+	struct usbtll_omap_platform_data	*pdata = &tll->platdata;
+	unsigned long				flags;
+
+	dev_dbg(dev, "usbtll_runtime_resume\n");
+
+	if (!pdata) {
+		dev_dbg(dev, "missing platform_data\n");
+		return  -ENODEV;
+	}
+
+	spin_lock_irqsave(&tll->lock, flags);
+
+	if (is_ehci_tll_mode(pdata->port_mode[0]))
+		clk_enable(tll->usbtll_p1_fck);
+
+	if (is_ehci_tll_mode(pdata->port_mode[1]))
+		clk_enable(tll->usbtll_p2_fck);
+
+	spin_unlock_irqrestore(&tll->lock, flags);
+
+	return 0;
+}
+
+static int usbtll_runtime_suspend(struct device *dev)
+{
+	struct usbtll_omap			*tll = dev_get_drvdata(dev);
+	struct usbtll_omap_platform_data	*pdata = &tll->platdata;
+	unsigned long				flags;
+
+	dev_dbg(dev, "usbtll_runtime_suspend\n");
+
+	if (!pdata) {
+		dev_dbg(dev, "missing platform_data\n");
+		return  -ENODEV;
+	}
+
+	spin_lock_irqsave(&tll->lock, flags);
+
+	if (is_ehci_tll_mode(pdata->port_mode[0]))
+		clk_disable(tll->usbtll_p1_fck);
+
+	if (is_ehci_tll_mode(pdata->port_mode[1]))
+		clk_disable(tll->usbtll_p2_fck);
+
+	spin_unlock_irqrestore(&tll->lock, flags);
+
+	return 0;
+}
+
+static const struct dev_pm_ops usbtllomap_dev_pm_ops = {
+	SET_RUNTIME_PM_OPS(usbtll_runtime_suspend,
+			   usbtll_runtime_resume,
+			   NULL)
+};
+
+static struct platform_driver usbtll_omap_driver = {
+	.driver = {
+		.name		= (char *)usbtll_driver_name,
+		.owner		= THIS_MODULE,
+		.pm		= &usbtllomap_dev_pm_ops,
+	},
+	.probe		= usbtll_omap_probe,
+	.remove		= __devexit_p(usbtll_omap_remove),
+};
+
+int omap_tll_enable(void)
+{
+	if (!tll_pdev) {
+		pr_err("missing omap usbhs tll platform_data\n");
+		return  -ENODEV;
+	}
+	return pm_runtime_get_sync(&tll_pdev->dev);
+}
+EXPORT_SYMBOL_GPL(omap_tll_enable);
+
+int omap_tll_disable(void)
+{
+	if (!tll_pdev) {
+		pr_err("missing omap usbhs tll platform_data\n");
+		return  -ENODEV;
+	}
+	return pm_runtime_put_sync(&tll_pdev->dev);
+}
+EXPORT_SYMBOL_GPL(omap_tll_disable);
+
+MODULE_AUTHOR("Keshava Munegowda <keshava_mgowda@ti.com>");
+MODULE_ALIAS("platform:" USBHS_DRIVER_NAME);
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("usb tll driver for TI OMAP EHCI and OHCI controllers");
+
+static int __init omap_usbtll_drvinit(void)
+{
+	return platform_driver_register(&usbtll_omap_driver);
+}
+
+/*
+ * init before usbhs core driver;
+ * The usbtll driver should be initialized before
+ * the usbhs core driver probe function is called.
+ */
+fs_initcall(omap_usbtll_drvinit);
+
+static void __exit omap_usbtll_drvexit(void)
+{
+	platform_driver_unregister(&usbtll_omap_driver);
+}
+module_exit(omap_usbtll_drvexit);
diff --git a/drivers/mfd/palmas.c b/drivers/mfd/palmas.c
index a345f9bb..4f8d6e6 100644
--- a/drivers/mfd/palmas.c
+++ b/drivers/mfd/palmas.c
@@ -23,60 +23,7 @@
 #include <linux/err.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/palmas.h>
-
-static const struct resource gpadc_resource[] = {
-	{
-		.name = "EOC_SW",
-		.start = PALMAS_GPADC_EOC_SW_IRQ,
-		.end = PALMAS_GPADC_EOC_SW_IRQ,
-		.flags = IORESOURCE_IRQ,
-	}
-};
-
-static const struct resource usb_resource[] = {
-	{
-		.name = "ID",
-		.start = PALMAS_ID_OTG_IRQ,
-		.end = PALMAS_ID_OTG_IRQ,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "ID_WAKEUP",
-		.start = PALMAS_ID_IRQ,
-		.end = PALMAS_ID_IRQ,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "VBUS",
-		.start = PALMAS_VBUS_OTG_IRQ,
-		.end = PALMAS_VBUS_OTG_IRQ,
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "VBUS_WAKEUP",
-		.start = PALMAS_VBUS_IRQ,
-		.end = PALMAS_VBUS_IRQ,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-static const struct resource rtc_resource[] = {
-	{
-		.name = "RTC_ALARM",
-		.start = PALMAS_RTC_ALARM_IRQ,
-		.end = PALMAS_RTC_ALARM_IRQ,
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
-static const struct resource pwron_resource[] = {
-	{
-		.name = "PWRON_BUTTON",
-		.start = PALMAS_PWRON_IRQ,
-		.end = PALMAS_PWRON_IRQ,
-		.flags = IORESOURCE_IRQ,
-	},
-};
+#include <linux/of_platform.h>
 
 enum palmas_ids {
 	PALMAS_PMIC_ID,
@@ -111,20 +58,14 @@
 	},
 	{
 		.name = "palmas-rtc",
-		.num_resources = ARRAY_SIZE(rtc_resource),
-		.resources = rtc_resource,
 		.id = PALMAS_RTC_ID,
 	},
 	{
 		.name = "palmas-pwrbutton",
-		.num_resources = ARRAY_SIZE(pwron_resource),
-		.resources = pwron_resource,
 		.id = PALMAS_PWRBUTTON_ID,
 	},
 	{
 		.name = "palmas-gpadc",
-		.num_resources = ARRAY_SIZE(gpadc_resource),
-		.resources = gpadc_resource,
 		.id = PALMAS_GPADC_ID,
 	},
 	{
@@ -141,8 +82,6 @@
 	},
 	{
 		.name = "palmas-usb",
-		.num_resources = ARRAY_SIZE(usb_resource),
-		.resources = usb_resource,
 		.id = PALMAS_USB_ID,
 	}
 };
@@ -308,17 +247,56 @@
 			PALMAS_INT1_MASK),
 };
 
+static void __devinit palmas_dt_to_pdata(struct device_node *node,
+		struct palmas_platform_data *pdata)
+{
+	int ret;
+	u32 prop;
+
+	ret = of_property_read_u32(node, "ti,mux_pad1", &prop);
+	if (!ret) {
+		pdata->mux_from_pdata = 1;
+		pdata->pad1 = prop;
+	}
+
+	ret = of_property_read_u32(node, "ti,mux_pad2", &prop);
+	if (!ret) {
+		pdata->mux_from_pdata = 1;
+		pdata->pad2 = prop;
+	}
+
+	/* The default for this register is all masked */
+	ret = of_property_read_u32(node, "ti,power_ctrl", &prop);
+	if (!ret)
+		pdata->power_ctrl = prop;
+	else
+		pdata->power_ctrl = PALMAS_POWER_CTRL_NSLEEP_MASK |
+					PALMAS_POWER_CTRL_ENABLE1_MASK |
+					PALMAS_POWER_CTRL_ENABLE2_MASK;
+}
+
 static int __devinit palmas_i2c_probe(struct i2c_client *i2c,
 			    const struct i2c_device_id *id)
 {
 	struct palmas *palmas;
 	struct palmas_platform_data *pdata;
+	struct device_node *node = i2c->dev.of_node;
 	int ret = 0, i;
 	unsigned int reg, addr;
 	int slave;
 	struct mfd_cell *children;
 
 	pdata = dev_get_platdata(&i2c->dev);
+
+	if (node && !pdata) {
+		pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
+
+		if (!pdata)
+			return -ENOMEM;
+
+		palmas_dt_to_pdata(node, pdata);
+	}
+
 	if (!pdata)
 		return -EINVAL;
 
@@ -364,7 +342,7 @@
 	regmap_write(palmas->regmap[slave], addr, reg);
 
 	ret = regmap_add_irq_chip(palmas->regmap[slave], palmas->irq,
-			IRQF_ONESHOT | IRQF_TRIGGER_LOW, -1, &palmas_irq_chip,
+			IRQF_ONESHOT | IRQF_TRIGGER_LOW, 0, &palmas_irq_chip,
 			&palmas->irq_data);
 	if (ret < 0)
 		goto err;
@@ -377,11 +355,11 @@
 		reg = pdata->pad1;
 		ret = regmap_write(palmas->regmap[slave], addr, reg);
 		if (ret)
-			goto err;
+			goto err_irq;
 	} else {
 		ret = regmap_read(palmas->regmap[slave], addr, &reg);
 		if (ret)
-			goto err;
+			goto err_irq;
 	}
 
 	if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD1_GPIO_0))
@@ -412,11 +390,11 @@
 		reg = pdata->pad2;
 		ret = regmap_write(palmas->regmap[slave], addr, reg);
 		if (ret)
-			goto err;
+			goto err_irq;
 	} else {
 		ret = regmap_read(palmas->regmap[slave], addr, &reg);
 		if (ret)
-			goto err;
+			goto err_irq;
 	}
 
 	if (!(reg & PALMAS_PRIMARY_SECONDARY_PAD2_GPIO_4))
@@ -439,18 +417,43 @@
 
 	ret = regmap_write(palmas->regmap[slave], addr, reg);
 	if (ret)
-		goto err;
+		goto err_irq;
+
+	/*
+	 * If we are probing with DT do this the DT way and return here
+	 * otherwise continue and add devices using mfd helpers.
+	 */
+	if (node) {
+		ret = of_platform_populate(node, NULL, NULL, &i2c->dev);
+		if (ret < 0)
+			goto err_irq;
+		else
+			return ret;
+	}
 
 	children = kmemdup(palmas_children, sizeof(palmas_children),
 			   GFP_KERNEL);
 	if (!children) {
 		ret = -ENOMEM;
-		goto err;
+		goto err_irq;
 	}
 
 	children[PALMAS_PMIC_ID].platform_data = pdata->pmic_pdata;
 	children[PALMAS_PMIC_ID].pdata_size = sizeof(*pdata->pmic_pdata);
 
+	children[PALMAS_GPADC_ID].platform_data = pdata->gpadc_pdata;
+	children[PALMAS_GPADC_ID].pdata_size = sizeof(*pdata->gpadc_pdata);
+
+	children[PALMAS_RESOURCE_ID].platform_data = pdata->resource_pdata;
+	children[PALMAS_RESOURCE_ID].pdata_size =
+			sizeof(*pdata->resource_pdata);
+
+	children[PALMAS_USB_ID].platform_data = pdata->usb_pdata;
+	children[PALMAS_USB_ID].pdata_size = sizeof(*pdata->usb_pdata);
+
+	children[PALMAS_CLK_ID].platform_data = pdata->clk_pdata;
+	children[PALMAS_CLK_ID].pdata_size = sizeof(*pdata->clk_pdata);
+
 	ret = mfd_add_devices(palmas->dev, -1,
 			      children, ARRAY_SIZE(palmas_children),
 			      NULL, regmap_irq_chip_get_base(palmas->irq_data),
@@ -458,13 +461,15 @@
 	kfree(children);
 
 	if (ret < 0)
-		goto err;
+		goto err_devices;
 
 	return ret;
 
-err:
+err_devices:
 	mfd_remove_devices(palmas->dev);
-	kfree(palmas);
+err_irq:
+	regmap_del_irq_chip(palmas->irq, palmas->irq_data);
+err:
 	return ret;
 }
 
diff --git a/drivers/mfd/rc5t583-irq.c b/drivers/mfd/rc5t583-irq.c
index fa6f80f..fe00cdd 100644
--- a/drivers/mfd/rc5t583-irq.c
+++ b/drivers/mfd/rc5t583-irq.c
@@ -255,7 +255,7 @@
 {
 	struct rc5t583 *rc5t583 = data;
 	uint8_t int_sts[RC5T583_MAX_INTERRUPT_MASK_REGS];
-	uint8_t master_int;
+	uint8_t master_int = 0;
 	int i;
 	int ret;
 	unsigned int rtc_int_sts = 0;
diff --git a/drivers/mfd/rc5t583.c b/drivers/mfd/rc5t583.c
index ff61efc..f1a024e 100644
--- a/drivers/mfd/rc5t583.c
+++ b/drivers/mfd/rc5t583.c
@@ -85,7 +85,7 @@
 	int id, int ext_pwr, int slots)
 {
 	int ret;
-	uint8_t sleepseq_val;
+	uint8_t sleepseq_val = 0;
 	unsigned int en_bit;
 	unsigned int slot_bit;
 
diff --git a/drivers/mfd/smsc-ece1099.c b/drivers/mfd/smsc-ece1099.c
new file mode 100644
index 0000000..24ae3d8
--- /dev/null
+++ b/drivers/mfd/smsc-ece1099.c
@@ -0,0 +1,113 @@
+/*
+ * TI SMSC MFD Driver
+ *
+ * Copyright (C) 2012 Texas Instruments Incorporated - http://www.ti.com
+ *
+ * Author: Sourav Poddar <sourav.poddar@ti.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;  GPL v2.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/moduleparam.h>
+#include <linux/init.h>
+#include <linux/slab.h>
+#include <linux/i2c.h>
+#include <linux/gpio.h>
+#include <linux/workqueue.h>
+#include <linux/irq.h>
+#include <linux/regmap.h>
+#include <linux/err.h>
+#include <linux/mfd/core.h>
+#include <linux/mfd/smsc.h>
+#include <linux/of_platform.h>
+
+static struct regmap_config smsc_regmap_config = {
+		.reg_bits = 8,
+		.val_bits = 8,
+		.max_register = SMSC_VEN_ID_H,
+		.cache_type = REGCACHE_RBTREE,
+};
+
+static int smsc_i2c_probe(struct i2c_client *i2c,
+			const struct i2c_device_id *id)
+{
+	struct smsc *smsc;
+	int devid, rev, venid_l, venid_h;
+	int ret = 0;
+
+	smsc = devm_kzalloc(&i2c->dev, sizeof(struct smsc),
+				GFP_KERNEL);
+	if (!smsc) {
+		dev_err(&i2c->dev, "smsc mfd driver memory allocation failed\n");
+		return -ENOMEM;
+	}
+
+	smsc->regmap = devm_regmap_init_i2c(i2c, &smsc_regmap_config);
+	if (IS_ERR(smsc->regmap)) {
+		ret = PTR_ERR(smsc->regmap);
+		goto err;
+	}
+
+	i2c_set_clientdata(i2c, smsc);
+	smsc->dev = &i2c->dev;
+
+#ifdef CONFIG_OF
+	of_property_read_u32(i2c->dev.of_node, "clock", &smsc->clk);
+#endif
+
+	regmap_read(smsc->regmap, SMSC_DEV_ID, &devid);
+	regmap_read(smsc->regmap, SMSC_DEV_REV, &rev);
+	regmap_read(smsc->regmap, SMSC_VEN_ID_L, &venid_l);
+	regmap_read(smsc->regmap, SMSC_VEN_ID_H, &venid_h);
+
+	dev_info(&i2c->dev, "SMSCxxx devid: %02x rev: %02x venid: %02x\n",
+		devid, rev, (venid_h << 8) | venid_l);
+
+	ret = regmap_write(smsc->regmap, SMSC_CLK_CTRL, smsc->clk);
+	if (ret)
+		goto err;
+
+#ifdef CONFIG_OF
+	if (i2c->dev.of_node)
+		ret = of_platform_populate(i2c->dev.of_node,
+					   NULL, NULL, &i2c->dev);
+#endif
+
+err:
+	return ret;
+}
+
+static int smsc_i2c_remove(struct i2c_client *i2c)
+{
+	struct smsc *smsc = i2c_get_clientdata(i2c);
+
+	mfd_remove_devices(smsc->dev);
+
+	return 0;
+}
+
+static const struct i2c_device_id smsc_i2c_id[] = {
+	{ "smscece1099", 0},
+	{},
+};
+MODULE_DEVICE_TABLE(i2c, smsc_i2c_id);
+
+static struct i2c_driver smsc_i2c_driver = {
+	.driver = {
+		   .name = "smsc",
+		   .owner = THIS_MODULE,
+	},
+	.probe = smsc_i2c_probe,
+	.remove = smsc_i2c_remove,
+	.id_table = smsc_i2c_id,
+};
+
+module_i2c_driver(smsc_i2c_driver);
+
+MODULE_AUTHOR("Sourav Poddar <sourav.poddar@ti.com>");
+MODULE_DESCRIPTION("SMSC chip multi-function driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/syscon.c b/drivers/mfd/syscon.c
new file mode 100644
index 0000000..65fe609
--- /dev/null
+++ b/drivers/mfd/syscon.c
@@ -0,0 +1,176 @@
+/*
+ * System Control Driver
+ *
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ * Copyright (C) 2012 Linaro Ltd.
+ *
+ * Author: Dong Aisheng <dong.aisheng@linaro.org>
+ *
+ * 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.
+ */
+
+#include <linux/err.h>
+#include <linux/io.h>
+#include <linux/module.h>
+#include <linux/of.h>
+#include <linux/of_address.h>
+#include <linux/of_platform.h>
+#include <linux/platform_device.h>
+#include <linux/regmap.h>
+
+static struct platform_driver syscon_driver;
+
+struct syscon {
+	struct device *dev;
+	void __iomem *base;
+	struct regmap *regmap;
+};
+
+static int syscon_match(struct device *dev, void *data)
+{
+	struct syscon *syscon = dev_get_drvdata(dev);
+	struct device_node *dn = data;
+
+	return (syscon->dev->of_node == dn) ? 1 : 0;
+}
+
+struct regmap *syscon_node_to_regmap(struct device_node *np)
+{
+	struct syscon *syscon;
+	struct device *dev;
+
+	dev = driver_find_device(&syscon_driver.driver, NULL, np,
+				 syscon_match);
+	if (!dev)
+		return ERR_PTR(-EPROBE_DEFER);
+
+	syscon = dev_get_drvdata(dev);
+
+	return syscon->regmap;
+}
+EXPORT_SYMBOL_GPL(syscon_node_to_regmap);
+
+struct regmap *syscon_regmap_lookup_by_compatible(const char *s)
+{
+	struct device_node *syscon_np;
+	struct regmap *regmap;
+
+	syscon_np = of_find_compatible_node(NULL, NULL, s);
+	if (!syscon_np)
+		return ERR_PTR(-ENODEV);
+
+	regmap = syscon_node_to_regmap(syscon_np);
+	of_node_put(syscon_np);
+
+	return regmap;
+}
+EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_compatible);
+
+struct regmap *syscon_regmap_lookup_by_phandle(struct device_node *np,
+					const char *property)
+{
+	struct device_node *syscon_np;
+	struct regmap *regmap;
+
+	syscon_np = of_parse_phandle(np, property, 0);
+	if (!syscon_np)
+		return ERR_PTR(-ENODEV);
+
+	regmap = syscon_node_to_regmap(syscon_np);
+	of_node_put(syscon_np);
+
+	return regmap;
+}
+EXPORT_SYMBOL_GPL(syscon_regmap_lookup_by_phandle);
+
+static const struct of_device_id of_syscon_match[] = {
+	{ .compatible = "syscon", },
+	{ },
+};
+
+static struct regmap_config syscon_regmap_config = {
+	.reg_bits = 32,
+	.val_bits = 32,
+	.reg_stride = 4,
+};
+
+static int __devinit syscon_probe(struct platform_device *pdev)
+{
+	struct device *dev = &pdev->dev;
+	struct device_node *np = dev->of_node;
+	struct syscon *syscon;
+	struct resource res;
+	int ret;
+
+	if (!np)
+		return -ENOENT;
+
+	syscon = devm_kzalloc(dev, sizeof(struct syscon),
+			    GFP_KERNEL);
+	if (!syscon)
+		return -ENOMEM;
+
+	syscon->base = of_iomap(np, 0);
+	if (!syscon->base)
+		return -EADDRNOTAVAIL;
+
+	ret = of_address_to_resource(np, 0, &res);
+	if (ret)
+		return ret;
+
+	syscon_regmap_config.max_register = res.end - res.start - 3;
+	syscon->regmap = devm_regmap_init_mmio(dev, syscon->base,
+					&syscon_regmap_config);
+	if (IS_ERR(syscon->regmap)) {
+		dev_err(dev, "regmap init failed\n");
+		return PTR_ERR(syscon->regmap);
+	}
+
+	syscon->dev = dev;
+	platform_set_drvdata(pdev, syscon);
+
+	dev_info(dev, "syscon regmap start 0x%x end 0x%x registered\n",
+		res.start, res.end);
+
+	return 0;
+}
+
+static int __devexit syscon_remove(struct platform_device *pdev)
+{
+	struct syscon *syscon;
+
+	syscon = platform_get_drvdata(pdev);
+	iounmap(syscon->base);
+	platform_set_drvdata(pdev, NULL);
+
+	return 0;
+}
+
+static struct platform_driver syscon_driver = {
+	.driver = {
+		.name = "syscon",
+		.owner = THIS_MODULE,
+		.of_match_table = of_syscon_match,
+	},
+	.probe		= syscon_probe,
+	.remove		= __devexit_p(syscon_remove),
+};
+
+static int __init syscon_init(void)
+{
+	return platform_driver_register(&syscon_driver);
+}
+postcore_initcall(syscon_init);
+
+static void __exit syscon_exit(void)
+{
+	platform_driver_unregister(&syscon_driver);
+}
+module_exit(syscon_exit);
+
+MODULE_AUTHOR("Dong Aisheng <dong.aisheng@linaro.org>");
+MODULE_DESCRIPTION("System Control driver");
+MODULE_LICENSE("GPL v2");
diff --git a/drivers/mfd/tc3589x.c b/drivers/mfd/tc3589x.c
index b56ba6b..8f4c853 100644
--- a/drivers/mfd/tc3589x.c
+++ b/drivers/mfd/tc3589x.c
@@ -9,8 +9,10 @@
 #include <linux/module.h>
 #include <linux/interrupt.h>
 #include <linux/irq.h>
+#include <linux/irqdomain.h>
 #include <linux/slab.h>
 #include <linux/i2c.h>
+#include <linux/of.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/tc3589x.h>
 
@@ -145,6 +147,7 @@
 		.name		= "tc3589x-gpio",
 		.num_resources	= ARRAY_SIZE(gpio_resources),
 		.resources	= &gpio_resources[0],
+		.of_compatible	= "tc3589x-gpio",
 	},
 };
 
@@ -153,6 +156,7 @@
 		.name           = "tc3589x-keypad",
 		.num_resources  = ARRAY_SIZE(keypad_resources),
 		.resources      = &keypad_resources[0],
+		.of_compatible	= "tc3589x-keypad",
 	},
 };
 
@@ -168,8 +172,9 @@
 
 	while (status) {
 		int bit = __ffs(status);
+		int virq = irq_create_mapping(tc3589x->domain, bit);
 
-		handle_nested_irq(tc3589x->irq_base + bit);
+		handle_nested_irq(virq);
 		status &= ~(1 << bit);
 	}
 
@@ -186,38 +191,60 @@
 	return IRQ_HANDLED;
 }
 
-static int tc3589x_irq_init(struct tc3589x *tc3589x)
+static int tc3589x_irq_map(struct irq_domain *d, unsigned int virq,
+				irq_hw_number_t hwirq)
 {
-	int base = tc3589x->irq_base;
-	int irq;
+	struct tc3589x *tc3589x = d->host_data;
 
-	for (irq = base; irq < base + TC3589x_NR_INTERNAL_IRQS; irq++) {
-		irq_set_chip_data(irq, tc3589x);
-		irq_set_chip_and_handler(irq, &dummy_irq_chip,
-					 handle_edge_irq);
-		irq_set_nested_thread(irq, 1);
+	irq_set_chip_data(virq, tc3589x);
+	irq_set_chip_and_handler(virq, &dummy_irq_chip,
+				handle_edge_irq);
+	irq_set_nested_thread(virq, 1);
 #ifdef CONFIG_ARM
-		set_irq_flags(irq, IRQF_VALID);
+	set_irq_flags(virq, IRQF_VALID);
 #else
-		irq_set_noprobe(irq);
+	irq_set_noprobe(virq);
 #endif
-	}
 
 	return 0;
 }
 
-static void tc3589x_irq_remove(struct tc3589x *tc3589x)
+static void tc3589x_irq_unmap(struct irq_domain *d, unsigned int virq)
+{
+#ifdef CONFIG_ARM
+	set_irq_flags(virq, 0);
+#endif
+	irq_set_chip_and_handler(virq, NULL, NULL);
+	irq_set_chip_data(virq, NULL);
+}
+
+static struct irq_domain_ops tc3589x_irq_ops = {
+        .map    = tc3589x_irq_map,
+	.unmap  = tc3589x_irq_unmap,
+        .xlate  = irq_domain_xlate_twocell,
+};
+
+static int tc3589x_irq_init(struct tc3589x *tc3589x, struct device_node *np)
 {
 	int base = tc3589x->irq_base;
-	int irq;
 
-	for (irq = base; irq < base + TC3589x_NR_INTERNAL_IRQS; irq++) {
-#ifdef CONFIG_ARM
-		set_irq_flags(irq, 0);
-#endif
-		irq_set_chip_and_handler(irq, NULL, NULL);
-		irq_set_chip_data(irq, NULL);
+	if (base) {
+		tc3589x->domain = irq_domain_add_legacy(
+			NULL, TC3589x_NR_INTERNAL_IRQS, base,
+			0, &tc3589x_irq_ops, tc3589x);
 	}
+	else {
+		tc3589x->domain = irq_domain_add_linear(
+			np, TC3589x_NR_INTERNAL_IRQS,
+			&tc3589x_irq_ops, tc3589x);
+	}
+
+	if (!tc3589x->domain) {
+		dev_err(tc3589x->dev, "Failed to create irqdomain\n");
+		return -ENOSYS;
+	}
+
+	return 0;
 }
 
 static int tc3589x_chip_init(struct tc3589x *tc3589x)
@@ -263,7 +290,7 @@
 	if (blocks & TC3589x_BLOCK_GPIO) {
 		ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_gpio,
 				      ARRAY_SIZE(tc3589x_dev_gpio), NULL,
-				      tc3589x->irq_base, NULL);
+				      tc3589x->irq_base, tc3589x->domain);
 		if (ret) {
 			dev_err(tc3589x->dev, "failed to add gpio child\n");
 			return ret;
@@ -274,7 +301,7 @@
 	if (blocks & TC3589x_BLOCK_KEYPAD) {
 		ret = mfd_add_devices(tc3589x->dev, -1, tc3589x_dev_keypad,
 				      ARRAY_SIZE(tc3589x_dev_keypad), NULL,
-				      tc3589x->irq_base, NULL);
+				      tc3589x->irq_base, tc3589x->domain);
 		if (ret) {
 			dev_err(tc3589x->dev, "failed to keypad child\n");
 			return ret;
@@ -285,13 +312,47 @@
 	return ret;
 }
 
+static int tc3589x_of_probe(struct device_node *np,
+			struct tc3589x_platform_data *pdata)
+{
+	struct device_node *child;
+
+	for_each_child_of_node(np, child) {
+		if (!strcmp(child->name, "tc3589x_gpio")) {
+			pdata->block |= TC3589x_BLOCK_GPIO;
+		}
+		if (!strcmp(child->name, "tc3589x_keypad")) {
+			pdata->block |= TC3589x_BLOCK_KEYPAD;
+		}
+	}
+
+	return 0;
+}
+
 static int __devinit tc3589x_probe(struct i2c_client *i2c,
 				   const struct i2c_device_id *id)
 {
 	struct tc3589x_platform_data *pdata = i2c->dev.platform_data;
+	struct device_node *np = i2c->dev.of_node;
 	struct tc3589x *tc3589x;
 	int ret;
 
+	if (!pdata) {
+		if (np) {
+			pdata = devm_kzalloc(&i2c->dev, sizeof(*pdata), GFP_KERNEL);
+			if (!pdata)
+				return -ENOMEM;
+
+			ret = tc3589x_of_probe(np, pdata);
+			if (ret)
+				return ret;
+		}
+		else {
+			dev_err(&i2c->dev, "No platform data or DT found\n");
+			return -EINVAL;
+		}
+	}
+
 	if (!i2c_check_functionality(i2c->adapter, I2C_FUNC_SMBUS_BYTE_DATA
 				     | I2C_FUNC_SMBUS_I2C_BLOCK))
 		return -EIO;
@@ -314,7 +375,7 @@
 	if (ret)
 		goto out_free;
 
-	ret = tc3589x_irq_init(tc3589x);
+	ret = tc3589x_irq_init(tc3589x, np);
 	if (ret)
 		goto out_free;
 
@@ -323,7 +384,7 @@
 				   "tc3589x", tc3589x);
 	if (ret) {
 		dev_err(tc3589x->dev, "failed to request IRQ: %d\n", ret);
-		goto out_removeirq;
+		goto out_free;
 	}
 
 	ret = tc3589x_device_init(tc3589x);
@@ -336,8 +397,6 @@
 
 out_freeirq:
 	free_irq(tc3589x->i2c->irq, tc3589x);
-out_removeirq:
-	tc3589x_irq_remove(tc3589x);
 out_free:
 	kfree(tc3589x);
 	return ret;
@@ -350,7 +409,6 @@
 	mfd_remove_devices(tc3589x->dev);
 
 	free_irq(tc3589x->i2c->irq, tc3589x);
-	tc3589x_irq_remove(tc3589x);
 
 	kfree(tc3589x);
 
diff --git a/drivers/mfd/tps65090.c b/drivers/mfd/tps65090.c
index 50fd87c..074ae32 100644
--- a/drivers/mfd/tps65090.c
+++ b/drivers/mfd/tps65090.c
@@ -236,7 +236,7 @@
 
 static bool is_volatile_reg(struct device *dev, unsigned int reg)
 {
-	if ((reg == TPS65090_INT_STS) || (reg == TPS65090_INT_STS))
+	if (reg == TPS65090_INT_STS)
 		return true;
 	else
 		return false;
diff --git a/drivers/mfd/tps65217.c b/drivers/mfd/tps65217.c
index a95e942..3fb32e6 100644
--- a/drivers/mfd/tps65217.c
+++ b/drivers/mfd/tps65217.c
@@ -34,6 +34,9 @@
 	{
 		.name = "tps65217-pmic",
 	},
+	{
+		.name = "tps65217-bl",
+	},
 };
 
 /**
diff --git a/drivers/mfd/tps6586x.c b/drivers/mfd/tps6586x.c
index 345960ca..4674643 100644
--- a/drivers/mfd/tps6586x.c
+++ b/drivers/mfd/tps6586x.c
@@ -30,6 +30,10 @@
 #include <linux/mfd/core.h>
 #include <linux/mfd/tps6586x.h>
 
+#define TPS6586X_SUPPLYENE	0x14
+#define EXITSLREQ_BIT		BIT(1)
+#define SLEEP_MODE_BIT		BIT(3)
+
 /* interrupt control registers */
 #define TPS6586X_INT_ACK1	0xb5
 #define TPS6586X_INT_ACK2	0xb6
@@ -422,6 +426,7 @@
 	pdata->subdevs = devs;
 	pdata->gpio_base = -1;
 	pdata->irq_base = -1;
+	pdata->pm_off = of_property_read_bool(np, "ti,system-power-controller");
 
 	return pdata;
 }
@@ -454,6 +459,15 @@
 	.cache_type = REGCACHE_RBTREE,
 };
 
+static struct device *tps6586x_dev;
+static void tps6586x_power_off(void)
+{
+	if (tps6586x_clr_bits(tps6586x_dev, TPS6586X_SUPPLYENE, EXITSLREQ_BIT))
+		return;
+
+	tps6586x_set_bits(tps6586x_dev, TPS6586X_SUPPLYENE, SLEEP_MODE_BIT);
+}
+
 static int __devinit tps6586x_i2c_probe(struct i2c_client *client,
 					const struct i2c_device_id *id)
 {
@@ -519,6 +533,11 @@
 		goto err_add_devs;
 	}
 
+	if (pdata->pm_off && !pm_power_off) {
+		tps6586x_dev = &client->dev;
+		pm_power_off = tps6586x_power_off;
+	}
+
 	return 0;
 
 err_add_devs:
diff --git a/drivers/mfd/tps65910.c b/drivers/mfd/tps65910.c
index d3ce4d5..0d79ce2 100644
--- a/drivers/mfd/tps65910.c
+++ b/drivers/mfd/tps65910.c
@@ -24,6 +24,14 @@
 #include <linux/mfd/tps65910.h>
 #include <linux/of_device.h>
 
+static struct resource rtc_resources[] = {
+	{
+		.start  = TPS65910_IRQ_RTC_ALARM,
+		.end    = TPS65910_IRQ_RTC_ALARM,
+		.flags  = IORESOURCE_IRQ,
+	}
+};
+
 static struct mfd_cell tps65910s[] = {
 	{
 		.name = "tps65910-gpio",
@@ -33,6 +41,8 @@
 	},
 	{
 		.name = "tps65910-rtc",
+		.num_resources = ARRAY_SIZE(rtc_resources),
+		.resources = &rtc_resources[0],
 	},
 	{
 		.name = "tps65910-power",
@@ -198,6 +208,8 @@
 
 	board_info->irq = client->irq;
 	board_info->irq_base = -1;
+	board_info->pm_off = of_property_read_bool(np,
+			"ti,system-power-controller");
 
 	return board_info;
 }
@@ -210,6 +222,21 @@
 }
 #endif
 
+static struct i2c_client *tps65910_i2c_client;
+static void tps65910_power_off(void)
+{
+	struct tps65910 *tps65910;
+
+	tps65910 = dev_get_drvdata(&tps65910_i2c_client->dev);
+
+	if (tps65910_reg_set_bits(tps65910, TPS65910_DEVCTRL,
+			DEVCTRL_PWR_OFF_MASK) < 0)
+		return;
+
+	tps65910_reg_clear_bits(tps65910, TPS65910_DEVCTRL,
+			DEVCTRL_DEV_ON_MASK);
+}
+
 static __devinit int tps65910_i2c_probe(struct i2c_client *i2c,
 					const struct i2c_device_id *id)
 {
@@ -267,6 +294,11 @@
 	tps65910_ck32k_init(tps65910, pmic_plat_data);
 	tps65910_sleepinit(tps65910, pmic_plat_data);
 
+	if (pmic_plat_data->pm_off && !pm_power_off) {
+		tps65910_i2c_client = i2c;
+		pm_power_off = tps65910_power_off;
+	}
+
 	return ret;
 }
 
diff --git a/drivers/mfd/twl-core.c b/drivers/mfd/twl-core.c
index 9d3a0bc..4ae6423 100644
--- a/drivers/mfd/twl-core.c
+++ b/drivers/mfd/twl-core.c
@@ -63,70 +63,6 @@
 
 #define DRIVER_NAME			"twl"
 
-#if defined(CONFIG_KEYBOARD_TWL4030) || defined(CONFIG_KEYBOARD_TWL4030_MODULE)
-#define twl_has_keypad()	true
-#else
-#define twl_has_keypad()	false
-#endif
-
-#if defined(CONFIG_GPIO_TWL4030) || defined(CONFIG_GPIO_TWL4030_MODULE)
-#define twl_has_gpio()	true
-#else
-#define twl_has_gpio()	false
-#endif
-
-#if defined(CONFIG_REGULATOR_TWL4030) \
-	|| defined(CONFIG_REGULATOR_TWL4030_MODULE)
-#define twl_has_regulator()	true
-#else
-#define twl_has_regulator()	false
-#endif
-
-#if defined(CONFIG_TWL4030_MADC) || defined(CONFIG_TWL4030_MADC_MODULE)
-#define twl_has_madc()	true
-#else
-#define twl_has_madc()	false
-#endif
-
-#ifdef CONFIG_TWL4030_POWER
-#define twl_has_power()        true
-#else
-#define twl_has_power()        false
-#endif
-
-#if defined(CONFIG_RTC_DRV_TWL4030) || defined(CONFIG_RTC_DRV_TWL4030_MODULE)
-#define twl_has_rtc()	true
-#else
-#define twl_has_rtc()	false
-#endif
-
-#if defined(CONFIG_TWL4030_USB) || defined(CONFIG_TWL4030_USB_MODULE) ||\
-	defined(CONFIG_TWL6030_USB) || defined(CONFIG_TWL6030_USB_MODULE)
-#define twl_has_usb()	true
-#else
-#define twl_has_usb()	false
-#endif
-
-#if defined(CONFIG_TWL4030_WATCHDOG) || \
-	defined(CONFIG_TWL4030_WATCHDOG_MODULE)
-#define twl_has_watchdog()        true
-#else
-#define twl_has_watchdog()        false
-#endif
-
-#if defined(CONFIG_MFD_TWL4030_AUDIO) || \
-	defined(CONFIG_MFD_TWL4030_AUDIO_MODULE)
-#define twl_has_codec()	true
-#else
-#define twl_has_codec()	false
-#endif
-
-#if defined(CONFIG_CHARGER_TWL4030) || defined(CONFIG_CHARGER_TWL4030_MODULE)
-#define twl_has_bci()	true
-#else
-#define twl_has_bci()	false
-#endif
-
 /* Triton Core internal information (BEGIN) */
 
 /* Last - for index max*/
@@ -134,13 +70,6 @@
 
 #define TWL_NUM_SLAVES		4
 
-#if defined(CONFIG_INPUT_TWL4030_PWRBUTTON) \
-	|| defined(CONFIG_INPUT_TWL4030_PWRBUTTON_MODULE)
-#define twl_has_pwrbutton()	true
-#else
-#define twl_has_pwrbutton()	false
-#endif
-
 #define SUB_CHIP_ID0 0
 #define SUB_CHIP_ID1 1
 #define SUB_CHIP_ID2 2
@@ -552,6 +481,38 @@
 }
 EXPORT_SYMBOL_GPL(twl_get_version);
 
+/**
+ * twl_get_hfclk_rate - API to get TWL external HFCLK clock rate.
+ *
+ * Api to get the TWL HFCLK rate based on BOOT_CFG register.
+ */
+int twl_get_hfclk_rate(void)
+{
+	u8 ctrl;
+	int rate;
+
+	twl_i2c_read_u8(TWL_MODULE_PM_MASTER, &ctrl, R_CFG_BOOT);
+
+	switch (ctrl & 0x3) {
+	case HFCLK_FREQ_19p2_MHZ:
+		rate = 19200000;
+		break;
+	case HFCLK_FREQ_26_MHZ:
+		rate = 26000000;
+		break;
+	case HFCLK_FREQ_38p4_MHZ:
+		rate = 38400000;
+		break;
+	default:
+		pr_err("TWL4030: HFCLK is not configured\n");
+		rate = -EINVAL;
+		break;
+	}
+
+	return rate;
+}
+EXPORT_SYMBOL_GPL(twl_get_hfclk_rate);
+
 static struct device *
 add_numbered_child(unsigned chip, const char *name, int num,
 		void *pdata, unsigned pdata_len,
@@ -669,7 +630,7 @@
 	struct device	*child;
 	unsigned sub_chip_id;
 
-	if (twl_has_gpio() && pdata->gpio) {
+	if (IS_ENABLED(CONFIG_GPIO_TWL4030) && pdata->gpio) {
 		child = add_child(SUB_CHIP_ID1, "twl4030_gpio",
 				pdata->gpio, sizeof(*pdata->gpio),
 				false, irq_base + GPIO_INTR_OFFSET, 0);
@@ -677,7 +638,7 @@
 			return PTR_ERR(child);
 	}
 
-	if (twl_has_keypad() && pdata->keypad) {
+	if (IS_ENABLED(CONFIG_KEYBOARD_TWL4030) && pdata->keypad) {
 		child = add_child(SUB_CHIP_ID2, "twl4030_keypad",
 				pdata->keypad, sizeof(*pdata->keypad),
 				true, irq_base + KEYPAD_INTR_OFFSET, 0);
@@ -685,7 +646,7 @@
 			return PTR_ERR(child);
 	}
 
-	if (twl_has_madc() && pdata->madc) {
+	if (IS_ENABLED(CONFIG_TWL4030_MADC) && pdata->madc) {
 		child = add_child(2, "twl4030_madc",
 				pdata->madc, sizeof(*pdata->madc),
 				true, irq_base + MADC_INTR_OFFSET, 0);
@@ -693,7 +654,7 @@
 			return PTR_ERR(child);
 	}
 
-	if (twl_has_rtc()) {
+	if (IS_ENABLED(CONFIG_RTC_DRV_TWL4030)) {
 		/*
 		 * REVISIT platform_data here currently might expose the
 		 * "msecure" line ... but for now we just expect board
@@ -709,7 +670,15 @@
 			return PTR_ERR(child);
 	}
 
-	if (twl_has_usb() && pdata->usb && twl_class_is_4030()) {
+	if (IS_ENABLED(CONFIG_PWM_TWL6030) && twl_class_is_6030()) {
+		child = add_child(TWL6030_MODULE_ID1, "twl6030-pwm", NULL, 0,
+				  false, 0, 0);
+		if (IS_ERR(child))
+			return PTR_ERR(child);
+	}
+
+	if (IS_ENABLED(CONFIG_TWL4030_USB) && pdata->usb &&
+	    twl_class_is_4030()) {
 
 		static struct regulator_consumer_supply usb1v5 = {
 			.supply =	"usb1v5",
@@ -723,7 +692,7 @@
 		};
 
 	/* First add the regulators so that they can be used by transceiver */
-		if (twl_has_regulator()) {
+		if (IS_ENABLED(CONFIG_REGULATOR_TWL4030)) {
 			/* this is a template that gets copied */
 			struct regulator_init_data usb_fixed = {
 				.constraints.valid_modes_mask =
@@ -765,18 +734,19 @@
 			return PTR_ERR(child);
 
 		/* we need to connect regulators to this transceiver */
-		if (twl_has_regulator() && child) {
+		if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && child) {
 			usb1v5.dev_name = dev_name(child);
 			usb1v8.dev_name = dev_name(child);
 			usb3v1[0].dev_name = dev_name(child);
 		}
 	}
-	if (twl_has_usb() && pdata->usb && twl_class_is_6030()) {
+	if (IS_ENABLED(CONFIG_TWL6030_USB) && pdata->usb &&
+	    twl_class_is_6030()) {
 
 		static struct regulator_consumer_supply usb3v3;
 		int regulator;
 
-		if (twl_has_regulator()) {
+		if (IS_ENABLED(CONFIG_REGULATOR_TWL4030)) {
 			/* this is a template that gets copied */
 			struct regulator_init_data usb_fixed = {
 				.constraints.valid_modes_mask =
@@ -813,9 +783,10 @@
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 		/* we need to connect regulators to this transceiver */
-		if (twl_has_regulator() && child)
+		if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && child)
 			usb3v3.dev_name = dev_name(child);
-	} else if (twl_has_regulator() && twl_class_is_6030()) {
+	} else if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) &&
+		   twl_class_is_6030()) {
 		if (features & TWL6025_SUBCLASS)
 			child = add_regulator(TWL6025_REG_LDOUSB,
 						pdata->ldousb, features);
@@ -827,20 +798,21 @@
 					return PTR_ERR(child);
 	}
 
-	if (twl_has_watchdog() && twl_class_is_4030()) {
+	if (IS_ENABLED(CONFIG_TWL4030_WATCHDOG) && twl_class_is_4030()) {
 		child = add_child(0, "twl4030_wdt", NULL, 0, false, 0, 0);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 	}
 
-	if (twl_has_pwrbutton() && twl_class_is_4030()) {
+	if (IS_ENABLED(CONFIG_INPUT_TWL4030_PWRBUTTON) && twl_class_is_4030()) {
 		child = add_child(1, "twl4030_pwrbutton",
 				NULL, 0, true, irq_base + 8 + 0, 0);
 		if (IS_ERR(child))
 			return PTR_ERR(child);
 	}
 
-	if (twl_has_codec() && pdata->audio && twl_class_is_4030()) {
+	if (IS_ENABLED(CONFIG_MFD_TWL4030_AUDIO) && pdata->audio &&
+	    twl_class_is_4030()) {
 		sub_chip_id = twl_map[TWL_MODULE_AUDIO_VOICE].sid;
 		child = add_child(sub_chip_id, "twl4030-audio",
 				pdata->audio, sizeof(*pdata->audio),
@@ -850,7 +822,7 @@
 	}
 
 	/* twl4030 regulators */
-	if (twl_has_regulator() && twl_class_is_4030()) {
+	if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_4030()) {
 		child = add_regulator(TWL4030_REG_VPLL1, pdata->vpll1,
 					features);
 		if (IS_ERR(child))
@@ -905,7 +877,7 @@
 	}
 
 	/* maybe add LDOs that are omitted on cost-reduced parts */
-	if (twl_has_regulator() && !(features & TPS_SUBSET)
+	if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && !(features & TPS_SUBSET)
 	  && twl_class_is_4030()) {
 		child = add_regulator(TWL4030_REG_VPLL2, pdata->vpll2,
 					features);
@@ -939,7 +911,7 @@
 	}
 
 	/* twl6030 regulators */
-	if (twl_has_regulator() && twl_class_is_6030() &&
+	if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_6030() &&
 			!(features & TWL6025_SUBCLASS)) {
 		child = add_regulator(TWL6030_REG_VDD1, pdata->vdd1,
 					features);
@@ -1013,7 +985,7 @@
 	}
 
 	/* 6030 and 6025 share this regulator */
-	if (twl_has_regulator() && twl_class_is_6030()) {
+	if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_6030()) {
 		child = add_regulator(TWL6030_REG_VANA, pdata->vana,
 					features);
 		if (IS_ERR(child))
@@ -1021,7 +993,7 @@
 	}
 
 	/* twl6025 regulators */
-	if (twl_has_regulator() && twl_class_is_6030() &&
+	if (IS_ENABLED(CONFIG_REGULATOR_TWL4030) && twl_class_is_6030() &&
 			(features & TWL6025_SUBCLASS)) {
 		child = add_regulator(TWL6025_REG_LDO5, pdata->ldo5,
 					features);
@@ -1080,7 +1052,7 @@
 
 	}
 
-	if (twl_has_bci() && pdata->bci &&
+	if (IS_ENABLED(CONFIG_CHARGER_TWL4030) && pdata->bci &&
 			!(features & (TPS_SUBSET | TWL5031))) {
 		child = add_child(3, "twl4030_bci",
 				pdata->bci, sizeof(*pdata->bci), false,
@@ -1295,7 +1267,7 @@
 	}
 
 	/* load power event scripts */
-	if (twl_has_power() && pdata->power)
+	if (IS_ENABLED(CONFIG_TWL4030_POWER) && pdata->power)
 		twl4030_power_init(pdata->power);
 
 	/* Maybe init the T2 Interrupt subsystem */
diff --git a/drivers/mfd/twl4030-audio.c b/drivers/mfd/twl4030-audio.c
index 77c9acb..5c11acf 100644
--- a/drivers/mfd/twl4030-audio.c
+++ b/drivers/mfd/twl4030-audio.c
@@ -28,6 +28,8 @@
 #include <linux/kernel.h>
 #include <linux/fs.h>
 #include <linux/platform_device.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
 #include <linux/i2c/twl.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/twl4030-audio.h>
@@ -156,47 +158,70 @@
 }
 EXPORT_SYMBOL_GPL(twl4030_audio_get_mclk);
 
+static bool twl4030_audio_has_codec(struct twl4030_audio_data *pdata,
+			      struct device_node *node)
+{
+	if (pdata && pdata->codec)
+		return true;
+
+	if (of_find_node_by_name(node, "codec"))
+		return true;
+
+	return false;
+}
+
+static bool twl4030_audio_has_vibra(struct twl4030_audio_data *pdata,
+			      struct device_node *node)
+{
+	int vibra;
+
+	if (pdata && pdata->vibra)
+		return true;
+
+	if (!of_property_read_u32(node, "ti,enable-vibra", &vibra) && vibra)
+		return true;
+
+	return false;
+}
+
 static int __devinit twl4030_audio_probe(struct platform_device *pdev)
 {
 	struct twl4030_audio *audio;
 	struct twl4030_audio_data *pdata = pdev->dev.platform_data;
+	struct device_node *node = pdev->dev.of_node;
 	struct mfd_cell *cell = NULL;
 	int ret, childs = 0;
 	u8 val;
 
-	if (!pdata) {
+	if (!pdata && !node) {
 		dev_err(&pdev->dev, "Platform data is missing\n");
 		return -EINVAL;
 	}
 
+	audio = devm_kzalloc(&pdev->dev, sizeof(struct twl4030_audio),
+			     GFP_KERNEL);
+	if (!audio)
+		return -ENOMEM;
+
+	mutex_init(&audio->mutex);
+	audio->audio_mclk = twl_get_hfclk_rate();
+
 	/* Configure APLL_INFREQ and disable APLL if enabled */
-	val = 0;
-	switch (pdata->audio_mclk) {
+	switch (audio->audio_mclk) {
 	case 19200000:
-		val |= TWL4030_APLL_INFREQ_19200KHZ;
+		val = TWL4030_APLL_INFREQ_19200KHZ;
 		break;
 	case 26000000:
-		val |= TWL4030_APLL_INFREQ_26000KHZ;
+		val = TWL4030_APLL_INFREQ_26000KHZ;
 		break;
 	case 38400000:
-		val |= TWL4030_APLL_INFREQ_38400KHZ;
+		val = TWL4030_APLL_INFREQ_38400KHZ;
 		break;
 	default:
 		dev_err(&pdev->dev, "Invalid audio_mclk\n");
 		return -EINVAL;
 	}
-	twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE,
-					val, TWL4030_REG_APLL_CTL);
-
-	audio = kzalloc(sizeof(struct twl4030_audio), GFP_KERNEL);
-	if (!audio)
-		return -ENOMEM;
-
-	platform_set_drvdata(pdev, audio);
-
-	twl4030_audio_dev = pdev;
-	mutex_init(&audio->mutex);
-	audio->audio_mclk = pdata->audio_mclk;
+	twl_i2c_write_u8(TWL4030_MODULE_AUDIO_VOICE, val, TWL4030_REG_APLL_CTL);
 
 	/* Codec power */
 	audio->resource[TWL4030_AUDIO_RES_POWER].reg = TWL4030_REG_CODEC_MODE;
@@ -206,21 +231,28 @@
 	audio->resource[TWL4030_AUDIO_RES_APLL].reg = TWL4030_REG_APLL_CTL;
 	audio->resource[TWL4030_AUDIO_RES_APLL].mask = TWL4030_APLL_EN;
 
-	if (pdata->codec) {
+	if (twl4030_audio_has_codec(pdata, node)) {
 		cell = &audio->cells[childs];
 		cell->name = "twl4030-codec";
-		cell->platform_data = pdata->codec;
-		cell->pdata_size = sizeof(*pdata->codec);
+		if (pdata) {
+			cell->platform_data = pdata->codec;
+			cell->pdata_size = sizeof(*pdata->codec);
+		}
 		childs++;
 	}
-	if (pdata->vibra) {
+	if (twl4030_audio_has_vibra(pdata, node)) {
 		cell = &audio->cells[childs];
 		cell->name = "twl4030-vibra";
-		cell->platform_data = pdata->vibra;
-		cell->pdata_size = sizeof(*pdata->vibra);
+		if (pdata) {
+			cell->platform_data = pdata->vibra;
+			cell->pdata_size = sizeof(*pdata->vibra);
+		}
 		childs++;
 	}
 
+	platform_set_drvdata(pdev, audio);
+	twl4030_audio_dev = pdev;
+
 	if (childs)
 		ret = mfd_add_devices(&pdev->dev, pdev->id, audio->cells,
 				      childs, NULL, 0, NULL);
@@ -229,39 +261,42 @@
 		ret = -ENODEV;
 	}
 
-	if (!ret)
-		return 0;
+	if (ret) {
+		platform_set_drvdata(pdev, NULL);
+		twl4030_audio_dev = NULL;
+	}
 
-	platform_set_drvdata(pdev, NULL);
-	kfree(audio);
-	twl4030_audio_dev = NULL;
 	return ret;
 }
 
 static int __devexit twl4030_audio_remove(struct platform_device *pdev)
 {
-	struct twl4030_audio *audio = platform_get_drvdata(pdev);
-
 	mfd_remove_devices(&pdev->dev);
 	platform_set_drvdata(pdev, NULL);
-	kfree(audio);
 	twl4030_audio_dev = NULL;
 
 	return 0;
 }
 
-MODULE_ALIAS("platform:twl4030-audio");
+static const struct of_device_id twl4030_audio_of_match[] = {
+	{.compatible = "ti,twl4030-audio", },
+	{ },
+};
+MODULE_DEVICE_TABLE(of, twl4030_audio_of_match);
 
 static struct platform_driver twl4030_audio_driver = {
-	.probe		= twl4030_audio_probe,
-	.remove		= __devexit_p(twl4030_audio_remove),
 	.driver		= {
 		.owner	= THIS_MODULE,
 		.name	= "twl4030-audio",
+		.of_match_table = twl4030_audio_of_match,
 	},
+	.probe		= twl4030_audio_probe,
+	.remove		= __devexit_p(twl4030_audio_remove),
 };
 
 module_platform_driver(twl4030_audio_driver);
 
 MODULE_AUTHOR("Peter Ujfalusi <peter.ujfalusi@ti.com>");
+MODULE_DESCRIPTION("TWL4030 audio block MFD driver");
 MODULE_LICENSE("GPL");
+MODULE_ALIAS("platform:twl4030-audio");
diff --git a/drivers/mfd/twl6030-pwm.c b/drivers/mfd/twl6030-pwm.c
deleted file mode 100644
index e8fee14..0000000
--- a/drivers/mfd/twl6030-pwm.c
+++ /dev/null
@@ -1,165 +0,0 @@
-/*
- * twl6030_pwm.c
- * Driver for PHOENIX (TWL6030) Pulse Width Modulator
- *
- * Copyright (C) 2010 Texas Instruments
- * Author: Hemanth V <hemanthv@ti.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.
- *
- * 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, see <http://www.gnu.org/licenses/>.
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/i2c/twl.h>
-#include <linux/slab.h>
-
-#define LED_PWM_CTRL1	0xF4
-#define LED_PWM_CTRL2	0xF5
-
-/* Max value for CTRL1 register */
-#define PWM_CTRL1_MAX	255
-
-/* Pull down disable */
-#define PWM_CTRL2_DIS_PD	(1 << 6)
-
-/* Current control 2.5 milli Amps */
-#define PWM_CTRL2_CURR_02	(2 << 4)
-
-/* LED supply source */
-#define PWM_CTRL2_SRC_VAC	(1 << 2)
-
-/* LED modes */
-#define PWM_CTRL2_MODE_HW	(0 << 0)
-#define PWM_CTRL2_MODE_SW	(1 << 0)
-#define PWM_CTRL2_MODE_DIS	(2 << 0)
-
-#define PWM_CTRL2_MODE_MASK	0x3
-
-struct pwm_device {
-	const char *label;
-	unsigned int pwm_id;
-};
-
-int pwm_config(struct pwm_device *pwm, int duty_ns, int period_ns)
-{
-	u8 duty_cycle;
-	int ret;
-
-	if (pwm == NULL || period_ns == 0 || duty_ns > period_ns)
-		return -EINVAL;
-
-	duty_cycle = (duty_ns * PWM_CTRL1_MAX) / period_ns;
-
-	ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, duty_cycle, LED_PWM_CTRL1);
-
-	if (ret < 0) {
-		pr_err("%s: Failed to configure PWM, Error %d\n",
-			pwm->label, ret);
-		return ret;
-	}
-	return 0;
-}
-EXPORT_SYMBOL(pwm_config);
-
-int pwm_enable(struct pwm_device *pwm)
-{
-	u8 val;
-	int ret;
-
-	ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2);
-	if (ret < 0) {
-		pr_err("%s: Failed to enable PWM, Error %d\n", pwm->label, ret);
-		return ret;
-	}
-
-	/* Change mode to software control */
-	val &= ~PWM_CTRL2_MODE_MASK;
-	val |= PWM_CTRL2_MODE_SW;
-
-	ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2);
-	if (ret < 0) {
-		pr_err("%s: Failed to enable PWM, Error %d\n", pwm->label, ret);
-		return ret;
-	}
-
-	twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2);
-	return 0;
-}
-EXPORT_SYMBOL(pwm_enable);
-
-void pwm_disable(struct pwm_device *pwm)
-{
-	u8 val;
-	int ret;
-
-	ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2);
-	if (ret < 0) {
-		pr_err("%s: Failed to disable PWM, Error %d\n",
-			pwm->label, ret);
-		return;
-	}
-
-	val &= ~PWM_CTRL2_MODE_MASK;
-	val |= PWM_CTRL2_MODE_HW;
-
-	ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2);
-	if (ret < 0) {
-		pr_err("%s: Failed to disable PWM, Error %d\n",
-			pwm->label, ret);
-		return;
-	}
-	return;
-}
-EXPORT_SYMBOL(pwm_disable);
-
-struct pwm_device *pwm_request(int pwm_id, const char *label)
-{
-	u8 val;
-	int ret;
-	struct pwm_device *pwm;
-
-	pwm = kzalloc(sizeof(struct pwm_device), GFP_KERNEL);
-	if (pwm == NULL) {
-		pr_err("%s: failed to allocate memory\n", label);
-		return NULL;
-	}
-
-	pwm->label = label;
-	pwm->pwm_id = pwm_id;
-
-	/* Configure PWM */
-	val = PWM_CTRL2_DIS_PD | PWM_CTRL2_CURR_02 | PWM_CTRL2_SRC_VAC |
-		PWM_CTRL2_MODE_HW;
-
-	ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2);
-
-	if (ret < 0) {
-		pr_err("%s: Failed to configure PWM, Error %d\n",
-			 pwm->label, ret);
-
-		kfree(pwm);
-		return NULL;
-	}
-
-	return pwm;
-}
-EXPORT_SYMBOL(pwm_request);
-
-void pwm_free(struct pwm_device *pwm)
-{
-	pwm_disable(pwm);
-	kfree(pwm);
-}
-EXPORT_SYMBOL(pwm_free);
-
-MODULE_LICENSE("GPL");
diff --git a/drivers/mfd/twl6040-core.c b/drivers/mfd/twl6040-core.c
index 3dca5c1..3f2a1cf 100644
--- a/drivers/mfd/twl6040-core.c
+++ b/drivers/mfd/twl6040-core.c
@@ -584,7 +584,7 @@
 		goto irq_init_err;
 
 	ret = request_threaded_irq(twl6040->irq_base + TWL6040_IRQ_READY,
-				   NULL, twl6040_naudint_handler, 0,
+				   NULL, twl6040_naudint_handler, IRQF_ONESHOT,
 				   "twl6040_irq_ready", twl6040);
 	if (ret) {
 		dev_err(twl6040->dev, "READY IRQ request failed: %d\n",
@@ -631,6 +631,21 @@
 		children++;
 	}
 
+	/*
+	 * Enable the GPO driver in the following cases:
+	 * DT booted kernel or legacy boot with valid gpo platform_data
+	 */
+	if (!pdata || (pdata && pdata->gpo)) {
+		cell = &twl6040->cells[children];
+		cell->name = "twl6040-gpo";
+
+		if (pdata) {
+			cell->platform_data = pdata->gpo;
+			cell->pdata_size = sizeof(*pdata->gpo);
+		}
+		children++;
+	}
+
 	ret = mfd_add_devices(&client->dev, -1, twl6040->cells, children,
 			      NULL, 0, NULL);
 	if (ret)
diff --git a/drivers/mfd/wm5110-tables.c b/drivers/mfd/wm5110-tables.c
index bd8782c..adda6b1 100644
--- a/drivers/mfd/wm5110-tables.c
+++ b/drivers/mfd/wm5110-tables.c
@@ -133,15 +133,109 @@
 	{ 0x209, 0x002A },
 };
 
+static const struct reg_default wm5110_revb_patch[] = {
+	{ 0x80, 0x3 },
+	{ 0x36e, 0x0210 },
+	{ 0x370, 0x0210 },
+	{ 0x372, 0x0210 },
+	{ 0x374, 0x0210 },
+	{ 0x376, 0x0210 },
+	{ 0x378, 0x0210 },
+	{ 0x36d, 0x0028 },
+	{ 0x36f, 0x0028 },
+	{ 0x371, 0x0028 },
+	{ 0x373, 0x0028 },
+	{ 0x375, 0x0028 },
+	{ 0x377, 0x0028 },
+	{ 0x280, 0x2002 },
+	{ 0x44, 0x20 },
+	{ 0x45, 0x40 },
+	{ 0x46, 0x60 },
+	{ 0x47, 0x80 },
+	{ 0x48, 0xa0 },
+	{ 0x51, 0x13 },
+	{ 0x52, 0x33 },
+	{ 0x53, 0x53 },
+	{ 0x54, 0x73 },
+	{ 0x55, 0x93 },
+	{ 0x56, 0xb3 },
+	{ 0xc30, 0x3e3e },
+	{ 0xc31, 0x3e },
+	{ 0xc32, 0x3e3e },
+	{ 0xc33, 0x3e3e },
+	{ 0xc34, 0x3e3e },
+	{ 0xc35, 0x3e3e },
+	{ 0xc36, 0x3e3e },
+	{ 0xc37, 0x3e3e },
+	{ 0xc38, 0x3e3e },
+	{ 0xc39, 0x3e3e },
+	{ 0xc3a, 0x3e3e },
+	{ 0xc3b, 0x3e3e },
+	{ 0xc3c, 0x3e },
+	{ 0x201, 0x18a5 },
+	{ 0x202, 0x4100 },
+	{ 0x460, 0x0c40 },
+	{ 0x461, 0x8000 },
+	{ 0x462, 0x0c41 },
+	{ 0x463, 0x4820 },
+	{ 0x464, 0x0c41 },
+	{ 0x465, 0x4040 },
+	{ 0x466, 0x0841 },
+	{ 0x467, 0x3940 },
+	{ 0x468, 0x0841 },
+	{ 0x469, 0x2030 },
+	{ 0x46a, 0x0842 },
+	{ 0x46b, 0x1990 },
+	{ 0x46c, 0x08c2 },
+	{ 0x46d, 0x1450 },
+	{ 0x46e, 0x08c6 },
+	{ 0x46f, 0x1020 },
+	{ 0x470, 0x08c6 },
+	{ 0x471, 0x0cd0 },
+	{ 0x472, 0x08c6 },
+	{ 0x473, 0x0a30 },
+	{ 0x474, 0x0442 },
+	{ 0x475, 0x0660 },
+	{ 0x476, 0x0446 },
+	{ 0x477, 0x0510 },
+	{ 0x478, 0x04c6 },
+	{ 0x479, 0x0400 },
+	{ 0x47a, 0x04ce },
+	{ 0x47b, 0x0330 },
+	{ 0x47c, 0x05df },
+	{ 0x47d, 0x0001 },
+	{ 0x47e, 0x07ff },
+	{ 0x2db, 0x0a00 },
+	{ 0x2dd, 0x0023 },
+	{ 0x2df, 0x0102 },
+	{ 0x2ef, 0x924 },
+	{ 0x2f0, 0x924 },
+	{ 0x2f1, 0x924 },
+	{ 0x2f2, 0x924 },
+	{ 0x2f3, 0x924 },
+	{ 0x2f4, 0x924 },
+	{ 0x2eb, 0x60 },
+	{ 0x2ec, 0x60 },
+	{ 0x2ed, 0x60 },
+	{ 0x4f2, 0x33e },
+	{ 0x458, 0x0000 },
+	{ 0x15a, 0x0003 },
+	{ 0x80, 0x0 },
+};
+
 /* We use a function so we can use ARRAY_SIZE() */
 int wm5110_patch(struct arizona *arizona)
 {
 	switch (arizona->rev) {
 	case 0:
-	case 1:
 		return regmap_register_patch(arizona->regmap,
 					     wm5110_reva_patch,
 					     ARRAY_SIZE(wm5110_reva_patch));
+	case 1:
+		return regmap_register_patch(arizona->regmap,
+					     wm5110_revb_patch,
+					     ARRAY_SIZE(wm5110_revb_patch));
+
 	default:
 		return 0;
 	}
diff --git a/drivers/mfd/wm831x-core.c b/drivers/mfd/wm831x-core.c
index 3017310..521340a 100644
--- a/drivers/mfd/wm831x-core.c
+++ b/drivers/mfd/wm831x-core.c
@@ -614,18 +614,11 @@
 }
 EXPORT_SYMBOL_GPL(wm831x_set_bits);
 
-static struct resource wm831x_io_parent = {
-	.start = 0,
-	.end   = 0xffffffff,
-	.flags = IORESOURCE_IO,
-};
-
 static struct resource wm831x_dcdc1_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_DC1_CONTROL_1,
 		.end   = WM831X_DC1_DVS_CONTROL,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 	{
 		.name  = "UV",
@@ -644,10 +637,9 @@
 
 static struct resource wm831x_dcdc2_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_DC2_CONTROL_1,
 		.end   = WM831X_DC2_DVS_CONTROL,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 	{
 		.name  = "UV",
@@ -665,10 +657,9 @@
 
 static struct resource wm831x_dcdc3_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_DC3_CONTROL_1,
 		.end   = WM831X_DC3_SLEEP_CONTROL,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 	{
 		.name  = "UV",
@@ -680,10 +671,9 @@
 
 static struct resource wm831x_dcdc4_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_DC4_CONTROL,
 		.end   = WM831X_DC4_SLEEP_CONTROL,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 	{
 		.name  = "UV",
@@ -695,10 +685,9 @@
 
 static struct resource wm8320_dcdc4_buck_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_DC4_CONTROL,
 		.end   = WM832X_DC4_SLEEP_CONTROL,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 	{
 		.name  = "UV",
@@ -718,10 +707,9 @@
 
 static struct resource wm831x_isink1_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_CURRENT_SINK_1,
 		.end   = WM831X_CURRENT_SINK_1,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 	{
 		.start = WM831X_IRQ_CS1,
@@ -732,10 +720,9 @@
 
 static struct resource wm831x_isink2_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_CURRENT_SINK_2,
 		.end   = WM831X_CURRENT_SINK_2,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 	{
 		.start = WM831X_IRQ_CS2,
@@ -746,10 +733,9 @@
 
 static struct resource wm831x_ldo1_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_LDO1_CONTROL,
 		.end   = WM831X_LDO1_SLEEP_CONTROL,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 	{
 		.name  = "UV",
@@ -761,10 +747,9 @@
 
 static struct resource wm831x_ldo2_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_LDO2_CONTROL,
 		.end   = WM831X_LDO2_SLEEP_CONTROL,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 	{
 		.name  = "UV",
@@ -776,10 +761,9 @@
 
 static struct resource wm831x_ldo3_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_LDO3_CONTROL,
 		.end   = WM831X_LDO3_SLEEP_CONTROL,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 	{
 		.name  = "UV",
@@ -791,10 +775,9 @@
 
 static struct resource wm831x_ldo4_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_LDO4_CONTROL,
 		.end   = WM831X_LDO4_SLEEP_CONTROL,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 	{
 		.name  = "UV",
@@ -806,10 +789,9 @@
 
 static struct resource wm831x_ldo5_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_LDO5_CONTROL,
 		.end   = WM831X_LDO5_SLEEP_CONTROL,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 	{
 		.name  = "UV",
@@ -821,10 +803,9 @@
 
 static struct resource wm831x_ldo6_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_LDO6_CONTROL,
 		.end   = WM831X_LDO6_SLEEP_CONTROL,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 	{
 		.name  = "UV",
@@ -836,10 +817,9 @@
 
 static struct resource wm831x_ldo7_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_LDO7_CONTROL,
 		.end   = WM831X_LDO7_SLEEP_CONTROL,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 	{
 		.name  = "UV",
@@ -851,10 +831,9 @@
 
 static struct resource wm831x_ldo8_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_LDO8_CONTROL,
 		.end   = WM831X_LDO8_SLEEP_CONTROL,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 	{
 		.name  = "UV",
@@ -866,10 +845,9 @@
 
 static struct resource wm831x_ldo9_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_LDO9_CONTROL,
 		.end   = WM831X_LDO9_SLEEP_CONTROL,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 	{
 		.name  = "UV",
@@ -881,10 +859,9 @@
 
 static struct resource wm831x_ldo10_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_LDO10_CONTROL,
 		.end   = WM831X_LDO10_SLEEP_CONTROL,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 	{
 		.name  = "UV",
@@ -896,10 +873,9 @@
 
 static struct resource wm831x_ldo11_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_LDO11_ON_CONTROL,
 		.end   = WM831X_LDO11_SLEEP_CONTROL,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 };
 
@@ -998,19 +974,17 @@
 
 static struct resource wm831x_status1_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_STATUS_LED_1,
 		.end   = WM831X_STATUS_LED_1,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 };
 
 static struct resource wm831x_status2_resources[] = {
 	{
-		.parent = &wm831x_io_parent,
 		.start = WM831X_STATUS_LED_2,
 		.end   = WM831X_STATUS_LED_2,
-		.flags = IORESOURCE_IO,
+		.flags = IORESOURCE_REG,
 	},
 };
 
diff --git a/drivers/mfd/wm8994-core.c b/drivers/mfd/wm8994-core.c
index 2febf88..3d6d9be 100644
--- a/drivers/mfd/wm8994-core.c
+++ b/drivers/mfd/wm8994-core.c
@@ -390,7 +390,7 @@
 
 static const __devinitdata struct reg_default wm1811_reva_patch[] = {
 	{ 0x102, 0x3 },
-	{ 0x56, 0x7 },
+	{ 0x56, 0xc07 },
 	{ 0x5d, 0x7e },
 	{ 0x5e, 0x0 },
 	{ 0x102, 0x0 },
diff --git a/drivers/mfd/wm8994-regmap.c b/drivers/mfd/wm8994-regmap.c
index 52e9e29..2fbce9c 100644
--- a/drivers/mfd/wm8994-regmap.c
+++ b/drivers/mfd/wm8994-regmap.c
@@ -1136,7 +1136,7 @@
 
 	switch (reg) {
 	case WM8994_GPIO_6:
-		if (wm8994->revision > 1)
+		if (wm8994->cust_id > 1 || wm8994->revision > 1)
 			return true;
 		else
 			return false;
diff --git a/drivers/pwm/Kconfig b/drivers/pwm/Kconfig
index 90c5c73..d7c6b83 100644
--- a/drivers/pwm/Kconfig
+++ b/drivers/pwm/Kconfig
@@ -115,6 +115,15 @@
 	  To compile this driver as a module, choose M here: the module
 	  will be called pwm-tiehrpwm.
 
+config PWM_TWL6030
+	tristate "TWL6030 PWM support"
+	depends on TWL4030_CORE
+	help
+	  Generic PWM framework driver for TWL6030.
+
+	  To compile this driver as a module, choose M here: the module
+	  will be called pwm-twl6030.
+
 config PWM_VT8500
 	tristate "vt8500 pwm support"
 	depends on ARCH_VT8500
diff --git a/drivers/pwm/Makefile b/drivers/pwm/Makefile
index e4b2c898..78f123d 100644
--- a/drivers/pwm/Makefile
+++ b/drivers/pwm/Makefile
@@ -8,4 +8,5 @@
 obj-$(CONFIG_PWM_TEGRA)		+= pwm-tegra.o
 obj-$(CONFIG_PWM_TIECAP)	+= pwm-tiecap.o
 obj-$(CONFIG_PWM_TIEHRPWM)	+= pwm-tiehrpwm.o
+obj-$(CONFIG_PWM_TWL6030)	+= pwm-twl6030.o
 obj-$(CONFIG_PWM_VT8500)	+= pwm-vt8500.o
diff --git a/drivers/pwm/pwm-twl6030.c b/drivers/pwm/pwm-twl6030.c
new file mode 100644
index 0000000..8e63878
--- /dev/null
+++ b/drivers/pwm/pwm-twl6030.c
@@ -0,0 +1,184 @@
+/*
+ * twl6030_pwm.c
+ * Driver for PHOENIX (TWL6030) Pulse Width Modulator
+ *
+ * Copyright (C) 2010 Texas Instruments
+ * Author: Hemanth V <hemanthv@ti.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.
+ *
+ * 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, see <http://www.gnu.org/licenses/>.
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/pwm.h>
+#include <linux/i2c/twl.h>
+#include <linux/slab.h>
+
+#define LED_PWM_CTRL1	0xF4
+#define LED_PWM_CTRL2	0xF5
+
+/* Max value for CTRL1 register */
+#define PWM_CTRL1_MAX	255
+
+/* Pull down disable */
+#define PWM_CTRL2_DIS_PD	(1 << 6)
+
+/* Current control 2.5 milli Amps */
+#define PWM_CTRL2_CURR_02	(2 << 4)
+
+/* LED supply source */
+#define PWM_CTRL2_SRC_VAC	(1 << 2)
+
+/* LED modes */
+#define PWM_CTRL2_MODE_HW	(0 << 0)
+#define PWM_CTRL2_MODE_SW	(1 << 0)
+#define PWM_CTRL2_MODE_DIS	(2 << 0)
+
+#define PWM_CTRL2_MODE_MASK	0x3
+
+struct twl6030_pwm_chip {
+	struct pwm_chip chip;
+};
+
+static int twl6030_pwm_request(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	int ret;
+	u8 val;
+
+	/* Configure PWM */
+	val = PWM_CTRL2_DIS_PD | PWM_CTRL2_CURR_02 | PWM_CTRL2_SRC_VAC |
+	      PWM_CTRL2_MODE_HW;
+
+	ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2);
+	if (ret < 0) {
+		dev_err(chip->dev, "%s: Failed to configure PWM, Error %d\n",
+			pwm->label, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int twl6030_pwm_config(struct pwm_chip *chip, struct pwm_device *pwm,
+			      int duty_ns, int period_ns)
+{
+	u8 duty_cycle = (duty_ns * PWM_CTRL1_MAX) / period_ns;
+	int ret;
+
+	ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, duty_cycle, LED_PWM_CTRL1);
+	if (ret < 0) {
+		pr_err("%s: Failed to configure PWM, Error %d\n",
+			pwm->label, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
+static int twl6030_pwm_enable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	int ret;
+	u8 val;
+
+	ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2);
+	if (ret < 0) {
+		dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n",
+			pwm->label, ret);
+		return ret;
+	}
+
+	/* Change mode to software control */
+	val &= ~PWM_CTRL2_MODE_MASK;
+	val |= PWM_CTRL2_MODE_SW;
+
+	ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2);
+	if (ret < 0) {
+		dev_err(chip->dev, "%s: Failed to enable PWM, Error %d\n",
+			pwm->label, ret);
+		return ret;
+	}
+
+	twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2);
+	return 0;
+}
+
+static void twl6030_pwm_disable(struct pwm_chip *chip, struct pwm_device *pwm)
+{
+	int ret;
+	u8 val;
+
+	ret = twl_i2c_read_u8(TWL6030_MODULE_ID1, &val, LED_PWM_CTRL2);
+	if (ret < 0) {
+		dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n",
+			pwm->label, ret);
+		return;
+	}
+
+	val &= ~PWM_CTRL2_MODE_MASK;
+	val |= PWM_CTRL2_MODE_HW;
+
+	ret = twl_i2c_write_u8(TWL6030_MODULE_ID1, val, LED_PWM_CTRL2);
+	if (ret < 0) {
+		dev_err(chip->dev, "%s: Failed to disable PWM, Error %d\n",
+			pwm->label, ret);
+	}
+}
+
+static const struct pwm_ops twl6030_pwm_ops = {
+	.request = twl6030_pwm_request,
+	.config = twl6030_pwm_config,
+	.enable = twl6030_pwm_enable,
+	.disable = twl6030_pwm_disable,
+};
+
+static int twl6030_pwm_probe(struct platform_device *pdev)
+{
+	struct twl6030_pwm_chip *twl6030;
+	int ret;
+
+	twl6030 = devm_kzalloc(&pdev->dev, sizeof(*twl6030), GFP_KERNEL);
+	if (!twl6030)
+		return -ENOMEM;
+
+	twl6030->chip.dev = &pdev->dev;
+	twl6030->chip.ops = &twl6030_pwm_ops;
+	twl6030->chip.base = -1;
+	twl6030->chip.npwm = 1;
+
+	ret = pwmchip_add(&twl6030->chip);
+	if (ret < 0)
+		return ret;
+
+	platform_set_drvdata(pdev, twl6030);
+
+	return 0;
+}
+
+static int twl6030_pwm_remove(struct platform_device *pdev)
+{
+	struct twl6030_pwm_chip *twl6030 = platform_get_drvdata(pdev);
+
+	return pwmchip_remove(&twl6030->chip);
+}
+
+static struct platform_driver twl6030_pwm_driver = {
+	.driver = {
+		.name = "twl6030-pwm",
+	},
+	.probe = twl6030_pwm_probe,
+	.remove = __devexit_p(twl6030_pwm_remove),
+};
+module_platform_driver(twl6030_pwm_driver);
+
+MODULE_ALIAS("platform:twl6030-pwm");
+MODULE_LICENSE("GPL");
diff --git a/drivers/regulator/88pm8607.c b/drivers/regulator/88pm8607.c
index c3482b9..1c5ab01 100644
--- a/drivers/regulator/88pm8607.c
+++ b/drivers/regulator/88pm8607.c
@@ -12,6 +12,8 @@
 #include <linux/init.h>
 #include <linux/err.h>
 #include <linux/i2c.h>
+#include <linux/of.h>
+#include <linux/regulator/of_regulator.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
@@ -23,6 +25,7 @@
 	struct pm860x_chip	*chip;
 	struct regulator_dev	*regulator;
 	struct i2c_client	*i2c;
+	struct i2c_client	*i2c_8606;
 
 	unsigned int	*vol_table;
 	unsigned int	*vol_suspend;
@@ -242,6 +245,35 @@
 	return ret;
 }
 
+static int pm8606_preg_enable(struct regulator_dev *rdev)
+{
+	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
+
+	return pm860x_set_bits(info->i2c, rdev->desc->enable_reg,
+			       1 << rdev->desc->enable_mask, 0);
+}
+
+static int pm8606_preg_disable(struct regulator_dev *rdev)
+{
+	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
+
+	return pm860x_set_bits(info->i2c, rdev->desc->enable_reg,
+			       1 << rdev->desc->enable_mask,
+			       1 << rdev->desc->enable_mask);
+}
+
+static int pm8606_preg_is_enabled(struct regulator_dev *rdev)
+{
+	struct pm8607_regulator_info *info = rdev_get_drvdata(rdev);
+	int ret;
+
+	ret = pm860x_reg_read(info->i2c, rdev->desc->enable_reg);
+	if (ret < 0)
+		return ret;
+
+	return !((unsigned char)ret & (1 << rdev->desc->enable_mask));
+}
+
 static struct regulator_ops pm8607_regulator_ops = {
 	.list_voltage	= pm8607_list_voltage,
 	.set_voltage_sel = pm8607_set_voltage_sel,
@@ -251,6 +283,25 @@
 	.is_enabled = regulator_is_enabled_regmap,
 };
 
+static struct regulator_ops pm8606_preg_ops = {
+	.enable		= pm8606_preg_enable,
+	.disable	= pm8606_preg_disable,
+	.is_enabled	= pm8606_preg_is_enabled,
+};
+
+#define PM8606_PREG(ereg, ebit)						\
+{									\
+	.desc	= {							\
+		.name	= "PREG",					\
+		.ops	= &pm8606_preg_ops,				\
+		.type	= REGULATOR_CURRENT,				\
+		.id	= PM8606_ID_PREG,				\
+		.owner	= THIS_MODULE,					\
+		.enable_reg = PM8606_##ereg,				\
+		.enable_mask = (ebit),					\
+	},								\
+}
+
 #define PM8607_DVC(vreg, ureg, ubit, ereg, ebit)			\
 {									\
 	.desc	= {							\
@@ -311,6 +362,38 @@
 	PM8607_LDO(14,        LDO14, 0, SUPPLIES_EN12, 6),
 };
 
+static struct pm8607_regulator_info pm8606_regulator_info[] = {
+	PM8606_PREG(PREREGULATORB, 5),
+};
+
+#ifdef CONFIG_OF
+static int pm8607_regulator_dt_init(struct platform_device *pdev,
+				    struct pm8607_regulator_info *info,
+				    struct regulator_config *config)
+{
+	struct device_node *nproot, *np;
+	nproot = pdev->dev.parent->of_node;
+	if (!nproot)
+		return -ENODEV;
+	nproot = of_find_node_by_name(nproot, "regulators");
+	if (!nproot) {
+		dev_err(&pdev->dev, "failed to find regulators node\n");
+		return -ENODEV;
+	}
+	for_each_child_of_node(nproot, np) {
+		if (!of_node_cmp(np->name, info->desc.name)) {
+			config->init_data =
+				of_get_regulator_init_data(&pdev->dev, np);
+			config->of_node = np;
+			break;
+		}
+	}
+	return 0;
+}
+#else
+#define pm8607_regulator_dt_init(x, y, z)	(-1)
+#endif
+
 static int __devinit pm8607_regulator_probe(struct platform_device *pdev)
 {
 	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -320,22 +403,28 @@
 	struct resource *res;
 	int i;
 
-	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "No I/O resource!\n");
-		return -EINVAL;
-	}
-	for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) {
-		info = &pm8607_regulator_info[i];
-		if (info->desc.id == res->start)
-			break;
-	}
-	if (i == ARRAY_SIZE(pm8607_regulator_info)) {
-		dev_err(&pdev->dev, "Failed to find regulator %llu\n",
-			(unsigned long long)res->start);
-		return -EINVAL;
+	res = platform_get_resource(pdev, IORESOURCE_REG, 0);
+	if (res) {
+		/* There're resources in 88PM8607 regulator driver */
+		for (i = 0; i < ARRAY_SIZE(pm8607_regulator_info); i++) {
+			info = &pm8607_regulator_info[i];
+			if (info->desc.vsel_reg == res->start)
+				break;
+		}
+		if (i == ARRAY_SIZE(pm8607_regulator_info)) {
+			dev_err(&pdev->dev, "Failed to find regulator %llu\n",
+				(unsigned long long)res->start);
+			return -EINVAL;
+		}
+	} else {
+		/* There's no resource in 88PM8606 PREG regulator driver */
+		info = &pm8606_regulator_info[0];
+		/* i is used to check regulator ID */
+		i = -1;
 	}
 	info->i2c = (chip->id == CHIP_PM8607) ? chip->client : chip->companion;
+	info->i2c_8606 = (chip->id == CHIP_PM8607) ? chip->companion :
+			chip->client;
 	info->chip = chip;
 
 	/* check DVC ramp slope double */
@@ -343,15 +432,17 @@
 		info->slope_double = 1;
 
 	config.dev = &pdev->dev;
-	config.init_data = pdata;
 	config.driver_data = info;
 
+	if (pm8607_regulator_dt_init(pdev, info, &config))
+		if (pdata)
+			config.init_data = pdata;
+
 	if (chip->id == CHIP_PM8607)
 		config.regmap = chip->regmap;
 	else
 		config.regmap = chip->regmap_companion;
 
-	/* replace driver_data with info */
 	info->regulator = regulator_register(&info->desc, &config);
 	if (IS_ERR(info->regulator)) {
 		dev_err(&pdev->dev, "failed to register regulator %s\n",
@@ -372,6 +463,18 @@
 	return 0;
 }
 
+static struct platform_device_id pm8607_regulator_driver_ids[] = {
+	{
+		.name	= "88pm860x-regulator",
+		.driver_data	= 0,
+	}, {
+		.name	= "88pm860x-preg",
+		.driver_data	= 0,
+	},
+	{ },
+};
+MODULE_DEVICE_TABLE(platform, pm8607_regulator_driver_ids);
+
 static struct platform_driver pm8607_regulator_driver = {
 	.driver		= {
 		.name	= "88pm860x-regulator",
@@ -379,6 +482,7 @@
 	},
 	.probe		= pm8607_regulator_probe,
 	.remove		= __devexit_p(pm8607_regulator_remove),
+	.id_table	= pm8607_regulator_driver_ids,
 };
 
 static int __init pm8607_regulator_init(void)
diff --git a/drivers/regulator/Kconfig b/drivers/regulator/Kconfig
index e98a5e7..67d47b59 100644
--- a/drivers/regulator/Kconfig
+++ b/drivers/regulator/Kconfig
@@ -122,7 +122,7 @@
 
 config REGULATOR_ANATOP
 	tristate "Freescale i.MX on-chip ANATOP LDO regulators"
-	depends on MFD_ANATOP
+	depends on MFD_SYSCON
 	help
 	  Say y here to support Freescale i.MX on-chip ANATOP LDOs
 	  regulators. It is recommended that this option be
diff --git a/drivers/regulator/ab3100.c b/drivers/regulator/ab3100.c
index 65ad2b3..df4ad89 100644
--- a/drivers/regulator/ab3100.c
+++ b/drivers/regulator/ab3100.c
@@ -15,6 +15,7 @@
 #include <linux/err.h>
 #include <linux/platform_device.h>
 #include <linux/regulator/driver.h>
+#include <linux/mfd/ab3100.h>
 #include <linux/mfd/abx500.h>
 
 /* LDO registers and some handy masking definitions for AB3100 */
diff --git a/drivers/regulator/anatop-regulator.c b/drivers/regulator/anatop-regulator.c
index ce0fe72..1af9768 100644
--- a/drivers/regulator/anatop-regulator.c
+++ b/drivers/regulator/anatop-regulator.c
@@ -21,19 +21,20 @@
 #include <linux/slab.h>
 #include <linux/device.h>
 #include <linux/module.h>
+#include <linux/mfd/syscon.h>
 #include <linux/err.h>
 #include <linux/io.h>
 #include <linux/platform_device.h>
 #include <linux/of.h>
 #include <linux/of_address.h>
-#include <linux/mfd/anatop.h>
+#include <linux/regmap.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/of_regulator.h>
 
 struct anatop_regulator {
 	const char *name;
 	u32 control_reg;
-	struct anatop *mfd;
+	struct regmap *anatop;
 	int vol_bit_shift;
 	int vol_bit_width;
 	int min_bit_val;
@@ -43,7 +44,8 @@
 	struct regulator_init_data *initdata;
 };
 
-static int anatop_set_voltage_sel(struct regulator_dev *reg, unsigned selector)
+static int anatop_regmap_set_voltage_sel(struct regulator_dev *reg,
+					unsigned selector)
 {
 	struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
 	u32 val, mask;
@@ -56,12 +58,13 @@
 	mask = ((1 << anatop_reg->vol_bit_width) - 1) <<
 		anatop_reg->vol_bit_shift;
 	val <<= anatop_reg->vol_bit_shift;
-	anatop_write_reg(anatop_reg->mfd, anatop_reg->control_reg, val, mask);
+	regmap_update_bits(anatop_reg->anatop, anatop_reg->control_reg,
+				mask, val);
 
 	return 0;
 }
 
-static int anatop_get_voltage_sel(struct regulator_dev *reg)
+static int anatop_regmap_get_voltage_sel(struct regulator_dev *reg)
 {
 	struct anatop_regulator *anatop_reg = rdev_get_drvdata(reg);
 	u32 val, mask;
@@ -69,7 +72,7 @@
 	if (!anatop_reg->control_reg)
 		return -ENOTSUPP;
 
-	val = anatop_read_reg(anatop_reg->mfd, anatop_reg->control_reg);
+	regmap_read(anatop_reg->anatop, anatop_reg->control_reg, &val);
 	mask = ((1 << anatop_reg->vol_bit_width) - 1) <<
 		anatop_reg->vol_bit_shift;
 	val = (val & mask) >> anatop_reg->vol_bit_shift;
@@ -78,8 +81,8 @@
 }
 
 static struct regulator_ops anatop_rops = {
-	.set_voltage_sel = anatop_set_voltage_sel,
-	.get_voltage_sel = anatop_get_voltage_sel,
+	.set_voltage_sel = anatop_regmap_set_voltage_sel,
+	.get_voltage_sel = anatop_regmap_get_voltage_sel,
 	.list_voltage = regulator_list_voltage_linear,
 	.map_voltage = regulator_map_voltage_linear,
 };
@@ -88,11 +91,11 @@
 {
 	struct device *dev = &pdev->dev;
 	struct device_node *np = dev->of_node;
+	struct device_node *anatop_np;
 	struct regulator_desc *rdesc;
 	struct regulator_dev *rdev;
 	struct anatop_regulator *sreg;
 	struct regulator_init_data *initdata;
-	struct anatop *anatopmfd = dev_get_drvdata(pdev->dev.parent);
 	struct regulator_config config = { };
 	int ret = 0;
 
@@ -109,7 +112,15 @@
 	rdesc->ops = &anatop_rops;
 	rdesc->type = REGULATOR_VOLTAGE;
 	rdesc->owner = THIS_MODULE;
-	sreg->mfd = anatopmfd;
+
+	anatop_np = of_get_parent(np);
+	if (!anatop_np)
+		return -ENODEV;
+	sreg->anatop = syscon_node_to_regmap(anatop_np);
+	of_node_put(anatop_np);
+	if (IS_ERR(sreg->anatop))
+		return PTR_ERR(sreg->anatop);
+
 	ret = of_property_read_u32(np, "anatop-reg-offset",
 				   &sreg->control_reg);
 	if (ret) {
diff --git a/drivers/regulator/max8925-regulator.c b/drivers/regulator/max8925-regulator.c
index 43dc97ec..9bb0be3 100644
--- a/drivers/regulator/max8925-regulator.c
+++ b/drivers/regulator/max8925-regulator.c
@@ -214,37 +214,36 @@
 	MAX8925_LDO(20, 750, 3900, 50),
 };
 
-static struct max8925_regulator_info * __devinit find_regulator_info(int id)
-{
-	struct max8925_regulator_info *ri;
-	int i;
-
-	for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) {
-		ri = &max8925_regulator_info[i];
-		if (ri->desc.id == id)
-			return ri;
-	}
-	return NULL;
-}
-
 static int __devinit max8925_regulator_probe(struct platform_device *pdev)
 {
 	struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
-	struct max8925_platform_data *pdata = chip->dev->platform_data;
+	struct regulator_init_data *pdata = pdev->dev.platform_data;
 	struct regulator_config config = { };
 	struct max8925_regulator_info *ri;
+	struct resource *res;
 	struct regulator_dev *rdev;
+	int i;
 
-	ri = find_regulator_info(pdev->id);
-	if (ri == NULL) {
-		dev_err(&pdev->dev, "invalid regulator ID specified\n");
+	res = platform_get_resource(pdev, IORESOURCE_REG, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "No REG resource!\n");
+		return -EINVAL;
+	}
+	for (i = 0; i < ARRAY_SIZE(max8925_regulator_info); i++) {
+		ri = &max8925_regulator_info[i];
+		if (ri->vol_reg == res->start)
+			break;
+	}
+	if (i == ARRAY_SIZE(max8925_regulator_info)) {
+		dev_err(&pdev->dev, "Failed to find regulator %llu\n",
+			(unsigned long long)res->start);
 		return -EINVAL;
 	}
 	ri->i2c = chip->i2c;
 	ri->chip = chip;
 
 	config.dev = &pdev->dev;
-	config.init_data = pdata->regulator[pdev->id];
+	config.init_data = pdata;
 	config.driver_data = ri;
 
 	rdev = regulator_register(&ri->desc, &config);
diff --git a/drivers/regulator/palmas-regulator.c b/drivers/regulator/palmas-regulator.c
index 2ba7502..07aee69 100644
--- a/drivers/regulator/palmas-regulator.c
+++ b/drivers/regulator/palmas-regulator.c
@@ -22,6 +22,9 @@
 #include <linux/slab.h>
 #include <linux/regmap.h>
 #include <linux/mfd/palmas.h>
+#include <linux/of.h>
+#include <linux/of_platform.h>
+#include <linux/regulator/of_regulator.h>
 
 struct regs_info {
 	char	*name;
@@ -568,10 +571,103 @@
 	return 0;
 }
 
+static struct of_regulator_match palmas_matches[] = {
+	{ .name = "smps12", },
+	{ .name = "smps123", },
+	{ .name = "smps3", },
+	{ .name = "smps45", },
+	{ .name = "smps457", },
+	{ .name = "smps6", },
+	{ .name = "smps7", },
+	{ .name = "smps8", },
+	{ .name = "smps9", },
+	{ .name = "smps10", },
+	{ .name = "ldo1", },
+	{ .name = "ldo2", },
+	{ .name = "ldo3", },
+	{ .name = "ldo4", },
+	{ .name = "ldo5", },
+	{ .name = "ldo6", },
+	{ .name = "ldo7", },
+	{ .name = "ldo8", },
+	{ .name = "ldo9", },
+	{ .name = "ldoln", },
+	{ .name = "ldousb", },
+};
+
+static void __devinit palmas_dt_to_pdata(struct device *dev,
+		struct device_node *node,
+		struct palmas_pmic_platform_data *pdata)
+{
+	struct device_node *regulators;
+	u32 prop;
+	int idx, ret;
+
+	regulators = of_find_node_by_name(node, "regulators");
+	if (!regulators) {
+		dev_info(dev, "regulator node not found\n");
+		return;
+	}
+
+	ret = of_regulator_match(dev, regulators, palmas_matches,
+			PALMAS_NUM_REGS);
+	if (ret < 0) {
+		dev_err(dev, "Error parsing regulator init data: %d\n", ret);
+		return;
+	}
+
+	for (idx = 0; idx < PALMAS_NUM_REGS; idx++) {
+		if (!palmas_matches[idx].init_data ||
+				!palmas_matches[idx].of_node)
+			continue;
+
+		pdata->reg_data[idx] = palmas_matches[idx].init_data;
+
+		pdata->reg_init[idx] = devm_kzalloc(dev,
+				sizeof(struct palmas_reg_init), GFP_KERNEL);
+
+		ret = of_property_read_u32(palmas_matches[idx].of_node,
+				"ti,warm_reset", &prop);
+		if (!ret)
+			pdata->reg_init[idx]->warm_reset = prop;
+
+		ret = of_property_read_u32(palmas_matches[idx].of_node,
+				"ti,roof_floor", &prop);
+		if (!ret)
+			pdata->reg_init[idx]->roof_floor = prop;
+
+		ret = of_property_read_u32(palmas_matches[idx].of_node,
+				"ti,mode_sleep", &prop);
+		if (!ret)
+			pdata->reg_init[idx]->mode_sleep = prop;
+
+		ret = of_property_read_u32(palmas_matches[idx].of_node,
+				"ti,warm_reset", &prop);
+		if (!ret)
+			pdata->reg_init[idx]->warm_reset = prop;
+
+		ret = of_property_read_u32(palmas_matches[idx].of_node,
+				"ti,tstep", &prop);
+		if (!ret)
+			pdata->reg_init[idx]->tstep = prop;
+
+		ret = of_property_read_u32(palmas_matches[idx].of_node,
+				"ti,vsel", &prop);
+		if (!ret)
+			pdata->reg_init[idx]->vsel = prop;
+	}
+
+	ret = of_property_read_u32(node, "ti,ldo6_vibrator", &prop);
+	if (!ret)
+		pdata->ldo6_vibrator = prop;
+}
+
+
 static __devinit int palmas_probe(struct platform_device *pdev)
 {
 	struct palmas *palmas = dev_get_drvdata(pdev->dev.parent);
 	struct palmas_pmic_platform_data *pdata = pdev->dev.platform_data;
+	struct device_node *node = pdev->dev.of_node;
 	struct regulator_dev *rdev;
 	struct regulator_config config = { };
 	struct palmas_pmic *pmic;
@@ -579,10 +675,14 @@
 	int id = 0, ret;
 	unsigned int addr, reg;
 
-	if (!pdata)
-		return -EINVAL;
-	if (!pdata->reg_data)
-		return -EINVAL;
+	if (node && !pdata) {
+		pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+
+		if (!pdata)
+			return -ENOMEM;
+
+		palmas_dt_to_pdata(&pdev->dev, node, pdata);
+	}
 
 	pmic = devm_kzalloc(&pdev->dev, sizeof(*pmic), GFP_KERNEL);
 	if (!pmic)
@@ -661,7 +761,7 @@
 		pmic->desc[id].owner = THIS_MODULE;
 
 		/* Initialise sleep/init values from platform data */
-		if (pdata && pdata->reg_init) {
+		if (pdata) {
 			reg_init = pdata->reg_init[id];
 			if (reg_init) {
 				ret = palmas_smps_init(palmas, id, reg_init);
@@ -685,11 +785,13 @@
 				pmic->range[id] = 1;
 		}
 
-		if (pdata && pdata->reg_data)
+		if (pdata)
 			config.init_data = pdata->reg_data[id];
 		else
 			config.init_data = NULL;
 
+		config.of_node = palmas_matches[id].of_node;
+
 		rdev = regulator_register(&pmic->desc[id], &config);
 		if (IS_ERR(rdev)) {
 			dev_err(&pdev->dev,
@@ -726,11 +828,13 @@
 						palmas_regs_info[id].ctrl_addr);
 		pmic->desc[id].enable_mask = PALMAS_LDO1_CTRL_MODE_ACTIVE;
 
-		if (pdata && pdata->reg_data)
+		if (pdata)
 			config.init_data = pdata->reg_data[id];
 		else
 			config.init_data = NULL;
 
+		config.of_node = palmas_matches[id].of_node;
+
 		rdev = regulator_register(&pmic->desc[id], &config);
 		if (IS_ERR(rdev)) {
 			dev_err(&pdev->dev,
@@ -744,7 +848,7 @@
 		pmic->rdev[id] = rdev;
 
 		/* Initialise sleep/init values from platform data */
-		if (pdata->reg_init) {
+		if (pdata) {
 			reg_init = pdata->reg_init[id];
 			if (reg_init) {
 				ret = palmas_ldo_init(palmas, id, reg_init);
@@ -774,9 +878,15 @@
 	return 0;
 }
 
+static struct of_device_id __devinitdata of_palmas_match_tbl[] = {
+	{ .compatible = "ti,palmas-pmic", },
+	{ /* end */ }
+};
+
 static struct platform_driver palmas_driver = {
 	.driver = {
 		.name = "palmas-pmic",
+		.of_match_table = of_palmas_match_tbl,
 		.owner = THIS_MODULE,
 	},
 	.probe = palmas_probe,
@@ -799,3 +909,4 @@
 MODULE_DESCRIPTION("Palmas voltage regulator driver");
 MODULE_LICENSE("GPL");
 MODULE_ALIAS("platform:palmas-pmic");
+MODULE_DEVICE_TABLE(of, of_palmas_match_tbl);
diff --git a/drivers/regulator/wm831x-dcdc.c b/drivers/regulator/wm831x-dcdc.c
index 90cbcc6..782c228 100644
--- a/drivers/regulator/wm831x-dcdc.c
+++ b/drivers/regulator/wm831x-dcdc.c
@@ -475,9 +475,9 @@
 
 	dcdc->wm831x = wm831x;
 
-	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	res = platform_get_resource(pdev, IORESOURCE_REG, 0);
 	if (res == NULL) {
-		dev_err(&pdev->dev, "No I/O resource\n");
+		dev_err(&pdev->dev, "No REG resource\n");
 		ret = -EINVAL;
 		goto err;
 	}
@@ -650,9 +650,9 @@
 
 	dcdc->wm831x = wm831x;
 
-	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	res = platform_get_resource(pdev, IORESOURCE_REG, 0);
 	if (res == NULL) {
-		dev_err(&pdev->dev, "No I/O resource\n");
+		dev_err(&pdev->dev, "No REG resource\n");
 		ret = -EINVAL;
 		goto err;
 	}
@@ -794,9 +794,9 @@
 
 	dcdc->wm831x = wm831x;
 
-	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	res = platform_get_resource(pdev, IORESOURCE_REG, 0);
 	if (res == NULL) {
-		dev_err(&pdev->dev, "No I/O resource\n");
+		dev_err(&pdev->dev, "No REG resource\n");
 		ret = -EINVAL;
 		goto err;
 	}
diff --git a/drivers/regulator/wm831x-isink.c b/drivers/regulator/wm831x-isink.c
index 0d207c2..2646a19 100644
--- a/drivers/regulator/wm831x-isink.c
+++ b/drivers/regulator/wm831x-isink.c
@@ -172,9 +172,9 @@
 
 	isink->wm831x = wm831x;
 
-	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	res = platform_get_resource(pdev, IORESOURCE_REG, 0);
 	if (res == NULL) {
-		dev_err(&pdev->dev, "No I/O resource\n");
+		dev_err(&pdev->dev, "No REG resource\n");
 		ret = -EINVAL;
 		goto err;
 	}
diff --git a/drivers/regulator/wm831x-ldo.c b/drivers/regulator/wm831x-ldo.c
index 9af5126..c2dc039 100644
--- a/drivers/regulator/wm831x-ldo.c
+++ b/drivers/regulator/wm831x-ldo.c
@@ -273,9 +273,9 @@
 
 	ldo->wm831x = wm831x;
 
-	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	res = platform_get_resource(pdev, IORESOURCE_REG, 0);
 	if (res == NULL) {
-		dev_err(&pdev->dev, "No I/O resource\n");
+		dev_err(&pdev->dev, "No REG resource\n");
 		ret = -EINVAL;
 		goto err;
 	}
@@ -530,9 +530,9 @@
 
 	ldo->wm831x = wm831x;
 
-	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	res = platform_get_resource(pdev, IORESOURCE_REG, 0);
 	if (res == NULL) {
-		dev_err(&pdev->dev, "No I/O resource\n");
+		dev_err(&pdev->dev, "No REG resource\n");
 		ret = -EINVAL;
 		goto err;
 	}
@@ -687,9 +687,9 @@
 
 	ldo->wm831x = wm831x;
 
-	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
+	res = platform_get_resource(pdev, IORESOURCE_REG, 0);
 	if (res == NULL) {
-		dev_err(&pdev->dev, "No I/O resource\n");
+		dev_err(&pdev->dev, "No REG resource\n");
 		ret = -EINVAL;
 		goto err;
 	}
diff --git a/drivers/rtc/rtc-88pm860x.c b/drivers/rtc/rtc-88pm860x.c
index feddefc..de9e854 100644
--- a/drivers/rtc/rtc-88pm860x.c
+++ b/drivers/rtc/rtc-88pm860x.c
@@ -11,6 +11,7 @@
 
 #include <linux/kernel.h>
 #include <linux/module.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/mutex.h>
@@ -284,6 +285,28 @@
 }
 #endif
 
+#ifdef CONFIG_OF
+static int __devinit pm860x_rtc_dt_init(struct platform_device *pdev,
+					struct pm860x_rtc_info *info)
+{
+	struct device_node *np = pdev->dev.parent->of_node;
+	int ret;
+	if (!np)
+		return -ENODEV;
+	np = of_find_node_by_name(np, "rtc");
+	if (!np) {
+		dev_err(&pdev->dev, "failed to find rtc node\n");
+		return -ENODEV;
+	}
+	ret = of_property_read_u32(np, "marvell,88pm860x-vrtc", &info->vrtc);
+	if (ret)
+		info->vrtc = 0;
+	return 0;
+}
+#else
+#define pm860x_rtc_dt_init(x, y)	(-1)
+#endif
+
 static int __devinit pm860x_rtc_probe(struct platform_device *pdev)
 {
 	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
@@ -294,8 +317,6 @@
 	int ret;
 
 	pdata = pdev->dev.platform_data;
-	if (pdata == NULL)
-		dev_warn(&pdev->dev, "No platform data!\n");
 
 	info = kzalloc(sizeof(struct pm860x_rtc_info), GFP_KERNEL);
 	if (!info)
@@ -345,9 +366,11 @@
 		}
 	}
 	rtc_tm_to_time(&tm, &ticks);
-	if (pdata && pdata->sync) {
-		pdata->sync(ticks);
-		info->sync = pdata->sync;
+	if (pm860x_rtc_dt_init(pdev, info)) {
+		if (pdata && pdata->sync) {
+			pdata->sync(ticks);
+			info->sync = pdata->sync;
+		}
 	}
 
 	info->rtc_dev = rtc_device_register("88pm860x-rtc", &pdev->dev,
@@ -366,10 +389,12 @@
 
 #ifdef VRTC_CALIBRATION
 	/* <00> -- 2.7V, <01> -- 2.9V, <10> -- 3.1V, <11> -- 3.3V */
-	if (pdata && pdata->vrtc)
-		info->vrtc = pdata->vrtc & 0x3;
-	else
-		info->vrtc = 1;
+	if (pm860x_rtc_dt_init(pdev, info)) {
+		if (pdata && pdata->vrtc)
+			info->vrtc = pdata->vrtc & 0x3;
+		else
+			info->vrtc = 1;
+	}
 	pm860x_set_bits(info->i2c, PM8607_MEAS_EN2, MEAS2_VRTC, MEAS2_VRTC);
 
 	/* calibrate VRTC */
diff --git a/drivers/video/backlight/88pm860x_bl.c b/drivers/video/backlight/88pm860x_bl.c
index f49181c..b7ec34c 100644
--- a/drivers/video/backlight/88pm860x_bl.c
+++ b/drivers/video/backlight/88pm860x_bl.c
@@ -11,6 +11,7 @@
 
 #include <linux/init.h>
 #include <linux/kernel.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/slab.h>
 #include <linux/fb.h>
@@ -31,57 +32,26 @@
 	int	port;
 	int	pwm;
 	int	iset;
+	int	reg_duty_cycle;
+	int	reg_always_on;
+	int	reg_current;
 };
 
-static inline int wled_a(int port)
-{
-	int ret;
-
-	ret = ((port - PM8606_BACKLIGHT1) << 1) + 2;
-	return ret;
-}
-
-static inline int wled_b(int port)
-{
-	int ret;
-
-	ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
-	return ret;
-}
-
-/* WLED2 & WLED3 share the same IDC */
-static inline int wled_idc(int port)
-{
-	int ret;
-
-	switch (port) {
-	case PM8606_BACKLIGHT1:
-	case PM8606_BACKLIGHT2:
-		ret = ((port - PM8606_BACKLIGHT1) << 1) + 3;
-		break;
-	case PM8606_BACKLIGHT3:
-	default:
-		ret = ((port - PM8606_BACKLIGHT2) << 1) + 3;
-		break;
-	}
-	return ret;
-}
-
 static int backlight_power_set(struct pm860x_chip *chip, int port,
 		int on)
 {
 	int ret = -EINVAL;
 
 	switch (port) {
-	case PM8606_BACKLIGHT1:
+	case 0:
 		ret = on ? pm8606_osc_enable(chip, WLED1_DUTY) :
 			pm8606_osc_disable(chip, WLED1_DUTY);
 		break;
-	case PM8606_BACKLIGHT2:
+	case 1:
 		ret = on ? pm8606_osc_enable(chip, WLED2_DUTY) :
 			pm8606_osc_disable(chip, WLED2_DUTY);
 		break;
-	case PM8606_BACKLIGHT3:
+	case 2:
 		ret = on ? pm8606_osc_enable(chip, WLED3_DUTY) :
 			pm8606_osc_disable(chip, WLED3_DUTY);
 		break;
@@ -104,13 +74,13 @@
 	if (brightness)
 		backlight_power_set(chip, data->port, 1);
 
-	ret = pm860x_reg_write(data->i2c, wled_a(data->port), value);
+	ret = pm860x_reg_write(data->i2c, data->reg_duty_cycle, value);
 	if (ret < 0)
 		goto out;
 
 	if ((data->current_brightness == 0) && brightness) {
 		if (data->iset) {
-			ret = pm860x_set_bits(data->i2c, wled_idc(data->port),
+			ret = pm860x_set_bits(data->i2c, data->reg_current,
 					      CURRENT_BITMASK, data->iset);
 			if (ret < 0)
 				goto out;
@@ -123,17 +93,17 @@
 		}
 		if (brightness == MAX_BRIGHTNESS) {
 			/* set WLED_ON bit as 100% */
-			ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+			ret = pm860x_set_bits(data->i2c, data->reg_always_on,
 					      PM8606_WLED_ON, PM8606_WLED_ON);
 		}
 	} else {
 		if (brightness == MAX_BRIGHTNESS) {
 			/* set WLED_ON bit as 100% */
-			ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+			ret = pm860x_set_bits(data->i2c, data->reg_always_on,
 					      PM8606_WLED_ON, PM8606_WLED_ON);
 		} else {
 			/* clear WLED_ON bit since it's not 100% */
-			ret = pm860x_set_bits(data->i2c, wled_b(data->port),
+			ret = pm860x_set_bits(data->i2c, data->reg_always_on,
 					      PM8606_WLED_ON, 0);
 		}
 	}
@@ -174,7 +144,7 @@
 	struct pm860x_chip *chip = data->chip;
 	int ret;
 
-	ret = pm860x_reg_read(data->i2c, wled_a(data->port));
+	ret = pm860x_reg_read(data->i2c, data->reg_duty_cycle);
 	if (ret < 0)
 		goto out;
 	data->current_brightness = ret;
@@ -190,45 +160,85 @@
 	.get_brightness	= pm860x_backlight_get_brightness,
 };
 
+#ifdef CONFIG_OF
+static int pm860x_backlight_dt_init(struct platform_device *pdev,
+				    struct pm860x_backlight_data *data,
+				    char *name)
+{
+	struct device_node *nproot = pdev->dev.parent->of_node, *np;
+	int iset = 0;
+	if (!nproot)
+		return -ENODEV;
+	nproot = of_find_node_by_name(nproot, "backlights");
+	if (!nproot) {
+		dev_err(&pdev->dev, "failed to find backlights node\n");
+		return -ENODEV;
+	}
+	for_each_child_of_node(nproot, np) {
+		if (!of_node_cmp(np->name, name)) {
+			of_property_read_u32(np, "marvell,88pm860x-iset",
+					     &iset);
+			data->iset = PM8606_WLED_CURRENT(iset);
+			of_property_read_u32(np, "marvell,88pm860x-pwm",
+					     &data->pwm);
+			break;
+		}
+	}
+	return 0;
+}
+#else
+#define pm860x_backlight_dt_init(x, y, z)	(-1)
+#endif
+
 static int pm860x_backlight_probe(struct platform_device *pdev)
 {
 	struct pm860x_chip *chip = dev_get_drvdata(pdev->dev.parent);
-	struct pm860x_backlight_pdata *pdata = NULL;
+	struct pm860x_backlight_pdata *pdata = pdev->dev.platform_data;
 	struct pm860x_backlight_data *data;
 	struct backlight_device *bl;
 	struct resource *res;
 	struct backlight_properties props;
 	char name[MFD_NAME_SIZE];
-	int ret;
-
-	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "No I/O resource!\n");
-		return -EINVAL;
-	}
-
-	pdata = pdev->dev.platform_data;
-	if (pdata == NULL) {
-		dev_err(&pdev->dev, "platform data isn't assigned to "
-			"backlight\n");
-		return -EINVAL;
-	}
+	int ret = 0;
 
 	data = devm_kzalloc(&pdev->dev, sizeof(struct pm860x_backlight_data),
 			    GFP_KERNEL);
 	if (data == NULL)
 		return -ENOMEM;
-	strncpy(name, res->name, MFD_NAME_SIZE);
+	res = platform_get_resource_byname(pdev, IORESOURCE_REG, "duty cycle");
+	if (!res) {
+		dev_err(&pdev->dev, "No REG resource for duty cycle\n");
+		ret = -ENXIO;
+		goto out;
+	}
+	data->reg_duty_cycle = res->start;
+	res = platform_get_resource_byname(pdev, IORESOURCE_REG, "always on");
+	if (!res) {
+		dev_err(&pdev->dev, "No REG resorce for always on\n");
+		ret = -ENXIO;
+		goto out;
+	}
+	data->reg_always_on = res->start;
+	res = platform_get_resource_byname(pdev, IORESOURCE_REG, "current");
+	if (!res) {
+		dev_err(&pdev->dev, "No REG resource for current\n");
+		ret = -ENXIO;
+		goto out;
+	}
+	data->reg_current = res->start;
+
+	memset(name, 0, MFD_NAME_SIZE);
+	sprintf(name, "backlight-%d", pdev->id);
+	data->port = pdev->id;
 	data->chip = chip;
 	data->i2c = (chip->id == CHIP_PM8606) ? chip->client	\
 			: chip->companion;
 	data->current_brightness = MAX_BRIGHTNESS;
-	data->pwm = pdata->pwm;
-	data->iset = pdata->iset;
-	data->port = pdata->flags;
-	if (data->port < 0) {
-		dev_err(&pdev->dev, "wrong platform data is assigned");
-		return -EINVAL;
+	if (pm860x_backlight_dt_init(pdev, data, name)) {
+		if (pdata) {
+			data->pwm = pdata->pwm;
+			data->iset = pdata->iset;
+		}
 	}
 
 	memset(&props, 0, sizeof(struct backlight_properties));
@@ -247,12 +257,14 @@
 	/* read current backlight */
 	ret = pm860x_backlight_get_brightness(bl);
 	if (ret < 0)
-		goto out;
+		goto out_brt;
 
 	backlight_update_status(bl);
 	return 0;
-out:
+out_brt:
 	backlight_device_unregister(bl);
+out:
+	devm_kfree(&pdev->dev, data);
 	return ret;
 }
 
diff --git a/drivers/video/backlight/Kconfig b/drivers/video/backlight/Kconfig
index cf28276..63cee2e 100644
--- a/drivers/video/backlight/Kconfig
+++ b/drivers/video/backlight/Kconfig
@@ -373,6 +373,13 @@
 	  If you have a Pandora console, say Y to enable the
 	  backlight driver.
 
+config BACKLIGHT_TPS65217
+	tristate "TPS65217 Backlight"
+	depends on BACKLIGHT_CLASS_DEVICE && MFD_TPS65217
+	help
+	  If you have a Texas Instruments TPS65217 say Y to enable the
+	  backlight driver.
+
 endif # BACKLIGHT_CLASS_DEVICE
 
 endif # BACKLIGHT_LCD_SUPPORT
diff --git a/drivers/video/backlight/Makefile b/drivers/video/backlight/Makefile
index a2ac9cf..00223a6 100644
--- a/drivers/video/backlight/Makefile
+++ b/drivers/video/backlight/Makefile
@@ -43,3 +43,4 @@
 obj-$(CONFIG_BACKLIGHT_PCF50633)	+= pcf50633-backlight.o
 obj-$(CONFIG_BACKLIGHT_AAT2870) += aat2870_bl.o
 obj-$(CONFIG_BACKLIGHT_OT200) += ot200_bl.o
+obj-$(CONFIG_BACKLIGHT_TPS65217) += tps65217_bl.o
diff --git a/drivers/video/backlight/max8925_bl.c b/drivers/video/backlight/max8925_bl.c
index e833ac7..f72ba54 100644
--- a/drivers/video/backlight/max8925_bl.c
+++ b/drivers/video/backlight/max8925_bl.c
@@ -27,7 +27,9 @@
 struct max8925_backlight_data {
 	struct max8925_chip	*chip;
 
-	int		current_brightness;
+	int	current_brightness;
+	int	reg_mode_cntl;
+	int	reg_cntl;
 };
 
 static int max8925_backlight_set(struct backlight_device *bl, int brightness)
@@ -42,16 +44,16 @@
 	else
 		value = brightness;
 
-	ret = max8925_reg_write(chip->i2c, MAX8925_WLED_CNTL, value);
+	ret = max8925_reg_write(chip->i2c, data->reg_cntl, value);
 	if (ret < 0)
 		goto out;
 
 	if (!data->current_brightness && brightness)
 		/* enable WLED output */
-		ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 1);
+		ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 1, 1);
 	else if (!brightness)
 		/* disable WLED output */
-		ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 1, 0);
+		ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 1, 0);
 	if (ret < 0)
 		goto out;
 	dev_dbg(chip->dev, "set brightness %d\n", value);
@@ -85,7 +87,7 @@
 	struct max8925_chip *chip = data->chip;
 	int ret;
 
-	ret = max8925_reg_read(chip->i2c, MAX8925_WLED_CNTL);
+	ret = max8925_reg_read(chip->i2c, data->reg_cntl);
 	if (ret < 0)
 		return -EINVAL;
 	data->current_brightness = ret;
@@ -102,69 +104,70 @@
 static int __devinit max8925_backlight_probe(struct platform_device *pdev)
 {
 	struct max8925_chip *chip = dev_get_drvdata(pdev->dev.parent);
-	struct max8925_platform_data *max8925_pdata;
-	struct max8925_backlight_pdata *pdata = NULL;
+	struct max8925_backlight_pdata *pdata = pdev->dev.platform_data;
 	struct max8925_backlight_data *data;
 	struct backlight_device *bl;
 	struct backlight_properties props;
 	struct resource *res;
-	char name[MAX8925_NAME_SIZE];
 	unsigned char value;
-	int ret;
-
-	res = platform_get_resource(pdev, IORESOURCE_IO, 0);
-	if (res == NULL) {
-		dev_err(&pdev->dev, "No I/O resource!\n");
-		return -EINVAL;
-	}
-
-	if (pdev->dev.parent->platform_data) {
-		max8925_pdata = pdev->dev.parent->platform_data;
-		pdata = max8925_pdata->backlight;
-	}
-
-	if (!pdata) {
-		dev_err(&pdev->dev, "platform data isn't assigned to "
-			"backlight\n");
-		return -EINVAL;
-	}
+	int ret = 0;
 
 	data = devm_kzalloc(&pdev->dev, sizeof(struct max8925_backlight_data),
 			    GFP_KERNEL);
 	if (data == NULL)
 		return -ENOMEM;
-	strncpy(name, res->name, MAX8925_NAME_SIZE);
+
+	res = platform_get_resource(pdev, IORESOURCE_REG, 0);
+	if (!res) {
+		dev_err(&pdev->dev, "No REG resource for mode control!\n");
+		ret = -ENXIO;
+		goto out;
+	}
+	data->reg_mode_cntl = res->start;
+	res = platform_get_resource(pdev, IORESOURCE_REG, 1);
+	if (!res) {
+		dev_err(&pdev->dev, "No REG resource for control!\n");
+		ret = -ENXIO;
+		goto out;
+	}
+	data->reg_cntl = res->start;
+
 	data->chip = chip;
 	data->current_brightness = 0;
 
 	memset(&props, 0, sizeof(struct backlight_properties));
 	props.type = BACKLIGHT_RAW;
 	props.max_brightness = MAX_BRIGHTNESS;
-	bl = backlight_device_register(name, &pdev->dev, data,
+	bl = backlight_device_register("max8925-backlight", &pdev->dev, data,
 					&max8925_backlight_ops, &props);
 	if (IS_ERR(bl)) {
 		dev_err(&pdev->dev, "failed to register backlight\n");
-		return PTR_ERR(bl);
+		ret = PTR_ERR(bl);
+		goto out;
 	}
 	bl->props.brightness = MAX_BRIGHTNESS;
 
 	platform_set_drvdata(pdev, bl);
 
 	value = 0;
-	if (pdata->lxw_scl)
-		value |= (1 << 7);
-	if (pdata->lxw_freq)
-		value |= (LWX_FREQ(pdata->lxw_freq) << 4);
-	if (pdata->dual_string)
-		value |= (1 << 1);
-	ret = max8925_set_bits(chip->i2c, MAX8925_WLED_MODE_CNTL, 0xfe, value);
+	if (pdata) {
+		if (pdata->lxw_scl)
+			value |= (1 << 7);
+		if (pdata->lxw_freq)
+			value |= (LWX_FREQ(pdata->lxw_freq) << 4);
+		if (pdata->dual_string)
+			value |= (1 << 1);
+	}
+	ret = max8925_set_bits(chip->i2c, data->reg_mode_cntl, 0xfe, value);
 	if (ret < 0)
-		goto out;
+		goto out_brt;
 
 	backlight_update_status(bl);
 	return 0;
-out:
+out_brt:
 	backlight_device_unregister(bl);
+out:
+	devm_kfree(&pdev->dev, data);
 	return ret;
 }
 
diff --git a/drivers/video/backlight/tps65217_bl.c b/drivers/video/backlight/tps65217_bl.c
new file mode 100644
index 0000000..7088163
--- /dev/null
+++ b/drivers/video/backlight/tps65217_bl.c
@@ -0,0 +1,342 @@
+/*
+ * tps65217_bl.c
+ *
+ * TPS65217 backlight driver
+ *
+ * Copyright (C) 2012 Matthias Kaehlcke
+ * Author: Matthias Kaehlcke <matthias@kaehlcke.net>
+ *
+ * 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 version 2.
+ *
+ * This program is distributed "as is" WITHOUT ANY WARRANTY of any
+ * kind, whether express or implied; without even the implied warranty
+ * of MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ */
+
+#include <linux/kernel.h>
+#include <linux/backlight.h>
+#include <linux/err.h>
+#include <linux/fb.h>
+#include <linux/mfd/tps65217.h>
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/slab.h>
+
+struct tps65217_bl {
+	struct tps65217 *tps;
+	struct device *dev;
+	struct backlight_device *bl;
+	bool is_enabled;
+};
+
+static int tps65217_bl_enable(struct tps65217_bl *tps65217_bl)
+{
+	int rc;
+
+	rc = tps65217_set_bits(tps65217_bl->tps, TPS65217_REG_WLEDCTRL1,
+			TPS65217_WLEDCTRL1_ISINK_ENABLE,
+			TPS65217_WLEDCTRL1_ISINK_ENABLE, TPS65217_PROTECT_NONE);
+	if (rc) {
+		dev_err(tps65217_bl->dev,
+			"failed to enable backlight: %d\n", rc);
+		return rc;
+	}
+
+	tps65217_bl->is_enabled = true;
+
+	dev_dbg(tps65217_bl->dev, "backlight enabled\n");
+
+	return 0;
+}
+
+static int tps65217_bl_disable(struct tps65217_bl *tps65217_bl)
+{
+	int rc;
+
+	rc = tps65217_clear_bits(tps65217_bl->tps,
+				TPS65217_REG_WLEDCTRL1,
+				TPS65217_WLEDCTRL1_ISINK_ENABLE,
+				TPS65217_PROTECT_NONE);
+	if (rc) {
+		dev_err(tps65217_bl->dev,
+			"failed to disable backlight: %d\n", rc);
+		return rc;
+	}
+
+	tps65217_bl->is_enabled = false;
+
+	dev_dbg(tps65217_bl->dev, "backlight disabled\n");
+
+	return 0;
+}
+
+static int tps65217_bl_update_status(struct backlight_device *bl)
+{
+	struct tps65217_bl *tps65217_bl = bl_get_data(bl);
+	int rc;
+	int brightness = bl->props.brightness;
+
+	if (bl->props.state & BL_CORE_SUSPENDED)
+		brightness = 0;
+
+	if ((bl->props.power != FB_BLANK_UNBLANK) ||
+		(bl->props.fb_blank != FB_BLANK_UNBLANK))
+		/* framebuffer in low power mode or blanking active */
+		brightness = 0;
+
+	if (brightness > 0) {
+		rc = tps65217_reg_write(tps65217_bl->tps,
+					TPS65217_REG_WLEDCTRL2,
+					brightness - 1,
+					TPS65217_PROTECT_NONE);
+		if (rc) {
+			dev_err(tps65217_bl->dev,
+				"failed to set brightness level: %d\n", rc);
+			return rc;
+		}
+
+		dev_dbg(tps65217_bl->dev, "brightness set to %d\n", brightness);
+
+		if (!tps65217_bl->is_enabled)
+			rc = tps65217_bl_enable(tps65217_bl);
+	} else {
+		rc = tps65217_bl_disable(tps65217_bl);
+	}
+
+	return rc;
+}
+
+static int tps65217_bl_get_brightness(struct backlight_device *bl)
+{
+	return bl->props.brightness;
+}
+
+static const struct backlight_ops tps65217_bl_ops = {
+	.options	= BL_CORE_SUSPENDRESUME,
+	.update_status	= tps65217_bl_update_status,
+	.get_brightness	= tps65217_bl_get_brightness
+};
+
+static int tps65217_bl_hw_init(struct tps65217_bl *tps65217_bl,
+			struct tps65217_bl_pdata *pdata)
+{
+	int rc;
+
+	rc = tps65217_bl_disable(tps65217_bl);
+	if (rc)
+		return rc;
+
+	switch (pdata->isel) {
+	case TPS65217_BL_ISET1:
+		/* select ISET_1 current level */
+		rc = tps65217_clear_bits(tps65217_bl->tps,
+					TPS65217_REG_WLEDCTRL1,
+					TPS65217_WLEDCTRL1_ISEL,
+					TPS65217_PROTECT_NONE);
+		if (rc) {
+			dev_err(tps65217_bl->dev,
+				"failed to select ISET1 current level: %d)\n",
+				rc);
+			return rc;
+		}
+
+		dev_dbg(tps65217_bl->dev, "selected ISET1 current level\n");
+
+		break;
+
+	case TPS65217_BL_ISET2:
+		/* select ISET2 current level */
+		rc = tps65217_set_bits(tps65217_bl->tps, TPS65217_REG_WLEDCTRL1,
+				TPS65217_WLEDCTRL1_ISEL,
+				TPS65217_WLEDCTRL1_ISEL, TPS65217_PROTECT_NONE);
+		if (rc) {
+			dev_err(tps65217_bl->dev,
+				"failed to select ISET2 current level: %d\n",
+				rc);
+			return rc;
+		}
+
+		dev_dbg(tps65217_bl->dev, "selected ISET2 current level\n");
+
+		break;
+
+	default:
+		dev_err(tps65217_bl->dev,
+			"invalid value for current level: %d\n", pdata->isel);
+		return -EINVAL;
+	}
+
+	/* set PWM frequency */
+	rc = tps65217_set_bits(tps65217_bl->tps,
+			TPS65217_REG_WLEDCTRL1,
+			TPS65217_WLEDCTRL1_FDIM_MASK,
+			pdata->fdim,
+			TPS65217_PROTECT_NONE);
+	if (rc) {
+		dev_err(tps65217_bl->dev,
+			"failed to select PWM dimming frequency: %d\n",
+			rc);
+		return rc;
+	}
+
+	return 0;
+}
+
+#ifdef CONFIG_OF
+static struct tps65217_bl_pdata *
+tps65217_bl_parse_dt(struct platform_device *pdev)
+{
+	struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
+	struct device_node *node = of_node_get(tps->dev->of_node);
+	struct tps65217_bl_pdata *pdata, *err;
+	u32 val;
+
+	node = of_find_node_by_name(node, "backlight");
+	if (!node)
+		return ERR_PTR(-ENODEV);
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		dev_err(&pdev->dev, "failed to allocate platform data\n");
+		err = ERR_PTR(-ENOMEM);
+		goto err;
+	}
+
+	pdata->isel = TPS65217_BL_ISET1;
+	if (!of_property_read_u32(node, "isel", &val)) {
+		if (val < TPS65217_BL_ISET1 ||
+			val > TPS65217_BL_ISET2) {
+			dev_err(&pdev->dev,
+				"invalid 'isel' value in the device tree\n");
+			err = ERR_PTR(-EINVAL);
+			goto err;
+		}
+
+		pdata->isel = val;
+	}
+
+	pdata->fdim = TPS65217_BL_FDIM_200HZ;
+	if (!of_property_read_u32(node, "fdim", &val)) {
+		switch (val) {
+		case 100:
+			pdata->fdim = TPS65217_BL_FDIM_100HZ;
+			break;
+
+		case 200:
+			pdata->fdim = TPS65217_BL_FDIM_200HZ;
+			break;
+
+		case 500:
+			pdata->fdim = TPS65217_BL_FDIM_500HZ;
+			break;
+
+		case 1000:
+			pdata->fdim = TPS65217_BL_FDIM_1000HZ;
+			break;
+
+		default:
+			dev_err(&pdev->dev,
+				"invalid 'fdim' value in the device tree\n");
+			err = ERR_PTR(-EINVAL);
+			goto err;
+		}
+	}
+
+	of_node_put(node);
+
+	return pdata;
+
+err:
+	of_node_put(node);
+
+	return err;
+}
+#else
+static struct tps65217_bl_pdata *
+tps65217_bl_parse_dt(struct platform_device *pdev)
+{
+	return NULL;
+}
+#endif
+
+static int tps65217_bl_probe(struct platform_device *pdev)
+{
+	int rc;
+	struct tps65217 *tps = dev_get_drvdata(pdev->dev.parent);
+	struct tps65217_bl *tps65217_bl;
+	struct tps65217_bl_pdata *pdata;
+	struct backlight_properties bl_props;
+
+	if (tps->dev->of_node) {
+		pdata = tps65217_bl_parse_dt(pdev);
+		if (IS_ERR(pdata))
+			return PTR_ERR(pdata);
+	} else {
+		if (!pdev->dev.platform_data) {
+			dev_err(&pdev->dev, "no platform data provided\n");
+			return -EINVAL;
+		}
+
+		pdata = pdev->dev.platform_data;
+	}
+
+	tps65217_bl = devm_kzalloc(&pdev->dev, sizeof(*tps65217_bl),
+				GFP_KERNEL);
+	if (tps65217_bl == NULL) {
+		dev_err(&pdev->dev, "allocation of struct tps65217_bl failed\n");
+		return -ENOMEM;
+	}
+
+	tps65217_bl->tps = tps;
+	tps65217_bl->dev = &pdev->dev;
+	tps65217_bl->is_enabled = false;
+
+	rc = tps65217_bl_hw_init(tps65217_bl, pdata);
+	if (rc)
+		return rc;
+
+	memset(&bl_props, 0, sizeof(struct backlight_properties));
+	bl_props.type = BACKLIGHT_RAW;
+	bl_props.max_brightness = 100;
+
+	tps65217_bl->bl = backlight_device_register(pdev->name,
+						tps65217_bl->dev, tps65217_bl,
+						&tps65217_bl_ops, &bl_props);
+	if (IS_ERR(tps65217_bl->bl)) {
+		dev_err(tps65217_bl->dev,
+			"registration of backlight device failed: %d\n", rc);
+		return PTR_ERR(tps65217_bl->bl);
+	}
+
+	tps65217_bl->bl->props.brightness = 0;
+	platform_set_drvdata(pdev, tps65217_bl);
+
+	return 0;
+}
+
+static int tps65217_bl_remove(struct platform_device *pdev)
+{
+	struct tps65217_bl *tps65217_bl = platform_get_drvdata(pdev);
+
+	backlight_device_unregister(tps65217_bl->bl);
+
+	return 0;
+}
+
+static struct platform_driver tps65217_bl_driver = {
+	.probe		= tps65217_bl_probe,
+	.remove		= tps65217_bl_remove,
+	.driver		= {
+		.owner	= THIS_MODULE,
+		.name	= "tps65217-bl",
+	},
+};
+
+module_platform_driver(tps65217_bl_driver);
+
+MODULE_DESCRIPTION("TPS65217 Backlight driver");
+MODULE_LICENSE("GPL v2");
+MODULE_AUTHOR("Matthias Kaehlcke <matthias@kaehlcke.net>");
diff --git a/drivers/watchdog/iTCO_wdt.c b/drivers/watchdog/iTCO_wdt.c
index ceed39f..545d387 100644
--- a/drivers/watchdog/iTCO_wdt.c
+++ b/drivers/watchdog/iTCO_wdt.c
@@ -37,6 +37,7 @@
  *	document number TBD                   : DH89xxCC
  *	document number TBD                   : Panther Point
  *	document number TBD                   : Lynx Point
+ *	document number TBD                   : Lynx Point-LP
  */
 
 /*
diff --git a/include/linux/i2c/twl.h b/include/linux/i2c/twl.h
index a12a381..1faa58f 100644
--- a/include/linux/i2c/twl.h
+++ b/include/linux/i2c/twl.h
@@ -188,6 +188,7 @@
 
 int twl_get_type(void);
 int twl_get_version(void);
+int twl_get_hfclk_rate(void);
 
 int twl6030_interrupt_unmask(u8 bit_mask, u8 offset);
 int twl6030_interrupt_mask(u8 bit_mask, u8 offset);
diff --git a/include/linux/ioport.h b/include/linux/ioport.h
index 589e0e7..85ac9b9b 100644
--- a/include/linux/ioport.h
+++ b/include/linux/ioport.h
@@ -29,8 +29,9 @@
 #define IORESOURCE_BITS		0x000000ff	/* Bus-specific bits */
 
 #define IORESOURCE_TYPE_BITS	0x00001f00	/* Resource type */
-#define IORESOURCE_IO		0x00000100
+#define IORESOURCE_IO		0x00000100	/* PCI/ISA I/O ports */
 #define IORESOURCE_MEM		0x00000200
+#define IORESOURCE_REG		0x00000300	/* Register offsets */
 #define IORESOURCE_IRQ		0x00000400
 #define IORESOURCE_DMA		0x00000800
 #define IORESOURCE_BUS		0x00001000
diff --git a/include/linux/mfd/88pm860x.h b/include/linux/mfd/88pm860x.h
index 7b24943..ef3e6b7 100644
--- a/include/linux/mfd/88pm860x.h
+++ b/include/linux/mfd/88pm860x.h
@@ -34,22 +34,6 @@
 	PM8606_ID_MAX,
 };
 
-enum {
-	PM8606_BACKLIGHT1 = 0,
-	PM8606_BACKLIGHT2,
-	PM8606_BACKLIGHT3,
-};
-
-enum {
-	PM8606_LED1_RED = 0,
-	PM8606_LED1_GREEN,
-	PM8606_LED1_BLUE,
-	PM8606_LED2_RED,
-	PM8606_LED2_GREEN,
-	PM8606_LED2_BLUE,
-	PM8607_LED_VIBRATOR,
-};
-
 
 /* 8606 Registers */
 #define PM8606_DCM_BOOST		(0x00)
@@ -322,7 +306,7 @@
 	struct regmap           *regmap_companion;
 
 	int			buck3_double;	/* DVC ramp slope double */
-	unsigned short		companion_addr;
+	int			companion_addr;
 	unsigned short		osc_vote;
 	int			id;
 	int			irq_mode;
@@ -340,16 +324,12 @@
 };
 
 struct pm860x_backlight_pdata {
-	int		id;
 	int		pwm;
 	int		iset;
-	unsigned long	flags;
 };
 
 struct pm860x_led_pdata {
-	int		id;
 	int		iset;
-	unsigned long	flags;
 };
 
 struct pm860x_rtc_pdata {
@@ -379,15 +359,29 @@
 	struct pm860x_rtc_pdata		*rtc;
 	struct pm860x_touch_pdata	*touch;
 	struct pm860x_power_pdata	*power;
-	struct regulator_init_data	*regulator;
+	struct regulator_init_data	*buck1;
+	struct regulator_init_data	*buck2;
+	struct regulator_init_data	*buck3;
+	struct regulator_init_data	*ldo1;
+	struct regulator_init_data	*ldo2;
+	struct regulator_init_data	*ldo3;
+	struct regulator_init_data	*ldo4;
+	struct regulator_init_data	*ldo5;
+	struct regulator_init_data	*ldo6;
+	struct regulator_init_data	*ldo7;
+	struct regulator_init_data	*ldo8;
+	struct regulator_init_data	*ldo9;
+	struct regulator_init_data	*ldo10;
+	struct regulator_init_data	*ldo12;
+	struct regulator_init_data	*ldo_vibrator;
+	struct regulator_init_data	*ldo14;
 
-	unsigned short	companion_addr;	/* I2C address of companion chip */
+	int 		companion_addr;	/* I2C address of companion chip */
 	int		i2c_port;	/* Controlled by GI2C or PI2C */
 	int		irq_mode;	/* Clear interrupt by read/write(0/1) */
 	int		irq_base;	/* IRQ base number of 88pm860x */
 	int		num_leds;
 	int		num_backlights;
-	int		num_regulators;
 };
 
 extern int pm8606_osc_enable(struct pm860x_chip *, unsigned short);
@@ -408,8 +402,4 @@
 extern int pm860x_page_set_bits(struct i2c_client *, int, unsigned char,
 				unsigned char);
 
-extern int pm860x_device_init(struct pm860x_chip *chip,
-			      struct pm860x_platform_data *pdata) __devinit ;
-extern void pm860x_device_exit(struct pm860x_chip *chip) __devexit ;
-
 #endif /* __LINUX_MFD_88PM860X_H */
diff --git a/include/linux/mfd/ab3100.h b/include/linux/mfd/ab3100.h
new file mode 100644
index 0000000..afd3080
--- /dev/null
+++ b/include/linux/mfd/ab3100.h
@@ -0,0 +1,129 @@
+/*
+ * Copyright (C) 2007-2009 ST-Ericsson AB
+ * License terms: GNU General Public License (GPL) version 2
+ * AB3100 core access functions
+ * Author: Linus Walleij <linus.walleij@stericsson.com>
+ *
+ */
+
+#include <linux/regulator/machine.h>
+
+struct device;
+
+#ifndef MFD_AB3100_H
+#define MFD_AB3100_H
+
+
+#define AB3100_P1A	0xc0
+#define AB3100_P1B	0xc1
+#define AB3100_P1C	0xc2
+#define AB3100_P1D	0xc3
+#define AB3100_P1E	0xc4
+#define AB3100_P1F	0xc5
+#define AB3100_P1G	0xc6
+#define AB3100_R2A	0xc7
+#define AB3100_R2B	0xc8
+
+/*
+ * AB3100, EVENTA1, A2 and A3 event register flags
+ * these are catenated into a single 32-bit flag in the code
+ * for event notification broadcasts.
+ */
+#define AB3100_EVENTA1_ONSWA				(0x01<<16)
+#define AB3100_EVENTA1_ONSWB				(0x02<<16)
+#define AB3100_EVENTA1_ONSWC				(0x04<<16)
+#define AB3100_EVENTA1_DCIO				(0x08<<16)
+#define AB3100_EVENTA1_OVER_TEMP			(0x10<<16)
+#define AB3100_EVENTA1_SIM_OFF				(0x20<<16)
+#define AB3100_EVENTA1_VBUS				(0x40<<16)
+#define AB3100_EVENTA1_VSET_USB				(0x80<<16)
+
+#define AB3100_EVENTA2_READY_TX				(0x01<<8)
+#define AB3100_EVENTA2_READY_RX				(0x02<<8)
+#define AB3100_EVENTA2_OVERRUN_ERROR			(0x04<<8)
+#define AB3100_EVENTA2_FRAMING_ERROR			(0x08<<8)
+#define AB3100_EVENTA2_CHARG_OVERCURRENT		(0x10<<8)
+#define AB3100_EVENTA2_MIDR				(0x20<<8)
+#define AB3100_EVENTA2_BATTERY_REM			(0x40<<8)
+#define AB3100_EVENTA2_ALARM				(0x80<<8)
+
+#define AB3100_EVENTA3_ADC_TRIG5			(0x01)
+#define AB3100_EVENTA3_ADC_TRIG4			(0x02)
+#define AB3100_EVENTA3_ADC_TRIG3			(0x04)
+#define AB3100_EVENTA3_ADC_TRIG2			(0x08)
+#define AB3100_EVENTA3_ADC_TRIGVBAT			(0x10)
+#define AB3100_EVENTA3_ADC_TRIGVTX			(0x20)
+#define AB3100_EVENTA3_ADC_TRIG1			(0x40)
+#define AB3100_EVENTA3_ADC_TRIG0			(0x80)
+
+/* AB3100, STR register flags */
+#define AB3100_STR_ONSWA				(0x01)
+#define AB3100_STR_ONSWB				(0x02)
+#define AB3100_STR_ONSWC				(0x04)
+#define AB3100_STR_DCIO					(0x08)
+#define AB3100_STR_BOOT_MODE				(0x10)
+#define AB3100_STR_SIM_OFF				(0x20)
+#define AB3100_STR_BATT_REMOVAL				(0x40)
+#define AB3100_STR_VBUS					(0x80)
+
+/*
+ * AB3100 contains 8 regulators, one external regulator controller
+ * and a buck converter, further the LDO E and buck converter can
+ * have separate settings if they are in sleep mode, this is
+ * modeled as a separate regulator.
+ */
+#define AB3100_NUM_REGULATORS				10
+
+/**
+ * struct ab3100
+ * @access_mutex: lock out concurrent accesses to the AB3100 registers
+ * @dev: pointer to the containing device
+ * @i2c_client: I2C client for this chip
+ * @testreg_client: secondary client for test registers
+ * @chip_name: name of this chip variant
+ * @chip_id: 8 bit chip ID for this chip variant
+ * @event_subscribers: event subscribers are listed here
+ * @startup_events: a copy of the first reading of the event registers
+ * @startup_events_read: whether the first events have been read
+ *
+ * This struct is PRIVATE and devices using it should NOT
+ * access ANY fields. It is used as a token for calling the
+ * AB3100 functions.
+ */
+struct ab3100 {
+	struct mutex access_mutex;
+	struct device *dev;
+	struct i2c_client *i2c_client;
+	struct i2c_client *testreg_client;
+	char chip_name[32];
+	u8 chip_id;
+	struct blocking_notifier_head event_subscribers;
+	u8 startup_events[3];
+	bool startup_events_read;
+};
+
+/**
+ * struct ab3100_platform_data
+ * Data supplied to initialize board connections to the AB3100
+ * @reg_constraints: regulator constraints for target board
+ *     the order of these constraints are: LDO A, C, D, E,
+ *     F, G, H, K, EXT and BUCK.
+ * @reg_initvals: initial values for the regulator registers
+ *     plus two sleep settings for LDO E and the BUCK converter.
+ *     exactly AB3100_NUM_REGULATORS+2 values must be sent in.
+ *     Order: LDO A, C, E, E sleep, F, G, H, K, EXT, BUCK,
+ *     BUCK sleep, LDO D. (LDO D need to be initialized last.)
+ * @external_voltage: voltage level of the external regulator.
+ */
+struct ab3100_platform_data {
+	struct regulator_init_data reg_constraints[AB3100_NUM_REGULATORS];
+	u8 reg_initvals[AB3100_NUM_REGULATORS+2];
+	int external_voltage;
+};
+
+int ab3100_event_register(struct ab3100 *ab3100,
+			  struct notifier_block *nb);
+int ab3100_event_unregister(struct ab3100 *ab3100,
+			    struct notifier_block *nb);
+
+#endif /*  MFD_AB3100_H */
diff --git a/include/linux/mfd/abx500.h b/include/linux/mfd/abx500.h
index 1318ca6..5d5298d 100644
--- a/include/linux/mfd/abx500.h
+++ b/include/linux/mfd/abx500.h
@@ -1,12 +1,9 @@
 /*
  * Copyright (C) 2007-2009 ST-Ericsson AB
  * License terms: GNU General Public License (GPL) version 2
- * AB3100 core access functions
- * Author: Linus Walleij <linus.walleij@stericsson.com>
  *
  * ABX500 core access functions.
- * The abx500 interface is used for the Analog Baseband chip
- * ab3100 and ab8500.
+ * The abx500 interface is used for the Analog Baseband chips.
  *
  * Author: Mattias Wallin <mattias.wallin@stericsson.com>
  * Author: Mattias Nilsson <mattias.i.nilsson@stericsson.com>
@@ -21,118 +18,6 @@
 #ifndef MFD_ABX500_H
 #define MFD_ABX500_H
 
-#define AB3100_P1A	0xc0
-#define AB3100_P1B	0xc1
-#define AB3100_P1C	0xc2
-#define AB3100_P1D	0xc3
-#define AB3100_P1E	0xc4
-#define AB3100_P1F	0xc5
-#define AB3100_P1G	0xc6
-#define AB3100_R2A	0xc7
-#define AB3100_R2B	0xc8
-
-/*
- * AB3100, EVENTA1, A2 and A3 event register flags
- * these are catenated into a single 32-bit flag in the code
- * for event notification broadcasts.
- */
-#define AB3100_EVENTA1_ONSWA				(0x01<<16)
-#define AB3100_EVENTA1_ONSWB				(0x02<<16)
-#define AB3100_EVENTA1_ONSWC				(0x04<<16)
-#define AB3100_EVENTA1_DCIO				(0x08<<16)
-#define AB3100_EVENTA1_OVER_TEMP			(0x10<<16)
-#define AB3100_EVENTA1_SIM_OFF				(0x20<<16)
-#define AB3100_EVENTA1_VBUS				(0x40<<16)
-#define AB3100_EVENTA1_VSET_USB				(0x80<<16)
-
-#define AB3100_EVENTA2_READY_TX				(0x01<<8)
-#define AB3100_EVENTA2_READY_RX				(0x02<<8)
-#define AB3100_EVENTA2_OVERRUN_ERROR			(0x04<<8)
-#define AB3100_EVENTA2_FRAMING_ERROR			(0x08<<8)
-#define AB3100_EVENTA2_CHARG_OVERCURRENT		(0x10<<8)
-#define AB3100_EVENTA2_MIDR				(0x20<<8)
-#define AB3100_EVENTA2_BATTERY_REM			(0x40<<8)
-#define AB3100_EVENTA2_ALARM				(0x80<<8)
-
-#define AB3100_EVENTA3_ADC_TRIG5			(0x01)
-#define AB3100_EVENTA3_ADC_TRIG4			(0x02)
-#define AB3100_EVENTA3_ADC_TRIG3			(0x04)
-#define AB3100_EVENTA3_ADC_TRIG2			(0x08)
-#define AB3100_EVENTA3_ADC_TRIGVBAT			(0x10)
-#define AB3100_EVENTA3_ADC_TRIGVTX			(0x20)
-#define AB3100_EVENTA3_ADC_TRIG1			(0x40)
-#define AB3100_EVENTA3_ADC_TRIG0			(0x80)
-
-/* AB3100, STR register flags */
-#define AB3100_STR_ONSWA				(0x01)
-#define AB3100_STR_ONSWB				(0x02)
-#define AB3100_STR_ONSWC				(0x04)
-#define AB3100_STR_DCIO					(0x08)
-#define AB3100_STR_BOOT_MODE				(0x10)
-#define AB3100_STR_SIM_OFF				(0x20)
-#define AB3100_STR_BATT_REMOVAL				(0x40)
-#define AB3100_STR_VBUS					(0x80)
-
-/*
- * AB3100 contains 8 regulators, one external regulator controller
- * and a buck converter, further the LDO E and buck converter can
- * have separate settings if they are in sleep mode, this is
- * modeled as a separate regulator.
- */
-#define AB3100_NUM_REGULATORS				10
-
-/**
- * struct ab3100
- * @access_mutex: lock out concurrent accesses to the AB3100 registers
- * @dev: pointer to the containing device
- * @i2c_client: I2C client for this chip
- * @testreg_client: secondary client for test registers
- * @chip_name: name of this chip variant
- * @chip_id: 8 bit chip ID for this chip variant
- * @event_subscribers: event subscribers are listed here
- * @startup_events: a copy of the first reading of the event registers
- * @startup_events_read: whether the first events have been read
- *
- * This struct is PRIVATE and devices using it should NOT
- * access ANY fields. It is used as a token for calling the
- * AB3100 functions.
- */
-struct ab3100 {
-	struct mutex access_mutex;
-	struct device *dev;
-	struct i2c_client *i2c_client;
-	struct i2c_client *testreg_client;
-	char chip_name[32];
-	u8 chip_id;
-	struct blocking_notifier_head event_subscribers;
-	u8 startup_events[3];
-	bool startup_events_read;
-};
-
-/**
- * struct ab3100_platform_data
- * Data supplied to initialize board connections to the AB3100
- * @reg_constraints: regulator constraints for target board
- *     the order of these constraints are: LDO A, C, D, E,
- *     F, G, H, K, EXT and BUCK.
- * @reg_initvals: initial values for the regulator registers
- *     plus two sleep settings for LDO E and the BUCK converter.
- *     exactly AB3100_NUM_REGULATORS+2 values must be sent in.
- *     Order: LDO A, C, E, E sleep, F, G, H, K, EXT, BUCK,
- *     BUCK sleep, LDO D. (LDO D need to be initialized last.)
- * @external_voltage: voltage level of the external regulator.
- */
-struct ab3100_platform_data {
-	struct regulator_init_data reg_constraints[AB3100_NUM_REGULATORS];
-	u8 reg_initvals[AB3100_NUM_REGULATORS+2];
-	int external_voltage;
-};
-
-int ab3100_event_register(struct ab3100 *ab3100,
-			  struct notifier_block *nb);
-int ab3100_event_unregister(struct ab3100 *ab3100,
-			    struct notifier_block *nb);
-
 /**
  * struct abx500_init_setting
  * Initial value of the registers for driver to use during setup.
diff --git a/include/linux/mfd/abx500/ab8500.h b/include/linux/mfd/abx500/ab8500.h
index 3764cb6..1491044 100644
--- a/include/linux/mfd/abx500/ab8500.h
+++ b/include/linux/mfd/abx500/ab8500.h
@@ -341,6 +341,4 @@
 	return (is_ab8500(ab) && (ab->chip_id == AB8500_CUT2P0));
 }
 
-int ab8500_irq_get_virq(struct ab8500 *ab8500, int irq);
-
 #endif /* MFD_AB8500_H */
diff --git a/include/linux/mfd/anatop.h b/include/linux/mfd/anatop.h
deleted file mode 100644
index 7f92acf..0000000
--- a/include/linux/mfd/anatop.h
+++ /dev/null
@@ -1,40 +0,0 @@
-/*
- * anatop.h - Anatop MFD driver
- *
- *  Copyright (C) 2012 Ying-Chun Liu (PaulLiu) <paul.liu@linaro.org>
- *  Copyright (C) 2012 Linaro
- *
- * 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., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
- */
-
-#ifndef __LINUX_MFD_ANATOP_H
-#define __LINUX_MFD_ANATOP_H
-
-#include <linux/spinlock.h>
-
-/**
- * anatop - MFD data
- * @ioreg: ioremap register
- * @reglock: spinlock for register read/write
- */
-struct anatop {
-	void *ioreg;
-	spinlock_t reglock;
-};
-
-extern u32 anatop_read_reg(struct anatop *, u32);
-extern void anatop_write_reg(struct anatop *, u32, u32, u32);
-
-#endif /*  __LINUX_MFD_ANATOP_H */
diff --git a/include/linux/mfd/da9055/core.h b/include/linux/mfd/da9055/core.h
new file mode 100644
index 0000000..c96ad68
--- /dev/null
+++ b/include/linux/mfd/da9055/core.h
@@ -0,0 +1,94 @@
+/*
+ * da9055 declarations for DA9055 PMICs.
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: David Dajun Chen <dchen@diasemi.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.
+ *
+ */
+
+#ifndef __DA9055_CORE_H
+#define __DA9055_CORE_H
+
+#include <linux/interrupt.h>
+#include <linux/regmap.h>
+
+/*
+ * PMIC IRQ
+ */
+#define DA9055_IRQ_ALARM	0x01
+#define DA9055_IRQ_TICK		0x02
+#define DA9055_IRQ_NONKEY	0x00
+#define DA9055_IRQ_REGULATOR	0x0B
+#define DA9055_IRQ_HWMON	0x03
+
+struct da9055_pdata;
+
+struct da9055 {
+	struct regmap *regmap;
+	struct regmap_irq_chip_data *irq_data;
+	struct device *dev;
+	struct i2c_client *i2c_client;
+
+	int irq_base;
+	int chip_irq;
+};
+
+/* Device I/O */
+static inline int da9055_reg_read(struct da9055 *da9055, unsigned char reg)
+{
+	int val, ret;
+
+	ret = regmap_read(da9055->regmap, reg, &val);
+	if (ret < 0)
+		return ret;
+
+	return val;
+}
+
+static inline int da9055_reg_write(struct da9055 *da9055, unsigned char reg,
+				    unsigned char val)
+{
+	return regmap_write(da9055->regmap, reg, val);
+}
+
+static inline int da9055_group_read(struct da9055 *da9055, unsigned char reg,
+				     unsigned reg_cnt, unsigned char *val)
+{
+	return regmap_bulk_read(da9055->regmap, reg, val, reg_cnt);
+}
+
+static inline int da9055_group_write(struct da9055 *da9055, unsigned char reg,
+				      unsigned reg_cnt, unsigned char *val)
+{
+	return regmap_raw_write(da9055->regmap, reg, val, reg_cnt);
+}
+
+static inline int da9055_reg_update(struct da9055 *da9055, unsigned char reg,
+				     unsigned char bit_mask,
+				     unsigned char reg_val)
+{
+	return regmap_update_bits(da9055->regmap, reg, bit_mask, reg_val);
+}
+
+/* Generic Device API */
+int da9055_device_init(struct da9055 *da9055);
+void da9055_device_exit(struct da9055 *da9055);
+
+extern struct regmap_config da9055_regmap_config;
+
+#endif /* __DA9055_CORE_H */
diff --git a/include/linux/mfd/da9055/pdata.h b/include/linux/mfd/da9055/pdata.h
new file mode 100644
index 0000000..147293b
--- /dev/null
+++ b/include/linux/mfd/da9055/pdata.h
@@ -0,0 +1,32 @@
+/* Copyright (C) 2012 Dialog Semiconductor Ltd.
+ *
+ *  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.
+ *
+ */
+#ifndef __DA9055_PDATA_H
+#define __DA9055_PDATA_H
+
+#define DA9055_MAX_REGULATORS	8
+
+struct da9055;
+
+enum gpio_select {
+	NO_GPIO = 0,
+	GPIO_1,
+	GPIO_2
+};
+
+struct da9055_pdata {
+	int (*init) (struct da9055 *da9055);
+	int irq_base;
+	int gpio_base;
+
+	struct regulator_init_data *regulators[DA9055_MAX_REGULATORS];
+	bool reset_enable;		/* Enable RTC in RESET Mode */
+	enum gpio_select *gpio_rsel;	/* Select regulator set thru GPIO 1/2 */
+	enum gpio_select *gpio_ren;	/* Enable regulator thru GPIO 1/2 */
+};
+#endif /* __DA9055_PDATA_H */
diff --git a/include/linux/mfd/da9055/reg.h b/include/linux/mfd/da9055/reg.h
new file mode 100644
index 0000000..df237ee
--- /dev/null
+++ b/include/linux/mfd/da9055/reg.h
@@ -0,0 +1,699 @@
+/*
+ * DA9055 declarations for DA9055 PMICs.
+ *
+ * Copyright(c) 2012 Dialog Semiconductor Ltd.
+ *
+ * Author: David Dajun Chen <dchen@diasemi.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.
+ *
+ */
+
+#ifndef __DA9055_REG_H
+#define __DA9055_REG_H
+
+/*
+ * PMIC registers
+ */
+ /* PAGE0 */
+#define	DA9055_REG_PAGE_CON		0x00
+
+/* System Control and Event Registers */
+#define	DA9055_REG_STATUS_A		0x01
+#define	DA9055_REG_STATUS_B		0x02
+#define	DA9055_REG_FAULT_LOG		0x03
+#define	DA9055_REG_EVENT_A		0x04
+#define	DA9055_REG_EVENT_B		0x05
+#define	DA9055_REG_EVENT_C		0x06
+#define	DA9055_REG_IRQ_MASK_A		0x07
+#define	DA9055_REG_IRQ_MASK_B		0x08
+#define	DA9055_REG_IRQ_MASK_C		0x09
+#define	DA9055_REG_CONTROL_A		0x0A
+#define	DA9055_REG_CONTROL_B		0x0B
+#define	DA9055_REG_CONTROL_C		0x0C
+#define	DA9055_REG_CONTROL_D		0x0D
+#define	DA9055_REG_CONTROL_E		0x0E
+#define	DA9055_REG_PD_DIS		0x0F
+
+/* GPIO Control Registers */
+#define	DA9055_REG_GPIO0_1		0x10
+#define	DA9055_REG_GPIO2		0x11
+#define	DA9055_REG_GPIO_MODE0_2		0x12
+
+/* Regulator Control Registers */
+#define	DA9055_REG_BCORE_CONT		0x13
+#define	DA9055_REG_BMEM_CONT		0x14
+#define	DA9055_REG_LDO1_CONT		0x15
+#define	DA9055_REG_LDO2_CONT		0x16
+#define	DA9055_REG_LDO3_CONT		0x17
+#define	DA9055_REG_LDO4_CONT		0x18
+#define	DA9055_REG_LDO5_CONT		0x19
+#define	DA9055_REG_LDO6_CONT		0x1A
+
+/* GP-ADC Control Registers */
+#define	DA9055_REG_ADC_MAN		0x1B
+#define	DA9055_REG_ADC_CONT		0x1C
+#define	DA9055_REG_VSYS_MON		0x1D
+#define	DA9055_REG_ADC_RES_L		0x1E
+#define	DA9055_REG_ADC_RES_H		0x1F
+#define	DA9055_REG_VSYS_RES		0x20
+#define	DA9055_REG_ADCIN1_RES		0x21
+#define	DA9055_REG_ADCIN2_RES		0x22
+#define	DA9055_REG_ADCIN3_RES		0x23
+
+/* Sequencer Control Registers */
+#define	DA9055_REG_EN_32K		0x35
+
+/* Regulator Setting Registers */
+#define	DA9055_REG_BUCK_LIM		0x37
+#define	DA9055_REG_BCORE_MODE		0x38
+#define	DA9055_REG_VBCORE_A		0x39
+#define	DA9055_REG_VBMEM_A		0x3A
+#define	DA9055_REG_VLDO1_A		0x3B
+#define	DA9055_REG_VLDO2_A		0x3C
+#define	DA9055_REG_VLDO3_A		0x3D
+#define	DA9055_REG_VLDO4_A		0x3E
+#define	DA9055_REG_VLDO5_A		0x3F
+#define	DA9055_REG_VLDO6_A		0x40
+#define	DA9055_REG_VBCORE_B		0x41
+#define	DA9055_REG_VBMEM_B		0x42
+#define	DA9055_REG_VLDO1_B		0x43
+#define	DA9055_REG_VLDO2_B		0x44
+#define	DA9055_REG_VLDO3_B		0x45
+#define	DA9055_REG_VLDO4_B		0x46
+#define	DA9055_REG_VLDO5_B		0x47
+#define	DA9055_REG_VLDO6_B		0x48
+
+/* GP-ADC Threshold Registers */
+#define	DA9055_REG_AUTO1_HIGH		0x49
+#define	DA9055_REG_AUTO1_LOW		0x4A
+#define	DA9055_REG_AUTO2_HIGH		0x4B
+#define	DA9055_REG_AUTO2_LOW		0x4C
+#define	DA9055_REG_AUTO3_HIGH		0x4D
+#define	DA9055_REG_AUTO3_LOW		0x4E
+
+/* OTP */
+#define	DA9055_REG_OPT_COUNT		0x50
+#define	DA9055_REG_OPT_ADDR		0x51
+#define	DA9055_REG_OPT_DATA		0x52
+
+/* RTC Calendar and Alarm Registers */
+#define	DA9055_REG_COUNT_S		0x53
+#define	DA9055_REG_COUNT_MI		0x54
+#define	DA9055_REG_COUNT_H		0x55
+#define	DA9055_REG_COUNT_D		0x56
+#define	DA9055_REG_COUNT_MO		0x57
+#define	DA9055_REG_COUNT_Y		0x58
+#define	DA9055_REG_ALARM_MI		0x59
+#define	DA9055_REG_ALARM_H		0x5A
+#define	DA9055_REG_ALARM_D		0x5B
+#define	DA9055_REG_ALARM_MO		0x5C
+#define	DA9055_REG_ALARM_Y		0x5D
+#define	DA9055_REG_SECOND_A		0x5E
+#define	DA9055_REG_SECOND_B		0x5F
+#define	DA9055_REG_SECOND_C		0x60
+#define	DA9055_REG_SECOND_D		0x61
+
+/* Customer Trim and Configuration */
+#define	DA9055_REG_T_OFFSET		0x63
+#define	DA9055_REG_INTERFACE		0x64
+#define	DA9055_REG_CONFIG_A		0x65
+#define	DA9055_REG_CONFIG_B		0x66
+#define	DA9055_REG_CONFIG_C		0x67
+#define	DA9055_REG_CONFIG_D		0x68
+#define	DA9055_REG_CONFIG_E		0x69
+#define	DA9055_REG_TRIM_CLDR		0x6F
+
+/* General Purpose Registers */
+#define	DA9055_REG_GP_ID_0		0x70
+#define	DA9055_REG_GP_ID_1		0x71
+#define	DA9055_REG_GP_ID_2		0x72
+#define	DA9055_REG_GP_ID_3		0x73
+#define	DA9055_REG_GP_ID_4		0x74
+#define	DA9055_REG_GP_ID_5		0x75
+#define	DA9055_REG_GP_ID_6		0x76
+#define	DA9055_REG_GP_ID_7		0x77
+#define	DA9055_REG_GP_ID_8		0x78
+#define	DA9055_REG_GP_ID_9		0x79
+#define	DA9055_REG_GP_ID_10		0x7A
+#define	DA9055_REG_GP_ID_11		0x7B
+#define	DA9055_REG_GP_ID_12		0x7C
+#define	DA9055_REG_GP_ID_13		0x7D
+#define	DA9055_REG_GP_ID_14		0x7E
+#define	DA9055_REG_GP_ID_15		0x7F
+#define	DA9055_REG_GP_ID_16		0x80
+#define	DA9055_REG_GP_ID_17		0x81
+#define	DA9055_REG_GP_ID_18		0x82
+#define	DA9055_REG_GP_ID_19		0x83
+
+#define DA9055_MAX_REGISTER_CNT		DA9055_REG_GP_ID_19
+
+/*
+ * PMIC registers bits
+ */
+
+/* DA9055_REG_PAGE_CON (addr=0x00) */
+#define	DA9055_PAGE_WRITE_MODE		(0<<6)
+#define	DA9055_REPEAT_WRITE_MODE	(1<<6)
+
+/* DA9055_REG_STATUS_A (addr=0x01) */
+#define	DA9055_NOKEY_STS		0x01
+#define	DA9055_WAKE_STS			0x02
+#define	DA9055_DVC_BUSY_STS		0x04
+#define	DA9055_COMP1V2_STS		0x08
+#define	DA9055_NJIG_STS			0x10
+#define	DA9055_LDO5_LIM_STS		0x20
+#define	DA9055_LDO6_LIM_STS		0x40
+
+/* DA9055_REG_STATUS_B (addr=0x02) */
+#define	DA9055_GPI0_STS			0x01
+#define	DA9055_GPI1_STS			0x02
+#define	DA9055_GPI2_STS			0x04
+
+/* DA9055_REG_FAULT_LOG (addr=0x03) */
+#define	DA9055_TWD_ERROR_FLG		0x01
+#define	DA9055_POR_FLG			0x02
+#define	DA9055_VDD_FAULT_FLG		0x04
+#define	DA9055_VDD_START_FLG		0x08
+#define	DA9055_TEMP_CRIT_FLG		0x10
+#define	DA9055_KEY_RESET_FLG		0x20
+#define	DA9055_WAIT_SHUT_FLG		0x80
+
+/* DA9055_REG_EVENT_A (addr=0x04) */
+#define	DA9055_NOKEY_EINT		0x01
+#define	DA9055_ALARM_EINT		0x02
+#define	DA9055_TICK_EINT		0x04
+#define	DA9055_ADC_RDY_EINT		0x08
+#define	DA9055_SEQ_RDY_EINT		0x10
+#define	DA9055_EVENTS_B_EINT		0x20
+#define	DA9055_EVENTS_C_EINT		0x40
+
+/* DA9055_REG_EVENT_B (addr=0x05) */
+#define	DA9055_E_WAKE_EINT		0x01
+#define	DA9055_E_TEMP_EINT		0x02
+#define	DA9055_E_COMP1V2_EINT		0x04
+#define	DA9055_E_LDO_LIM_EINT		0x08
+#define	DA9055_E_NJIG_EINT		0x20
+#define	DA9055_E_VDD_MON_EINT		0x40
+#define	DA9055_E_VDD_WARN_EINT		0x80
+
+/* DA9055_REG_EVENT_C (addr=0x06) */
+#define	DA9055_E_GPI0_EINT		0x01
+#define	DA9055_E_GPI1_EINT		0x02
+#define	DA9055_E_GPI2_EINT		0x04
+
+/* DA9055_REG_IRQ_MASK_A (addr=0x07) */
+#define	DA9055_M_NONKEY_EINT		0x01
+#define	DA9055_M_ALARM_EINT		0x02
+#define	DA9055_M_TICK_EINT		0x04
+#define	DA9055_M_ADC_RDY_EINT		0x08
+#define	DA9055_M_SEQ_RDY_EINT		0x10
+
+/* DA9055_REG_IRQ_MASK_B (addr=0x08) */
+#define	DA9055_M_WAKE_EINT		0x01
+#define	DA9055_M_TEMP_EINT		0x02
+#define	DA9055_M_COMP_1V2_EINT		0x04
+#define	DA9055_M_LDO_LIM_EINT		0x08
+#define	DA9055_M_NJIG_EINT		0x20
+#define	DA9055_M_VDD_MON_EINT		0x40
+#define	DA9055_M_VDD_WARN_EINT		0x80
+
+/* DA9055_REG_IRQ_MASK_C (addr=0x09) */
+#define	DA9055_M_GPI0_EINT		0x01
+#define	DA9055_M_GPI1_EINT		0x02
+#define	DA9055_M_GPI2_EINT		0x04
+
+/* DA9055_REG_CONTROL_A (addr=0xA) */
+#define	DA9055_DEBOUNCING_SHIFT		0x00
+#define	DA9055_DEBOUNCING_MASK		0x07
+#define	DA9055_NRES_MODE_SHIFT		0x03
+#define	DA9055_NRES_MODE_MASK		0x08
+#define	DA9055_SLEW_RATE_SHIFT		0x04
+#define	DA9055_SLEW_RATE_MASK		0x30
+#define	DA9055_NOKEY_LOCK_SHIFT		0x06
+#define	DA9055_NOKEY_LOCK_MASK		0x40
+
+/* DA9055_REG_CONTROL_B (addr=0xB) */
+#define	DA9055_RTC_MODE_PD		0x01
+#define	DA9055_RTC_MODE_SD_SHIFT	0x01
+#define	DA9055_RTC_MODE_SD		0x02
+#define	DA9055_RTC_EN			0x04
+#define	DA9055_ECO_MODE_SHIFT		0x03
+#define	DA9055_ECO_MODE_MASK		0x08
+#define	DA9055_TWDSCALE_SHIFT		4
+#define	DA9055_TWDSCALE_MASK		0x70
+#define	DA9055_V_LOCK_SHIFT		0x07
+#define	DA9055_V_LOCK_MASK		0x80
+
+/* DA9055_REG_CONTROL_C (addr=0xC) */
+#define	DA9055_SYSTEM_EN_SHIFT		0x00
+#define	DA9055_SYSTEM_EN_MASK		0x01
+#define	DA9055_POWERN_EN_SHIFT		0x01
+#define	DA9055_POWERN_EN_MASK		0x02
+#define	DA9055_POWER1_EN_SHIFT		0x02
+#define	DA9055_POWER1_EN_MASK		0x04
+
+/* DA9055_REG_CONTROL_D (addr=0xD) */
+#define	DA9055_STANDBY_SHIFT		0x02
+#define	DA9055_STANDBY_MASK		0x08
+#define	DA9055_AUTO_BOOT_SHIFT		0x03
+#define	DA9055_AUTO_BOOT_MASK		0x04
+
+/* DA9055_REG_CONTROL_E (addr=0xE) */
+#define	DA9055_WATCHDOG_SHIFT		0x00
+#define	DA9055_WATCHDOG_MASK		0x01
+#define	DA9055_SHUTDOWN_SHIFT		0x01
+#define	DA9055_SHUTDOWN_MASK		0x02
+#define	DA9055_WAKE_UP_SHIFT		0x02
+#define	DA9055_WAKE_UP_MASK		0x04
+
+/* DA9055_REG_GPIO (addr=0x10/0x11) */
+#define	DA9055_GPIO0_PIN_SHIFT		0x00
+#define	DA9055_GPIO0_PIN_MASK		0x03
+#define	DA9055_GPIO0_TYPE_SHIFT		0x02
+#define	DA9055_GPIO0_TYPE_MASK		0x04
+#define	DA9055_GPIO0_WEN_SHIFT		0x03
+#define	DA9055_GPIO0_WEN_MASK		0x08
+#define	DA9055_GPIO1_PIN_SHIFT		0x04
+#define	DA9055_GPIO1_PIN_MASK		0x30
+#define	DA9055_GPIO1_TYPE_SHIFT		0x06
+#define	DA9055_GPIO1_TYPE_MASK		0x40
+#define	DA9055_GPIO1_WEN_SHIFT		0x07
+#define	DA9055_GPIO1_WEN_MASK		0x80
+#define	DA9055_GPIO2_PIN_SHIFT		0x00
+#define	DA9055_GPIO2_PIN_MASK		0x30
+#define	DA9055_GPIO2_TYPE_SHIFT		0x02
+#define	DA9055_GPIO2_TYPE_MASK		0x04
+#define	DA9055_GPIO2_WEN_SHIFT		0x03
+#define	DA9055_GPIO2_WEN_MASK		0x08
+
+/* DA9055_REG_GPIO_MODE (addr=0x12) */
+#define	DA9055_GPIO0_MODE_SHIFT		0x00
+#define	DA9055_GPIO0_MODE_MASK		0x01
+#define	DA9055_GPIO1_MODE_SHIFT		0x01
+#define	DA9055_GPIO1_MODE_MASK		0x02
+#define	DA9055_GPIO2_MODE_SHIFT		0x02
+#define	DA9055_GPIO2_MODE_MASK		0x04
+
+/* DA9055_REG_BCORE_CONT (addr=0x13) */
+#define	DA9055_BCORE_EN_SHIFT		0x00
+#define	DA9055_BCORE_EN_MASK		0x01
+#define	DA9055_BCORE_GPI_SHIFT		0x01
+#define	DA9055_BCORE_GPI_MASK		0x02
+#define	DA9055_BCORE_PD_DIS_SHIFT	0x03
+#define	DA9055_BCORE_PD_DIS_MASK	0x04
+#define	DA9055_VBCORE_SEL_SHIFT		0x04
+#define	DA9055_SEL_REG_A		0x0
+#define	DA9055_SEL_REG_B		0x10
+#define	DA9055_VBCORE_SEL_MASK		0x10
+#define DA9055_V_GPI_MASK		0x60
+#define DA9055_V_GPI_SHIFT		0x05
+#define DA9055_E_GPI_MASK		0x06
+#define DA9055_E_GPI_SHIFT		0x01
+#define	DA9055_VBCORE_GPI_SHIFT		0x05
+#define	DA9055_VBCORE_GPI_MASK		0x60
+#define	DA9055_BCORE_CONF_SHIFT		0x07
+#define	DA9055_BCORE_CONF_MASK		0x80
+
+/* DA9055_REG_BMEM_CONT (addr=0x14) */
+#define	DA9055_BMEM_EN_SHIFT		0x00
+#define	DA9055_BMEM_EN_MASK		0x01
+#define	DA9055_BMEM_GPI_SHIFT		0x01
+#define	DA9055_BMEM_GPI_MASK		0x06
+#define	DA9055_BMEM_PD_DIS_SHIFT	0x03
+#define	DA9055_BMEM_PD_DIS_MASK		0x08
+#define	DA9055_VBMEM_SEL_SHIT		0x04
+#define	DA9055_VBMEM_SEL_VBMEM_A	(0<<4)
+#define	DA9055_VBMEM_SEL_VBMEM_B	(1<<4)
+#define	DA9055_VBMEM_SEL_MASK		0x10
+#define	DA9055_VBMEM_GPI_SHIFT		0x05
+#define	DA9055_VBMEM_GPI_MASK		0x60
+#define	DA9055_BMEM_CONF_SHIFT		0x07
+#define	DA9055_BMEM_CONF_MASK		0x80
+
+/* DA9055_REG_LDO_CONT (addr=0x15-0x1A) */
+#define	DA9055_LDO_EN_SHIFT		0x00
+#define	DA9055_LDO_EN_MASK		0x01
+#define	DA9055_LDO_GPI_SHIFT		0x01
+#define	DA9055_LDO_GPI_MASK		0x06
+#define	DA9055_LDO_PD_DIS_SHIFT		0x03
+#define	DA9055_LDO_PD_DIS_MASK		0x08
+#define	DA9055_VLDO_SEL_SHIFT		0x04
+#define	DA9055_VLDO_SEL_MASK		0x10
+#define	DA9055_VLDO_SEL_VLDO_A		0x00
+#define	DA9055_VLDO_SEL_VLDO_B		0x01
+#define	DA9055_VLDO_GPI_SHIFT		0x05
+#define	DA9055_VLDO_GPI_MASK		0x60
+#define	DA9055_LDO_CONF_SHIFT		0x07
+#define	DA9055_LDO_CONF_MASK		0x80
+#define	DA9055_REGUALTOR_SET_A		0x00
+#define	DA9055_REGUALTOR_SET_B		0x10
+
+/* DA9055_REG_ADC_MAN (addr=0x1B) */
+#define	DA9055_ADC_MUX_SHIFT		0
+#define	DA9055_ADC_MUX_MASK		0xF
+#define	DA9055_ADC_MUX_VSYS		0x0
+#define	DA9055_ADC_MUX_ADCIN1		0x01
+#define	DA9055_ADC_MUX_ADCIN2		0x02
+#define	DA9055_ADC_MUX_ADCIN3		0x03
+#define	DA9055_ADC_MUX_T_SENSE		0x04
+#define	DA9055_ADC_MAN_SHIFT		0x04
+#define	DA9055_ADC_MAN_CONV		0x10
+#define DA9055_ADC_LSB_MASK		0X03
+#define DA9055_ADC_MODE_MASK		0x20
+#define	DA9055_ADC_MODE_SHIFT		5
+#define	DA9055_ADC_MODE_1MS		(1<<5)
+#define	DA9055_COMP1V2_EN_SHIFT		7
+
+/* DA9055_REG_ADC_CONT (addr=0x1C) */
+#define	DA9055_ADC_AUTO_VSYS_EN_SHIFT	0
+#define	DA9055_ADC_AUTO_AD1_EN_SHIFT	1
+#define	DA9055_ADC_AUTO_AD2_EN_SHIFT	2
+#define	DA9055_ADC_AUTO_AD3_EN_SHIFT	3
+#define	DA9055_ADC_ISRC_EN_SHIFT	4
+#define	DA9055_ADC_ADCIN1_DEB_SHIFT	5
+#define	DA9055_ADC_ADCIN2_DEB_SHIFT	6
+#define	DA9055_ADC_ADCIN3_DEB_SHIFT	7
+#define DA9055_AD1_ISRC_MASK		0x10
+#define DA9055_AD1_ISRC_SHIFT		4
+
+/* DA9055_REG_VSYS_MON (addr=0x1D) */
+#define	DA9055_VSYS_VAL_SHIFT		0
+#define	DA9055_VSYS_VAL_MASK		0xFF
+#define	DA9055_VSYS_VAL_BASE		0x00
+#define	DA9055_VSYS_VAL_MAX		DA9055_VSYS_VAL_MASK
+#define	DA9055_VSYS_VOLT_BASE		2500
+#define	DA9055_VSYS_VOLT_INC		10
+#define	DA9055_VSYS_STEPS		255
+#define	DA9055_VSYS_VOLT_MIN		2500
+
+/* DA9044_REG_XXX_RES (addr=0x20-0x23) */
+#define	DA9055_ADC_VAL_SHIFT		0
+#define	DA9055_ADC_VAL_MASK		0xFF
+#define	DA9055_ADC_VAL_BASE		0x00
+#define	DA9055_ADC_VAL_MAX		DA9055_ADC_VAL_MASK
+#define	DA9055_ADC_VOLT_BASE		0
+#define	DA9055_ADC_VSYS_VOLT_BASE	2500
+#define	DA9055_ADC_VOLT_INC		10
+#define	DA9055_ADC_VSYS_VOLT_INC	12
+#define	DA9055_ADC_STEPS		255
+
+/* DA9055_REG_EN_32K  (addr=0x35)*/
+#define	DA9055_STARTUP_TIME_MASK	0x07
+#define	DA9055_STARTUP_TIME_0S		0x0
+#define	DA9055_STARTUP_TIME_0_52S	0x1
+#define	DA9055_STARTUP_TIME_1S		0x2
+#define	DA9055_CRYSTAL_EN		0x08
+#define	DA9055_DELAY_MODE_EN		0x10
+#define	DA9055_OUT_CLCK_GATED		0x20
+#define	DA9055_RTC_CLOCK_GATED		0x40
+#define	DA9055_EN_32KOUT_BUF		0x80
+
+/* DA9055_REG_RESET (addr=0x36) */
+/* Timer up to 31.744 ms */
+#define	DA9055_RESET_TIMER_VAL_SHIFT	0
+#define	DA9055_RESET_LOW_VAL_MASK	0x3F
+#define	DA9055_RESET_LOW_VAL_BASE	0
+#define	DA9055_RESET_LOW_VAL_MAX	DA9055_RESET_LOW_VAL_MASK
+#define	DA9055_RESET_US_LOW_BASE	1024 /* min val in units of us */
+#define	DA9055_RESET_US_LOW_INC		1024 /* inc val in units of us */
+#define	DA9055_RESET_US_LOW_STEP	30
+
+/* Timer up to 1048.576ms */
+#define	DA9055_RESET_HIGH_VAL_MASK	0x3F
+#define	DA9055_RESET_HIGH_VAL_BASE	0
+#define	DA9055_RESET_HIGH_VAL_MAX	DA9055_RESET_HIGH_VAL_MASK
+#define	DA9055_RESET_US_HIGH_BASE	32768 /* min val in units of us */
+#define	DA9055_RESET_US_HIGH_INC	32768 /* inv val in units of us */
+#define	DA9055_RESET_US_HIGH_STEP	31
+
+/* DA9055_REG_BUCK_ILIM (addr=0x37)*/
+#define	DA9055_BMEM_ILIM_SHIFT		0
+#define	DA9055_ILIM_MASK		0x3
+#define	DA9055_ILIM_500MA		0x0
+#define	DA9055_ILIM_600MA		0x1
+#define	DA9055_ILIM_700MA		0x2
+#define	DA9055_ILIM_800MA		0x3
+#define	DA9055_BCORE_ILIM_SHIFT		2
+
+/* DA9055_REG_BCORE_MODE (addr=0x38) */
+#define	DA9055_BMEM_MODE_SHIFT		0
+#define	DA9055_MODE_MASK		0x3
+#define	DA9055_MODE_AB			0x0
+#define	DA9055_MODE_SLEEP		0x1
+#define	DA9055_MODE_SYNCHRO		0x2
+#define	DA9055_MODE_AUTO		0x3
+#define	DA9055_BCORE_MODE_SHIFT		2
+
+/* DA9055_REG_VBCORE_A/B (addr=0x39/0x41)*/
+#define	DA9055_VBCORE_VAL_SHIFT		0
+#define	DA9055_VBCORE_VAL_MASK		0x3F
+#define	DA9055_VBCORE_VAL_BASE		0x09
+#define	DA9055_VBCORE_VAL_MAX		DA9055_VBCORE_VAL_MASK
+#define	DA9055_VBCORE_VOLT_BASE		750
+#define	DA9055_VBCORE_VOLT_INC		25
+#define	DA9055_VBCORE_STEPS		53
+#define	DA9055_VBCORE_VOLT_MIN		DA9055_VBCORE_VOLT_BASE
+#define	DA9055_BCORE_SL_SYNCHRO		(0<<7)
+#define	DA9055_BCORE_SL_SLEEP		(1<<7)
+
+/* DA9055_REG_VBMEM_A/B (addr=0x3A/0x42)*/
+#define	DA9055_VBMEM_VAL_SHIFT		0
+#define	DA9055_VBMEM_VAL_MASK		0x3F
+#define	DA9055_VBMEM_VAL_BASE		0x00
+#define	DA9055_VBMEM_VAL_MAX		DA9055_VBMEM_VAL_MASK
+#define	DA9055_VBMEM_VOLT_BASE		925
+#define	DA9055_VBMEM_VOLT_INC		25
+#define	DA9055_VBMEM_STEPS		63
+#define	DA9055_VBMEM_VOLT_MIN		DA9055_VBMEM_VOLT_BASE
+#define	DA9055_BCMEM_SL_SYNCHRO		(0<<7)
+#define	DA9055_BCMEM_SL_SLEEP		(1<<7)
+
+
+/* DA9055_REG_VLDO (addr=0x3B-0x40/0x43-0x48)*/
+#define	DA9055_VLDO_VAL_SHIFT		0
+#define	DA9055_VLDO_VAL_MASK		0x3F
+#define	DA9055_VLDO6_VAL_MASK		0x7F
+#define	DA9055_VLDO_VAL_BASE		0x02
+#define	DA9055_VLDO2_VAL_BASE		0x03
+#define	DA9055_VLDO6_VAL_BASE		0x00
+#define	DA9055_VLDO_VAL_MAX		DA9055_VLDO_VAL_MASK
+#define	DA9055_VLDO6_VAL_MAX		DA9055_VLDO6_VAL_MASK
+#define	DA9055_VLDO_VOLT_BASE		900
+#define	DA9055_VLDO_VOLT_INC		50
+#define	DA9055_VLDO6_VOLT_INC		20
+#define	DA9055_VLDO_STEPS		48
+#define	DA9055_VLDO5_STEPS		37
+#define	DA9055_VLDO6_STEPS		120
+#define	DA9055_VLDO_VOLT_MIN		DA9055_VLDO_VOLT_BASE
+#define	DA9055_LDO_MODE_SHIFT		7
+#define	DA9055_LDO_SL_NORMAL		0
+#define	DA9055_LDO_SL_SLEEP		1
+
+/* DA9055_REG_OTP_CONT (addr=0x50) */
+#define	DA9055_OTP_TIM_NORMAL		(0<<0)
+#define	DA9055_OTP_TIM_MARGINAL		(1<<0)
+#define	DA9055_OTP_GP_RD_SHIFT		1
+#define	DA9055_OTP_APPS_RD_SHIFT	2
+#define	DA9055_PC_DONE_SHIFT		3
+#define	DA9055_OTP_GP_LOCK_SHIFT	4
+#define	DA9055_OTP_APPS_LOCK_SHIFT	5
+#define	DA9055_OTP_CONF_LOCK_SHIFT	6
+#define	DA9055_OTP_WRITE_DIS_SHIFT	7
+
+/* DA9055_REG_COUNT_S (addr=0x53) */
+#define	DA9055_RTC_SEC			0x3F
+#define	DA9055_RTC_MONITOR_EN		0x40
+#define	DA9055_RTC_READ			0x80
+
+/* DA9055_REG_COUNT_MI (addr=0x54) */
+#define	DA9055_RTC_MIN			0x3F
+
+/* DA9055_REG_COUNT_H (addr=0x55) */
+#define	DA9055_RTC_HOUR			0x1F
+
+/* DA9055_REG_COUNT_D (addr=0x56) */
+#define	DA9055_RTC_DAY			0x1F
+
+/* DA9055_REG_COUNT_MO (addr=0x57) */
+#define	DA9055_RTC_MONTH		0x0F
+
+/* DA9055_REG_COUNT_Y (addr=0x58) */
+#define	DA9055_RTC_YEAR			0x3F
+#define	DA9055_RTC_YEAR_BASE		2000
+
+/* DA9055_REG_ALARM_MI (addr=0x59) */
+#define	DA9055_RTC_ALM_MIN		0x3F
+#define	DA9055_ALARM_STATUS_SHIFT	6
+#define	DA9055_ALARM_STATUS_MASK	0x3
+#define	DA9055_ALARM_STATUS_NO_ALARM	0x0
+#define	DA9055_ALARM_STATUS_TICK	0x1
+#define	DA9055_ALARM_STATUS_TIMER_ALARM	0x2
+#define	DA9055_ALARM_STATUS_BOTH	0x3
+
+/* DA9055_REG_ALARM_H (addr=0x5A) */
+#define	DA9055_RTC_ALM_HOUR		0x1F
+
+/* DA9055_REG_ALARM_D (addr=0x5B) */
+#define	DA9055_RTC_ALM_DAY		0x1F
+
+/* DA9055_REG_ALARM_MO (addr=0x5C) */
+#define	DA9055_RTC_ALM_MONTH		0x0F
+#define	DA9055_RTC_TICK_WAKE_MASK	0x20
+#define	DA9055_RTC_TICK_WAKE_SHIFT	5
+#define	DA9055_RTC_TICK_TYPE		0x10
+#define	DA9055_RTC_TICK_TYPE_SHIFT	0x4
+#define	DA9055_RTC_TICK_SEC		0x0
+#define	DA9055_RTC_TICK_MIN		0x1
+#define	DA9055_ALARAM_TICK_WAKE		0x20
+
+/* DA9055_REG_ALARM_Y (addr=0x5D) */
+#define	DA9055_RTC_TICK_EN		0x80
+#define	DA9055_RTC_ALM_EN		0x40
+#define	DA9055_RTC_TICK_ALM_MASK	0xC0
+#define	DA9055_RTC_ALM_YEAR		0x3F
+
+/* DA9055_REG_TRIM_CLDR (addr=0x62) */
+#define	DA9055_TRIM_32K_SHIFT		0
+#define	DA9055_TRIM_32K_MASK		0x7F
+#define	DA9055_TRIM_DECREMENT		(1<<7)
+#define	DA9055_TRIM_INCREMENT		(0<<7)
+#define	DA9055_TRIM_VAL_BASE		0x0
+#define	DA9055_TRIM_PPM_BASE		0x0 /* min val in units of 0.1PPM */
+#define	DA9055_TRIM_PPM_INC		19 /* min inc in units of 0.1PPM */
+#define	DA9055_TRIM_STEPS		127
+
+/* DA9055_REG_CONFIG_A (addr=0x65) */
+#define	DA9055_PM_I_V_VDDCORE		(0<<0)
+#define	DA9055_PM_I_V_VDD_IO		(1<<0)
+#define	DA9055_VDD_FAULT_TYPE_ACT_LOW	(0<<1)
+#define	DA9055_VDD_FAULT_TYPE_ACT_HIGH	(1<<1)
+#define	DA9055_PM_O_TYPE_PUSH_PULL	(0<<2)
+#define	DA9055_PM_O_TYPE_OPEN_DRAIN	(1<<2)
+#define	DA9055_IRQ_TYPE_ACT_LOW		(0<<3)
+#define	DA9055_IRQ_TYPE_ACT_HIGH	(1<<3)
+#define	DA9055_NIRQ_MODE_IMM		(0<<4)
+#define	DA9055_NIRQ_MODE_ACTIVE		(1<<4)
+#define	DA9055_GPI_V_VDDCORE		(0<<5)
+#define	DA9055_GPI_V_VDD_IO		(1<<5)
+#define	DA9055_PM_IF_V_VDDCORE		(0<<6)
+#define	DA9055_PM_IF_V_VDD_IO		(1<<6)
+
+/* DA9055_REG_CONFIG_B (addr=0x66) */
+#define	DA9055_VDD_FAULT_VAL_SHIFT	0
+#define	DA9055_VDD_FAULT_VAL_MASK	0xF
+#define	DA9055_VDD_FAULT_VAL_BASE	0x0
+#define	DA9055_VDD_FAULT_VAL_MAX	DA9055_VDD_FAULT_VAL_MASK
+#define	DA9055_VDD_FAULT_VOLT_BASE	2500
+#define	DA9055_VDD_FAULT_VOLT_INC	50
+#define	DA9055_VDD_FAULT_STEPS		15
+
+#define	DA9055_VDD_HYST_VAL_SHIFT	4
+#define	DA9055_VDD_HYST_VAL_MASK	0x7
+#define	DA9055_VDD_HYST_VAL_BASE	0x0
+#define	DA9055_VDD_HYST_VAL_MAX		DA9055_VDD_HYST_VAL_MASK
+#define	DA9055_VDD_HYST_VOLT_BASE	100
+#define	DA9055_VDD_HYST_VOLT_INC	50
+#define	DA9055_VDD_HYST_STEPS		7
+#define	DA9055_VDD_HYST_VOLT_MIN	DA9055_VDD_HYST_VOLT_BASE
+
+#define	DA9055_VDD_FAULT_EN_SHIFT	7
+
+/* DA9055_REG_CONFIG_C (addr=0x67) */
+#define	DA9055_BCORE_CLK_INV_SHIFT	0
+#define	DA9055_BMEM_CLK_INV_SHIFT	1
+#define	DA9055_NFAULT_CONF_SHIFT	2
+#define	DA9055_LDO_SD_SHIFT		4
+#define	DA9055_LDO5_BYP_SHIFT		6
+#define	DA9055_LDO6_BYP_SHIFT		7
+
+/* DA9055_REG_CONFIG_D (addr=0x68) */
+#define	DA9055_NONKEY_PIN_SHIFT		0
+#define	DA9055_NONKEY_PIN_MASK		0x3
+#define	DA9055_NONKEY_PIN_PORT_MODE	0x0
+#define	DA9055_NONKEY_PIN_KEY_MODE	0x1
+#define	DA9055_NONKEY_PIN_MULTI_FUNC	0x2
+#define	DA9055_NONKEY_PIN_DEDICT	0x3
+#define	DA9055_NONKEY_SD_SHIFT		2
+#define	DA9055_KEY_DELAY_SHIFT		3
+#define	DA9055_KEY_DELAY_MASK		0x3
+#define	DA9055_KEY_DELAY_4S		0x0
+#define	DA9055_KEY_DELAY_6S		0x1
+#define	DA9055_KEY_DELAY_8S		0x2
+#define	DA9055_KEY_DELAY_10S		0x3
+
+/* DA9055_REG_CONFIG_E (addr=0x69) */
+#define	DA9055_GPIO_PUPD_PULL_UP	0x0
+#define	DA9055_GPIO_PUPD_OPEN_DRAIN	0x1
+#define	DA9055_GPIO0_PUPD_SHIFT		0
+#define	DA9055_GPIO1_PUPD_SHIFT		1
+#define	DA9055_GPIO2_PUPD_SHIFT		2
+#define	DA9055_UVOV_DELAY_SHIFT		4
+#define	DA9055_UVOV_DELAY_MASK		0x3
+#define	DA9055_RESET_DURATION_SHIFT	6
+#define	DA9055_RESET_DURATION_MASK	0x3
+#define	DA9055_RESET_DURATION_0MS	0x0
+#define	DA9055_RESET_DURATION_100MS	0x1
+#define	DA9055_RESET_DURATION_500MS	0x2
+#define	DA9055_RESET_DURATION_1000MS	0x3
+
+/* DA9055_REG_MON_REG_1 (addr=0x6A) */
+#define	DA9055_MON_THRES_SHIFT		0
+#define	DA9055_MON_THRES_MASK		0x3
+#define	DA9055_MON_RES_SHIFT		2
+#define	DA9055_MON_DEB_SHIFT		3
+#define	DA9055_MON_MODE_SHIFT		4
+#define	DA9055_MON_MODE_MASK		0x3
+#define	DA9055_START_MAX_SHIFT		6
+#define	DA9055_START_MAX_MASK		0x3
+
+/* DA9055_REG_MON_REG_2 (addr=0x6B) */
+#define	DA9055_LDO1_MON_EN_SHIFT	0
+#define	DA9055_LDO2_MON_EN_SHIFT	1
+#define	DA9055_LDO3_MON_EN_SHIFT	2
+#define	DA9055_LDO4_MON_EN_SHIFT	3
+#define	DA9055_LDO5_MON_EN_SHIFT	4
+#define	DA9055_LDO6_MON_EN_SHIFT	5
+#define	DA9055_BCORE_MON_EN_SHIFT	6
+#define	DA9055_BMEM_MON_EN_SHIFT	7
+
+/* DA9055_REG_CONFIG_F (addr=0x6C) */
+#define	DA9055_LDO1_DEF_SHIFT		0
+#define	DA9055_LDO2_DEF_SHIFT		1
+#define	DA9055_LDO3_DEF_SHIFT		2
+#define	DA9055_LDO4_DEF_SHIFT		3
+#define	DA9055_LDO5_DEF_SHIFT		4
+#define	DA9055_LDO6_DEF_SHIFT		5
+#define	DA9055_BCORE_DEF_SHIFT		6
+#define	DA9055_BMEM_DEF_SHIFT		7
+
+/* DA9055_REG_MON_REG_4 (addr=0x6D) */
+#define	DA9055_MON_A8_IDX_SHIFT		0
+#define	DA9055_MON_A89_IDX_MASK		0x3
+#define	DA9055_MON_A89_IDX_NONE		0x0
+#define	DA9055_MON_A89_IDX_BUCKCORE	0x1
+#define	DA9055_MON_A89_IDX_LDO3		0x2
+#define	DA9055_MON_A9_IDX_SHIFT		5
+
+/* DA9055_REG_MON_REG_5 (addr=0x6E) */
+#define	DA9055_MON_A10_IDX_SHIFT	0
+#define	DA9055_MON_A10_IDX_MASK		0x3
+#define	DA9055_MON_A10_IDX_NONE		0x0
+#define	DA9055_MON_A10_IDX_LDO1		0x1
+#define	DA9055_MON_A10_IDX_LDO2		0x2
+#define	DA9055_MON_A10_IDX_LDO5		0x3
+#define	DA9055_MON_A10_IDX_LDO6		0x4
+
+#endif /* __DA9055_REG_H */
diff --git a/include/linux/mfd/lp8788-isink.h b/include/linux/mfd/lp8788-isink.h
new file mode 100644
index 0000000..f38262d
--- /dev/null
+++ b/include/linux/mfd/lp8788-isink.h
@@ -0,0 +1,52 @@
+/*
+ * TI LP8788 MFD - common definitions for current sinks
+ *
+ * Copyright 2012 Texas Instruments
+ *
+ * Author: Milo(Woogyom) Kim <milo.kim@ti.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.
+ *
+ */
+
+#ifndef __ISINK_LP8788_H__
+#define __ISINK_LP8788_H__
+
+/* register address */
+#define LP8788_ISINK_CTRL		0x99
+#define LP8788_ISINK12_IOUT		0x9A
+#define LP8788_ISINK3_IOUT		0x9B
+#define LP8788_ISINK1_PWM		0x9C
+#define LP8788_ISINK2_PWM		0x9D
+#define LP8788_ISINK3_PWM		0x9E
+
+/* mask bits */
+#define LP8788_ISINK1_IOUT_M		0x0F	/* Addr 9Ah */
+#define LP8788_ISINK2_IOUT_M		0xF0
+#define LP8788_ISINK3_IOUT_M		0x0F	/* Addr 9Bh */
+
+/* 6 bits used for PWM code : Addr 9C ~ 9Eh */
+#define LP8788_ISINK_MAX_PWM		63
+#define LP8788_ISINK_SCALE_OFFSET	3
+
+static const u8 lp8788_iout_addr[] = {
+	LP8788_ISINK12_IOUT,
+	LP8788_ISINK12_IOUT,
+	LP8788_ISINK3_IOUT,
+};
+
+static const u8 lp8788_iout_mask[] = {
+	LP8788_ISINK1_IOUT_M,
+	LP8788_ISINK2_IOUT_M,
+	LP8788_ISINK3_IOUT_M,
+};
+
+static const u8 lp8788_pwm_addr[] = {
+	LP8788_ISINK1_PWM,
+	LP8788_ISINK2_PWM,
+	LP8788_ISINK3_PWM,
+};
+
+#endif
diff --git a/include/linux/mfd/lp8788.h b/include/linux/mfd/lp8788.h
new file mode 100644
index 0000000..cec364b
--- /dev/null
+++ b/include/linux/mfd/lp8788.h
@@ -0,0 +1,364 @@
+/*
+ * TI LP8788 MFD Device
+ *
+ * Copyright 2012 Texas Instruments
+ *
+ * Author: Milo(Woogyom) Kim <milo.kim@ti.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.
+ *
+ */
+
+#ifndef __MFD_LP8788_H__
+#define __MFD_LP8788_H__
+
+#include <linux/gpio.h>
+#include <linux/irqdomain.h>
+#include <linux/regmap.h>
+
+#define LP8788_DEV_BUCK		"lp8788-buck"
+#define LP8788_DEV_DLDO		"lp8788-dldo"
+#define LP8788_DEV_ALDO		"lp8788-aldo"
+#define LP8788_DEV_CHARGER	"lp8788-charger"
+#define LP8788_DEV_RTC		"lp8788-rtc"
+#define LP8788_DEV_BACKLIGHT	"lp8788-backlight"
+#define LP8788_DEV_VIBRATOR	"lp8788-vibrator"
+#define LP8788_DEV_KEYLED	"lp8788-keyled"
+#define LP8788_DEV_ADC		"lp8788-adc"
+
+#define LP8788_NUM_BUCKS	4
+#define LP8788_NUM_DLDOS	12
+#define LP8788_NUM_ALDOS	10
+#define LP8788_NUM_BUCK2_DVS	2
+
+#define LP8788_CHG_IRQ		"CHG_IRQ"
+#define LP8788_PRSW_IRQ		"PRSW_IRQ"
+#define LP8788_BATT_IRQ		"BATT_IRQ"
+#define LP8788_ALM_IRQ		"ALARM_IRQ"
+
+enum lp8788_int_id {
+	/* interrup register 1 : Addr 00h */
+	LP8788_INT_TSDL,
+	LP8788_INT_TSDH,
+	LP8788_INT_UVLO,
+	LP8788_INT_FLAGMON,
+	LP8788_INT_PWRON_TIME,
+	LP8788_INT_PWRON,
+	LP8788_INT_COMP1,
+	LP8788_INT_COMP2,
+
+	/* interrupt register 2 : Addr 01h */
+	LP8788_INT_CHG_INPUT_STATE,
+	LP8788_INT_CHG_STATE,
+	LP8788_INT_EOC,
+	LP8788_INT_CHG_RESTART,
+	LP8788_INT_RESTART_TIMEOUT,
+	LP8788_INT_FULLCHG_TIMEOUT,
+	LP8788_INT_PRECHG_TIMEOUT,
+
+	/* interrupt register 3 : Addr 02h */
+	LP8788_INT_RTC_ALARM1 = 17,
+	LP8788_INT_RTC_ALARM2,
+	LP8788_INT_ENTER_SYS_SUPPORT,
+	LP8788_INT_EXIT_SYS_SUPPORT,
+	LP8788_INT_BATT_LOW,
+	LP8788_INT_NO_BATT,
+
+	LP8788_INT_MAX = 24,
+};
+
+enum lp8788_dvs_sel {
+	DVS_SEL_V0,
+	DVS_SEL_V1,
+	DVS_SEL_V2,
+	DVS_SEL_V3,
+};
+
+enum lp8788_ext_ldo_en_id {
+	EN_ALDO1,
+	EN_ALDO234,
+	EN_ALDO5,
+	EN_ALDO7,
+	EN_DLDO7,
+	EN_DLDO911,
+	EN_LDOS_MAX,
+};
+
+enum lp8788_charger_event {
+	NO_CHARGER,
+	CHARGER_DETECTED,
+};
+
+enum lp8788_bl_ctrl_mode {
+	LP8788_BL_REGISTER_ONLY,
+	LP8788_BL_COMB_PWM_BASED,	/* PWM + I2C, changed by PWM input */
+	LP8788_BL_COMB_REGISTER_BASED,	/* PWM + I2C, changed by I2C */
+};
+
+enum lp8788_bl_dim_mode {
+	LP8788_DIM_EXPONENTIAL,
+	LP8788_DIM_LINEAR,
+};
+
+enum lp8788_bl_full_scale_current {
+	LP8788_FULLSCALE_5000uA,
+	LP8788_FULLSCALE_8500uA,
+	LP8788_FULLSCALE_1200uA,
+	LP8788_FULLSCALE_1550uA,
+	LP8788_FULLSCALE_1900uA,
+	LP8788_FULLSCALE_2250uA,
+	LP8788_FULLSCALE_2600uA,
+	LP8788_FULLSCALE_2950uA,
+};
+
+enum lp8788_bl_ramp_step {
+	LP8788_RAMP_8us,
+	LP8788_RAMP_1024us,
+	LP8788_RAMP_2048us,
+	LP8788_RAMP_4096us,
+	LP8788_RAMP_8192us,
+	LP8788_RAMP_16384us,
+	LP8788_RAMP_32768us,
+	LP8788_RAMP_65538us,
+};
+
+enum lp8788_bl_pwm_polarity {
+	LP8788_PWM_ACTIVE_HIGH,
+	LP8788_PWM_ACTIVE_LOW,
+};
+
+enum lp8788_isink_scale {
+	LP8788_ISINK_SCALE_100mA,
+	LP8788_ISINK_SCALE_120mA,
+};
+
+enum lp8788_isink_number {
+	LP8788_ISINK_1,
+	LP8788_ISINK_2,
+	LP8788_ISINK_3,
+};
+
+enum lp8788_alarm_sel {
+	LP8788_ALARM_1,
+	LP8788_ALARM_2,
+	LP8788_ALARM_MAX,
+};
+
+enum lp8788_adc_id {
+	LPADC_VBATT_5P5,
+	LPADC_VIN_CHG,
+	LPADC_IBATT,
+	LPADC_IC_TEMP,
+	LPADC_VBATT_6P0,
+	LPADC_VBATT_5P0,
+	LPADC_ADC1,
+	LPADC_ADC2,
+	LPADC_VDD,
+	LPADC_VCOIN,
+	LPADC_VDD_LDO,
+	LPADC_ADC3,
+	LPADC_ADC4,
+	LPADC_MAX,
+};
+
+struct lp8788;
+
+/*
+ * lp8788_buck1_dvs
+ * @gpio         : gpio pin number for dvs control
+ * @vsel         : dvs selector for buck v1 register
+ */
+struct lp8788_buck1_dvs {
+	int gpio;
+	enum lp8788_dvs_sel vsel;
+};
+
+/*
+ * lp8788_buck2_dvs
+ * @gpio         : two gpio pin numbers are used for dvs
+ * @vsel         : dvs selector for buck v2 register
+ */
+struct lp8788_buck2_dvs {
+	int gpio[LP8788_NUM_BUCK2_DVS];
+	enum lp8788_dvs_sel vsel;
+};
+
+/*
+ * struct lp8788_ldo_enable_pin
+ *
+ *   Basically, all LDOs are enabled through the I2C commands.
+ *   But ALDO 1 ~ 5, 7, DLDO 7, 9, 11 can be enabled by external gpio pins.
+ *
+ * @gpio         : gpio number which is used for enabling ldos
+ * @init_state   : initial gpio state (ex. GPIOF_OUT_INIT_LOW)
+ */
+struct lp8788_ldo_enable_pin {
+	int gpio;
+	int init_state;
+};
+
+/*
+ * struct lp8788_chg_param
+ * @addr         : charging control register address (range : 0x11 ~ 0x1C)
+ * @val          : charging parameter value
+ */
+struct lp8788_chg_param {
+	u8 addr;
+	u8 val;
+};
+
+/*
+ * struct lp8788_charger_platform_data
+ * @vbatt_adc         : adc selection id for battery voltage
+ * @batt_temp_adc     : adc selection id for battery temperature
+ * @max_vbatt_mv      : used for calculating battery capacity
+ * @chg_params        : initial charging parameters
+ * @num_chg_params    : numbers of charging parameters
+ * @charger_event     : the charger event can be reported to the platform side
+ */
+struct lp8788_charger_platform_data {
+	enum lp8788_adc_id vbatt_adc;
+	enum lp8788_adc_id batt_temp_adc;
+	unsigned int max_vbatt_mv;
+	struct lp8788_chg_param *chg_params;
+	int num_chg_params;
+	void (*charger_event) (struct lp8788 *lp,
+				enum lp8788_charger_event event);
+};
+
+/*
+ * struct lp8788_bl_pwm_data
+ * @pwm_set_intensity     : set duty of pwm
+ * @pwm_get_intensity     : get current duty of pwm
+ */
+struct lp8788_bl_pwm_data {
+	void (*pwm_set_intensity) (int brightness, int max_brightness);
+	int (*pwm_get_intensity) (int max_brightness);
+};
+
+/*
+ * struct lp8788_backlight_platform_data
+ * @name                  : backlight driver name. (default: "lcd-backlight")
+ * @initial_brightness    : initial value of backlight brightness
+ * @bl_mode               : brightness control by pwm or lp8788 register
+ * @dim_mode              : dimming mode selection
+ * @full_scale            : full scale current setting
+ * @rise_time             : brightness ramp up step time
+ * @fall_time             : brightness ramp down step time
+ * @pwm_pol               : pwm polarity setting when bl_mode is pwm based
+ * @pwm_data              : platform specific pwm generation functions
+ *                          only valid when bl_mode is pwm based
+ */
+struct lp8788_backlight_platform_data {
+	char *name;
+	int initial_brightness;
+	enum lp8788_bl_ctrl_mode bl_mode;
+	enum lp8788_bl_dim_mode dim_mode;
+	enum lp8788_bl_full_scale_current full_scale;
+	enum lp8788_bl_ramp_step rise_time;
+	enum lp8788_bl_ramp_step fall_time;
+	enum lp8788_bl_pwm_polarity pwm_pol;
+	struct lp8788_bl_pwm_data pwm_data;
+};
+
+/*
+ * struct lp8788_led_platform_data
+ * @name         : led driver name. (default: "keyboard-backlight")
+ * @scale        : current scale
+ * @num          : current sink number
+ * @iout_code    : current output value (Addr 9Ah ~ 9Bh)
+ */
+struct lp8788_led_platform_data {
+	char *name;
+	enum lp8788_isink_scale scale;
+	enum lp8788_isink_number num;
+	int iout_code;
+};
+
+/*
+ * struct lp8788_vib_platform_data
+ * @name         : vibrator driver name
+ * @scale        : current scale
+ * @num          : current sink number
+ * @iout_code    : current output value (Addr 9Ah ~ 9Bh)
+ * @pwm_code     : PWM code value (Addr 9Ch ~ 9Eh)
+ */
+struct lp8788_vib_platform_data {
+	char *name;
+	enum lp8788_isink_scale scale;
+	enum lp8788_isink_number num;
+	int iout_code;
+	int pwm_code;
+};
+
+/*
+ * struct lp8788_platform_data
+ * @init_func    : used for initializing registers
+ *                 before mfd driver is registered
+ * @buck_data    : regulator initial data for buck
+ * @dldo_data    : regulator initial data for digital ldo
+ * @aldo_data    : regulator initial data for analog ldo
+ * @buck1_dvs    : gpio configurations for buck1 dvs
+ * @buck2_dvs    : gpio configurations for buck2 dvs
+ * @ldo_pin      : gpio configurations for enabling LDOs
+ * @chg_pdata    : platform data for charger driver
+ * @alarm_sel    : rtc alarm selection (1 or 2)
+ * @bl_pdata     : configurable data for backlight driver
+ * @led_pdata    : configurable data for led driver
+ * @vib_pdata    : configurable data for vibrator driver
+ * @adc_pdata    : iio map data for adc driver
+ */
+struct lp8788_platform_data {
+	/* general system information */
+	int (*init_func) (struct lp8788 *lp);
+
+	/* regulators */
+	struct regulator_init_data *buck_data[LP8788_NUM_BUCKS];
+	struct regulator_init_data *dldo_data[LP8788_NUM_DLDOS];
+	struct regulator_init_data *aldo_data[LP8788_NUM_ALDOS];
+	struct lp8788_buck1_dvs *buck1_dvs;
+	struct lp8788_buck2_dvs *buck2_dvs;
+	struct lp8788_ldo_enable_pin *ldo_pin[EN_LDOS_MAX];
+
+	/* charger */
+	struct lp8788_charger_platform_data *chg_pdata;
+
+	/* rtc alarm */
+	enum lp8788_alarm_sel alarm_sel;
+
+	/* backlight */
+	struct lp8788_backlight_platform_data *bl_pdata;
+
+	/* current sinks */
+	struct lp8788_led_platform_data *led_pdata;
+	struct lp8788_vib_platform_data *vib_pdata;
+
+	/* adc iio map data */
+	struct iio_map *adc_pdata;
+};
+
+/*
+ * struct lp8788
+ * @dev          : parent device pointer
+ * @regmap       : used for i2c communcation on accessing registers
+ * @irqdm        : interrupt domain for handling nested interrupt
+ * @irq          : pin number of IRQ_N
+ * @pdata        : lp8788 platform specific data
+ */
+struct lp8788 {
+	struct device *dev;
+	struct regmap *regmap;
+	struct irq_domain *irqdm;
+	int irq;
+	struct lp8788_platform_data *pdata;
+};
+
+int lp8788_irq_init(struct lp8788 *lp, int chip_irq);
+void lp8788_irq_exit(struct lp8788 *lp);
+int lp8788_read_byte(struct lp8788 *lp, u8 reg, u8 *data);
+int lp8788_read_multi_bytes(struct lp8788 *lp, u8 reg, u8 *data, size_t count);
+int lp8788_write_byte(struct lp8788 *lp, u8 reg, u8 data);
+int lp8788_update_bits(struct lp8788 *lp, u8 reg, u8 mask, u8 data);
+#endif
diff --git a/include/linux/mfd/lpc_ich.h b/include/linux/mfd/lpc_ich.h
index fec5256..3e1df64 100644
--- a/include/linux/mfd/lpc_ich.h
+++ b/include/linux/mfd/lpc_ich.h
@@ -43,6 +43,7 @@
 	char name[32];
 	unsigned int iTCO_version;
 	unsigned int gpio_version;
+	u8 use_gpio;
 };
 
 #endif
diff --git a/include/linux/mfd/max8907.h b/include/linux/mfd/max8907.h
new file mode 100644
index 0000000..b06f7a6
--- /dev/null
+++ b/include/linux/mfd/max8907.h
@@ -0,0 +1,252 @@
+/*
+ * Functions to access MAX8907 power management chip.
+ *
+ * Copyright (C) 2010 Gyungoh Yoo <jack.yoo@maxim-ic.com>
+ * Copyright (C) 2012, NVIDIA CORPORATION. All rights reserved.
+ *
+ * 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.
+ */
+
+#ifndef __LINUX_MFD_MAX8907_H
+#define __LINUX_MFD_MAX8907_H
+
+#include <linux/mutex.h>
+#include <linux/pm.h>
+
+#define MAX8907_GEN_I2C_ADDR		(0x78 >> 1)
+#define MAX8907_ADC_I2C_ADDR		(0x8e >> 1)
+#define MAX8907_RTC_I2C_ADDR		(0xd0 >> 1)
+
+/* MAX8907 register map */
+#define MAX8907_REG_SYSENSEL		0x00
+#define MAX8907_REG_ON_OFF_IRQ1		0x01
+#define MAX8907_REG_ON_OFF_IRQ1_MASK	0x02
+#define MAX8907_REG_ON_OFF_STAT		0x03
+#define MAX8907_REG_SDCTL1		0x04
+#define MAX8907_REG_SDSEQCNT1		0x05
+#define MAX8907_REG_SDV1		0x06
+#define MAX8907_REG_SDCTL2		0x07
+#define MAX8907_REG_SDSEQCNT2		0x08
+#define MAX8907_REG_SDV2		0x09
+#define MAX8907_REG_SDCTL3		0x0A
+#define MAX8907_REG_SDSEQCNT3		0x0B
+#define MAX8907_REG_SDV3		0x0C
+#define MAX8907_REG_ON_OFF_IRQ2		0x0D
+#define MAX8907_REG_ON_OFF_IRQ2_MASK	0x0E
+#define MAX8907_REG_RESET_CNFG		0x0F
+#define MAX8907_REG_LDOCTL16		0x10
+#define MAX8907_REG_LDOSEQCNT16		0x11
+#define MAX8907_REG_LDO16VOUT		0x12
+#define MAX8907_REG_SDBYSEQCNT		0x13
+#define MAX8907_REG_LDOCTL17		0x14
+#define MAX8907_REG_LDOSEQCNT17		0x15
+#define MAX8907_REG_LDO17VOUT		0x16
+#define MAX8907_REG_LDOCTL1		0x18
+#define MAX8907_REG_LDOSEQCNT1		0x19
+#define MAX8907_REG_LDO1VOUT		0x1A
+#define MAX8907_REG_LDOCTL2		0x1C
+#define MAX8907_REG_LDOSEQCNT2		0x1D
+#define MAX8907_REG_LDO2VOUT		0x1E
+#define MAX8907_REG_LDOCTL3		0x20
+#define MAX8907_REG_LDOSEQCNT3		0x21
+#define MAX8907_REG_LDO3VOUT		0x22
+#define MAX8907_REG_LDOCTL4		0x24
+#define MAX8907_REG_LDOSEQCNT4		0x25
+#define MAX8907_REG_LDO4VOUT		0x26
+#define MAX8907_REG_LDOCTL5		0x28
+#define MAX8907_REG_LDOSEQCNT5		0x29
+#define MAX8907_REG_LDO5VOUT		0x2A
+#define MAX8907_REG_LDOCTL6		0x2C
+#define MAX8907_REG_LDOSEQCNT6		0x2D
+#define MAX8907_REG_LDO6VOUT		0x2E
+#define MAX8907_REG_LDOCTL7		0x30
+#define MAX8907_REG_LDOSEQCNT7		0x31
+#define MAX8907_REG_LDO7VOUT		0x32
+#define MAX8907_REG_LDOCTL8		0x34
+#define MAX8907_REG_LDOSEQCNT8		0x35
+#define MAX8907_REG_LDO8VOUT		0x36
+#define MAX8907_REG_LDOCTL9		0x38
+#define MAX8907_REG_LDOSEQCNT9		0x39
+#define MAX8907_REG_LDO9VOUT		0x3A
+#define MAX8907_REG_LDOCTL10		0x3C
+#define MAX8907_REG_LDOSEQCNT10		0x3D
+#define MAX8907_REG_LDO10VOUT		0x3E
+#define MAX8907_REG_LDOCTL11		0x40
+#define MAX8907_REG_LDOSEQCNT11		0x41
+#define MAX8907_REG_LDO11VOUT		0x42
+#define MAX8907_REG_LDOCTL12		0x44
+#define MAX8907_REG_LDOSEQCNT12		0x45
+#define MAX8907_REG_LDO12VOUT		0x46
+#define MAX8907_REG_LDOCTL13		0x48
+#define MAX8907_REG_LDOSEQCNT13		0x49
+#define MAX8907_REG_LDO13VOUT		0x4A
+#define MAX8907_REG_LDOCTL14		0x4C
+#define MAX8907_REG_LDOSEQCNT14		0x4D
+#define MAX8907_REG_LDO14VOUT		0x4E
+#define MAX8907_REG_LDOCTL15		0x50
+#define MAX8907_REG_LDOSEQCNT15		0x51
+#define MAX8907_REG_LDO15VOUT		0x52
+#define MAX8907_REG_OUT5VEN		0x54
+#define MAX8907_REG_OUT5VSEQ		0x55
+#define MAX8907_REG_OUT33VEN		0x58
+#define MAX8907_REG_OUT33VSEQ		0x59
+#define MAX8907_REG_LDOCTL19		0x5C
+#define MAX8907_REG_LDOSEQCNT19		0x5D
+#define MAX8907_REG_LDO19VOUT		0x5E
+#define MAX8907_REG_LBCNFG		0x60
+#define MAX8907_REG_SEQ1CNFG		0x64
+#define MAX8907_REG_SEQ2CNFG		0x65
+#define MAX8907_REG_SEQ3CNFG		0x66
+#define MAX8907_REG_SEQ4CNFG		0x67
+#define MAX8907_REG_SEQ5CNFG		0x68
+#define MAX8907_REG_SEQ6CNFG		0x69
+#define MAX8907_REG_SEQ7CNFG		0x6A
+#define MAX8907_REG_LDOCTL18		0x72
+#define MAX8907_REG_LDOSEQCNT18		0x73
+#define MAX8907_REG_LDO18VOUT		0x74
+#define MAX8907_REG_BBAT_CNFG		0x78
+#define MAX8907_REG_CHG_CNTL1		0x7C
+#define MAX8907_REG_CHG_CNTL2		0x7D
+#define MAX8907_REG_CHG_IRQ1		0x7E
+#define MAX8907_REG_CHG_IRQ2		0x7F
+#define MAX8907_REG_CHG_IRQ1_MASK	0x80
+#define MAX8907_REG_CHG_IRQ2_MASK	0x81
+#define MAX8907_REG_CHG_STAT		0x82
+#define MAX8907_REG_WLED_MODE_CNTL	0x84
+#define MAX8907_REG_ILED_CNTL		0x84
+#define MAX8907_REG_II1RR		0x8E
+#define MAX8907_REG_II2RR		0x8F
+#define MAX8907_REG_LDOCTL20		0x9C
+#define MAX8907_REG_LDOSEQCNT20		0x9D
+#define MAX8907_REG_LDO20VOUT		0x9E
+
+/* RTC register map */
+#define MAX8907_REG_RTC_SEC		0x00
+#define MAX8907_REG_RTC_MIN		0x01
+#define MAX8907_REG_RTC_HOURS		0x02
+#define MAX8907_REG_RTC_WEEKDAY		0x03
+#define MAX8907_REG_RTC_DATE		0x04
+#define MAX8907_REG_RTC_MONTH		0x05
+#define MAX8907_REG_RTC_YEAR1		0x06
+#define MAX8907_REG_RTC_YEAR2		0x07
+#define MAX8907_REG_ALARM0_SEC		0x08
+#define MAX8907_REG_ALARM0_MIN		0x09
+#define MAX8907_REG_ALARM0_HOURS	0x0A
+#define MAX8907_REG_ALARM0_WEEKDAY	0x0B
+#define MAX8907_REG_ALARM0_DATE		0x0C
+#define MAX8907_REG_ALARM0_MONTH	0x0D
+#define MAX8907_REG_ALARM0_YEAR1	0x0E
+#define MAX8907_REG_ALARM0_YEAR2	0x0F
+#define MAX8907_REG_ALARM1_SEC		0x10
+#define MAX8907_REG_ALARM1_MIN		0x11
+#define MAX8907_REG_ALARM1_HOURS	0x12
+#define MAX8907_REG_ALARM1_WEEKDAY	0x13
+#define MAX8907_REG_ALARM1_DATE		0x14
+#define MAX8907_REG_ALARM1_MONTH	0x15
+#define MAX8907_REG_ALARM1_YEAR1	0x16
+#define MAX8907_REG_ALARM1_YEAR2	0x17
+#define MAX8907_REG_ALARM0_CNTL		0x18
+#define MAX8907_REG_ALARM1_CNTL		0x19
+#define MAX8907_REG_RTC_STATUS		0x1A
+#define MAX8907_REG_RTC_CNTL		0x1B
+#define MAX8907_REG_RTC_IRQ		0x1C
+#define MAX8907_REG_RTC_IRQ_MASK	0x1D
+#define MAX8907_REG_MPL_CNTL		0x1E
+
+/* ADC and Touch Screen Controller register map */
+#define MAX8907_CTL			0
+#define MAX8907_SEQCNT			1
+#define MAX8907_VOUT			2
+
+/* mask bit fields */
+#define MAX8907_MASK_LDO_SEQ		0x1C
+#define MAX8907_MASK_LDO_EN		0x01
+#define MAX8907_MASK_VBBATTCV		0x03
+#define MAX8907_MASK_OUT5V_VINEN	0x10
+#define MAX8907_MASK_OUT5V_ENSRC	0x0E
+#define MAX8907_MASK_OUT5V_EN		0x01
+#define MAX8907_MASK_POWER_OFF		0x40
+
+/* Regulator IDs */
+#define MAX8907_MBATT	0
+#define MAX8907_SD1	1
+#define MAX8907_SD2	2
+#define MAX8907_SD3	3
+#define MAX8907_LDO1	4
+#define MAX8907_LDO2	5
+#define MAX8907_LDO3	6
+#define MAX8907_LDO4	7
+#define MAX8907_LDO5	8
+#define MAX8907_LDO6	9
+#define MAX8907_LDO7	10
+#define MAX8907_LDO8	11
+#define MAX8907_LDO9	12
+#define MAX8907_LDO10	13
+#define MAX8907_LDO11	14
+#define MAX8907_LDO12	15
+#define MAX8907_LDO13	16
+#define MAX8907_LDO14	17
+#define MAX8907_LDO15	18
+#define MAX8907_LDO16	19
+#define MAX8907_LDO17	20
+#define MAX8907_LDO18	21
+#define MAX8907_LDO19	22
+#define MAX8907_LDO20	23
+#define MAX8907_OUT5V	24
+#define MAX8907_OUT33V	25
+#define MAX8907_BBAT	26
+#define MAX8907_SDBY	27
+#define MAX8907_VRTC	28
+#define MAX8907_NUM_REGULATORS (MAX8907_VRTC + 1)
+
+/* IRQ definitions */
+enum {
+	MAX8907_IRQ_VCHG_DC_OVP = 0,
+	MAX8907_IRQ_VCHG_DC_F,
+	MAX8907_IRQ_VCHG_DC_R,
+	MAX8907_IRQ_VCHG_THM_OK_R,
+	MAX8907_IRQ_VCHG_THM_OK_F,
+	MAX8907_IRQ_VCHG_MBATTLOW_F,
+	MAX8907_IRQ_VCHG_MBATTLOW_R,
+	MAX8907_IRQ_VCHG_RST,
+	MAX8907_IRQ_VCHG_DONE,
+	MAX8907_IRQ_VCHG_TOPOFF,
+	MAX8907_IRQ_VCHG_TMR_FAULT,
+
+	MAX8907_IRQ_GPM_RSTIN = 0,
+	MAX8907_IRQ_GPM_MPL,
+	MAX8907_IRQ_GPM_SW_3SEC,
+	MAX8907_IRQ_GPM_EXTON_F,
+	MAX8907_IRQ_GPM_EXTON_R,
+	MAX8907_IRQ_GPM_SW_1SEC,
+	MAX8907_IRQ_GPM_SW_F,
+	MAX8907_IRQ_GPM_SW_R,
+	MAX8907_IRQ_GPM_SYSCKEN_F,
+	MAX8907_IRQ_GPM_SYSCKEN_R,
+
+	MAX8907_IRQ_RTC_ALARM1 = 0,
+	MAX8907_IRQ_RTC_ALARM0,
+};
+
+struct max8907_platform_data {
+	struct regulator_init_data *init_data[MAX8907_NUM_REGULATORS];
+	bool pm_off;
+};
+
+struct regmap_irq_chips_data;
+
+struct max8907 {
+	struct device			*dev;
+	struct mutex			irq_lock;
+	struct i2c_client		*i2c_gen;
+	struct i2c_client		*i2c_rtc;
+	struct regmap			*regmap_gen;
+	struct regmap			*regmap_rtc;
+	struct regmap_irq_chip_data	*irqc_chg;
+	struct regmap_irq_chip_data	*irqc_on_off;
+	struct regmap_irq_chip_data	*irqc_rtc;
+};
+
+#endif
diff --git a/include/linux/mfd/max8925.h b/include/linux/mfd/max8925.h
index 15b2392..74d8e29 100644
--- a/include/linux/mfd/max8925.h
+++ b/include/linux/mfd/max8925.h
@@ -158,8 +158,6 @@
 #define TSC_IRQ_MASK			(0x03)
 #define RTC_IRQ_MASK			(0x0c)
 
-#define MAX8925_MAX_REGULATOR		(23)
-
 #define MAX8925_NAME_SIZE		(32)
 
 /* IRQ definitions */
@@ -236,7 +234,29 @@
 	struct max8925_backlight_pdata	*backlight;
 	struct max8925_touch_pdata	*touch;
 	struct max8925_power_pdata	*power;
-	struct regulator_init_data	*regulator[MAX8925_MAX_REGULATOR];
+	struct regulator_init_data	*sd1;
+	struct regulator_init_data	*sd2;
+	struct regulator_init_data	*sd3;
+	struct regulator_init_data	*ldo1;
+	struct regulator_init_data	*ldo2;
+	struct regulator_init_data	*ldo3;
+	struct regulator_init_data	*ldo4;
+	struct regulator_init_data	*ldo5;
+	struct regulator_init_data	*ldo6;
+	struct regulator_init_data	*ldo7;
+	struct regulator_init_data	*ldo8;
+	struct regulator_init_data	*ldo9;
+	struct regulator_init_data	*ldo10;
+	struct regulator_init_data	*ldo11;
+	struct regulator_init_data	*ldo12;
+	struct regulator_init_data	*ldo13;
+	struct regulator_init_data	*ldo14;
+	struct regulator_init_data	*ldo15;
+	struct regulator_init_data	*ldo16;
+	struct regulator_init_data	*ldo17;
+	struct regulator_init_data	*ldo18;
+	struct regulator_init_data	*ldo19;
+	struct regulator_init_data	*ldo20;
 
 	int		irq_base;
 	int		tsc_irq;
diff --git a/include/linux/mfd/palmas.h b/include/linux/mfd/palmas.h
index 9cbc642..29f6616 100644
--- a/include/linux/mfd/palmas.h
+++ b/include/linux/mfd/palmas.h
@@ -23,6 +23,9 @@
 #define PALMAS_NUM_CLIENTS		3
 
 struct palmas_pmic;
+struct palmas_gpadc;
+struct palmas_resource;
+struct palmas_usb;
 
 struct palmas {
 	struct device *dev;
@@ -41,6 +44,9 @@
 
 	/* Child Devices */
 	struct palmas_pmic *pmic;
+	struct palmas_gpadc *gpadc;
+	struct palmas_resource *resource;
+	struct palmas_usb *usb;
 
 	/* GPIO MUXing */
 	u8 gpio_muxed;
@@ -48,6 +54,23 @@
 	u8 pwm_muxed;
 };
 
+struct palmas_gpadc_platform_data {
+	/* Channel 3 current source is only enabled during conversion */
+	int ch3_current;
+
+	/* Channel 0 current source can be used for battery detection.
+	 * If used for battery detection this will cause a permanent current
+	 * consumption depending on current level set here.
+	 */
+	int ch0_current;
+
+	/* default BAT_REMOVAL_DAT setting on device probe */
+	int bat_removal;
+
+	/* Sets the START_POLARITY bit in the RT_CTRL register */
+	int start_polarity;
+};
+
 struct palmas_reg_init {
 	/* warm_rest controls the voltage levels after a warm reset
 	 *
@@ -107,21 +130,94 @@
 
 };
 
+enum palmas_regulators {
+	/* SMPS regulators */
+	PALMAS_REG_SMPS12,
+	PALMAS_REG_SMPS123,
+	PALMAS_REG_SMPS3,
+	PALMAS_REG_SMPS45,
+	PALMAS_REG_SMPS457,
+	PALMAS_REG_SMPS6,
+	PALMAS_REG_SMPS7,
+	PALMAS_REG_SMPS8,
+	PALMAS_REG_SMPS9,
+	PALMAS_REG_SMPS10,
+	/* LDO regulators */
+	PALMAS_REG_LDO1,
+	PALMAS_REG_LDO2,
+	PALMAS_REG_LDO3,
+	PALMAS_REG_LDO4,
+	PALMAS_REG_LDO5,
+	PALMAS_REG_LDO6,
+	PALMAS_REG_LDO7,
+	PALMAS_REG_LDO8,
+	PALMAS_REG_LDO9,
+	PALMAS_REG_LDOLN,
+	PALMAS_REG_LDOUSB,
+	/* Total number of regulators */
+	PALMAS_NUM_REGS,
+};
+
 struct palmas_pmic_platform_data {
 	/* An array of pointers to regulator init data indexed by regulator
 	 * ID
 	 */
-	struct regulator_init_data **reg_data;
+	struct regulator_init_data *reg_data[PALMAS_NUM_REGS];
 
 	/* An array of pointers to structures containing sleep mode and DVS
 	 * configuration for regulators indexed by ID
 	 */
-	struct palmas_reg_init **reg_init;
+	struct palmas_reg_init *reg_init[PALMAS_NUM_REGS];
 
 	/* use LDO6 for vibrator control */
 	int ldo6_vibrator;
+};
 
+struct palmas_usb_platform_data {
+	/* Set this if platform wishes its own vbus control */
+	int no_control_vbus;
 
+	/* Do we enable the wakeup comparator on probe */
+	int wakeup;
+};
+
+struct palmas_resource_platform_data {
+	int regen1_mode_sleep;
+	int regen2_mode_sleep;
+	int sysen1_mode_sleep;
+	int sysen2_mode_sleep;
+
+	/* bitfield to be loaded to NSLEEP_RES_ASSIGN */
+	u8 nsleep_res;
+	/* bitfield to be loaded to NSLEEP_SMPS_ASSIGN */
+	u8 nsleep_smps;
+	/* bitfield to be loaded to NSLEEP_LDO_ASSIGN1 */
+	u8 nsleep_ldo1;
+	/* bitfield to be loaded to NSLEEP_LDO_ASSIGN2 */
+	u8 nsleep_ldo2;
+
+	/* bitfield to be loaded to ENABLE1_RES_ASSIGN */
+	u8 enable1_res;
+	/* bitfield to be loaded to ENABLE1_SMPS_ASSIGN */
+	u8 enable1_smps;
+	/* bitfield to be loaded to ENABLE1_LDO_ASSIGN1 */
+	u8 enable1_ldo1;
+	/* bitfield to be loaded to ENABLE1_LDO_ASSIGN2 */
+	u8 enable1_ldo2;
+
+	/* bitfield to be loaded to ENABLE2_RES_ASSIGN */
+	u8 enable2_res;
+	/* bitfield to be loaded to ENABLE2_SMPS_ASSIGN */
+	u8 enable2_smps;
+	/* bitfield to be loaded to ENABLE2_LDO_ASSIGN1 */
+	u8 enable2_ldo1;
+	/* bitfield to be loaded to ENABLE2_LDO_ASSIGN2 */
+	u8 enable2_ldo2;
+};
+
+struct palmas_clk_platform_data {
+	int clk32kg_mode_sleep;
+	int clk32kgaudio_mode_sleep;
 };
 
 struct palmas_platform_data {
@@ -138,8 +234,49 @@
 	u8 pad1, pad2;
 
 	struct palmas_pmic_platform_data *pmic_pdata;
+	struct palmas_gpadc_platform_data *gpadc_pdata;
+	struct palmas_usb_platform_data *usb_pdata;
+	struct palmas_resource_platform_data *resource_pdata;
+	struct palmas_clk_platform_data *clk_pdata;
 };
 
+struct palmas_gpadc_calibration {
+	s32 gain;
+	s32 gain_error;
+	s32 offset_error;
+};
+
+struct palmas_gpadc {
+	struct device *dev;
+	struct palmas *palmas;
+
+	int ch3_current;
+	int ch0_current;
+
+	int gpadc_force;
+
+	int bat_removal;
+
+	struct mutex reading_lock;
+	struct completion irq_complete;
+
+	int eoc_sw_irq;
+
+	struct palmas_gpadc_calibration *palmas_cal_tbl;
+
+	int conv0_channel;
+	int conv1_channel;
+	int rt_channel;
+};
+
+struct palmas_gpadc_result {
+	s32 raw_code;
+	s32 corrected_code;
+	s32 result;
+};
+
+#define PALMAS_MAX_CHANNELS 16
+
 /* Define the palmas IRQ numbers */
 enum palmas_irqs {
 	/* INT1 registers */
@@ -182,34 +319,6 @@
 	PALMAS_NUM_IRQ,
 };
 
-enum palmas_regulators {
-	/* SMPS regulators */
-	PALMAS_REG_SMPS12,
-	PALMAS_REG_SMPS123,
-	PALMAS_REG_SMPS3,
-	PALMAS_REG_SMPS45,
-	PALMAS_REG_SMPS457,
-	PALMAS_REG_SMPS6,
-	PALMAS_REG_SMPS7,
-	PALMAS_REG_SMPS8,
-	PALMAS_REG_SMPS9,
-	PALMAS_REG_SMPS10,
-	/* LDO regulators */
-	PALMAS_REG_LDO1,
-	PALMAS_REG_LDO2,
-	PALMAS_REG_LDO3,
-	PALMAS_REG_LDO4,
-	PALMAS_REG_LDO5,
-	PALMAS_REG_LDO6,
-	PALMAS_REG_LDO7,
-	PALMAS_REG_LDO8,
-	PALMAS_REG_LDO9,
-	PALMAS_REG_LDOLN,
-	PALMAS_REG_LDOUSB,
-	/* Total number of regulators */
-	PALMAS_NUM_REGS,
-};
-
 struct palmas_pmic {
 	struct palmas *palmas;
 	struct device *dev;
@@ -223,6 +332,69 @@
 	int range[PALMAS_REG_SMPS10];
 };
 
+struct palmas_resource {
+	struct palmas *palmas;
+	struct device *dev;
+};
+
+struct palmas_usb {
+	struct palmas *palmas;
+	struct device *dev;
+
+	/* for vbus reporting with irqs disabled */
+	spinlock_t lock;
+
+	struct regulator *vbus_reg;
+
+	/* used to set vbus, in atomic path */
+	struct work_struct set_vbus_work;
+
+	int irq1;
+	int irq2;
+	int irq3;
+	int irq4;
+
+	int vbus_enable;
+
+	u8 linkstat;
+};
+
+#define comparator_to_palmas(x) container_of((x), struct palmas_usb, comparator)
+
+enum usb_irq_events {
+	/* Wakeup events from INT3 */
+	PALMAS_USB_ID_WAKEPUP,
+	PALMAS_USB_VBUS_WAKEUP,
+
+	/* ID_OTG_EVENTS */
+	PALMAS_USB_ID_GND,
+	N_PALMAS_USB_ID_GND,
+	PALMAS_USB_ID_C,
+	N_PALMAS_USB_ID_C,
+	PALMAS_USB_ID_B,
+	N_PALMAS_USB_ID_B,
+	PALMAS_USB_ID_A,
+	N_PALMAS_USB_ID_A,
+	PALMAS_USB_ID_FLOAT,
+	N_PALMAS_USB_ID_FLOAT,
+
+	/* VBUS_OTG_EVENTS */
+	PALMAS_USB_VB_SESS_END,
+	N_PALMAS_USB_VB_SESS_END,
+	PALMAS_USB_VB_SESS_VLD,
+	N_PALMAS_USB_VB_SESS_VLD,
+	PALMAS_USB_VA_SESS_VLD,
+	N_PALMAS_USB_VA_SESS_VLD,
+	PALMAS_USB_VA_VBUS_VLD,
+	N_PALMAS_USB_VA_VBUS_VLD,
+	PALMAS_USB_VADP_SNS,
+	N_PALMAS_USB_VADP_SNS,
+	PALMAS_USB_VADP_PRB,
+	N_PALMAS_USB_VADP_PRB,
+	PALMAS_USB_VOTG_SESS_VLD,
+	N_PALMAS_USB_VOTG_SESS_VLD,
+};
+
 /* defines so we can store the mux settings */
 #define PALMAS_GPIO_0_MUXED					(1 << 0)
 #define PALMAS_GPIO_1_MUXED					(1 << 1)
diff --git a/include/linux/mfd/smsc.h b/include/linux/mfd/smsc.h
new file mode 100644
index 0000000..9747b29
--- /dev/null
+++ b/include/linux/mfd/smsc.h
@@ -0,0 +1,109 @@
+/*
+ * SMSC ECE1099
+ *
+ * Copyright 2012 Texas Instruments Inc.
+ *
+ * Author: Sourav Poddar <sourav.poddar@ti.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.
+ *
+ */
+
+#ifndef __LINUX_MFD_SMSC_H
+#define __LINUX_MFD_SMSC_H
+
+#include <linux/regmap.h>
+
+#define SMSC_ID_ECE1099			1
+#define SMSC_NUM_CLIENTS		2
+
+#define SMSC_BASE_ADDR			0x38
+#define OMAP_GPIO_SMSC_IRQ		151
+
+#define SMSC_MAXGPIO         32
+#define SMSC_BANK(offs)      ((offs) >> 3)
+#define SMSC_BIT(offs)       (1u << ((offs) & 0x7))
+
+struct smsc {
+	struct device *dev;
+	struct i2c_client *i2c_clients[SMSC_NUM_CLIENTS];
+	struct regmap *regmap;
+	int clk;
+	/* Stored chip id */
+	int id;
+};
+
+struct smsc_gpio;
+struct smsc_keypad;
+
+static inline int smsc_read(struct device *child, unsigned int reg,
+	unsigned int *dest)
+{
+	struct smsc     *smsc = dev_get_drvdata(child->parent);
+
+	return regmap_read(smsc->regmap, reg, dest);
+}
+
+static inline int smsc_write(struct device *child, unsigned int reg,
+	unsigned int value)
+{
+	struct smsc     *smsc = dev_get_drvdata(child->parent);
+
+	return regmap_write(smsc->regmap, reg, value);
+}
+
+/* Registers for SMSC */
+#define SMSC_RESET						0xF5
+#define SMSC_GRP_INT						0xF9
+#define SMSC_CLK_CTRL						0xFA
+#define SMSC_WKUP_CTRL						0xFB
+#define SMSC_DEV_ID						0xFC
+#define SMSC_DEV_REV						0xFD
+#define SMSC_VEN_ID_L						0xFE
+#define SMSC_VEN_ID_H						0xFF
+
+/* CLK VALUE */
+#define SMSC_CLK_VALUE						0x13
+
+/* Registers for function GPIO INPUT */
+#define SMSC_GPIO_DATA_IN_START					0x00
+
+/* Registers for function GPIO OUPUT */
+#define SMSC_GPIO_DATA_OUT_START                                       0x05
+
+/* Definitions for SMSC GPIO CONFIGURATION REGISTER*/
+#define SMSC_GPIO_INPUT_LOW					0x01
+#define SMSC_GPIO_INPUT_RISING					0x09
+#define SMSC_GPIO_INPUT_FALLING					0x11
+#define SMSC_GPIO_INPUT_BOTH_EDGE				0x19
+#define SMSC_GPIO_OUTPUT_PP					0x21
+#define SMSC_GPIO_OUTPUT_OP					0x31
+
+#define GRP_INT_STAT						0xf9
+#define	SMSC_GPI_INT						0x0f
+#define SMSC_CFG_START						0x0A
+
+/* Registers for SMSC GPIO INTERRUPT STATUS REGISTER*/
+#define SMSC_GPIO_INT_STAT_START                                  0x32
+
+/* Registers for SMSC GPIO INTERRUPT MASK REGISTER*/
+#define SMSC_GPIO_INT_MASK_START                               0x37
+
+/* Registers for SMSC function KEYPAD*/
+#define SMSC_KP_OUT						0x40
+#define SMSC_KP_IN						0x41
+#define SMSC_KP_INT_STAT					0x42
+#define SMSC_KP_INT_MASK					0x43
+
+/* Definitions for keypad */
+#define SMSC_KP_KSO           0x70
+#define SMSC_KP_KSI           0x51
+#define SMSC_KSO_ALL_LOW        0x20
+#define SMSC_KP_SET_LOW_PWR        0x0B
+#define SMSC_KP_SET_HIGH           0xFF
+#define SMSC_KSO_EVAL           0x00
+
+#endif /*  __LINUX_MFD_SMSC_H */
diff --git a/include/linux/mfd/syscon.h b/include/linux/mfd/syscon.h
new file mode 100644
index 0000000..6aeb6b8
--- /dev/null
+++ b/include/linux/mfd/syscon.h
@@ -0,0 +1,23 @@
+/*
+ * System Control Driver
+ *
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ * Copyright (C) 2012 Linaro Ltd.
+ *
+ * Author: Dong Aisheng <dong.aisheng@linaro.org>
+ *
+ * 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.
+ */
+
+#ifndef __LINUX_MFD_SYSCON_H__
+#define __LINUX_MFD_SYSCON_H__
+
+extern struct regmap *syscon_node_to_regmap(struct device_node *np);
+extern struct regmap *syscon_regmap_lookup_by_compatible(const char *s);
+extern struct regmap *syscon_regmap_lookup_by_phandle(
+					struct device_node *np,
+					const char *property);
+#endif /* __LINUX_MFD_SYSCON_H__ */
diff --git a/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
new file mode 100644
index 0000000..dab34a1
--- /dev/null
+++ b/include/linux/mfd/syscon/imx6q-iomuxc-gpr.h
@@ -0,0 +1,319 @@
+/*
+ * Copyright (C) 2012 Freescale Semiconductor, Inc.
+ *
+ * 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.
+ */
+
+#ifndef __LINUX_IMX6Q_IOMUXC_GPR_H
+#define __LINUX_IMX6Q_IOMUXC_GPR_H
+
+#include <linux/bitops.h>
+
+#define IOMUXC_GPR0	0x00
+#define IOMUXC_GPR1	0x04
+#define IOMUXC_GPR2	0x08
+#define IOMUXC_GPR3	0x0c
+#define IOMUXC_GPR4	0x10
+#define IOMUXC_GPR5	0x14
+#define IOMUXC_GPR6	0x18
+#define IOMUXC_GPR7	0x1c
+#define IOMUXC_GPR8	0x20
+#define IOMUXC_GPR9	0x24
+#define IOMUXC_GPR10	0x28
+#define IOMUXC_GPR11	0x2c
+#define IOMUXC_GPR12	0x30
+#define IOMUXC_GPR13	0x34
+
+#define IMX6Q_GPR0_CLOCK_8_MUX_SEL_MASK		(0x3 << 30)
+#define IMX6Q_GPR0_CLOCK_8_MUX_SEL_AUDMUX_RXCLK_P7_MUXED	(0x0 << 30)
+#define IMX6Q_GPR0_CLOCK_8_MUX_SEL_AUDMUX_RXCLK_P7	(0x1 << 30)
+#define IMX6Q_GPR0_CLOCK_8_MUX_SEL_SSI3_SSI_SRCK	(0x2 << 30)
+#define IMX6Q_GPR0_CLOCK_8_MUX_SEL_SSI3_RX_BIT_CLK	(0x3 << 30)
+#define IMX6Q_GPR0_CLOCK_0_MUX_SEL_MASK		(0x3 << 28)
+#define IMX6Q_GPR0_CLOCK_0_MUX_SEL_ESAI1_IPP_IND_SCKR_MUXED	(0x0 << 28)
+#define IMX6Q_GPR0_CLOCK_0_MUX_SEL_ESAI1_IPP_IND_SCKR	(0x1 << 28)
+#define IMX6Q_GPR0_CLOCK_0_MUX_SEL_ESAI1_IPP_DO_SCKR	(0x2 << 28)
+#define IMX6Q_GPR0_CLOCK_B_MUX_SEL_MASK		(0x3 << 26)
+#define IMX6Q_GPR0_CLOCK_B_MUX_SEL_AUDMUX_TXCLK_P7_MUXED	(0x0 << 26)
+#define IMX6Q_GPR0_CLOCK_B_MUX_SEL_AUDMUX_TXCLK_P7	(0x1 << 26)
+#define IMX6Q_GPR0_CLOCK_B_MUX_SEL_SSI3_SSI_STCK	(0x2 << 26)
+#define IMX6Q_GPR0_CLOCK_B_MUX_SEL_SSI3_TX_BIT_CLK	(0x3 << 26)
+#define IMX6Q_GPR0_CLOCK_3_MUX_SEL_MASK		(0x3 << 24)
+#define IMX6Q_GPR0_CLOCK_3_MUX_SEL_AUDMUX_RXCLK_P7_MUXED	(0x3 << 24)
+#define IMX6Q_GPR0_CLOCK_3_MUX_SEL_AUDMUX_RXCLK_P7	(0x3 << 24)
+#define IMX6Q_GPR0_CLOCK_3_MUX_SEL_SSI3_SSI_SRCK	(0x3 << 24)
+#define IMX6Q_GPR0_CLOCK_3_MUX_SEL_SSI3_RX_BIT_CLK	(0x3 << 24)
+#define IMX6Q_GPR0_CLOCK_A_MUX_SEL_MASK		(0x3 << 22)
+#define IMX6Q_GPR0_CLOCK_A_MUX_SEL_AUDMUX_TXCLK_P2_MUXED	(0x0 << 22)
+#define IMX6Q_GPR0_CLOCK_A_MUX_SEL_AUDMUX_TXCLK_P2	(0x1 << 22)
+#define IMX6Q_GPR0_CLOCK_A_MUX_SEL_SSI2_SSI_STCK	(0x2 << 22)
+#define IMX6Q_GPR0_CLOCK_A_MUX_SEL_SSI2_TX_BIT_CLK	(0x3 << 22)
+#define IMX6Q_GPR0_CLOCK_2_MUX_SEL_MASK		(0x3 << 20)
+#define IMX6Q_GPR0_CLOCK_2_MUX_SEL_AUDMUX_RXCLK_P2_MUXED	(0x0 << 20)
+#define IMX6Q_GPR0_CLOCK_2_MUX_SEL_AUDMUX_RXCLK_P2	(0x1 << 20)
+#define IMX6Q_GPR0_CLOCK_2_MUX_SEL_SSI2_SSI_SRCK	(0x2 << 20)
+#define IMX6Q_GPR0_CLOCK_2_MUX_SEL_SSI2_RX_BIT_CLK	(0x3 << 20)
+#define IMX6Q_GPR0_CLOCK_9_MUX_SEL_MASK		(0x3 << 18)
+#define IMX6Q_GPR0_CLOCK_9_MUX_SEL_AUDMUX_TXCLK_P1_MUXED	(0x0 << 18)
+#define IMX6Q_GPR0_CLOCK_9_MUX_SEL_AUDMUX_TXCLK_P1	(0x1 << 18)
+#define IMX6Q_GPR0_CLOCK_9_MUX_SEL_SSI1_SSI_STCK	(0x2 << 18)
+#define IMX6Q_GPR0_CLOCK_9_MUX_SEL_SSI1_SSI_TX_BIT_CLK	(0x3 << 18)
+#define IMX6Q_GPR0_CLOCK_1_MUX_SEL_MASK		(0x3 << 16)
+#define IMX6Q_GPR0_CLOCK_1_MUX_SEL_AUDMUX_RXCLK_P1_MUXED	(0x0 << 16)
+#define IMX6Q_GPR0_CLOCK_1_MUX_SEL_AUDMUX_RXCLK_P1	(0x1 << 16)
+#define IMX6Q_GPR0_CLOCK_1_MUX_SEL_SSI1_SSI_SRCK	(0x2 << 16)
+#define IMX6Q_GPR0_CLOCK_1_MUX_SEL_SSI1_SSI_RX_BIT_CLK	(0x3 << 16)
+#define IMX6Q_GPR0_TX_CLK2_MUX_SEL_MASK		(0x3 << 14)
+#define IMX6Q_GPR0_TX_CLK2_MUX_SEL_ASRCK_CLK1	(0x0 << 14)
+#define IMX6Q_GPR0_TX_CLK2_MUX_SEL_ASRCK_CLK2	(0x1 << 14)
+#define IMX6Q_GPR0_TX_CLK2_MUX_SEL_ASRCK_CLK3	(0x2 << 14)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL7_MASK		BIT(7)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL7_SPDIF	0x0
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL7_IOMUX	BIT(7)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL6_MASK		BIT(6)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL6_ESAI		0x0
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL6_I2C3		BIT(6)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL5_MASK		BIT(5)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL5_ECSPI4	0x0
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL5_EPIT2	BIT(5)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL4_MASK		BIT(4)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL4_ECSPI4	0x0
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL4_I2C1		BIT(4)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL3_MASK		BIT(3)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL3_ECSPI2	0x0
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL3_I2C1		BIT(3)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL2_MASK		BIT(2)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL2_ECSPI1	0x0
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL2_I2C2		BIT(2)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL1_MASK		BIT(1)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL1_ECSPI1	0x0
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL1_I2C3		BIT(1)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL0_MASK		BIT(0)
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL0_IPU1		0x0
+#define IMX6Q_GPR0_DMAREQ_MUX_SEL0_IOMUX	BIT(0)
+
+#define IMX6Q_GPR1_PCIE_REQ_MASK		(0x3 << 30)
+#define IMX6Q_GPR1_PCIE_EXIT_L1			BIT(28)
+#define IMX6Q_GPR1_PCIE_RDY_L23			BIT(27)
+#define IMX6Q_GPR1_PCIE_ENTER_L1		BIT(26)
+#define IMX6Q_GPR1_MIPI_COLOR_SW		BIT(25)
+#define IMX6Q_GPR1_DPI_OFF			BIT(24)
+#define IMX6Q_GPR1_EXC_MON_MASK			BIT(22)
+#define IMX6Q_GPR1_EXC_MON_OKAY			0x0
+#define IMX6Q_GPR1_EXC_MON_SLVE			BIT(22)
+#define IMX6Q_GPR1_MIPI_IPU2_SEL_MASK		BIT(21)
+#define IMX6Q_GPR1_MIPI_IPU2_SEL_GASKET		0x0
+#define IMX6Q_GPR1_MIPI_IPU2_SEL_IOMUX		BIT(21)
+#define IMX6Q_GPR1_MIPI_IPU1_MUX_MASK		BIT(20)
+#define IMX6Q_GPR1_MIPI_IPU1_MUX_GASKET		0x0
+#define IMX6Q_GPR1_MIPI_IPU1_MUX_IOMUX		BIT(20)
+#define IMX6Q_GPR1_MIPI_IPU2_MUX_MASK		BIT(19)
+#define IMX6Q_GPR1_MIPI_IPU2_MUX_GASKET		0x0
+#define IMX6Q_GPR1_MIPI_IPU2_MUX_IOMUX		BIT(19)
+#define IMX6Q_GPR1_PCIE_TEST_PD			BIT(18)
+#define IMX6Q_GPR1_IPU_VPU_MUX_MASK		BIT(17)
+#define IMX6Q_GPR1_IPU_VPU_MUX_IPU1		0x0
+#define IMX6Q_GPR1_IPU_VPU_MUX_IPU2		BIT(17)
+#define IMX6Q_GPR1_PCIE_REF_CLK_EN		BIT(16)
+#define IMX6Q_GPR1_USB_EXP_MODE			BIT(15)
+#define IMX6Q_GPR1_PCIE_INT			BIT(14)
+#define IMX6Q_GPR1_USB_OTG_ID_SEL_MASK		BIT(13)
+#define IMX6Q_GPR1_USB_OTG_ID_SEL_ENET_RX_ER	0x0
+#define IMX6Q_GPR1_USB_OTG_ID_SEL_GPIO_1	BIT(13)
+#define IMX6Q_GPR1_GINT				BIT(12)
+#define IMX6Q_GPR1_ADDRS3_MASK			(0x3 << 10)
+#define IMX6Q_GPR1_ADDRS3_32MB			(0x0 << 10)
+#define IMX6Q_GPR1_ADDRS3_64MB			(0x1 << 10)
+#define IMX6Q_GPR1_ADDRS3_128MB			(0x2 << 10)
+#define IMX6Q_GPR1_ACT_CS3			BIT(9)
+#define IMX6Q_GPR1_ADDRS2_MASK			(0x3 << 7)
+#define IMX6Q_GPR1_ACT_CS2			BIT(6)
+#define IMX6Q_GPR1_ADDRS1_MASK			(0x3 << 4)
+#define IMX6Q_GPR1_ACT_CS1			BIT(3)
+#define IMX6Q_GPR1_ADDRS0_MASK			(0x3 << 1)
+#define IMX6Q_GPR1_ACT_CS0			BIT(0)
+
+#define IMX6Q_GPR2_COUNTER_RESET_VAL_MASK	(0x3 << 20)
+#define IMX6Q_GPR2_COUNTER_RESET_VAL_5		(0x0 << 20)
+#define IMX6Q_GPR2_COUNTER_RESET_VAL_3		(0x1 << 20)
+#define IMX6Q_GPR2_COUNTER_RESET_VAL_4		(0x2 << 20)
+#define IMX6Q_GPR2_COUNTER_RESET_VAL_6		(0x3 << 20)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_MASK		(0x7 << 16)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_0		(0x0 << 16)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_1		(0x1 << 16)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_2		(0x2 << 16)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_3		(0x3 << 16)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_4		(0x4 << 16)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_5		(0x5 << 16)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_6		(0x6 << 16)
+#define IMX6Q_GPR2_LVDS_CLK_SHIFT_7		(0x7 << 16)
+#define IMX6Q_GPR2_BGREF_RRMODE_MASK		BIT(15)
+#define IMX6Q_GPR2_BGREF_RRMODE_EXT_RESISTOR	0x0
+#define IMX6Q_GPR2_BGREF_RRMODE_INT_RESISTOR	BIT(15)
+#define IMX6Q_GPR2_DI1_VS_POLARITY_MASK		BIT(10)
+#define IMX6Q_GPR2_DI1_VS_POLARITY_ACTIVE_H	0x0
+#define IMX6Q_GPR2_DI1_VS_POLARITY_ACTIVE_L	BIT(10)
+#define IMX6Q_GPR2_DI0_VS_POLARITY_MASK		BIT(9)
+#define IMX6Q_GPR2_DI0_VS_POLARITY_ACTIVE_H	0x0
+#define IMX6Q_GPR2_DI0_VS_POLARITY_ACTIVE_L	BIT(9)
+#define IMX6Q_GPR2_BIT_MAPPING_CH1_MASK		BIT(8)
+#define IMX6Q_GPR2_BIT_MAPPING_CH1_SPWG		0x0
+#define IMX6Q_GPR2_BIT_MAPPING_CH1_JEIDA	BIT(8)
+#define IMX6Q_GPR2_DATA_WIDTH_CH1_MASK		BIT(7)
+#define IMX6Q_GPR2_DATA_WIDTH_CH1_18BIT		0x0
+#define IMX6Q_GPR2_DATA_WIDTH_CH1_24BIT		BIT(7)
+#define IMX6Q_GPR2_BIT_MAPPING_CH0_MASK		BIT(6)
+#define IMX6Q_GPR2_BIT_MAPPING_CH0_SPWG		0x0
+#define IMX6Q_GPR2_BIT_MAPPING_CH0_JEIDA	BIT(6)
+#define IMX6Q_GPR2_DATA_WIDTH_CH0_MASK		BIT(5)
+#define IMX6Q_GPR2_DATA_WIDTH_CH0_18BIT		0x0
+#define IMX6Q_GPR2_DATA_WIDTH_CH0_24BIT		BIT(5)
+#define IMX6Q_GPR2_SPLIT_MODE_EN		BIT(4)
+#define IMX6Q_GPR2_CH1_MODE_MASK		(0x3 << 2)
+#define IMX6Q_GPR2_CH1_MODE_DISABLE		(0x0 << 2)
+#define IMX6Q_GPR2_CH1_MODE_EN_ROUTE_DI0	(0x1 << 2)
+#define IMX6Q_GPR2_CH1_MODE_EN_ROUTE_DI1	(0x3 << 2)
+#define IMX6Q_GPR2_CH0_MODE_MASK		(0x3 << 0)
+#define IMX6Q_GPR2_CH0_MODE_DISABLE		(0x0 << 0)
+#define IMX6Q_GPR2_CH0_MODE_EN_ROUTE_DI0	(0x1 << 0)
+#define IMX6Q_GPR2_CH0_MODE_EN_ROUTE_DI1	(0x3 << 0)
+
+#define IMX6Q_GPR3_GPU_DBG_MASK			(0x3 << 29)
+#define IMX6Q_GPR3_GPU_DBG_GPU3D		(0x0 << 29)
+#define IMX6Q_GPR3_GPU_DBG_GPU2D		(0x1 << 29)
+#define IMX6Q_GPR3_GPU_DBG_OPENVG		(0x2 << 29)
+#define IMX6Q_GPR3_BCH_WR_CACHE_CTL		BIT(28)
+#define IMX6Q_GPR3_BCH_RD_CACHE_CTL		BIT(27)
+#define IMX6Q_GPR3_USDHCX_WR_CACHE_CTL		BIT(26)
+#define IMX6Q_GPR3_USDHCX_RD_CACHE_CTL		BIT(25)
+#define IMX6Q_GPR3_OCRAM_CTL_MASK		(0xf << 21)
+#define IMX6Q_GPR3_OCRAM_STATUS_MASK		(0xf << 17)
+#define IMX6Q_GPR3_CORE3_DBG_ACK_EN		BIT(16)
+#define IMX6Q_GPR3_CORE2_DBG_ACK_EN		BIT(15)
+#define IMX6Q_GPR3_CORE1_DBG_ACK_EN		BIT(14)
+#define IMX6Q_GPR3_CORE0_DBG_ACK_EN		BIT(13)
+#define IMX6Q_GPR3_TZASC2_BOOT_LOCK		BIT(12)
+#define IMX6Q_GPR3_TZASC1_BOOT_LOCK		BIT(11)
+#define IMX6Q_GPR3_IPU_DIAG_MASK		BIT(10)
+#define IMX6Q_GPR3_LVDS1_MUX_CTL_MASK		(0x3 << 8)
+#define IMX6Q_GPR3_LVDS1_MUX_CTL_IPU1_DI0	(0x0 << 8)
+#define IMX6Q_GPR3_LVDS1_MUX_CTL_IPU1_DI1	(0x1 << 8)
+#define IMX6Q_GPR3_LVDS1_MUX_CTL_IPU2_DI0	(0x2 << 8)
+#define IMX6Q_GPR3_LVDS1_MUX_CTL_IPU2_DI1	(0x3 << 8)
+#define IMX6Q_GPR3_LVDS0_MUX_CTL_MASK		(0x3 << 6)
+#define IMX6Q_GPR3_LVDS0_MUX_CTL_IPU1_DI0	(0x0 << 6)
+#define IMX6Q_GPR3_LVDS0_MUX_CTL_IPU1_DI1	(0x1 << 6)
+#define IMX6Q_GPR3_LVDS0_MUX_CTL_IPU2_DI0	(0x2 << 6)
+#define IMX6Q_GPR3_LVDS0_MUX_CTL_IPU2_DI1	(0x3 << 6)
+#define IMX6Q_GPR3_MIPI_MUX_CTL_MASK		(0x3 << 4)
+#define IMX6Q_GPR3_MIPI_MUX_CTL_IPU1_DI0	(0x0 << 4)
+#define IMX6Q_GPR3_MIPI_MUX_CTL_IPU1_DI1	(0x1 << 4)
+#define IMX6Q_GPR3_MIPI_MUX_CTL_IPU2_DI0	(0x2 << 4)
+#define IMX6Q_GPR3_MIPI_MUX_CTL_IPU2_DI1	(0x3 << 4)
+#define IMX6Q_GPR3_HDMI_MUX_CTL_MASK		(0x3 << 2)
+#define IMX6Q_GPR3_HDMI_MUX_CTL_IPU1_DI0	(0x0 << 2)
+#define IMX6Q_GPR3_HDMI_MUX_CTL_IPU1_DI1	(0x1 << 2)
+#define IMX6Q_GPR3_HDMI_MUX_CTL_IPU2_DI0	(0x2 << 2)
+#define IMX6Q_GPR3_HDMI_MUX_CTL_IPU2_DI1	(0x3 << 2)
+
+#define IMX6Q_GPR4_VDOA_WR_CACHE_SEL		BIT(31)
+#define IMX6Q_GPR4_VDOA_RD_CACHE_SEL		BIT(30)
+#define IMX6Q_GPR4_VDOA_WR_CACHE_VAL		BIT(29)
+#define IMX6Q_GPR4_VDOA_RD_CACHE_VAL		BIT(28)
+#define IMX6Q_GPR4_PCIE_WR_CACHE_SEL		BIT(27)
+#define IMX6Q_GPR4_PCIE_RD_CACHE_SEL		BIT(26)
+#define IMX6Q_GPR4_PCIE_WR_CACHE_VAL		BIT(25)
+#define IMX6Q_GPR4_PCIE_RD_CACHE_VAL		BIT(24)
+#define IMX6Q_GPR4_SDMA_STOP_ACK		BIT(19)
+#define IMX6Q_GPR4_CAN2_STOP_ACK		BIT(18)
+#define IMX6Q_GPR4_CAN1_STOP_ACK		BIT(17)
+#define IMX6Q_GPR4_ENET_STOP_ACK		BIT(16)
+#define IMX6Q_GPR4_SOC_VERSION_MASK		(0xff << 8)
+#define IMX6Q_GPR4_SOC_VERSION_OFF		0x8
+#define IMX6Q_GPR4_VPU_WR_CACHE_SEL		BIT(7)
+#define IMX6Q_GPR4_VPU_RD_CACHE_SEL		BIT(6)
+#define IMX6Q_GPR4_VPU_P_WR_CACHE_VAL		BIT(3)
+#define IMX6Q_GPR4_VPU_P_RD_CACHE_VAL_MASK	BIT(2)
+#define IMX6Q_GPR4_IPU_WR_CACHE_CTL		BIT(1)
+#define IMX6Q_GPR4_IPU_RD_CACHE_CTL		BIT(0)
+
+#define IMX6Q_GPR5_L2_CLK_STOP			BIT(8)
+
+#define IMX6Q_GPR9_TZASC2_BYP			BIT(1)
+#define IMX6Q_GPR9_TZASC1_BYP			BIT(0)
+
+#define IMX6Q_GPR10_LOCK_DBG_EN			BIT(29)
+#define IMX6Q_GPR10_LOCK_DBG_CLK_EN		BIT(28)
+#define IMX6Q_GPR10_LOCK_SEC_ERR_RESP		BIT(27)
+#define IMX6Q_GPR10_LOCK_OCRAM_TZ_ADDR		(0x3f << 21)
+#define IMX6Q_GPR10_LOCK_OCRAM_TZ_EN		BIT(20)
+#define IMX6Q_GPR10_LOCK_DCIC2_MUX_MASK		(0x3 << 18)
+#define IMX6Q_GPR10_LOCK_DCIC1_MUX_MASK		(0x3 << 16)
+#define IMX6Q_GPR10_DBG_EN			BIT(13)
+#define IMX6Q_GPR10_DBG_CLK_EN			BIT(12)
+#define IMX6Q_GPR10_SEC_ERR_RESP_MASK		BIT(11)
+#define IMX6Q_GPR10_SEC_ERR_RESP_OKEY		0x0
+#define IMX6Q_GPR10_SEC_ERR_RESP_SLVE		BIT(11)
+#define IMX6Q_GPR10_OCRAM_TZ_ADDR_MASK		(0x3f << 5)
+#define IMX6Q_GPR10_OCRAM_TZ_EN_MASK		BIT(4)
+#define IMX6Q_GPR10_DCIC2_MUX_CTL_MASK		(0x3 << 2)
+#define IMX6Q_GPR10_DCIC2_MUX_CTL_IPU1_DI0	(0x0 << 2)
+#define IMX6Q_GPR10_DCIC2_MUX_CTL_IPU1_DI1	(0x1 << 2)
+#define IMX6Q_GPR10_DCIC2_MUX_CTL_IPU2_DI0	(0x2 << 2)
+#define IMX6Q_GPR10_DCIC2_MUX_CTL_IPU2_DI1	(0x3 << 2)
+#define IMX6Q_GPR10_DCIC1_MUX_CTL_MASK		(0x3 << 0)
+#define IMX6Q_GPR10_DCIC1_MUX_CTL_IPU1_DI0	(0x0 << 0)
+#define IMX6Q_GPR10_DCIC1_MUX_CTL_IPU1_DI1	(0x1 << 0)
+#define IMX6Q_GPR10_DCIC1_MUX_CTL_IPU2_DI0	(0x2 << 0)
+#define IMX6Q_GPR10_DCIC1_MUX_CTL_IPU2_DI1	(0x3 << 0)
+
+#define IMX6Q_GPR12_ARMP_IPG_CLK_EN		BIT(27)
+#define IMX6Q_GPR12_ARMP_AHB_CLK_EN		BIT(26)
+#define IMX6Q_GPR12_ARMP_ATB_CLK_EN		BIT(25)
+#define IMX6Q_GPR12_ARMP_APB_CLK_EN		BIT(24)
+#define IMX6Q_GPR12_PCIE_CTL_2			BIT(10)
+
+#define IMX6Q_GPR13_SDMA_STOP_REQ		BIT(30)
+#define IMX6Q_GPR13_CAN2_STOP_REQ		BIT(29)
+#define IMX6Q_GPR13_CAN1_STOP_REQ		BIT(28)
+#define IMX6Q_GPR13_ENET_STOP_REQ		BIT(27)
+#define IMX6Q_GPR13_SATA_PHY_8_MASK		(0x7 << 24)
+#define IMX6Q_GPR13_SATA_PHY_8_0_5_DB		(0x0 << 24)
+#define IMX6Q_GPR13_SATA_PHY_8_1_0_DB		(0x1 << 24)
+#define IMX6Q_GPR13_SATA_PHY_8_1_5_DB		(0x2 << 24)
+#define IMX6Q_GPR13_SATA_PHY_8_2_0_DB		(0x3 << 24)
+#define IMX6Q_GPR13_SATA_PHY_8_2_5_DB		(0x4 << 24)
+#define IMX6Q_GPR13_SATA_PHY_8_3_0_DB		(0x5 << 24)
+#define IMX6Q_GPR13_SATA_PHY_8_3_5_DB		(0x6 << 24)
+#define IMX6Q_GPR13_SATA_PHY_8_4_0_DB		(0x7 << 24)
+#define IMX6Q_GPR13_SATA_PHY_7_MASK		(0x1f << 19)
+#define IMX6Q_GPR13_SATA_PHY_7_SATA1I		(0x10 << 19)
+#define IMX6Q_GPR13_SATA_PHY_7_SATA1M		(0x10 << 19)
+#define IMX6Q_GPR13_SATA_PHY_7_SATA1X		(0x1a << 19)
+#define IMX6Q_GPR13_SATA_PHY_7_SATA2I		(0x12 << 19)
+#define IMX6Q_GPR13_SATA_PHY_7_SATA2M		(0x12 << 19)
+#define IMX6Q_GPR13_SATA_PHY_7_SATA2X		(0x1a << 19)
+#define IMX6Q_GPR13_SATA_PHY_6_MASK		(0x7 << 16)
+#define IMX6Q_GPR13_SATA_SPEED_MASK		BIT(15)
+#define IMX6Q_GPR13_SATA_SPEED_1P5G		0x0
+#define IMX6Q_GPR13_SATA_SPEED_3P0G		BIT(15)
+#define IMX6Q_GPR13_SATA_PHY_5			BIT(14)
+#define IMX6Q_GPR13_SATA_PHY_4_MASK		(0x7 << 11)
+#define IMX6Q_GPR13_SATA_PHY_4_16_16		(0x0 << 11)
+#define IMX6Q_GPR13_SATA_PHY_4_14_16		(0x1 << 11)
+#define IMX6Q_GPR13_SATA_PHY_4_12_16		(0x2 << 11)
+#define IMX6Q_GPR13_SATA_PHY_4_10_16		(0x3 << 11)
+#define IMX6Q_GPR13_SATA_PHY_4_9_16		(0x4 << 11)
+#define IMX6Q_GPR13_SATA_PHY_4_8_16		(0x5 << 11)
+#define IMX6Q_GPR13_SATA_PHY_3_MASK		(0xf << 7)
+#define IMX6Q_GPR13_SATA_PHY_3_OFF		0x7
+#define IMX6Q_GPR13_SATA_PHY_2_MASK		(0x1f << 2)
+#define IMX6Q_GPR13_SATA_PHY_2_OFF		0x2
+#define IMX6Q_GPR13_SATA_PHY_1_MASK		(0x3 << 0)
+#define IMX6Q_GPR13_SATA_PHY_1_FAST		(0x0 << 0)
+#define IMX6Q_GPR13_SATA_PHY_1_MED		(0x1 << 0)
+#define IMX6Q_GPR13_SATA_PHY_1_SLOW		(0x2 << 0)
+
+#endif /* __LINUX_IMX6Q_IOMUXC_GPR_H */
diff --git a/include/linux/mfd/tc3589x.h b/include/linux/mfd/tc3589x.h
index 3acb3a8..6b8e1ff 100644
--- a/include/linux/mfd/tc3589x.h
+++ b/include/linux/mfd/tc3589x.h
@@ -117,6 +117,7 @@
 	struct mutex lock;
 	struct device *dev;
 	struct i2c_client *i2c;
+	struct irq_domain *domain;
 
 	int irq_base;
 	int num_gpio;
diff --git a/include/linux/mfd/tps65217.h b/include/linux/mfd/tps65217.h
index 7cd83d8..290762f 100644
--- a/include/linux/mfd/tps65217.h
+++ b/include/linux/mfd/tps65217.h
@@ -213,6 +213,23 @@
 /* Number of total regulators available */
 #define TPS65217_NUM_REGULATOR		(TPS65217_NUM_DCDC + TPS65217_NUM_LDO)
 
+enum tps65217_bl_isel {
+	TPS65217_BL_ISET1 = 1,
+	TPS65217_BL_ISET2,
+};
+
+enum tps65217_bl_fdim {
+	TPS65217_BL_FDIM_100HZ,
+	TPS65217_BL_FDIM_200HZ,
+	TPS65217_BL_FDIM_500HZ,
+	TPS65217_BL_FDIM_1000HZ,
+};
+
+struct tps65217_bl_pdata {
+	enum tps65217_bl_isel isel;
+	enum tps65217_bl_fdim fdim;
+};
+
 /**
  * struct tps65217_board - packages regulator init data
  * @tps65217_regulator_data: regulator initialization values
@@ -222,6 +239,7 @@
 struct tps65217_board {
 	struct regulator_init_data *tps65217_init_data[TPS65217_NUM_REGULATOR];
 	struct device_node *of_node[TPS65217_NUM_REGULATOR];
+	struct tps65217_bl_pdata *bl_pdata;
 };
 
 /**
diff --git a/include/linux/mfd/tps6586x.h b/include/linux/mfd/tps6586x.h
index 9451471..2dd1231 100644
--- a/include/linux/mfd/tps6586x.h
+++ b/include/linux/mfd/tps6586x.h
@@ -78,6 +78,7 @@
 
 	int gpio_base;
 	int irq_base;
+	bool pm_off;
 };
 
 /*
diff --git a/include/linux/mfd/tps65910.h b/include/linux/mfd/tps65910.h
index 9bf876781..ac772b3 100644
--- a/include/linux/mfd/tps65910.h
+++ b/include/linux/mfd/tps65910.h
@@ -366,6 +366,8 @@
 
 
 /*Register DEVCTRL  (0x80) register.RegisterDescription */
+#define DEVCTRL_PWR_OFF_MASK				0x80
+#define DEVCTRL_PWR_OFF_SHIFT				7
 #define DEVCTRL_RTC_PWDN_MASK				0x40
 #define DEVCTRL_RTC_PWDN_SHIFT				6
 #define DEVCTRL_CK32K_CTRL_MASK				0x20
@@ -809,6 +811,7 @@
 	int vmbch2_threshold;
 	bool en_ck32k_xtal;
 	bool en_dev_slp;
+	bool pm_off;
 	struct tps65910_sleep_keepon_data *slp_keepon;
 	bool en_gpio_sleep[TPS6591X_MAX_NUM_GPIO];
 	unsigned long regulator_ext_sleep_control[TPS65910_NUM_REGS];
diff --git a/include/linux/mfd/twl6040.h b/include/linux/mfd/twl6040.h
index ba43d48..a8eff4a 100644
--- a/include/linux/mfd/twl6040.h
+++ b/include/linux/mfd/twl6040.h
@@ -143,7 +143,7 @@
 
 #define TWL6040_GPO1			0x01
 #define TWL6040_GPO2			0x02
-#define TWL6040_GPO3			0x03
+#define TWL6040_GPO3			0x04
 
 /* ACCCTL (0x2D) fields */
 
@@ -158,7 +158,7 @@
 #define TWL6040_VIBROCDET		0x20
 #define TWL6040_TSHUTDET                0x40
 
-#define TWL6040_CELLS			2
+#define TWL6040_CELLS			3
 
 #define TWL6040_REV_ES1_0		0x00
 #define TWL6040_REV_ES1_1		0x01 /* Rev ES1.1 and ES1.2 */
@@ -176,6 +176,8 @@
 #define TWL6040_SYSCLK_SEL_LPPLL	0
 #define TWL6040_SYSCLK_SEL_HPPLL	1
 
+#define TWL6040_GPO_MAX	3
+
 struct twl6040_codec_data {
 	u16 hs_left_step;
 	u16 hs_right_step;
@@ -192,11 +194,16 @@
 	int vddvibr_uV;			/* VDDVIBR volt, set 0 for fixed reg */
 };
 
+struct twl6040_gpo_data {
+	int gpio_base;
+};
+
 struct twl6040_platform_data {
 	int audpwron_gpio;	/* audio power-on gpio */
 
 	struct twl6040_codec_data *codec;
 	struct twl6040_vibra_data *vibra;
+	struct twl6040_gpo_data *gpo;
 };
 
 struct regmap;
diff --git a/include/linux/of.h b/include/linux/of.h
index f594c52..72843b7 100644
--- a/include/linux/of.h
+++ b/include/linux/of.h
@@ -317,6 +317,12 @@
 	return "<no-node>";
 }
 
+static inline struct device_node *of_find_node_by_name(struct device_node *from,
+	const char *name)
+{
+	return NULL;
+}
+
 static inline bool of_have_populated_dt(void)
 {
 	return false;