mfd: pm8901: Modify pm8901 subdevices to pm8xxx interface

Move the following  subdevices to use the pm8xxx interface -
mpp, irq, thermal, regulators.

This allows usage of a common driver for modules which are same
across multiple PM8XXX PMICs. It also provides flexibility
to add/remove subdevices for multiple board configurations.

Change-Id: I6478ec1b99b1ab55ca370d314dbeb590103a4b1c
Signed-off-by: Anirudh Ghayal <aghayal@codeaurora.org>
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index 25ba590..255d06e 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -294,6 +294,7 @@
 CONFIG_DEBUG_GPIO=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_SX150X=y
+# CONFIG_MPP_PMIC8901 is not set
 CONFIG_POWER_SUPPLY=y
 # CONFIG_BATTERY_MSM is not set
 CONFIG_BATTERY_MSM8X60=y
@@ -305,7 +306,6 @@
 CONFIG_SENSORS_MSM_ADC=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_HWMON=y
-CONFIG_THERMAL_PM8901=y
 CONFIG_THERMAL_TSENS=y
 CONFIG_THERMAL_PM8XXX=y
 CONFIG_PMIC8058=y
@@ -314,6 +314,7 @@
 CONFIG_TIMPANI_CODEC=y
 # CONFIG_MFD_PM8XXX_PWM is not set
 CONFIG_MFD_PM8XXX_BATT_ALARM=y
+CONFIG_REGULATOR_GPIO=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_VIDEO_DEV=y
 # CONFIG_MEDIA_TUNER_CUSTOMISE is not set
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index ae33597..0a88039 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -284,6 +284,7 @@
 CONFIG_DEBUG_GPIO=y
 CONFIG_GPIO_SYSFS=y
 CONFIG_GPIO_SX150X=y
+# CONFIG_MPP_PMIC8901 is not set
 CONFIG_POWER_SUPPLY=y
 # CONFIG_BATTERY_MSM is not set
 CONFIG_BATTERY_MSM8X60=y
@@ -294,7 +295,6 @@
 CONFIG_BATTERY_BQ27541=y
 CONFIG_SENSORS_MSM_ADC=y
 CONFIG_THERMAL=y
-CONFIG_THERMAL_PM8901=y
 CONFIG_THERMAL_TSENS=y
 CONFIG_THERMAL_PM8XXX=y
 CONFIG_PMIC8058=y
@@ -303,6 +303,7 @@
 CONFIG_TIMPANI_CODEC=y
 # CONFIG_MFD_PM8XXX_PWM is not set
 CONFIG_MFD_PM8XXX_BATT_ALARM=y
+CONFIG_REGULATOR_GPIO=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_VIDEO_DEV=y
 # CONFIG_MEDIA_TUNER_CUSTOMISE is not set
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 3038ff0..765f49e 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -22,6 +22,7 @@
 #include <linux/leds.h>
 #include <linux/pmic8058-othc.h>
 #include <linux/mfd/pmic8901.h>
+#include <linux/regulator/gpio-regulator.h>
 #include <linux/regulator/pmic8901-regulator.h>
 #include <linux/bootmem.h>
 #include <linux/msm_adc.h>
@@ -54,7 +55,6 @@
 #include <asm/setup.h>
 
 #include <mach/dma.h>
-#include <mach/mpp.h>
 #include <mach/board.h>
 #include <mach/irqs.h>
 #include <mach/msm_spi.h>
@@ -83,6 +83,7 @@
 #include <mach/rpm.h>
 #include <mach/rpm-regulator.h>
 #include <mach/restart.h>
+#include <mach/board-msm8660.h>
 
 #include "devices.h"
 #include "devices-msm8x60.h"
@@ -104,23 +105,6 @@
 #include <mach/ion.h>
 
 #define MSM_SHARED_RAM_PHYS 0x40000000
-
-/* Macros assume PMIC GPIOs start at 0 */
-#define PM8058_GPIO_BASE			NR_MSM_GPIOS
-#define PM8058_GPIO_PM_TO_SYS(pm_gpio)		(pm_gpio + PM8058_GPIO_BASE)
-#define PM8058_GPIO_SYS_TO_PM(sys_gpio)		(sys_gpio - PM8058_GPIO_BASE)
-#define PM8058_MPP_BASE			(PM8058_GPIO_BASE + PM8058_GPIOS)
-#define PM8058_MPP_PM_TO_SYS(pm_gpio)		(pm_gpio + PM8058_MPP_BASE)
-#define PM8058_MPP_SYS_TO_PM(sys_gpio)		(sys_gpio - PM8058_MPP_BASE)
-#define PM8058_IRQ_BASE				(NR_MSM_IRQS + NR_GPIO_IRQS)
-
-#define PM8901_GPIO_BASE			(PM8058_GPIO_BASE + \
-						PM8058_GPIOS + PM8058_MPPS)
-#define PM8901_GPIO_PM_TO_SYS(pm_gpio)		(pm_gpio + PM8901_GPIO_BASE)
-#define PM8901_GPIO_SYS_TO_PM(sys_gpio)		(sys_gpio - PM901_GPIO_BASE)
-#define PM8901_IRQ_BASE				(PM8058_IRQ_BASE + \
-						NR_PMIC8058_IRQS)
-
 #define MDM2AP_SYNC 129
 
 #define GPIO_ETHERNET_RESET_N_DRAGON	30
@@ -150,7 +134,7 @@
 
 enum {
 	GPIO_EXPANDER_IRQ_BASE  = PM8901_IRQ_BASE + NR_PMIC8901_IRQS,
-	GPIO_EXPANDER_GPIO_BASE = PM8901_GPIO_BASE + PM8901_MPPS,
+	GPIO_EXPANDER_GPIO_BASE = PM8901_MPP_BASE + PM8901_MPPS,
 	/* CORE expander */
 	GPIO_CORE_EXPANDER_BASE = GPIO_EXPANDER_GPIO_BASE,
 	GPIO_CLASS_D1_EN        = GPIO_CORE_EXPANDER_BASE,
@@ -273,7 +257,7 @@
 	struct pm8xxx_mpp_config_data	config;
 };
 
-#define PM8XXX_MPP_INIT(_mpp, _type, _level, _control) \
+#define PM8058_MPP_INIT(_mpp, _type, _level, _control) \
 { \
 	.mpp	= PM8058_MPP_PM_TO_SYS(_mpp), \
 	.config	= { \
@@ -283,6 +267,16 @@
 	} \
 }
 
+#define PM8901_MPP_INIT(_mpp, _type, _level, _control) \
+{ \
+	.mpp	= PM8901_MPP_PM_TO_SYS(_mpp), \
+	.config	= { \
+		.type		= PM8XXX_MPP_TYPE_##_type, \
+		.level		= _level, \
+		.control	= PM8XXX_MPP_##_control, \
+	} \
+}
+
 /*
  * The UI_INTx_N lines are pmic gpio lines which connect i2c
  * gpio expanders to the pm8058.
@@ -1045,14 +1039,21 @@
 {
 	unsigned ret;
 
+	struct pm8xxx_mpp_config_data hsusb_phy_mpp = {
+		.type	= PM8XXX_MPP_TYPE_D_OUTPUT,
+		.level	= PM8901_MPP_DIG_LEVEL_L5,
+	};
+
 	if (init) {
-		ret = pm8901_mpp_config_digital_out(1,
-			PM8901_MPP_DIG_LEVEL_L5, 1);
+		hsusb_phy_mpp.control = PM8XXX_MPP_DOUT_CTRL_HIGH;
+		ret = pm8xxx_mpp_config(PM8901_MPP_PM_TO_SYS(1),
+							&hsusb_phy_mpp);
 		if (ret < 0)
 			pr_err("%s:MPP2 configuration failed\n", __func__);
 	} else {
-		ret = pm8901_mpp_config_digital_out(1,
-			PM8901_MPP_DIG_LEVEL_L5, 0);
+		hsusb_phy_mpp.control = PM8XXX_MPP_DOUT_CTRL_LOW;
+		ret = pm8xxx_mpp_config(PM8901_MPP_PM_TO_SYS(1),
+							&hsusb_phy_mpp);
 		if (ret < 0)
 			pr_err("%s:MPP2 un config failed\n", __func__);
 	}
@@ -4837,23 +4838,20 @@
 {
 	int rc, i;
 	struct pm8xxx_mpp_init_info xoadc_mpps[] = {
-		PM8XXX_MPP_INIT(XOADC_MPP_3, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH5,
+		PM8058_MPP_INIT(XOADC_MPP_3, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH5,
 							AOUT_CTRL_DISABLE),
-		PM8XXX_MPP_INIT(XOADC_MPP_5, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH9,
+		PM8058_MPP_INIT(XOADC_MPP_5, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH9,
 							AOUT_CTRL_DISABLE),
-		PM8XXX_MPP_INIT(XOADC_MPP_7, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH6,
+		PM8058_MPP_INIT(XOADC_MPP_7, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH6,
 							AOUT_CTRL_DISABLE),
-		PM8XXX_MPP_INIT(XOADC_MPP_8, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH8,
+		PM8058_MPP_INIT(XOADC_MPP_8, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH8,
 							AOUT_CTRL_DISABLE),
-		PM8XXX_MPP_INIT(XOADC_MPP_10, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH7,
+		PM8058_MPP_INIT(XOADC_MPP_10, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH7,
 							AOUT_CTRL_DISABLE),
+		PM8901_MPP_INIT(XOADC_MPP_4, D_OUTPUT, PM8901_MPP_DIG_LEVEL_S4,
+							DOUT_CTRL_LOW),
 	};
 
-	rc = pm8901_mpp_config_digital_out(XOADC_MPP_4,
-			PM8901_MPP_DIG_LEVEL_S4, PM_MPP_DOUT_CTL_LOW);
-	if (rc)
-		pr_err("%s: Config mpp4 on pmic 8901 failed\n", __func__);
-
 	for (i = 0; i < ARRAY_SIZE(xoadc_mpps); i++) {
 		rc = pm8xxx_mpp_config(xoadc_mpps[i].mpp,
 					&xoadc_mpps[i].config);
@@ -4982,6 +4980,75 @@
 
 #endif /* CONFIG_MSM_SDIO_AL */
 
+#define GPIO_VREG_ID_EXT_5V		0
+
+static struct regulator_consumer_supply vreg_consumers_EXT_5V[] = {
+	REGULATOR_SUPPLY("ext_5v",	NULL),
+	REGULATOR_SUPPLY("8901_mpp0",	NULL),
+};
+
+#define GPIO_VREG_INIT(_id, _reg_name, _gpio_label, _gpio, _active_low) \
+	[GPIO_VREG_ID_##_id] = { \
+		.init_data = { \
+			.constraints = { \
+				.valid_ops_mask	= REGULATOR_CHANGE_STATUS, \
+			}, \
+			.num_consumer_supplies	= \
+					ARRAY_SIZE(vreg_consumers_##_id), \
+			.consumer_supplies	= vreg_consumers_##_id, \
+		}, \
+		.regulator_name	= _reg_name, \
+		.active_low	= _active_low, \
+		.gpio_label	= _gpio_label, \
+		.gpio		= _gpio, \
+	}
+
+/* GPIO regulator constraints */
+static struct gpio_regulator_platform_data msm_gpio_regulator_pdata[] = {
+	GPIO_VREG_INIT(EXT_5V, "ext_5v", "ext_5v_en",
+					PM8901_MPP_PM_TO_SYS(0), 0),
+};
+
+/* GPIO regulator */
+static struct platform_device msm8x60_8901_mpp_vreg __devinitdata = {
+	.name	= GPIO_REGULATOR_DEV_NAME,
+	.id	= PM8901_MPP_PM_TO_SYS(0),
+	.dev	= {
+		.platform_data =
+			&msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_5V],
+	},
+};
+
+static void __init pm8901_vreg_mpp0_init(void)
+{
+	int rc;
+
+	struct pm8xxx_mpp_init_info pm8901_vreg_mpp0 = {
+		.mpp	= PM8901_MPP_PM_TO_SYS(0),
+		.config =  {
+			.type	= PM8XXX_MPP_TYPE_D_OUTPUT,
+			.level	= PM8901_MPP_DIG_LEVEL_VPH,
+		},
+	};
+
+	/*
+	 * Set PMIC 8901 MPP0 active_high to 0 for surf and charm_surf. This
+	 * implies that the regulator connected to MPP0 is enabled when
+	 * MPP0 is low.
+	 */
+	if (machine_is_msm8x60_surf() || machine_is_msm8x60_fusion()) {
+		msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_5V].active_low = 1;
+		pm8901_vreg_mpp0.config.control = PM8XXX_MPP_DOUT_CTRL_HIGH;
+	} else {
+		msm_gpio_regulator_pdata[GPIO_VREG_ID_EXT_5V].active_low = 0;
+		pm8901_vreg_mpp0.config.control = PM8XXX_MPP_DOUT_CTRL_LOW;
+	}
+
+	rc = pm8xxx_mpp_config(pm8901_vreg_mpp0.mpp, &pm8901_vreg_mpp0.config);
+	if (rc)
+		pr_err("%s: pm8xxx_mpp_config: rc=%d\n", __func__, rc);
+}
+
 static struct platform_device *charm_devices[] __initdata = {
 	&msm_charm_modem,
 #ifdef CONFIG_MSM_SDIO_AL
@@ -5309,9 +5376,9 @@
 #define EXT_CHG_VALID_MPP_2 11
 
 static struct pm8xxx_mpp_init_info isl_mpp[] = {
-	PM8XXX_MPP_INIT(EXT_CHG_VALID_MPP, D_INPUT,
+	PM8058_MPP_INIT(EXT_CHG_VALID_MPP, D_INPUT,
 		PM8058_MPP_DIG_LEVEL_S3, DIN_TO_INT),
-	PM8XXX_MPP_INIT(EXT_CHG_VALID_MPP_2, D_BI_DIR,
+	PM8058_MPP_INIT(EXT_CHG_VALID_MPP_2, D_BI_DIR,
 		PM8058_MPP_DIG_LEVEL_S3, BI_PULLUP_10KOHM),
 };
 
@@ -6526,32 +6593,10 @@
 #ifdef CONFIG_PMIC8901
 
 #define PM8901_GPIO_INT           91
-
-static struct pm8901_gpio_platform_data pm8901_mpp_data = {
-	.gpio_base	= PM8901_GPIO_PM_TO_SYS(0),
-	.irq_base	= PM8901_MPP_IRQ(PM8901_IRQ_BASE, 0),
-};
-
-static struct resource pm8901_temp_alarm[] = {
-	{
-		.start = PM8901_TEMP_ALARM_IRQ(PM8901_IRQ_BASE),
-		.end = PM8901_TEMP_ALARM_IRQ(PM8901_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = PM8901_TEMP_HI_ALARM_IRQ(PM8901_IRQ_BASE),
-		.end = PM8901_TEMP_HI_ALARM_IRQ(PM8901_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
 /*
  * Consumer specific regulator names:
  *			 regulator name		consumer dev_name
  */
-static struct regulator_consumer_supply vreg_consumers_8901_MPP0[] = {
-	REGULATOR_SUPPLY("8901_mpp0",		NULL),
-};
 static struct regulator_consumer_supply vreg_consumers_8901_USB_OTG[] = {
 	REGULATOR_SUPPLY("8901_usb_otg",	NULL),
 };
@@ -6560,8 +6605,8 @@
 };
 
 #define PM8901_VREG_INIT(_id, _min_uV, _max_uV, _modes, _ops, _apply_uV, \
-			 _always_on, _active_high) \
-	[PM8901_VREG_ID_##_id] = { \
+			 _always_on) \
+	{ \
 		.init_data = { \
 			.constraints = { \
 				.valid_modes_mask = _modes, \
@@ -6576,53 +6621,33 @@
 			.num_consumer_supplies = \
 				ARRAY_SIZE(vreg_consumers_8901_##_id), \
 		}, \
-		.active_high = _active_high, \
+		.id = PM8901_VREG_ID_##_id, \
 	}
 
-#define PM8901_VREG_INIT_MPP(_id, _active_high) \
-	PM8901_VREG_INIT(_id, 0, 0, REGULATOR_MODE_NORMAL, \
-			REGULATOR_CHANGE_STATUS, 0, 0, _active_high)
-
 #define PM8901_VREG_INIT_VS(_id) \
 	PM8901_VREG_INIT(_id, 0, 0, REGULATOR_MODE_NORMAL, \
-			REGULATOR_CHANGE_STATUS, 0, 0, 0)
+			REGULATOR_CHANGE_STATUS, 0, 0)
 
-static struct pm8901_vreg_pdata pm8901_vreg_init_pdata[PM8901_VREG_MAX] = {
-	PM8901_VREG_INIT_MPP(MPP0, 1),
-
+static struct pm8901_vreg_pdata pm8901_vreg_init[] = {
 	PM8901_VREG_INIT_VS(USB_OTG),
 	PM8901_VREG_INIT_VS(HDMI_MVS),
 };
 
-#define PM8901_VREG(_id) { \
-	.name = "pm8901-regulator", \
-	.id = _id, \
-	.platform_data = &pm8901_vreg_init_pdata[_id], \
-	.pdata_size = sizeof(pm8901_vreg_init_pdata[_id]), \
-}
+static struct pm8xxx_irq_platform_data pm8901_irq_pdata = {
+	.irq_base		= PM8901_IRQ_BASE,
+	.devirq			= MSM_GPIO_TO_INT(PM8901_GPIO_INT),
+	.irq_trigger_flag	= IRQF_TRIGGER_LOW,
+};
 
-static struct mfd_cell pm8901_subdevs[] = {
-	{	.name = "pm8901-mpp",
-		.id		= -1,
-		.platform_data	= &pm8901_mpp_data,
-		.pdata_size      = sizeof(pm8901_mpp_data),
-	},
-	{	.name = "pm8901-tm",
-		.id		= -1,
-		.num_resources  = ARRAY_SIZE(pm8901_temp_alarm),
-		.resources      = pm8901_temp_alarm,
-	},
-	PM8901_VREG(PM8901_VREG_ID_MPP0),
-	PM8901_VREG(PM8901_VREG_ID_USB_OTG),
-	PM8901_VREG(PM8901_VREG_ID_HDMI_MVS),
+static struct pm8xxx_mpp_platform_data pm8901_mpp_pdata = {
+	.mpp_base		= PM8901_MPP_PM_TO_SYS(0),
 };
 
 static struct pm8901_platform_data pm8901_platform_data = {
-	.irq_base = PM8901_IRQ_BASE,
-	.irq = MSM_GPIO_TO_INT(PM8901_GPIO_INT),
-	.num_subdevs = ARRAY_SIZE(pm8901_subdevs),
-	.sub_devices = pm8901_subdevs,
-	.irq_trigger_flags = IRQF_TRIGGER_LOW,
+	.irq_pdata		= &pm8901_irq_pdata,
+	.mpp_pdata		= &pm8901_mpp_pdata,
+	.regulator_pdatas	= pm8901_vreg_init,
+	.num_regulators		= ARRAY_SIZE(pm8901_vreg_init),
 };
 
 static struct msm_ssbi_platform_data msm8x60_ssbi_pm8901_pdata __devinitdata = {
@@ -7106,15 +7131,6 @@
 		sx150x_data[SX150X_CORE_FLUID].irq_summary =
 			PM8058_GPIO_IRQ(PM8058_IRQ_BASE, UI_INT1_N);
 #endif
-	/*
-	 * Set PMIC 8901 MPP0 active_high to 0 for surf and charm_surf. This
-	 * implies that the regulator connected to MPP0 is enabled when
-	 * MPP0 is low.
-	 */
-	if (machine_is_msm8x60_surf() || machine_is_msm8x60_fusion())
-		pm8901_vreg_init_pdata[PM8901_VREG_ID_MPP0].active_high = 0;
-	else
-		pm8901_vreg_init_pdata[PM8901_VREG_ID_MPP0].active_high = 1;
 #endif
 }
 
@@ -9905,7 +9921,13 @@
 static void __init msm8x60_init(struct msm_board_data *board_data)
 {
 	uint32_t soc_platform_version;
-
+#ifdef CONFIG_USB_EHCI_MSM_72K
+	struct pm8xxx_mpp_config_data hsusb_phy_mpp = {
+		.type		= PM8XXX_MPP_TYPE_D_OUTPUT,
+		.level		= PM8901_MPP_DIG_LEVEL_L5,
+		.control	= PM8XXX_MPP_DOUT_CTRL_HIGH,
+	};
+#endif
 	pmic_reset_irq = PM8058_IRQ_BASE + PM8058_RESOUT_IRQ;
 
 	/*
@@ -10057,16 +10079,18 @@
 		}
 #endif
 
+	pm8901_vreg_mpp0_init();
+
+	platform_device_register(&msm8x60_8901_mpp_vreg);
+
 #ifdef CONFIG_USB_EHCI_MSM_72K
 	/*
 	 * Drive MPP2 pin HIGH for PHY to generate ID interrupts on 8660
 	 * fluid
 	 */
-	if (machine_is_msm8x60_fluid()) {
-		pm8901_mpp_config_digital_out(1,
-			PM8901_MPP_DIG_LEVEL_L5, 1);
-	}
-		msm_add_host(0, &msm_usb_host_pdata);
+	if (machine_is_msm8x60_fluid())
+		pm8xxx_mpp_config(PM8901_MPP_PM_TO_SYS(1), &hsusb_phy_mpp);
+	msm_add_host(0, &msm_usb_host_pdata);
 #endif
 
 #ifdef CONFIG_SND_SOC_MSM8660_APQ
diff --git a/arch/arm/mach-msm/include/mach/board-msm8660.h b/arch/arm/mach-msm/include/mach/board-msm8660.h
new file mode 100644
index 0000000..b07cc62
--- /dev/null
+++ b/arch/arm/mach-msm/include/mach/board-msm8660.h
@@ -0,0 +1,36 @@
+/* Copyright (c) 2011, Code Aurora Forum. 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 and
+ * only 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.
+ */
+
+#ifndef __ARCH_ARM_MACH_MSM_BOARD_MSM8660_H
+#define __ARCH_ARM_MACH_MSM_BOARD_MSM8660_H
+
+#include <linux/mfd/pmic8058.h>
+#include <linux/mfd/pmic8901.h>
+#include <mach/irqs.h>
+
+/* Macros assume PMIC GPIOs start at 0 */
+#define PM8058_GPIO_BASE			NR_MSM_GPIOS
+#define PM8058_GPIO_PM_TO_SYS(pm_gpio)		(pm_gpio + PM8058_GPIO_BASE)
+#define PM8058_GPIO_SYS_TO_PM(sys_gpio)		(sys_gpio - PM8058_GPIO_BASE)
+#define PM8058_MPP_BASE			(PM8058_GPIO_BASE + PM8058_GPIOS)
+#define PM8058_MPP_PM_TO_SYS(pm_gpio)		(pm_gpio + PM8058_MPP_BASE)
+#define PM8058_MPP_SYS_TO_PM(sys_gpio)		(sys_gpio - PM8058_MPP_BASE)
+#define PM8058_IRQ_BASE				(NR_MSM_IRQS + NR_GPIO_IRQS)
+
+#define PM8901_MPP_BASE				(PM8058_GPIO_BASE + \
+						PM8058_GPIOS + PM8058_MPPS)
+#define PM8901_MPP_PM_TO_SYS(pm_gpio)		(pm_gpio + PM8901_MPP_BASE)
+#define PM8901_MPP_SYS_TO_PM(sys_gpio)		(sys_gpio - PM901_MPP_BASE)
+#define PM8901_IRQ_BASE				(PM8058_IRQ_BASE + \
+						NR_PMIC8058_IRQS)
+
+#endif
diff --git a/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c b/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
index 135dd03..11687ac 100644
--- a/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
+++ b/arch/arm/mach-msm/qdsp6v2/board-msm8x60-audio.c
@@ -17,19 +17,16 @@
 #include <linux/delay.h>
 #include <linux/debugfs.h>
 #include <linux/mfd/pmic8058.h>
-#include <linux/pmic8058-othc.h>
 #include <linux/mfd/pmic8901.h>
 #include <linux/mfd/msm-adie-codec.h>
-#include <linux/regulator/pmic8058-regulator.h>
-#include <linux/regulator/pmic8901-regulator.h>
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/machine.h>
 
 #include <mach/qdsp6v2/audio_dev_ctl.h>
-#include <mach/mpp.h>
 #include <sound/apr_audio.h>
 #include <asm/mach-types.h>
 #include <asm/uaccess.h>
+#include <mach/board-msm8660.h>
 
 #include "snddev_icodec.h"
 #include "snddev_ecodec.h"
@@ -266,10 +263,15 @@
 {
 	int rc;
 
-	if (enable) {
-		rc = pm8901_mpp_config_digital_out(PM8901_MPP_3,
-			PM8901_MPP_DIG_LEVEL_MSMIO, 1);
+	struct pm8xxx_mpp_config_data class_d0_mpp = {
+		.type		= PM8XXX_MPP_TYPE_D_OUTPUT,
+		.level		= PM8901_MPP_DIG_LEVEL_MSMIO,
+	};
 
+	if (enable) {
+		class_d0_mpp.control = PM8XXX_MPP_DOUT_CTRL_HIGH;
+		rc = pm8xxx_mpp_config(PM8901_MPP_PM_TO_SYS(PM8901_MPP_3),
+							&class_d0_mpp);
 		if (rc) {
 			pr_err("%s: CLASS_D0_EN failed\n", __func__);
 			return rc;
@@ -280,18 +282,20 @@
 		if (rc) {
 			pr_err("%s: spkr pamp gpio pm8901 mpp3 request"
 			"failed\n", __func__);
-			pm8901_mpp_config_digital_out(PM8901_MPP_3,
-			PM8901_MPP_DIG_LEVEL_MSMIO, 0);
+			class_d0_mpp.control = PM8XXX_MPP_DOUT_CTRL_LOW;
+			pm8xxx_mpp_config(PM8901_MPP_PM_TO_SYS(PM8901_MPP_3),
+						&class_d0_mpp);
 			return rc;
 		}
 
 		gpio_direction_output(SNDDEV_GPIO_CLASS_D0_EN, 1);
-		gpio_set_value(SNDDEV_GPIO_CLASS_D0_EN, 1);
+		gpio_set_value_cansleep(SNDDEV_GPIO_CLASS_D0_EN, 1);
 
 	} else {
-		pm8901_mpp_config_digital_out(PM8901_MPP_3,
-		PM8901_MPP_DIG_LEVEL_MSMIO, 0);
-		gpio_set_value(SNDDEV_GPIO_CLASS_D0_EN, 0);
+		class_d0_mpp.control = PM8XXX_MPP_DOUT_CTRL_LOW;
+		pm8xxx_mpp_config(PM8901_MPP_PM_TO_SYS(PM8901_MPP_3),
+						&class_d0_mpp);
+		gpio_set_value_cansleep(SNDDEV_GPIO_CLASS_D0_EN, 0);
 		gpio_free(SNDDEV_GPIO_CLASS_D0_EN);
 	}
 	return 0;
diff --git a/drivers/mfd/pmic8901.c b/drivers/mfd/pmic8901.c
index 3d87f0b..9e8786e 100644
--- a/drivers/mfd/pmic8901.c
+++ b/drivers/mfd/pmic8901.c
@@ -11,51 +11,25 @@
  */
 
 #include <linux/interrupt.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/ratelimit.h>
-#include <linux/gpio.h>
+#include <linux/delay.h>
 #include <linux/mfd/core.h>
 #include <linux/msm_ssbi.h>
 #include <linux/mfd/pmic8901.h>
-#include <linux/platform_device.h>
-#include <linux/debugfs.h>
-#include <linux/delay.h>
+#include <linux/mfd/pm8xxx/core.h>
 
 /* PMIC8901 Revision */
-#define SSBI_REG_REV			0x002  /* PMIC4 revision */
+#define PM8901_REG_REV			0x002
+#define PM8901_VERSION_MASK		0xF0
+#define PM8901_REVISION_MASK		0x0F
+#define PM8901_VERSION_VALUE		0xF0
 
-/* PMIC8901 IRQ */
-#define	SSBI_REG_ADDR_IRQ_BASE		0xD5
+#define REG_IRQ_BASE			0xD5
+#define REG_MPP_BASE			0x27
 
-#define	SSBI_REG_ADDR_IRQ_ROOT		(SSBI_REG_ADDR_IRQ_BASE + 0)
-#define	SSBI_REG_ADDR_IRQ_M_STATUS1	(SSBI_REG_ADDR_IRQ_BASE + 1)
-#define	SSBI_REG_ADDR_IRQ_M_STATUS2	(SSBI_REG_ADDR_IRQ_BASE + 2)
-#define	SSBI_REG_ADDR_IRQ_M_STATUS3	(SSBI_REG_ADDR_IRQ_BASE + 3)
-#define	SSBI_REG_ADDR_IRQ_M_STATUS4	(SSBI_REG_ADDR_IRQ_BASE + 4)
-#define	SSBI_REG_ADDR_IRQ_BLK_SEL	(SSBI_REG_ADDR_IRQ_BASE + 5)
-#define	SSBI_REG_ADDR_IRQ_IT_STATUS	(SSBI_REG_ADDR_IRQ_BASE + 6)
-#define	SSBI_REG_ADDR_IRQ_CONFIG	(SSBI_REG_ADDR_IRQ_BASE + 7)
-#define	SSBI_REG_ADDR_IRQ_RT_STATUS	(SSBI_REG_ADDR_IRQ_BASE + 8)
-
-#define	PM8901_IRQF_LVL_SEL		0x01	/* level select */
-#define	PM8901_IRQF_MASK_FE		0x02	/* mask falling edge */
-#define	PM8901_IRQF_MASK_RE		0x04	/* mask rising edge */
-#define	PM8901_IRQF_CLR			0x08	/* clear interrupt */
-#define	PM8901_IRQF_BITS_MASK		0x70
-#define	PM8901_IRQF_BITS_SHIFT		4
-#define	PM8901_IRQF_WRITE		0x80
-
-#define	PM8901_IRQF_MASK_ALL		(PM8901_IRQF_MASK_FE | \
-					PM8901_IRQF_MASK_RE)
-#define PM8901_IRQF_W_C_M		(PM8901_IRQF_WRITE |	\
-					PM8901_IRQF_CLR |	\
-					PM8901_IRQF_MASK_ALL)
-
-#define	MAX_PM_IRQ			72
-#define	MAX_PM_BLOCKS			(MAX_PM_IRQ / 8 + 1)
-#define	MAX_PM_MASTERS			(MAX_PM_BLOCKS / 8 + 1)
-
-#define MPP_IRQ_BLOCK			1
+#define REG_TEMP_ALRM_CTRL		0x23
+#define REG_TEMP_ALRM_PWM		0x24
 
 /* FTS regulator PMR registers */
 #define SSBI_REG_ADDR_S1_PMR		(0xA7)
@@ -70,47 +44,24 @@
 #define DELAY_AFTER_REG_DISABLE_MS	4
 #define DELAY_BEFORE_SHUTDOWN_MS	8
 
+#define SINGLE_IRQ_RESOURCE(_name, _irq) \
+{ \
+	.name	= _name, \
+	.start	= _irq, \
+	.end	= _irq, \
+	.flags	= IORESOURCE_IRQ, \
+}
+
 struct pm8901_chip {
 	struct pm8901_platform_data	pdata;
 	struct device			*dev;
-
-	u8	irqs_allowed[MAX_PM_BLOCKS];
-	u8	blocks_allowed[MAX_PM_MASTERS];
-	u8	masters_allowed;
-	int	pm_max_irq;
-	int	pm_max_blocks;
-	int	pm_max_masters;
-
-	u8	config[MAX_PM_IRQ];
-	u8	wake_enable[MAX_PM_IRQ];
-	u16	count_wakeable;
-
-	u8	revision;
-
-	spinlock_t	pm_lock;
+	struct pm_irq_chip		*irq_chip;
+	struct mfd_cell			*mfd_regulators;
+	u8				revision;
 };
 
-#if defined(CONFIG_DEBUG_FS)
-struct pm8901_dbg_device {
-	struct mutex		dbg_mutex;
-	struct pm8901_chip	*pm_chip;
-	struct dentry		*dent;
-	int			addr;
-};
-
-static struct pm8901_dbg_device *pmic_dbg_device;
-#endif
-
 static struct pm8901_chip *pmic_chip;
 
-/* Helper Functions */
-DEFINE_RATELIMIT_STATE(pm8901_msg_ratelimit, 60 * HZ, 10);
-
-static inline int pm8901_can_print(void)
-{
-	return __ratelimit(&pm8901_msg_ratelimit);
-}
-
 static inline int
 ssbi_read(struct device *dev, u16 addr, u8 *buf, size_t len)
 {
@@ -123,80 +74,6 @@
 	return msm_ssbi_write(dev->parent, addr, buf, len);
 }
 
-/* External APIs */
-int pm8901_rev(struct pm8901_chip *chip)
-{
-	if (chip == NULL) {
-		if (pmic_chip != NULL)
-			return pmic_chip->revision;
-		else
-			return -EINVAL;
-	}
-
-	return chip->revision;
-}
-EXPORT_SYMBOL(pm8901_rev);
-
-int pm8901_read(struct pm8901_chip *chip, u16 addr, u8 *values,
-		unsigned int len)
-{
-	if (chip == NULL)
-		return -EINVAL;
-
-	return ssbi_read(chip->dev, addr, values, len);
-}
-EXPORT_SYMBOL(pm8901_read);
-
-int pm8901_write(struct pm8901_chip *chip, u16 addr, u8 *values,
-		 unsigned int len)
-{
-	if (chip == NULL)
-		return -EINVAL;
-
-	return ssbi_write(chip->dev, addr, values, len);
-}
-EXPORT_SYMBOL(pm8901_write);
-
-int pm8901_irq_get_rt_status(struct pm8901_chip *chip, int irq)
-{
-	int     rc;
-	u8      block, bits, bit;
-	unsigned long   irqsave;
-
-	if (chip == NULL || irq < chip->pdata.irq_base ||
-			irq >= chip->pdata.irq_base + MAX_PM_IRQ)
-		return -EINVAL;
-
-	irq -= chip->pdata.irq_base;
-
-	block = irq / 8;
-	bit = irq % 8;
-
-	spin_lock_irqsave(&chip->pm_lock, irqsave);
-
-	rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, &block, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_write(): rc=%d (Select Block)\n",
-				__func__, rc);
-		goto bail_out;
-	}
-
-	rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_read(): rc=%d (Read RT Status)\n",
-				__func__, rc);
-		goto bail_out;
-	}
-
-	rc = (bits & (1 << bit)) ? 1 : 0;
-
-bail_out:
-	spin_unlock_irqrestore(&chip->pm_lock, irqsave);
-
-	return rc;
-}
-EXPORT_SYMBOL(pm8901_irq_get_rt_status);
-
 int pm8901_reset_pwr_off(int reset)
 {
 	int rc = 0, i;
@@ -240,673 +117,283 @@
 }
 EXPORT_SYMBOL(pm8901_reset_pwr_off);
 
-/* Internal functions */
-static inline int
-pm8901_config_irq(struct pm8901_chip *chip, u8 *bp, u8 *cp)
+static int pm8901_readb(const struct device *dev, u16 addr, u8 *val)
 {
-	int	rc;
+	const struct pm8xxx_drvdata *pm8901_drvdata = dev_get_drvdata(dev);
+	const struct pm8901_chip *pmic = pm8901_drvdata->pm_chip_data;
 
-	rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp, 1);
-	if (rc) {
-		pr_err("%s: ssbi_write: rc=%d (Select block)\n",
-			__func__, rc);
-		goto bail_out;
-	}
-
-	rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_CONFIG, cp, 1);
-	if (rc)
-		pr_err("%s: ssbi_write: rc=%d (Configure IRQ)\n",
-			__func__, rc);
-
-bail_out:
-	return rc;
+	return msm_ssbi_read(pmic->dev->parent, addr, val, 1);
 }
 
-static void pm8901_irq_mask(struct irq_data *d)
+static int pm8901_writeb(const struct device *dev, u16 addr, u8 val)
 {
-	int	master, irq_bit;
-	struct	pm8901_chip *chip = irq_data_get_irq_handler_data(d);
-	u8	block, config;
-	unsigned int irq = d->irq;
+	const struct pm8xxx_drvdata *pm8901_drvdata = dev_get_drvdata(dev);
+	const struct pm8901_chip *pmic = pm8901_drvdata->pm_chip_data;
 
-	irq -= chip->pdata.irq_base;
-	block = irq / 8;
-	master = block / 8;
-	irq_bit = irq % 8;
-
-	chip->irqs_allowed[block] &= ~(1 << irq_bit);
-	if (!chip->irqs_allowed[block]) {
-		chip->blocks_allowed[master] &= ~(1 << (block % 8));
-
-		if (!chip->blocks_allowed[master])
-			chip->masters_allowed &= ~(1 << master);
-	}
-
-	config = PM8901_IRQF_WRITE | chip->config[irq] |
-		PM8901_IRQF_MASK_FE | PM8901_IRQF_MASK_RE;
-	pm8901_config_irq(chip, &block, &config);
+	return msm_ssbi_write(pmic->dev->parent, addr, &val, 1);
 }
 
-static void pm8901_irq_unmask(struct irq_data *d)
+static int pm8901_read_buf(const struct device *dev, u16 addr, u8 *buf,
+								int cnt)
 {
-	int	master, irq_bit;
-	struct	pm8901_chip *chip = irq_data_get_irq_handler_data(d);
-	u8	block, config, old_irqs_allowed, old_blocks_allowed;
-	unsigned int irq = d->irq;
+	const struct pm8xxx_drvdata *pm8901_drvdata = dev_get_drvdata(dev);
+	const struct pm8901_chip *pmic = pm8901_drvdata->pm_chip_data;
 
-	irq -= chip->pdata.irq_base;
-	block = irq / 8;
-	master = block / 8;
-	irq_bit = irq % 8;
-
-	old_irqs_allowed = chip->irqs_allowed[block];
-	chip->irqs_allowed[block] |= 1 << irq_bit;
-	if (!old_irqs_allowed) {
-		master = block / 8;
-
-		old_blocks_allowed = chip->blocks_allowed[master];
-		chip->blocks_allowed[master] |= 1 << (block % 8);
-
-		if (!old_blocks_allowed)
-			chip->masters_allowed |= 1 << master;
-	}
-
-	config = PM8901_IRQF_WRITE | chip->config[irq];
-	pm8901_config_irq(chip, &block, &config);
+	return msm_ssbi_read(pmic->dev->parent, addr, buf, cnt);
 }
 
-static void pm8901_irq_ack(struct irq_data *d)
+static int pm8901_write_buf(const struct device *dev, u16 addr, u8 *buf,
+								int cnt)
 {
-	struct	pm8901_chip *chip = irq_data_get_irq_handler_data(d);
-	u8	block, config;
-	unsigned int irq = d->irq;
+	const struct pm8xxx_drvdata *pm8901_drvdata = dev_get_drvdata(dev);
+	const struct pm8901_chip *pmic = pm8901_drvdata->pm_chip_data;
 
-	irq -= chip->pdata.irq_base;
-	block = irq / 8;
-
-	config = PM8901_IRQF_WRITE | chip->config[irq] | PM8901_IRQF_CLR;
-	pm8901_config_irq(chip, &block, &config);
+	return msm_ssbi_write(pmic->dev->parent, addr, buf, cnt);
 }
 
-static int pm8901_irq_set_type(struct irq_data *d, unsigned int flow_type)
+static int pm8901_read_irq_stat(const struct device *dev, int irq)
 {
-	int	master, irq_bit;
-	struct	pm8901_chip *chip = irq_data_get_irq_handler_data(d);
-	u8	block, config;
-	unsigned int irq = d->irq;
+	const struct pm8xxx_drvdata *pm8901_drvdata = dev_get_drvdata(dev);
+	const struct pm8901_chip *pmic = pm8901_drvdata->pm_chip_data;
 
-	irq -= chip->pdata.irq_base;
-	if (irq > chip->pm_max_irq) {
-		chip->pm_max_irq = irq;
-		chip->pm_max_blocks =
-			chip->pm_max_irq / 8 + 1;
-		chip->pm_max_masters =
-			chip->pm_max_blocks / 8 + 1;
-	}
-	block = irq / 8;
-	master = block / 8;
-	irq_bit = irq % 8;
-
-	chip->config[irq] = (irq_bit << PM8901_IRQF_BITS_SHIFT) |
-			PM8901_IRQF_MASK_RE | PM8901_IRQF_MASK_FE;
-	if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
-		if (flow_type & IRQF_TRIGGER_RISING)
-			chip->config[irq] &= ~PM8901_IRQF_MASK_RE;
-		if (flow_type & IRQF_TRIGGER_FALLING)
-			chip->config[irq] &= ~PM8901_IRQF_MASK_FE;
-	} else {
-		chip->config[irq] |= PM8901_IRQF_LVL_SEL;
-
-		if (flow_type & IRQF_TRIGGER_HIGH)
-			chip->config[irq] &= ~PM8901_IRQF_MASK_RE;
-		else
-			chip->config[irq] &= ~PM8901_IRQF_MASK_FE;
-	}
-
-	config = PM8901_IRQF_WRITE | chip->config[irq] | PM8901_IRQF_CLR;
-	return pm8901_config_irq(chip, &block, &config);
-}
-
-static int pm8901_irq_set_wake(struct irq_data *d, unsigned int on)
-{
-	struct	pm8901_chip *chip = irq_data_get_irq_handler_data(d);
-	unsigned int irq = d->irq;
-
-	irq -= chip->pdata.irq_base;
-	if (on) {
-		if (!chip->wake_enable[irq]) {
-			chip->wake_enable[irq] = 1;
-			chip->count_wakeable++;
-		}
-	} else {
-		if (chip->wake_enable[irq]) {
-			chip->wake_enable[irq] = 0;
-			chip->count_wakeable--;
-		}
-	}
+	return pm8xxx_get_irq_stat(pmic->irq_chip, irq);
 
 	return 0;
 }
 
-static inline int
-pm8901_read_root(struct pm8901_chip *chip, u8 *rp)
+static enum pm8xxx_version pm8901_get_version(const struct device *dev)
 {
-	int	rc;
+	const struct pm8xxx_drvdata *pm8901_drvdata = dev_get_drvdata(dev);
+	const struct pm8901_chip *pmic = pm8901_drvdata->pm_chip_data;
+	enum pm8xxx_version version = -ENODEV;
 
-	rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_ROOT, rp, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_read(): rc=%d (Read Root)\n",
-			__func__, rc);
-		*rp = 0;
-	}
+	if ((pmic->revision & PM8901_VERSION_MASK) == PM8901_VERSION_VALUE)
+		version = PM8XXX_VERSION_8901;
 
-	return rc;
+	return version;
 }
 
-static inline int
-pm8901_read_master(struct pm8901_chip *chip, u8 m, u8 *bp)
+static int pm8901_get_revision(const struct device *dev)
 {
-	int	rc;
+	const struct pm8xxx_drvdata *pm8901_drvdata = dev_get_drvdata(dev);
+	const struct pm8901_chip *pmic = pm8901_drvdata->pm_chip_data;
 
-	rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_M_STATUS1 + m, bp, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_read(): rc=%d (Read Master)\n",
-			__func__, rc);
-		*bp = 0;
-	}
-
-	return rc;
+	return pmic->revision & PM8901_REVISION_MASK;
 }
 
-static inline int
-pm8901_read_block(struct pm8901_chip *chip, u8 *bp, u8 *ip)
-{
-	int	rc;
-
-	rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_write(): rc=%d (Select Block)\n",
-		       __func__, rc);
-		*bp = 0;
-		goto bail_out;
-	}
-
-	rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_IT_STATUS, ip, 1);
-	if (rc)
-		pr_err("%s: FAIL ssbi_read(): rc=%d (Read Status)\n",
-		       __func__, rc);
-
-bail_out:
-	return rc;
-}
-
-static irqreturn_t pm8901_isr_thread(int irq_requested, void *data)
-{
-	struct pm8901_chip *chip = data;
-	int	i, j, k;
-	u8	root, block, config, bits;
-	u8	blocks[MAX_PM_MASTERS];
-	int	masters = 0, irq, handled = 0, spurious = 0;
-	u16     irqs_to_handle[MAX_PM_IRQ];
-	unsigned long	irqsave;
-
-	spin_lock_irqsave(&chip->pm_lock, irqsave);
-
-	/* Read root for masters */
-	if (pm8901_read_root(chip, &root))
-		goto bail_out;
-
-	masters = root >> 1;
-
-	if (!(masters & chip->masters_allowed) ||
-	    (masters & ~chip->masters_allowed)) {
-		spurious = 1000000;
-	}
-
-	/* Read allowed masters for blocks. */
-	for (i = 0; i < chip->pm_max_masters; i++) {
-		if (masters & (1 << i)) {
-			if (pm8901_read_master(chip, i, &blocks[i]))
-				goto bail_out;
-
-			if (!blocks[i]) {
-				if (pm8901_can_print())
-					pr_err("%s: Spurious master: %d "
-					       "(blocks=0)", __func__, i);
-				spurious += 10000;
-			}
-		} else
-			blocks[i] = 0;
-	}
-
-	/* Select block, read status and call isr */
-	for (i = 0; i < chip->pm_max_masters; i++) {
-		if (!blocks[i])
-			continue;
-
-		for (j = 0; j < 8; j++) {
-			if (!(blocks[i] & (1 << j)))
-				continue;
-
-			block = i * 8 + j;	/* block # */
-			if (pm8901_read_block(chip, &block, &bits))
-				goto bail_out;
-
-			if (!bits) {
-				if (pm8901_can_print())
-					pr_err("%s: Spurious block: "
-					       "[master, block]=[%d, %d] "
-					       "(bits=0)\n", __func__, i, j);
-				spurious += 100;
-				continue;
-			}
-
-			/* Check IRQ bits */
-			for (k = 0; k < 8; k++) {
-				if (!(bits & (1 << k)))
-					continue;
-
-				/* Check spurious interrupts */
-				if (((1 << i) & chip->masters_allowed) &&
-				    (blocks[i] & chip->blocks_allowed[i]) &&
-				    (bits & chip->irqs_allowed[block])) {
-
-					/* Found one */
-					irq = block * 8 + k;
-					irqs_to_handle[handled] = irq +
-						chip->pdata.irq_base;
-					handled++;
-				} else {
-					/* Clear and mask wrong one */
-					config = PM8901_IRQF_W_C_M |
-						(k < PM8901_IRQF_BITS_SHIFT);
-
-					pm8901_config_irq(chip,
-							  &block, &config);
-
-					if (pm8901_can_print())
-						pr_err("%s: Spurious IRQ: "
-						       "[master, block, bit]="
-						       "[%d, %d (%d), %d]\n",
-							__func__,
-						       i, j, block, k);
-					spurious++;
-				}
-			}
-		}
-
-	}
-
-bail_out:
-
-	spin_unlock_irqrestore(&chip->pm_lock, irqsave);
-
-	for (i = 0; i < handled; i++)
-		generic_handle_irq(irqs_to_handle[i]);
-
-	if (spurious) {
-		if (!pm8901_can_print())
-			return IRQ_HANDLED;
-
-		pr_err("%s: spurious = %d (handled = %d)\n",
-		       __func__, spurious, handled);
-		pr_err("   root = 0x%x (masters_allowed<<1 = 0x%x)\n",
-		       root, chip->masters_allowed << 1);
-		for (i = 0; i < chip->pm_max_masters; i++) {
-			if (masters & (1 << i))
-				pr_err("   blocks[%d]=0x%x, "
-				       "allowed[%d]=0x%x\n",
-				       i, blocks[i],
-				       i, chip->blocks_allowed[i]);
-		}
-	}
-
-	return IRQ_HANDLED;
-}
-
-#if defined(CONFIG_DEBUG_FS)
-
-static int check_addr(int addr, const char *func_name)
-{
-	if (addr < 0 || addr > 0x3FF) {
-		pr_err("%s: PMIC 8901 register address is invalid: %d\n",
-			func_name, addr);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int data_set(void *data, u64 val)
-{
-	struct pm8901_dbg_device *dbgdev = data;
-	u8 reg = val;
-	int rc;
-
-	mutex_lock(&dbgdev->dbg_mutex);
-
-	rc = check_addr(dbgdev->addr, __func__);
-	if (rc)
-		goto done;
-
-	rc = pm8901_write(dbgdev->pm_chip, dbgdev->addr, &reg, 1);
-
-	if (rc)
-		pr_err("%s: FAIL pm8901_write(0x%03X)=0x%02X: rc=%d\n",
-			__func__, dbgdev->addr, reg, rc);
-done:
-	mutex_unlock(&dbgdev->dbg_mutex);
-	return rc;
-}
-
-static int data_get(void *data, u64 *val)
-{
-	struct pm8901_dbg_device *dbgdev = data;
-	int rc;
-	u8 reg;
-
-	mutex_lock(&dbgdev->dbg_mutex);
-
-	rc = check_addr(dbgdev->addr, __func__);
-	if (rc)
-		goto done;
-
-	rc = pm8901_read(dbgdev->pm_chip, dbgdev->addr, &reg, 1);
-
-	if (rc) {
-		pr_err("%s: FAIL pm8901_read(0x%03X)=0x%02X: rc=%d\n",
-			__func__, dbgdev->addr, reg, rc);
-		goto done;
-	}
-
-	*val = reg;
-done:
-	mutex_unlock(&dbgdev->dbg_mutex);
-	return rc;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(dbg_data_fops, data_get, data_set, "0x%02llX\n");
-
-static int addr_set(void *data, u64 val)
-{
-	struct pm8901_dbg_device *dbgdev = data;
-	int rc;
-
-	rc = check_addr(val, __func__);
-	if (rc)
-		return rc;
-
-	mutex_lock(&dbgdev->dbg_mutex);
-	dbgdev->addr = val;
-	mutex_unlock(&dbgdev->dbg_mutex);
-
-	return 0;
-}
-
-static int addr_get(void *data, u64 *val)
-{
-	struct pm8901_dbg_device *dbgdev = data;
-	int rc;
-
-	mutex_lock(&dbgdev->dbg_mutex);
-
-	rc = check_addr(dbgdev->addr, __func__);
-	if (rc) {
-		mutex_unlock(&dbgdev->dbg_mutex);
-		return rc;
-	}
-	*val = dbgdev->addr;
-
-	mutex_unlock(&dbgdev->dbg_mutex);
-
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(dbg_addr_fops, addr_get, addr_set, "0x%03llX\n");
-
-static int __devinit pmic8901_dbg_probe(struct pm8901_chip *chip)
-{
-	struct pm8901_dbg_device *dbgdev;
-	struct dentry *dent;
-	struct dentry *temp;
-	int rc;
-
-	if (chip == NULL) {
-		pr_err("%s: no parent data passed in.\n", __func__);
-		return -EINVAL;
-	}
-
-	dbgdev = kzalloc(sizeof *dbgdev, GFP_KERNEL);
-	if (dbgdev == NULL) {
-		pr_err("%s: kzalloc() failed.\n", __func__);
-		return -ENOMEM;
-	}
-
-	dbgdev->pm_chip = chip;
-	dbgdev->addr = -1;
-
-	dent = debugfs_create_dir("pm8901-dbg", NULL);
-	if (dent == NULL || IS_ERR(dent)) {
-		pr_err("%s: ERR debugfs_create_dir: dent=0x%X\n",
-					__func__, (unsigned)dent);
-		rc = PTR_ERR(dent);
-		goto dir_error;
-	}
-
-	temp = debugfs_create_file("addr", S_IRUSR | S_IWUSR, dent,
-					dbgdev, &dbg_addr_fops);
-	if (temp == NULL || IS_ERR(temp)) {
-		pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
-					__func__, (unsigned)temp);
-		rc = PTR_ERR(temp);
-		goto debug_error;
-	}
-
-	temp = debugfs_create_file("data", S_IRUSR | S_IWUSR, dent,
-					dbgdev, &dbg_data_fops);
-	if (temp == NULL || IS_ERR(temp)) {
-		pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
-					__func__, (unsigned)temp);
-		rc = PTR_ERR(temp);
-		goto debug_error;
-	}
-
-	mutex_init(&dbgdev->dbg_mutex);
-
-	dbgdev->dent = dent;
-
-	pmic_dbg_device = dbgdev;
-
-	return 0;
-
-debug_error:
-	debugfs_remove_recursive(dent);
-dir_error:
-	kfree(dbgdev);
-
-	return rc;
-}
-
-static int __devexit pmic8901_dbg_remove(void)
-{
-	if (pmic_dbg_device) {
-		debugfs_remove_recursive(pmic_dbg_device->dent);
-		mutex_destroy(&pmic_dbg_device->dbg_mutex);
-		kfree(pmic_dbg_device);
-	}
-	return 0;
-}
-
-#else
-
-static int __devinit pmic8901_dbg_probe(struct pm8901_chip *chip)
-{
-	return 0;
-}
-
-static int __devexit pmic8901_dbg_remove(void)
-{
-	return 0;
-}
-
-#endif
-
-static struct irq_chip pm8901_irq_chip = {
-	.name      = "pm8901",
-	.irq_ack       = pm8901_irq_ack,
-	.irq_mask      = pm8901_irq_mask,
-	.irq_unmask    = pm8901_irq_unmask,
-	.irq_set_type  = pm8901_irq_set_type,
-	.irq_set_wake  = pm8901_irq_set_wake,
+static struct pm8xxx_drvdata pm8901_drvdata = {
+	.pmic_readb		= pm8901_readb,
+	.pmic_writeb		= pm8901_writeb,
+	.pmic_read_buf		= pm8901_read_buf,
+	.pmic_write_buf		= pm8901_write_buf,
+	.pmic_read_irq_stat	= pm8901_read_irq_stat,
+	.pmic_get_version	= pm8901_get_version,
+	.pmic_get_revision	= pm8901_get_revision,
 };
 
+static struct mfd_cell debugfs_cell = {
+	.name		= "pm8xxx-debug",
+	.id		= 1,
+	.platform_data	= "pm8901-dbg",
+	.pdata_size	= sizeof("pm8901-dbg"),
+};
+
+static const struct resource thermal_alarm_cell_resources[] = {
+	SINGLE_IRQ_RESOURCE("pm8901_tempstat_irq", PM8901_TEMPSTAT_IRQ),
+	SINGLE_IRQ_RESOURCE("pm8901_overtemp_irq", PM8901_OVERTEMP_IRQ),
+};
+
+static struct pm8xxx_tm_core_data thermal_alarm_cdata = {
+	.adc_type			= PM8XXX_TM_ADC_NONE,
+	.reg_addr_temp_alarm_ctrl	= REG_TEMP_ALRM_CTRL,
+	.reg_addr_temp_alarm_pwm	= REG_TEMP_ALRM_PWM,
+	.tm_name			= "pm8901_tz",
+	.irq_name_temp_stat		= "pm8901_tempstat_irq",
+	.irq_name_over_temp		= "pm8901_overtemp_irq",
+};
+
+static struct mfd_cell thermal_alarm_cell = {
+	.name		= PM8XXX_TM_DEV_NAME,
+	.id		= 1,
+	.resources	= thermal_alarm_cell_resources,
+	.num_resources	= ARRAY_SIZE(thermal_alarm_cell_resources),
+	.platform_data	= &thermal_alarm_cdata,
+	.pdata_size	= sizeof(struct pm8xxx_tm_core_data),
+};
+
+static const struct resource mpp_cell_resources[] = {
+	{
+		.start	= PM8901_IRQ_BLOCK_BIT(PM8901_MPP_BLOCK_START, 0),
+		.end	= PM8901_IRQ_BLOCK_BIT(PM8901_MPP_BLOCK_START, 0)
+			  + PM8901_MPPS - 1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mfd_cell mpp_cell = {
+	.name		= PM8XXX_MPP_DEV_NAME,
+	.id		= 1,
+	.resources	= mpp_cell_resources,
+	.num_resources	= ARRAY_SIZE(mpp_cell_resources),
+};
+
+static int __devinit
+pm8901_add_subdevices(const struct pm8901_platform_data *pdata,
+				struct pm8901_chip *pmic)
+{
+	int rc = 0, irq_base = 0, i;
+	struct pm_irq_chip *irq_chip;
+	static struct mfd_cell *mfd_regulators;
+
+	if (pdata->irq_pdata) {
+		pdata->irq_pdata->irq_cdata.nirqs = PM8901_NR_IRQS;
+		pdata->irq_pdata->irq_cdata.base_addr = REG_IRQ_BASE;
+		irq_base = pdata->irq_pdata->irq_base;
+		irq_chip = pm8xxx_irq_init(pmic->dev, pdata->irq_pdata);
+
+		if (IS_ERR(irq_chip)) {
+			pr_err("Failed to init interrupts ret=%ld\n",
+					PTR_ERR(irq_chip));
+			return PTR_ERR(irq_chip);
+		}
+		pmic->irq_chip = irq_chip;
+	}
+
+	if (pdata->mpp_pdata) {
+		pdata->mpp_pdata->core_data.nmpps = PM8901_MPPS;
+		pdata->mpp_pdata->core_data.base_addr = REG_MPP_BASE;
+		mpp_cell.platform_data = pdata->mpp_pdata;
+		mpp_cell.pdata_size = sizeof(struct pm8xxx_mpp_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &mpp_cell, 1, NULL,
+					irq_base);
+		if (rc) {
+			pr_err("Failed to add mpp subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->num_regulators > 0 && pdata->regulator_pdatas) {
+		mfd_regulators = kzalloc(sizeof(struct mfd_cell)
+					 * (pdata->num_regulators), GFP_KERNEL);
+		if (!mfd_regulators) {
+			pr_err("Cannot allocate %d bytes for pm8901 regulator "
+				"mfd cells\n", sizeof(struct mfd_cell)
+						* (pdata->num_regulators));
+			rc = -ENOMEM;
+			goto bail;
+		}
+		for (i = 0; i < pdata->num_regulators; i++) {
+			mfd_regulators[i].name = "pm8901-regulator";
+			mfd_regulators[i].id = pdata->regulator_pdatas[i].id;
+			mfd_regulators[i].platform_data =
+				&(pdata->regulator_pdatas[i]);
+			mfd_regulators[i].pdata_size =
+					sizeof(struct pm8901_vreg_pdata);
+		}
+		rc = mfd_add_devices(pmic->dev, 0, mfd_regulators,
+				pdata->num_regulators, NULL, irq_base);
+		if (rc) {
+			pr_err("Failed to add regulator subdevices ret=%d\n",
+				rc);
+			kfree(mfd_regulators);
+			goto bail;
+		}
+		pmic->mfd_regulators = mfd_regulators;
+	}
+
+	rc = mfd_add_devices(pmic->dev, 0, &thermal_alarm_cell, 1, NULL,
+							irq_base);
+	if (rc) {
+		pr_err("Failed to add thermal alarm subdevice ret=%d\n",
+			rc);
+		goto bail;
+	}
+
+	rc = mfd_add_devices(pmic->dev, 0, &debugfs_cell, 1, NULL, irq_base);
+	if (rc) {
+		pr_err("Failed to add debugfs subdevice ret=%d\n", rc);
+		goto bail;
+	}
+
+	return rc;
+
+bail:
+	if (pmic->irq_chip) {
+		pm8xxx_irq_exit(pmic->irq_chip);
+		pmic->irq_chip = NULL;
+	}
+	return rc;
+}
+
 static int pm8901_probe(struct platform_device *pdev)
 {
-	int i, rc;
+	int rc;
 	struct pm8901_platform_data *pdata = pdev->dev.platform_data;
-	struct pm8901_chip *chip;
+	struct pm8901_chip *pmic;
 
-	if (pdata == NULL || pdata->irq <= 0) {
+	if (pdata == NULL) {
 		pr_err("%s: No platform_data or IRQ.\n", __func__);
 		return -ENODEV;
 	}
 
-	chip = kzalloc(sizeof *chip, GFP_KERNEL);
-	if (chip == NULL) {
+	pmic = kzalloc(sizeof *pmic, GFP_KERNEL);
+	if (pmic == NULL) {
 		pr_err("%s: kzalloc() failed.\n", __func__);
 		return -ENOMEM;
 	}
 
-	chip->dev = &pdev->dev;
+	pmic->dev = &pdev->dev;
+
+	pm8901_drvdata.pm_chip_data = pmic;
+	platform_set_drvdata(pdev, &pm8901_drvdata);
+	pmic_chip = pmic;
 
 	/* Read PMIC chip revision */
-	rc = ssbi_read(chip->dev, SSBI_REG_REV, &chip->revision, 1);
+	rc = pm8901_readb(pmic->dev, PM8901_REG_REV, &pmic->revision);
 	if (rc)
-		pr_err("%s: Failed on ssbi_read for revision: rc=%d.\n",
+		pr_err("%s: Failed reading version register rc=%d.\n",
 			__func__, rc);
-	pr_info("%s: PMIC revision: %X\n", __func__, chip->revision);
 
-	(void) memcpy((void *)&chip->pdata, (const void *)pdata,
-		      sizeof(chip->pdata));
+	pr_info("%s: PMIC REVISION = %X\n", __func__, pmic->revision);
 
-	irq_set_handler_data(pdata->irq, (void *)chip);
-	irq_set_irq_wake(pdata->irq, 1);
+	(void) memcpy((void *)&pmic->pdata, (const void *)pdata,
+		      sizeof(pmic->pdata));
 
-	chip->pm_max_irq = 0;
-	chip->pm_max_blocks = 0;
-	chip->pm_max_masters = 0;
-
-	platform_set_drvdata(pdev, chip);
-
-	pmic_chip = chip;
-	spin_lock_init(&chip->pm_lock);
-
-	/* Register for all reserved IRQs */
-	for (i = pdata->irq_base; i < (pdata->irq_base + MAX_PM_IRQ); i++) {
-		irq_set_chip(i, &pm8901_irq_chip);
-		irq_set_handler(i, handle_edge_irq);
-		set_irq_flags(i, IRQF_VALID);
-		irq_set_handler_data(i, (void *)chip);
-	}
-
-	rc = mfd_add_devices(chip->dev, 0, pdata->sub_devices,
-			     pdata->num_subdevs, NULL, 0);
+	rc = pm8901_add_subdevices(pdata, pmic);
 	if (rc) {
-		pr_err("%s: could not add devices %d\n", __func__, rc);
-		return rc;
+		pr_err("Cannot add subdevices rc=%d\n", rc);
+		goto err;
 	}
 
-	rc = request_threaded_irq(pdata->irq, NULL, pm8901_isr_thread,
-			IRQF_ONESHOT | IRQF_DISABLED | pdata->irq_trigger_flags,
-			"pm8901-irq", chip);
-	if (rc)
-		pr_err("%s: could not request irq %d: %d\n", __func__,
-				pdata->irq, rc);
+	return 0;
 
-	rc = pmic8901_dbg_probe(chip);
-	if (rc < 0)
-		pr_err("%s: could not set up debugfs: %d\n", __func__, rc);
-
+err:
+	platform_set_drvdata(pdev, NULL);
+	kfree(pmic);
 	return rc;
 }
 
 static int __devexit pm8901_remove(struct platform_device *pdev)
 {
-	struct	pm8901_chip *chip;
+	struct pm8xxx_drvdata *drvdata;
+	struct pm8901_chip *pmic = NULL;
 
-	chip = platform_get_drvdata(pdev);
-	if (chip) {
-		if (chip->pm_max_irq) {
-			irq_set_irq_wake(chip->pdata.irq, 0);
-			free_irq(chip->pdata.irq, chip);
-		}
-
-		mfd_remove_devices(chip->dev);
-
-		chip->dev = NULL;
-
-		kfree(chip);
+	drvdata = platform_get_drvdata(pdev);
+	if (drvdata)
+		pmic = drvdata->pm_chip_data;
+	if (pmic) {
+		if (pmic->dev)
+			mfd_remove_devices(pmic->dev);
+		if (pmic->irq_chip)
+			pm8xxx_irq_exit(pmic->irq_chip);
+		kfree(pmic->mfd_regulators);
+		kfree(pmic);
 	}
-
-	pmic8901_dbg_remove();
+	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
 
-#ifdef CONFIG_PM
-static int pm8901_suspend(struct platform_device *pdev, pm_message_t mesg)
-{
-	struct	pm8901_chip *chip;
-	int	i;
-	unsigned long	irqsave;
-
-	chip = platform_get_drvdata(pdev);
-
-	for (i = 0; i < MAX_PM_IRQ; i++) {
-		spin_lock_irqsave(&chip->pm_lock, irqsave);
-		if (chip->config[i] && !chip->wake_enable[i]) {
-			if (!((chip->config[i] & PM8901_IRQF_MASK_ALL)
-			      == PM8901_IRQF_MASK_ALL))
-				pm8901_irq_mask(irq_get_irq_data(i +
-							chip->pdata.irq_base));
-		}
-		spin_unlock_irqrestore(&chip->pm_lock, irqsave);
-	}
-
-	if (!chip->count_wakeable)
-		disable_irq(chip->pdata.irq);
-
-	return 0;
-}
-
-static int pm8901_resume(struct platform_device *pdev)
-{
-	struct	pm8901_chip *chip;
-	int	i;
-	unsigned long	irqsave;
-
-	chip = platform_get_drvdata(pdev);
-
-	for (i = 0; i < MAX_PM_IRQ; i++) {
-		spin_lock_irqsave(&chip->pm_lock, irqsave);
-		if (chip->config[i] && !chip->wake_enable[i]) {
-			if (!((chip->config[i] & PM8901_IRQF_MASK_ALL)
-			      == PM8901_IRQF_MASK_ALL))
-				pm8901_irq_unmask(irq_get_irq_data(i +
-							chip->pdata.irq_base));
-		}
-		spin_unlock_irqrestore(&chip->pm_lock, irqsave);
-	}
-
-	if (!chip->count_wakeable)
-		enable_irq(chip->pdata.irq);
-
-	return 0;
-}
-#else
-#define	pm8901_suspend		NULL
-#define	pm8901_resume		NULL
-#endif
-
 static struct platform_driver pm8901_driver = {
 	.probe		= pm8901_probe,
 	.remove		= __devexit_p(pm8901_remove),
@@ -914,15 +401,13 @@
 		.name	= "pm8901-core",
 		.owner	= THIS_MODULE,
 	},
-	.suspend	= pm8901_suspend,
-	.resume		= pm8901_resume,
 };
 
 static int __init pm8901_init(void)
 {
 	return  platform_driver_register(&pm8901_driver);
 }
-arch_initcall(pm8901_init);
+postcore_initcall(pm8901_init);
 
 static void __exit pm8901_exit(void)
 {
diff --git a/drivers/regulator/pmic8901-regulator.c b/drivers/regulator/pmic8901-regulator.c
index 5b4b907..6fd0a05 100644
--- a/drivers/regulator/pmic8901-regulator.c
+++ b/drivers/regulator/pmic8901-regulator.c
@@ -16,14 +16,13 @@
 #include <linux/init.h>
 #include <linux/mfd/pmic8901.h>
 #include <linux/regulator/driver.h>
+#include <linux/mfd/pm8xxx/core.h>
 #include <linux/regulator/pmic8901-regulator.h>
-#include <mach/mpp.h>
 
 /* Regulator types */
 #define REGULATOR_TYPE_LDO		0
 #define REGULATOR_TYPE_SMPS		1
 #define REGULATOR_TYPE_VS		2
-#define REGULATOR_TYPE_MPP		3
 
 /* Bank select/write macros */
 #define REGULATOR_BANK_SEL(n)           ((n) << 4)
@@ -140,9 +139,9 @@
 #define VS_PULL_DOWN_ENABLE		0x20
 
 struct pm8901_vreg {
+	struct device			*dev;
 	struct pm8901_vreg_pdata	*pdata;
 	struct regulator_dev		*rdev;
-	struct pm8901_chip		*chip;
 	int				hpm_min_load;
 	unsigned			pc_vote;
 	unsigned			optimum;
@@ -159,7 +158,6 @@
 	u8				pfm_ctrl_reg;
 	u8				pwr_cnfg_reg;
 	u8				is_nmos;
-	u8				mpp_id;
 	u8				state;
 };
 
@@ -167,8 +165,8 @@
  * These are used to compensate for the PMIC 8901 v1 FTS regulators which
  * output ~10% higher than the programmed set point.
  */
-#define IS_PMIC_8901_V1(rev)		((rev) == PM_8901_REV_1p0 || \
-					 (rev) == PM_8901_REV_1p1)
+#define IS_PMIC_8901_V1(rev)		((rev) == PM8XXX_REVISION_8901_1p0 || \
+					 (rev) == PM8XXX_REVISION_8901_1p1)
 
 #define PMIC_8901_V1_SCALE(uV)		((((uV) - 62100) * 23) / 25)
 
@@ -207,12 +205,6 @@
 		.type = REGULATOR_TYPE_VS, \
 	}
 
-#define MPP(_id, _mpp_id) \
-	[_id] = { \
-		.mpp_id = _mpp_id, \
-		.type = REGULATOR_TYPE_MPP, \
-	}
-
 static struct pm8901_vreg pm8901_vreg[] = {
 	/*  id                 ctrl   pmr    tst    n/p */
 	LDO(PM8901_VREG_ID_L0, 0x02F, 0x0AB, 0x030, 1),
@@ -230,9 +222,6 @@
 	SMPS(PM8901_VREG_ID_S3, 0x088, 0x0A9, 0x089, 0x0F6),
 	SMPS(PM8901_VREG_ID_S4, 0x097, 0x0AA, 0x098, 0x0FB),
 
-	/* id			  MPP ID */
-	MPP(PM8901_VREG_ID_MPP0,    0),
-
 	/* id                       ctrl   pmr */
 	VS(PM8901_VREG_ID_LVS0,     0x046, 0x0B2),
 	VS(PM8901_VREG_ID_LVS1,     0x048, 0x0B3),
@@ -246,7 +235,7 @@
 static void print_write_error(struct pm8901_vreg *vreg, int rc,
 				const char *func);
 
-static int pm8901_vreg_write(struct pm8901_chip *chip,
+static int pm8901_vreg_write(struct pm8901_vreg *vreg,
 		u16 addr, u8 val, u8 mask, u8 *reg_save)
 {
 	int rc = 0;
@@ -254,7 +243,7 @@
 
 	reg = (*reg_save & ~mask) | (val & mask);
 	if (reg != *reg_save)
-		rc = pm8901_write(chip, addr, &reg, 1);
+		rc = pm8xxx_writeb(vreg->dev->parent, addr, reg);
 	if (!rc)
 		*reg_save = reg;
 	return rc;
@@ -283,7 +272,6 @@
 static int pm8901_vreg_enable(struct regulator_dev *dev)
 {
 	struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8901_chip *chip = vreg->chip;
 	u8 val = VREG_PMR_STATE_HPM;
 	int rc;
 
@@ -298,7 +286,7 @@
 
 	pm8901_vreg_select_pin_ctrl(vreg, &val);
 
-	rc = pm8901_vreg_write(chip, vreg->pmr_addr,
+	rc = pm8901_vreg_write(vreg, vreg->pmr_addr,
 			val,
 			VREG_PMR_STATE_MASK | VREG_PMR_PIN_CTRL_ALL_MASK,
 			&vreg->pmr_reg);
@@ -311,10 +299,9 @@
 static int pm8901_vreg_disable(struct regulator_dev *dev)
 {
 	struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8901_chip *chip = vreg->chip;
 	int rc;
 
-	rc = pm8901_vreg_write(chip, vreg->pmr_addr,
+	rc = pm8901_vreg_write(vreg, vreg->pmr_addr,
 			VREG_PMR_STATE_OFF | VREG_PMR_PIN_CTRL_ALL_MASKED,
 			VREG_PMR_STATE_MASK | VREG_PMR_PIN_CTRL_ALL_MASK,
 			&vreg->pmr_reg);
@@ -359,11 +346,10 @@
 static int pm8901_ldo_disable(struct regulator_dev *dev)
 {
 	struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8901_chip *chip = vreg->chip;
 	int rc;
 
 	/* Disassert local enable bit in CTRL register. */
-	rc = pm8901_vreg_write(chip, vreg->ctrl_addr, 0, LDO_LOCAL_ENABLE_MASK,
+	rc = pm8901_vreg_write(vreg, vreg->ctrl_addr, 0, LDO_LOCAL_ENABLE_MASK,
 			&vreg->ctrl_reg);
 	if (rc)
 		print_write_error(vreg, rc, __func__);
@@ -374,8 +360,7 @@
 	return rc;
 }
 
-static int pm8901_pldo_set_voltage(struct pm8901_chip *chip,
-		struct pm8901_vreg *vreg, int uV)
+static int pm8901_pldo_set_voltage(struct pm8901_vreg *vreg, int uV)
 {
 	int vmin, rc = 0;
 	unsigned vprog, fine_step;
@@ -414,7 +399,7 @@
 		|| ((range_sel ^ vreg->test_reg[2]) & LDO_TEST_RANGE_SEL_MASK)
 		|| ((fine_step_reg ^ vreg->test_reg[2])
 			& LDO_TEST_FINE_STEP_MASK))) {
-		rc = pm8901_vreg_write(chip, vreg->test_addr,
+		rc = pm8901_vreg_write(vreg, vreg->test_addr,
 			REGULATOR_BANK_SEL(2) | REGULATOR_BANK_WRITE,
 			REGULATOR_BANK_MASK | LDO_TEST_VPROG_UPDATE_MASK,
 			&vreg->test_reg[2]);
@@ -423,13 +408,13 @@
 	}
 
 	/* Write new voltage. */
-	rc = pm8901_vreg_write(chip, vreg->ctrl_addr, vprog,
+	rc = pm8901_vreg_write(vreg, vreg->ctrl_addr, vprog,
 				LDO_CTRL_VPROG_MASK, &vreg->ctrl_reg);
 	if (rc)
 		goto bail;
 
 	/* Write range extension. */
-	rc = pm8901_vreg_write(chip, vreg->test_addr,
+	rc = pm8901_vreg_write(vreg, vreg->test_addr,
 			range_ext | REGULATOR_BANK_SEL(4)
 			 | REGULATOR_BANK_WRITE,
 			LDO_TEST_RANGE_EXT_MASK | REGULATOR_BANK_MASK,
@@ -438,7 +423,7 @@
 		goto bail;
 
 	/* Write fine step, range select and program voltage update. */
-	rc = pm8901_vreg_write(chip, vreg->test_addr,
+	rc = pm8901_vreg_write(vreg, vreg->test_addr,
 			fine_step_reg | range_sel | REGULATOR_BANK_SEL(2)
 			 | REGULATOR_BANK_WRITE | LDO_TEST_VPROG_UPDATE_MASK,
 			LDO_TEST_FINE_STEP_MASK | LDO_TEST_RANGE_SEL_MASK
@@ -451,8 +436,7 @@
 	return rc;
 }
 
-static int pm8901_nldo_set_voltage(struct pm8901_chip *chip,
-		struct pm8901_vreg *vreg, int uV)
+static int pm8901_nldo_set_voltage(struct pm8901_vreg *vreg, int uV)
 {
 	unsigned vprog, fine_step_reg;
 	int rc;
@@ -465,13 +449,13 @@
 	vprog >>= 1;
 
 	/* Write new voltage. */
-	rc = pm8901_vreg_write(chip, vreg->ctrl_addr, vprog,
+	rc = pm8901_vreg_write(vreg, vreg->ctrl_addr, vprog,
 				LDO_CTRL_VPROG_MASK, &vreg->ctrl_reg);
 	if (rc)
 		print_write_error(vreg, rc, __func__);
 
 	/* Write fine step. */
-	rc = pm8901_vreg_write(chip, vreg->test_addr,
+	rc = pm8901_vreg_write(vreg, vreg->test_addr,
 			fine_step_reg | REGULATOR_BANK_SEL(2)
 			 | REGULATOR_BANK_WRITE | LDO_TEST_VPROG_UPDATE_MASK,
 			LDO_TEST_FINE_STEP_MASK | REGULATOR_BANK_MASK
@@ -487,12 +471,11 @@
 		int min_uV, int max_uV, unsigned *selector)
 {
 	struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8901_chip *chip = vreg->chip;
 
 	if (vreg->is_nmos)
-		return pm8901_nldo_set_voltage(chip, vreg, min_uV);
+		return pm8901_nldo_set_voltage(vreg, min_uV);
 	else
-		return pm8901_pldo_set_voltage(chip, vreg, min_uV);
+		return pm8901_pldo_set_voltage(vreg, min_uV);
 }
 
 static int pm8901_pldo_get_voltage(struct pm8901_vreg *vreg)
@@ -560,7 +543,6 @@
 static int pm8901_vreg_set_mode(struct regulator_dev *dev, unsigned int mode)
 {
 	struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8901_chip *chip = vreg->chip;
 	unsigned optimum = vreg->optimum;
 	unsigned pc_vote = vreg->pc_vote;
 	unsigned mode_initialized = vreg->mode_initialized;
@@ -614,7 +596,7 @@
 
 	/* Only apply mode setting to hardware if currently enabled. */
 	if (pm8901_vreg_is_enabled(dev))
-		rc = pm8901_vreg_write(chip, vreg->pmr_addr, val,
+		rc = pm8901_vreg_write(vreg, vreg->pmr_addr, val,
 			       VREG_PMR_STATE_MASK | VREG_PMR_PIN_CTRL_ALL_MASK,
 			       &vreg->pmr_reg);
 
@@ -678,11 +660,10 @@
 		int min_uV, int max_uV, unsigned *selector)
 {
 	struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8901_chip *chip = vreg->chip;
 	int rc;
 	u8 val, band;
 
-	if (IS_PMIC_8901_V1(pm8901_rev(chip)))
+	if (IS_PMIC_8901_V1(pm8xxx_get_revision(vreg->dev->parent)))
 		min_uV = PMIC_8901_V1_SCALE(min_uV);
 
 	if (min_uV < SMPS_BAND_1_UV_MIN || min_uV > SMPS_BAND_3_UV_MAX)
@@ -707,13 +688,13 @@
 		band = SMPS_VCTRL_BAND_3;
 	}
 
-	rc = pm8901_vreg_write(chip, vreg->ctrl_addr, band | val,
+	rc = pm8901_vreg_write(vreg, vreg->ctrl_addr, band | val,
 			SMPS_VCTRL_BAND_MASK | SMPS_VCTRL_VPROG_MASK,
 			&vreg->ctrl_reg);
 	if (rc)
 		goto bail;
 
-	rc = pm8901_vreg_write(chip, vreg->pfm_ctrl_addr, band | val,
+	rc = pm8901_vreg_write(vreg, vreg->pfm_ctrl_addr, band | val,
 			SMPS_VCTRL_BAND_MASK | SMPS_VCTRL_VPROG_MASK,
 			&vreg->pfm_ctrl_reg);
 bail:
@@ -726,7 +707,6 @@
 static int pm8901_smps_get_voltage(struct regulator_dev *dev)
 {
 	struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8901_chip *chip = vreg->chip;
 	u8 vprog, band;
 	int ret = 0;
 
@@ -745,7 +725,7 @@
 	else
 		ret = vprog * SMPS_BAND_3_UV_STEP + SMPS_BAND_3_UV_MIN;
 
-	if (IS_PMIC_8901_V1(pm8901_rev(chip)))
+	if (IS_PMIC_8901_V1(pm8xxx_get_revision(vreg->dev->parent)))
 		ret = PMIC_8901_V1_SCALE_INV(ret);
 
 	return ret;
@@ -754,14 +734,13 @@
 static int pm8901_vs_enable(struct regulator_dev *dev)
 {
 	struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8901_chip *chip = vreg->chip;
 	int rc;
 
 	/* Assert enable bit in PMR register. */
 	rc = pm8901_vreg_enable(dev);
 
 	/* Make sure that switch is controlled via PMR register */
-	rc = pm8901_vreg_write(chip, vreg->ctrl_addr, VS_CTRL_USE_PMR,
+	rc = pm8901_vreg_write(vreg, vreg->ctrl_addr, VS_CTRL_USE_PMR,
 			VS_CTRL_ENABLE_MASK, &vreg->ctrl_reg);
 	if (rc)
 		print_write_error(vreg, rc, __func__);
@@ -772,14 +751,13 @@
 static int pm8901_vs_disable(struct regulator_dev *dev)
 {
 	struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8901_chip *chip = vreg->chip;
 	int rc;
 
 	/* Disassert enable bit in PMR register. */
 	rc = pm8901_vreg_disable(dev);
 
 	/* Make sure that switch is controlled via PMR register */
-	rc = pm8901_vreg_write(chip, vreg->ctrl_addr, VS_CTRL_USE_PMR,
+	rc = pm8901_vreg_write(vreg, vreg->ctrl_addr, VS_CTRL_USE_PMR,
 			VS_CTRL_ENABLE_MASK, &vreg->ctrl_reg);
 	if (rc)
 		print_write_error(vreg, rc, __func__);
@@ -787,52 +765,6 @@
 	return rc;
 }
 
-static int pm8901_mpp_enable(struct regulator_dev *dev)
-{
-	struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
-	int out_val;
-	int rc;
-
-	out_val = (vreg->pdata->active_high
-		   ? PM_MPP_DOUT_CTL_HIGH : PM_MPP_DOUT_CTL_LOW);
-
-	rc = pm8901_mpp_config(vreg->mpp_id, PM_MPP_TYPE_D_OUTPUT,
-			PM8901_MPP_DIG_LEVEL_VPH, out_val);
-
-	if (rc)
-		pr_err("%s: pm8901_mpp_config failed, rc=%d\n", __func__, rc);
-	else
-		vreg->state = 1;
-
-	return rc;
-}
-
-static int pm8901_mpp_disable(struct regulator_dev *dev)
-{
-	struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
-	int out_val;
-	int rc;
-
-	out_val = (vreg->pdata->active_high
-		   ? PM_MPP_DOUT_CTL_LOW : PM_MPP_DOUT_CTL_HIGH);
-
-	rc = pm8901_mpp_config(vreg->mpp_id, PM_MPP_TYPE_D_OUTPUT,
-			PM8901_MPP_DIG_LEVEL_VPH, out_val);
-
-	if (rc)
-		pr_err("%s: pm8901_mpp_config failed, rc=%d\n", __func__, rc);
-	else
-		vreg->state = 0;
-
-	return rc;
-}
-
-static int pm8901_mpp_is_enabled(struct regulator_dev *dev)
-{
-	struct pm8901_vreg *vreg = rdev_get_drvdata(dev);
-	return vreg->state;
-}
-
 static struct regulator_ops pm8901_ldo_ops = {
 	.enable = pm8901_vreg_enable,
 	.disable = pm8901_ldo_disable,
@@ -863,12 +795,6 @@
 	.get_mode = pm8901_vreg_get_mode,
 };
 
-static struct regulator_ops pm8901_mpp_ops = {
-	.enable = pm8901_mpp_enable,
-	.disable = pm8901_mpp_disable,
-	.is_enabled = pm8901_mpp_is_enabled,
-};
-
 #define VREG_DESCRIP(_id, _name, _ops) \
 	[_id] = { \
 		.name = _name, \
@@ -893,8 +819,6 @@
 	VREG_DESCRIP(PM8901_VREG_ID_S3, "8901_s3", &pm8901_smps_ops),
 	VREG_DESCRIP(PM8901_VREG_ID_S4, "8901_s4", &pm8901_smps_ops),
 
-	VREG_DESCRIP(PM8901_VREG_ID_MPP0,     "8901_mpp0",     &pm8901_mpp_ops),
-
 	VREG_DESCRIP(PM8901_VREG_ID_LVS0,     "8901_lvs0",     &pm8901_vs_ops),
 	VREG_DESCRIP(PM8901_VREG_ID_LVS1,     "8901_lvs1",     &pm8901_vs_ops),
 	VREG_DESCRIP(PM8901_VREG_ID_LVS2,     "8901_lvs2",     &pm8901_vs_ops),
@@ -904,7 +828,7 @@
 	VREG_DESCRIP(PM8901_VREG_ID_HDMI_MVS, "8901_hdmi_mvs", &pm8901_vs_ops),
 };
 
-static int pm8901_init_ldo(struct pm8901_chip *chip, struct pm8901_vreg *vreg)
+static int pm8901_init_ldo(struct pm8901_vreg *vreg)
 {
 	int rc = 0, i;
 	u8 bank;
@@ -912,11 +836,12 @@
 	/* Store current regulator register values. */
 	for (i = 0; i < LDO_TEST_BANKS; i++) {
 		bank = REGULATOR_BANK_SEL(i);
-		rc = pm8901_write(chip, vreg->test_addr, &bank, 1);
+		rc = pm8xxx_writeb(vreg->dev->parent, vreg->test_addr, bank);
 		if (rc)
 			goto bail;
 
-		rc = pm8901_read(chip, vreg->test_addr, &vreg->test_reg[i], 1);
+		rc = pm8xxx_readb(vreg->dev->parent, vreg->test_addr,
+							&vreg->test_reg[i]);
 		if (rc)
 			goto bail;
 
@@ -924,30 +849,30 @@
 	}
 
 	/* Set pull down enable based on platform data. */
-	rc = pm8901_vreg_write(chip, vreg->ctrl_addr,
+	rc = pm8901_vreg_write(vreg, vreg->ctrl_addr,
 		     (vreg->pdata->pull_down_enable ? LDO_PULL_DOWN_ENABLE : 0),
 		     LDO_PULL_DOWN_ENABLE_MASK, &vreg->ctrl_reg);
 bail:
 	return rc;
 }
 
-static int pm8901_init_smps(struct pm8901_chip *chip, struct pm8901_vreg *vreg)
+static int pm8901_init_smps(struct pm8901_vreg *vreg)
 {
 	int rc;
 
 	/* Store current regulator register values. */
-	rc = pm8901_read(chip, vreg->pfm_ctrl_addr,
-			 &vreg->pfm_ctrl_reg, 1);
+	rc = pm8xxx_readb(vreg->dev->parent, vreg->pfm_ctrl_addr,
+					 &vreg->pfm_ctrl_reg);
 	if (rc)
 		goto bail;
 
-	rc = pm8901_read(chip, vreg->pwr_cnfg_addr,
-			 &vreg->pwr_cnfg_reg, 1);
+	rc = pm8xxx_readb(vreg->dev->parent, vreg->pwr_cnfg_addr,
+				 &vreg->pwr_cnfg_reg);
 	if (rc)
 		goto bail;
 
 	/* Set pull down enable based on platform data. */
-	rc = pm8901_vreg_write(chip, vreg->pwr_cnfg_addr,
+	rc = pm8901_vreg_write(vreg, vreg->pwr_cnfg_addr,
 		    (vreg->pdata->pull_down_enable ? SMPS_PULL_DOWN_ENABLE : 0),
 		    SMPS_PULL_DOWN_ENABLE_MASK, &vreg->pwr_cnfg_reg);
 
@@ -955,33 +880,30 @@
 	return rc;
 }
 
-static int pm8901_init_vs(struct pm8901_chip *chip, struct pm8901_vreg *vreg)
+static int pm8901_init_vs(struct pm8901_vreg *vreg)
 {
 	int rc = 0;
 
 	/* Set pull down enable based on platform data. */
-	rc = pm8901_vreg_write(chip, vreg->ctrl_addr,
+	rc = pm8901_vreg_write(vreg, vreg->ctrl_addr,
 		      (vreg->pdata->pull_down_enable ? VS_PULL_DOWN_ENABLE : 0),
 		      VS_PULL_DOWN_ENABLE_MASK, &vreg->ctrl_reg);
 
 	return rc;
 }
 
-static int pm8901_init_regulator(struct pm8901_chip *chip,
-		struct pm8901_vreg *vreg)
+static int pm8901_init_regulator(struct pm8901_vreg *vreg)
 {
 	int rc;
 
 	/* Store current regulator register values. */
-	if (vreg->type != REGULATOR_TYPE_MPP) {
-		rc = pm8901_read(chip, vreg->ctrl_addr, &vreg->ctrl_reg, 1);
-		if (rc)
-			goto bail;
+	rc = pm8xxx_readb(vreg->dev->parent, vreg->ctrl_addr, &vreg->ctrl_reg);
+	if (rc)
+		goto bail;
 
-		rc = pm8901_read(chip, vreg->pmr_addr, &vreg->pmr_reg, 1);
-		if (rc)
-			goto bail;
-	}
+	rc = pm8xxx_readb(vreg->dev->parent, vreg->pmr_addr, &vreg->pmr_reg);
+	if (rc)
+		goto bail;
 
 	/* Set initial mode based on hardware state. */
 	if ((vreg->pmr_reg & VREG_PMR_STATE_MASK) == VREG_PMR_STATE_LPM)
@@ -992,11 +914,11 @@
 	vreg->mode_initialized = 0;
 
 	if (vreg->type == REGULATOR_TYPE_LDO)
-		rc = pm8901_init_ldo(chip, vreg);
+		rc = pm8901_init_ldo(vreg);
 	else if (vreg->type == REGULATOR_TYPE_SMPS)
-		rc = pm8901_init_smps(chip, vreg);
+		rc = pm8901_init_smps(vreg);
 	else if (vreg->type == REGULATOR_TYPE_VS)
-		rc = pm8901_init_vs(chip, vreg);
+		rc = pm8901_init_vs(vreg);
 bail:
 	if (rc)
 		pr_err("%s: pm8901_read/write failed; initial register states "
@@ -1008,7 +930,6 @@
 static int __devinit pm8901_vreg_probe(struct platform_device *pdev)
 {
 	struct regulator_desc *rdesc;
-	struct pm8901_chip *chip;
 	struct pm8901_vreg *vreg;
 	const char *reg_name = NULL;
 	int rc = 0;
@@ -1017,14 +938,13 @@
 		return -EINVAL;
 
 	if (pdev->id >= 0 && pdev->id < PM8901_VREG_MAX) {
-		chip = dev_get_drvdata(pdev->dev.parent);
 		rdesc = &pm8901_vreg_descrip[pdev->id];
 		vreg = &pm8901_vreg[pdev->id];
 		vreg->pdata = pdev->dev.platform_data;
-		vreg->chip = chip;
 		reg_name = pm8901_vreg_descrip[pdev->id].name;
+		vreg->dev = &pdev->dev;
 
-		rc = pm8901_init_regulator(chip, vreg);
+		rc = pm8901_init_regulator(vreg);
 		if (rc)
 			goto bail;
 
diff --git a/include/linux/mfd/pmic8901.h b/include/linux/mfd/pmic8901.h
index 5d23edc..932f8da 100644
--- a/include/linux/mfd/pmic8901.h
+++ b/include/linux/mfd/pmic8901.h
@@ -19,51 +19,33 @@
 
 #include <linux/irq.h>
 #include <linux/mfd/core.h>
-
-/* PM8901 interrupt numbers */
-
-#define PM8901_MPPS		4
+#include <linux/mfd/pm8xxx/irq.h>
+#include <linux/mfd/pm8xxx/mpp.h>
+#include <linux/mfd/pm8xxx/tm.h>
+#include <linux/regulator/pmic8901-regulator.h>
 
 #define PM8901_IRQ_BLOCK_BIT(block, bit) ((block) * 8 + (bit))
 
-/* MPPs [0,N) */
-#define PM8901_MPP_IRQ(base, mpp)	((base) + \
-					PM8901_IRQ_BLOCK_BIT(6, (mpp)))
+#define PM8901_NR_IRQS			72
 
-#define PM8901_TEMP_ALARM_IRQ(base)	((base) + PM8901_IRQ_BLOCK_BIT(6, 4))
-#define PM8901_TEMP_HI_ALARM_IRQ(base)	((base) + PM8901_IRQ_BLOCK_BIT(6, 5))
+/* PM8901 MPP */
+#define PM8901_MPP_BLOCK_START		6
+#define PM8901_MPPS			4
+
+/* PM8901 IRQs */
+#define PM8901_MPP_IRQ(mpp)		PM8901_IRQ_BLOCK_BIT(6, (mpp))
+#define PM8901_TEMPSTAT_IRQ		PM8901_IRQ_BLOCK_BIT(6, 4)
+#define PM8901_OVERTEMP_IRQ		PM8901_IRQ_BLOCK_BIT(6, 5)
 
 struct pm8901_chip;
 
 struct pm8901_platform_data {
-	/* This table is only needed for misc interrupts. */
-	int		irq_base;
-	int		irq;
-
-	int		num_subdevs;
-	struct mfd_cell *sub_devices;
-	int		irq_trigger_flags;
+	struct pm8xxx_irq_platform_data *irq_pdata;
+	struct pm8xxx_mpp_platform_data *mpp_pdata;
+	struct pm8901_vreg_pdata	*regulator_pdatas;
+	int				num_regulators;
 };
 
-struct pm8901_gpio_platform_data {
-	int	gpio_base;
-	int	irq_base;
-};
-
-/* chip revision */
-#define PM_8901_REV_1p0			0xF1
-#define PM_8901_REV_1p1			0xF2
-#define PM_8901_REV_2p0			0xF3
-
-int pm8901_read(struct pm8901_chip *pm_chip, u16 addr, u8 *values,
-		unsigned int len);
-int pm8901_write(struct pm8901_chip *pm_chip, u16 addr, u8 *values,
-		 unsigned int len);
-
-int pm8901_rev(struct pm8901_chip *pm_chip);
-
-int pm8901_irq_get_rt_status(struct pm8901_chip *pm_chip, int irq);
-
 #ifdef CONFIG_PMIC8901
 int pm8901_reset_pwr_off(int reset);
 #else
diff --git a/include/linux/regulator/pmic8901-regulator.h b/include/linux/regulator/pmic8901-regulator.h
index 953c4ad..ec842bc 100644
--- a/include/linux/regulator/pmic8901-regulator.h
+++ b/include/linux/regulator/pmic8901-regulator.h
@@ -32,23 +32,20 @@
 #define PM8901_VREG_ID_S3	10
 #define PM8901_VREG_ID_S4	11
 
-/* External regulator controlled by MPP pin ids */
-#define PM8901_VREG_ID_MPP0	12
-
 /* Low voltage switch regulator ids */
-#define PM8901_VREG_ID_LVS0	13
-#define PM8901_VREG_ID_LVS1	14
-#define PM8901_VREG_ID_LVS2	15
-#define PM8901_VREG_ID_LVS3	16
+#define PM8901_VREG_ID_LVS0	12
+#define PM8901_VREG_ID_LVS1	13
+#define PM8901_VREG_ID_LVS2	14
+#define PM8901_VREG_ID_LVS3	15
 
 /* Medium voltage switch regulator ids */
-#define PM8901_VREG_ID_MVS0	17
+#define PM8901_VREG_ID_MVS0	16
 
 /* USB OTG voltage switch regulator ids */
-#define PM8901_VREG_ID_USB_OTG	18
+#define PM8901_VREG_ID_USB_OTG	17
 
 /* HDMI medium voltage switch regulator ids */
-#define PM8901_VREG_ID_HDMI_MVS	19
+#define PM8901_VREG_ID_HDMI_MVS	18
 
 #define PM8901_VREG_MAX		(PM8901_VREG_ID_HDMI_MVS + 1)
 
@@ -70,10 +67,10 @@
 
 struct pm8901_vreg_pdata {
 	struct regulator_init_data	init_data;
+	int				id;
 	unsigned			pull_down_enable;
 	unsigned			pin_ctrl;
 	enum pm8901_vreg_pin_fn		pin_fn;
-	unsigned			active_high; /* For use with MPP. */
 };
 
 #endif