mfd: pm8058: Modify pm8058 subdevices to pm8xxx interface

Move the following  subdevices to use the pm8xxx interface -
mpp, irq, gpio, keypad, power-key, leds, othc, vibrator,
rtc, batt-alarm, thermal, upl, nfc, pwm, xoadc, regulators,
xo-buffers, charger.

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: Id9795552fc9f4a2c920c070babfaef1f4cd6ca61
Signed-off-by: Anirudh Ghayal <aghayal@codeaurora.org>
diff --git a/arch/arm/configs/fsm9xxx-perf_defconfig b/arch/arm/configs/fsm9xxx-perf_defconfig
index b6bc4f1..5717577 100644
--- a/arch/arm/configs/fsm9xxx-perf_defconfig
+++ b/arch/arm/configs/fsm9xxx-perf_defconfig
@@ -134,6 +134,8 @@
 CONFIG_POWER_SUPPLY=y
 CONFIG_SENSORS_MSM_ADC=y
 CONFIG_PMIC8058=y
+# CONFIG_MFD_PM8XXX_PWM is not set
+# CONFIG_MFD_PM8XXX_MISC is not set
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_PM8058_XO=y
 # CONFIG_USB_SUPPORT is not set
diff --git a/arch/arm/configs/fsm9xxx_defconfig b/arch/arm/configs/fsm9xxx_defconfig
index dd9797a..ebff2d2 100644
--- a/arch/arm/configs/fsm9xxx_defconfig
+++ b/arch/arm/configs/fsm9xxx_defconfig
@@ -132,6 +132,8 @@
 CONFIG_POWER_SUPPLY=y
 CONFIG_SENSORS_MSM_ADC=y
 CONFIG_PMIC8058=y
+# CONFIG_MFD_PM8XXX_PWM is not set
+# CONFIG_MFD_PM8XXX_MISC is not set
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_PM8058_XO=y
 # CONFIG_USB_SUPPORT is not set
diff --git a/arch/arm/configs/msm7630-perf_defconfig b/arch/arm/configs/msm7630-perf_defconfig
index 56710d7..042d751 100644
--- a/arch/arm/configs/msm7630-perf_defconfig
+++ b/arch/arm/configs/msm7630-perf_defconfig
@@ -187,7 +187,7 @@
 CONFIG_BLK_DEV_RAM_SIZE=16384
 CONFIG_MISC_DEVICES=y
 CONFIG_HAPTIC_ISA1200=y
-CONFIG_PMIC8058_UPL=y
+CONFIG_PMIC8XXX_UPL=y
 CONFIG_SCSI=y
 CONFIG_SCSI_TGT=y
 CONFIG_BLK_DEV_SD=y
@@ -216,6 +216,8 @@
 CONFIG_INPUT_EVDEV=y
 CONFIG_INPUT_EVBUG=m
 # CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_PMIC8XXX=y
+# CONFIG_KEYBOARD_PMIC8058 is not set
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_MSM=y
@@ -249,6 +251,9 @@
 CONFIG_MARIMBA_CORE=y
 CONFIG_MARIMBA_CODEC=y
 CONFIG_TIMPANI_CODEC=y
+# CONFIG_MFD_PM8XXX_DEBUG is not set
+# CONFIG_MFD_PM8XXX_PWM is not set
+# CONFIG_MFD_PM8XXX_MISC is not set
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_VIDEO_DEV=y
 # CONFIG_MEDIA_TUNER_CUSTOMISE is not set
diff --git a/arch/arm/configs/msm7630_defconfig b/arch/arm/configs/msm7630_defconfig
index 115ce98..362babe 100644
--- a/arch/arm/configs/msm7630_defconfig
+++ b/arch/arm/configs/msm7630_defconfig
@@ -186,7 +186,7 @@
 CONFIG_BLK_DEV_RAM_SIZE=16384
 CONFIG_MISC_DEVICES=y
 CONFIG_HAPTIC_ISA1200=y
-CONFIG_PMIC8058_UPL=y
+CONFIG_PMIC8XXX_UPL=y
 CONFIG_SCSI=y
 CONFIG_SCSI_TGT=y
 CONFIG_BLK_DEV_SD=y
@@ -215,6 +215,8 @@
 CONFIG_INPUT_EVDEV=y
 CONFIG_INPUT_EVBUG=m
 # CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_PMIC8XXX=y
+# CONFIG_KEYBOARD_PMIC8058 is not set
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_MSM=y
@@ -248,6 +250,9 @@
 CONFIG_MARIMBA_CORE=y
 CONFIG_MARIMBA_CODEC=y
 CONFIG_TIMPANI_CODEC=y
+# CONFIG_MFD_PM8XXX_DEBUG is not set
+# CONFIG_MFD_PM8XXX_PWM is not set
+# CONFIG_MFD_PM8XXX_MISC is not set
 CONFIG_MSM_KGSL=y
 CONFIG_VIDEO_OUTPUT_CONTROL=y
 CONFIG_FB=y
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index de58931..dcdf9e5 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -222,10 +222,9 @@
 CONFIG_TSIF=m
 CONFIG_TSIF_CHRDEV=m
 CONFIG_HAPTIC_ISA1200=y
-CONFIG_PMIC8058_VIBRATOR=y
-CONFIG_PMIC8058_UPL=y
+CONFIG_PMIC8XXX_VIBRATOR=y
+CONFIG_PMIC8XXX_UPL=y
 CONFIG_PMIC8058_XOADC=y
-CONFIG_PMIC8058_MISC=y
 CONFIG_TZCOM=y
 CONFIG_SCSI=y
 CONFIG_SCSI_TGT=y
@@ -262,6 +261,8 @@
 CONFIG_INPUT_KEYRESET=y
 CONFIG_KEYBOARD_GPIO=y
 CONFIG_KEYBOARD_MATRIX=y
+CONFIG_KEYBOARD_PMIC8XXX=y
+# CONFIG_KEYBOARD_PMIC8058 is not set
 CONFIG_INPUT_JOYSTICK=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
@@ -269,7 +270,7 @@
 CONFIG_TOUCHSCREEN_CYTTSP_I2C=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
-CONFIG_PMIC8058_PWRKEY=y
+CONFIG_INPUT_PMIC8XXX_PWRKEY=y
 CONFIG_PMIC8058_OTHC=y
 CONFIG_SERIAL_MSM_HS=y
 CONFIG_SERIAL_MSM_HSL=y
@@ -300,11 +301,13 @@
 CONFIG_THERMAL=y
 CONFIG_THERMAL_HWMON=y
 CONFIG_THERMAL_PM8901=y
-CONFIG_THERMAL_PM8058=y
 CONFIG_THERMAL_TSENS=y
+CONFIG_THERMAL_PM8XXX=y
 CONFIG_PMIC8058=y
 CONFIG_MARIMBA_CORE=y
 CONFIG_TIMPANI_CODEC=y
+# CONFIG_MFD_PM8XXX_PWM is not set
+CONFIG_MFD_PM8XXX_BATT_ALARM=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_VIDEO_DEV=y
 # CONFIG_MEDIA_TUNER_CUSTOMISE is not set
@@ -387,7 +390,7 @@
 CONFIG_SWITCH_GPIO=y
 CONFIG_RTC_CLASS=y
 # CONFIG_RTC_DRV_MSM is not set
-CONFIG_RTC_PM8058=y
+CONFIG_RTC_DRV_PM8XXX=y
 CONFIG_STAGING=y
 CONFIG_ANDROID=y
 CONFIG_ANDROID_BINDER_IPC=y
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index 6d99df7..8f049a5 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -214,10 +214,9 @@
 CONFIG_TSIF=m
 CONFIG_TSIF_CHRDEV=m
 CONFIG_HAPTIC_ISA1200=y
-CONFIG_PMIC8058_VIBRATOR=y
-CONFIG_PMIC8058_UPL=y
+CONFIG_PMIC8XXX_VIBRATOR=y
+CONFIG_PMIC8XXX_UPL=y
 CONFIG_PMIC8058_XOADC=y
-CONFIG_PMIC8058_MISC=y
 CONFIG_TZCOM=y
 CONFIG_SCSI=y
 CONFIG_SCSI_TGT=y
@@ -254,6 +253,8 @@
 CONFIG_INPUT_KEYRESET=y
 CONFIG_KEYBOARD_GPIO=y
 CONFIG_KEYBOARD_MATRIX=y
+CONFIG_KEYBOARD_PMIC8XXX=y
+# CONFIG_KEYBOARD_PMIC8058 is not set
 CONFIG_INPUT_JOYSTICK=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
@@ -261,7 +262,7 @@
 CONFIG_TOUCHSCREEN_CYTTSP_I2C=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
-CONFIG_PMIC8058_PWRKEY=y
+CONFIG_INPUT_PMIC8XXX_PWRKEY=y
 CONFIG_PMIC8058_OTHC=y
 CONFIG_SERIAL_MSM_HS=y
 CONFIG_SERIAL_MSM_HSL=y
@@ -291,11 +292,13 @@
 CONFIG_SENSORS_MSM_ADC=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_PM8901=y
-CONFIG_THERMAL_PM8058=y
 CONFIG_THERMAL_TSENS=y
+CONFIG_THERMAL_PM8XXX=y
 CONFIG_PMIC8058=y
 CONFIG_MARIMBA_CORE=y
 CONFIG_TIMPANI_CODEC=y
+# CONFIG_MFD_PM8XXX_PWM is not set
+CONFIG_MFD_PM8XXX_BATT_ALARM=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_VIDEO_DEV=y
 # CONFIG_MEDIA_TUNER_CUSTOMISE is not set
@@ -374,7 +377,7 @@
 CONFIG_SWITCH_GPIO=y
 CONFIG_RTC_CLASS=y
 # CONFIG_RTC_DRV_MSM is not set
-CONFIG_RTC_PM8058=y
+CONFIG_RTC_DRV_PM8XXX=y
 CONFIG_STAGING=y
 CONFIG_ANDROID=y
 CONFIG_ANDROID_BINDER_IPC=y
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 60259ca..604989d 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -253,7 +253,6 @@
 obj-$(CONFIG_HTC_HEADSET) += htc_headset.o
 obj-$(CONFIG_MSM_RMT_STORAGE_CLIENT) += rmt_storage_client.o
 obj-$(CONFIG_MSM_SDIO_SMEM) += sdio_smem.o
-obj-$(CONFIG_PMIC8058) += pmic8058-gpio.o pmic8058-mpp.o
 obj-$(CONFIG_MSM_RPM) += rpm.o rpm_resources.o
 obj-$(CONFIG_MSM_MPM) += mpm.o
 obj-$(CONFIG_MSM_RPM_STATS_LOG) += rpm_stats.o
diff --git a/arch/arm/mach-msm/board-fsm9xxx.c b/arch/arm/mach-msm/board-fsm9xxx.c
index eb936e4..333d366 100644
--- a/arch/arm/mach-msm/board-fsm9xxx.c
+++ b/arch/arm/mach-msm/board-fsm9xxx.c
@@ -28,15 +28,12 @@
 #include <asm/mach/arch.h>
 #include <asm/setup.h>
 
-#include <mach/mpp.h>
 #include <mach/board.h>
 #include <mach/memory.h>
 #include <mach/msm_iomap.h>
 #include <mach/dma.h>
 #include <mach/sirc.h>
-#include <mach/pmic.h>
 
-#include <mach/vreg.h>
 #include <mach/socinfo.h>
 #include "devices.h"
 #include "timer.h"
@@ -46,7 +43,6 @@
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/machine.h>
 #include <linux/msm_adc.h>
-#include <linux/pmic8058-xoadc.h>
 #include <linux/m_adcproc.h>
 #include <linux/platform_data/qcom_crypto_device.h>
 
@@ -89,8 +85,11 @@
 #define FPGA_SDCC_STATUS        0x8E0001A8
 
 /* Macros assume PMIC GPIOs start at 0 */
-#define PM8058_GPIO_PM_TO_SYS(pm_gpio)	   (pm_gpio + NR_MSM_GPIOS)
-#define PM8058_GPIO_SYS_TO_PM(sys_gpio)    (sys_gpio - NR_MSM_GPIOS)
+#define PM8058_GPIO_PM_TO_SYS(pm_gpio)  (pm_gpio + NR_MSM_GPIOS)
+#define PM8058_GPIO_SYS_TO_PM(sys_gpio) (sys_gpio - NR_MSM_GPIOS)
+#define PM8058_MPP_BASE			(NR_MSM_GPIOS + 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 PMIC_GPIO_5V_PA_PWR	21	/* PMIC GPIO Number 22 */
 #define PMIC_GPIO_4_2V_PA_PWR	22	/* PMIC GPIO Number 23 */
@@ -102,19 +101,33 @@
 /*
  * PM8058
  */
+struct pm8xxx_mpp_init_info {
+	unsigned			mpp;
+	struct pm8xxx_mpp_config_data	config;
+};
+
+#define PM8XXX_MPP_INIT(_mpp, _type, _level, _control) \
+{ \
+	.mpp	= PM8058_MPP_PM_TO_SYS(_mpp), \
+	.config	= { \
+		.type		= PM8XXX_MPP_TYPE_##_type, \
+		.level		= _level, \
+		.control	= PM8XXX_MPP_##_control, \
+	} \
+}
 
 static int pm8058_gpios_init(void)
 {
 	int i;
 	int rc;
 	struct pm8058_gpio_cfg {
-		int gpio;
-		struct pm8058_gpio cfg;
+		int                gpio;
+		struct pm_gpio	   cfg;
 	};
 
 	struct pm8058_gpio_cfg gpio_cfgs[] = {
 		{				/* 5V PA Power */
-			PMIC_GPIO_5V_PA_PWR,
+			PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_5V_PA_PWR),
 			{
 				.vin_sel = 0,
 				.direction = PM_GPIO_DIR_BOTH,
@@ -127,7 +140,7 @@
 			},
 		},
 		{				/* 4.2V PA Power */
-			PMIC_GPIO_4_2V_PA_PWR,
+			PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_4_2V_PA_PWR),
 			{
 				.vin_sel = 0,
 				.direction = PM_GPIO_DIR_BOTH,
@@ -142,7 +155,7 @@
 	};
 
 	for (i = 0; i < ARRAY_SIZE(gpio_cfgs); ++i) {
-		rc = pm8058_gpio_config(gpio_cfgs[i].gpio, &gpio_cfgs[i].cfg);
+		rc = pm8xxx_gpio_config(gpio_cfgs[i].gpio, &gpio_cfgs[i].cfg);
 		if (rc < 0) {
 			pr_err("%s pmic gpio config failed\n", __func__);
 			return rc;
@@ -154,37 +167,28 @@
 
 static int pm8058_mpps_init(void)
 {
-	int rc;
+	int rc, i;
 
-	/* Set up MPP 3 and 6 as analog outputs at 1.25V */
-	rc = pm8058_mpp_config_analog_output(PMIC_MPP_3,
-			PM_MPP_AOUT_LVL_1V25_2, PM_MPP_AOUT_CTL_ENABLE);
-	if (rc) {
-		pr_err("%s: Config mpp3 on pmic 8058 failed\n", __func__);
-		return rc;
+	struct pm8xxx_mpp_init_info pm8058_mpps[] = {
+		PM8XXX_MPP_INIT(PMIC_MPP_3, A_OUTPUT,
+			PM8XXX_MPP_AOUT_LVL_1V25_2, AOUT_CTRL_ENABLE),
+		PM8XXX_MPP_INIT(PMIC_MPP_6, A_OUTPUT,
+			PM8XXX_MPP_AOUT_LVL_1V25_2, AOUT_CTRL_ENABLE),
+	};
+
+	for (i = 0; i < ARRAY_SIZE(pm8058_mpps); i++) {
+		rc = pm8xxx_mpp_config(pm8058_mpps[i].mpp,
+					&pm8058_mpps[i].config);
+		if (rc) {
+			pr_err("%s: Config %d mpp pm 8058 failed\n",
+						__func__, pm8058_mpps[i].mpp);
+			return rc;
+		}
 	}
 
-	rc = pm8058_mpp_config_analog_output(PMIC_MPP_6,
-			PM_MPP_AOUT_LVL_1V25_2, PM_MPP_AOUT_CTL_ENABLE);
-	if (rc) {
-		pr_err("%s: Config mpp5 on pmic 8058 failed\n", __func__);
-		return rc;
-	}
 	return 0;
 }
 
-static struct pm8058_gpio_platform_data pm8058_gpio_data = {
-	.gpio_base = PM8058_GPIO_PM_TO_SYS(0),
-	.irq_base = PM8058_GPIO_IRQ(PMIC8058_IRQ_BASE, 0),
-	.init = pm8058_gpios_init,
-};
-
-static struct pm8058_gpio_platform_data pm8058_mpp_data = {
-	.gpio_base = PM8058_GPIO_PM_TO_SYS(PM8058_GPIOS),
-	.irq_base = PM8058_MPP_IRQ(PMIC8058_IRQ_BASE, 0),
-	.init = pm8058_mpps_init,
-};
-
 static struct regulator_consumer_supply pm8058_vreg_supply[PM8058_VREG_MAX] = {
 	[PM8058_VREG_ID_L3] = REGULATOR_SUPPLY("8058_l3", NULL),
 	[PM8058_VREG_ID_L8] = REGULATOR_SUPPLY("8058_l8", NULL),
@@ -199,7 +203,7 @@
 
 #define PM8058_VREG_INIT(_id, _min_uV, _max_uV, _modes, _ops, _apply_uV, \
 			_always_on, _pull_down) \
-	[_id] = { \
+	{ \
 		.init_data = { \
 			.constraints = { \
 				.valid_modes_mask = _modes, \
@@ -212,6 +216,7 @@
 			.num_consumer_supplies = 1, \
 			.consumer_supplies = &pm8058_vreg_supply[_id], \
 		}, \
+		.id = _id, \
 		.pull_down_enable = _pull_down, \
 		.pin_ctrl = 0, \
 		.pin_fn = PM8058_VREG_PIN_FN_ENABLE, \
@@ -233,7 +238,7 @@
 	PM8058_VREG_INIT(_id, _min_uV, _min_uV, REGULATOR_MODE_NORMAL, \
 			REGULATOR_CHANGE_STATUS, 0, 0, 1)
 
-static struct pm8058_vreg_pdata pm8058_vreg_init[PM8058_VREG_MAX] = {
+static struct pm8058_vreg_pdata pm8058_vreg_init[] = {
 	PM8058_VREG_INIT_LDO(PM8058_VREG_ID_L3, 1800000, 1800000),
 	PM8058_VREG_INIT_LDO(PM8058_VREG_ID_L8, 2200000, 2200000),
 	PM8058_VREG_INIT_LDO(PM8058_VREG_ID_L9, 2050000, 2050000),
@@ -244,22 +249,7 @@
 	PM8058_VREG_INIT_SMPS(PM8058_VREG_ID_S4, 1300000, 1300000),
 };
 
-#define PM8058_VREG(_id) { \
-	.name = "pm8058-regulator", \
-	.id = _id, \
-	.platform_data = &pm8058_vreg_init[_id], \
-	.pdata_size    = sizeof(pm8058_vreg_init[_id]), \
-}
-
 #ifdef CONFIG_SENSORS_MSM_ADC
-static struct resource resources_adc[] = {
-	{
-		.start = PM8058_ADC_IRQ(PMIC8058_IRQ_BASE),
-		.end   = PM8058_ADC_IRQ(PMIC8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
 static struct adc_access_fn xoadc_fn = {
 	pm8058_xoadc_select_chan_and_start_conv,
 	pm8058_xoadc_read_adc_code,
@@ -298,17 +288,21 @@
 
 static void pmic8058_xoadc_mpp_config(void)
 {
-	int rc;
-
-	rc = pm8058_mpp_config_analog_input(XOADC_MPP_7,
-			PM_MPP_AIN_AMUX_CH5, PM_MPP_AOUT_CTL_DISABLE);
-	if (rc)
-		pr_err("%s: Config mpp7 on pmic 8058 failed\n", __func__);
-
-	rc = pm8058_mpp_config_analog_input(XOADC_MPP_10,
-			PM_MPP_AIN_AMUX_CH6, PM_MPP_AOUT_CTL_DISABLE);
-	if (rc)
-		pr_err("%s: Config mpp10 on pmic 8058 failed\n", __func__);
+	int rc, i;
+	struct pm8xxx_mpp_init_info xoadc_mpps[] = {
+		PM8XXX_MPP_INIT(PMIC_MPP_7, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH5,
+							AOUT_CTRL_DISABLE),
+		PM8XXX_MPP_INIT(PMIC_MPP_10, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH6,
+							AOUT_CTRL_DISABLE),
+	};
+	for (i = 0; i < ARRAY_SIZE(xoadc_mpps); i++) {
+		rc = pm8xxx_mpp_config(xoadc_mpps[i].mpp,
+					&xoadc_mpps[i].config);
+		if (rc) {
+			pr_err("%s: Config MPP %d of PM8058 failed\n",
+					__func__, xoadc_mpps[i].mpp);
+		}
+	}
 }
 
 static struct regulator *vreg_ldo18_adc;
@@ -373,7 +367,7 @@
 	.conversiontime         = 54,
 };
 
-static struct xoadc_platform_data xoadc_pdata = {
+static struct xoadc_platform_data pm8058_xoadc_pdata = {
 	.xoadc_prop = &pm8058_xoadc_data,
 	.xoadc_mpp_config = pmic8058_xoadc_mpp_config,
 	.xoadc_vreg_set = pmic8058_xoadc_vreg_config,
@@ -400,7 +394,7 @@
 };
 
 #define PM8058_XO_INIT(_id, _modes, _ops, _always_on) \
-	[PM8058_XO_ID_##_id] = { \
+	{ \
 		.init_data = { \
 			.constraints = { \
 				.valid_modes_mask = _modes, \
@@ -412,63 +406,44 @@
 				ARRAY_SIZE(xo_consumers_##_id),\
 			.consumer_supplies = xo_consumers_##_id, \
 		}, \
+		.id = PM8058_XO_ID_##_id, \
 	}
 
 #define PM8058_XO_INIT_AX(_id) \
 	PM8058_XO_INIT(_id, REGULATOR_MODE_NORMAL, REGULATOR_CHANGE_STATUS, 0)
 
-static struct pm8058_xo_pdata pm8058_xo_init_pdata[PM8058_XO_ID_MAX] = {
+static struct pm8058_xo_pdata pm8058_xo_init_pdata[] = {
 	PM8058_XO_INIT_AX(A0),
 	PM8058_XO_INIT_AX(A1),
 };
 
-#define PM8058_XO(_id) { \
-	.name = PM8058_XO_BUFFER_DEV_NAME, \
-	.id = _id, \
-	.platform_data = &pm8058_xo_init_pdata[_id], \
-	.pdata_size = sizeof(pm8058_xo_init_pdata[_id]), \
-}
+#define PM8058_GPIO_INT		47
 
-/* Put sub devices with fixed location first in sub_devices array */
-static struct mfd_cell pm8058_subdevs[] = {
-	{	.name = "pm8058-mpp",
-		.platform_data	= &pm8058_mpp_data,
-		.pdata_size	= sizeof(pm8058_mpp_data),
-	},
-	{
-		.name = "pm8058-gpio",
-		.id = -1,
-		.platform_data = &pm8058_gpio_data,
-		.pdata_size	= sizeof(pm8058_gpio_data),
-	},
-#ifdef CONFIG_SENSORS_MSM_ADC
-	{
-		.name = "pm8058-xoadc",
-		.id = -1,
-		.num_resources = ARRAY_SIZE(resources_adc),
-		.resources = resources_adc,
-		.platform_data = &xoadc_pdata,
-		.pdata_size	=sizeof(xoadc_pdata),
-	},
-#endif
-	PM8058_VREG(PM8058_VREG_ID_L3),
-	PM8058_VREG(PM8058_VREG_ID_L8),
-	PM8058_VREG(PM8058_VREG_ID_L9),
-	PM8058_VREG(PM8058_VREG_ID_L14),
-	PM8058_VREG(PM8058_VREG_ID_L15),
-	PM8058_VREG(PM8058_VREG_ID_L18),
-	PM8058_VREG(PM8058_VREG_ID_S4),
-	PM8058_VREG(PM8058_VREG_ID_LVS0),
-	PM8058_XO(PM8058_XO_ID_A0),
-	PM8058_XO(PM8058_XO_ID_A1),
+static struct pm8xxx_irq_platform_data pm8xxx_irq_pdata = {
+	.irq_base		= PMIC8058_IRQ_BASE,
+	.devirq			= MSM_GPIO_TO_INT(PM8058_GPIO_INT),
+	.irq_trigger_flag	= IRQF_TRIGGER_LOW,
+};
+
+static struct pm8xxx_gpio_platform_data pm8xxx_gpio_pdata = {
+	.gpio_base	= PM8058_GPIO_PM_TO_SYS(0),
+};
+
+static struct pm8xxx_mpp_platform_data pm8xxx_mpp_pdata = {
+	.mpp_base	= PM8058_MPP_PM_TO_SYS(0),
 };
 
 static struct pm8058_platform_data pm8058_fsm9xxx_data = {
-	.irq_base = PMIC8058_IRQ_BASE,
-	.irq = MSM_GPIO_TO_INT(47),
-
-	.num_subdevs = ARRAY_SIZE(pm8058_subdevs),
-	.sub_devices = pm8058_subdevs,
+	.irq_pdata		= &pm8xxx_irq_pdata,
+	.gpio_pdata		= &pm8xxx_gpio_pdata,
+	.mpp_pdata		= &pm8xxx_mpp_pdata,
+	.regulator_pdatas	= pm8058_vreg_init,
+	.num_regulators		= ARRAY_SIZE(pm8058_vreg_init),
+	.xo_buffer_pdata	= pm8058_xo_init_pdata,
+	.num_xo_buffers		= ARRAY_SIZE(pm8058_xo_init_pdata),
+#ifdef CONFIG_SENSORS_MSM_ADC
+	.xoadc_pdata		= &pm8058_xoadc_pdata,
+#endif
 };
 
 #ifdef CONFIG_MSM_SSBI
@@ -882,13 +857,15 @@
 	msm_device_ssbi_pmic1.dev.platform_data =
 			&fsm9xxx_ssbi_pm8058_pdata;
 #endif
+	buses_init();
 
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 
 #ifdef CONFIG_MSM_SPM
 	msm_spm_init(&msm_spm_data, 1);
 #endif
-	buses_init();
+	pm8058_gpios_init();
+	pm8058_mpps_init();
 	phy_init();
 	grfc_init();
 	user_gpios_init();
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 9155e0c..eda29cd 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -23,16 +23,14 @@
 #endif
 #include <linux/msm_ssbi.h>
 #include <linux/mfd/pmic8058.h>
+#include <linux/leds.h>
 #include <linux/mfd/marimba.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
 #include <linux/smsc911x.h>
 #include <linux/ofn_atlab.h>
 #include <linux/power_supply.h>
-#include <linux/input/pmic8058-keypad.h>
 #include <linux/i2c/isa1200.h>
-#include <linux/pwm.h>
-#include <linux/pmic8058-pwm.h>
 #include <linux/i2c/tsc2007.h>
 #include <linux/input/kp_flip_switch.h>
 #include <linux/leds-pmic8058.h>
@@ -123,6 +121,8 @@
 /* Macros assume PMIC GPIOs start at 0 */
 #define PM8058_GPIO_PM_TO_SYS(pm_gpio)     (pm_gpio + NR_GPIO_IRQS)
 #define PM8058_GPIO_SYS_TO_PM(sys_gpio)    (sys_gpio - NR_GPIO_IRQS)
+#define PM8058_MPP_BASE			   PM8058_GPIO_PM_TO_SYS(PM8058_GPIOS)
+#define PM8058_MPP_PM_TO_SYS(pm_gpio)	   (pm_gpio + PM8058_MPP_BASE)
 
 #define PMIC_GPIO_FLASH_BOOST_ENABLE	15	/* PMIC GPIO Number 16 */
 #define PMIC_GPIO_HAP_ENABLE   16  /* PMIC GPIO Number 17 */
@@ -136,61 +136,71 @@
 #define PMIC_GPIO_QUICKVX_CLK 37 /* PMIC GPIO 38 */
 
 #define	PM_FLIP_MPP 5 /* PMIC MPP 06 */
+
+struct pm8xxx_gpio_init_info {
+	unsigned			gpio;
+	struct pm_gpio			config;
+};
+
 static int pm8058_gpios_init(void)
 {
 	int rc;
-	int pmic_gpio_hdmi_5v_en;
 
-#ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
-	struct pm8058_gpio sdcc_det = {
-		.direction      = PM_GPIO_DIR_IN,
-		.pull           = PM_GPIO_PULL_UP_1P5,
-		.vin_sel        = 2,
-		.function       = PM_GPIO_FUNC_NORMAL,
-		.inv_int_pol    = 0,
-	};
-#endif
-	struct pm8058_gpio sdc4_en = {
-		.direction      = PM_GPIO_DIR_OUT,
-		.pull           = PM_GPIO_PULL_NO,
-		.vin_sel        = PM_GPIO_VIN_L5,
-		.function       = PM_GPIO_FUNC_NORMAL,
-		.inv_int_pol    = 0,
-		.out_strength   = PM_GPIO_STRENGTH_LOW,
-		.output_value   = 0,
+	struct pm8xxx_gpio_init_info sdc4_en = {
+		PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SDC4_EN_N),
+		{
+			.direction      = PM_GPIO_DIR_OUT,
+			.pull           = PM_GPIO_PULL_NO,
+			.vin_sel        = PM8058_GPIO_VIN_L5,
+			.function       = PM_GPIO_FUNC_NORMAL,
+			.inv_int_pol    = 0,
+			.out_strength   = PM_GPIO_STRENGTH_LOW,
+			.output_value   = 0,
+		},
 	};
 
-	struct pm8058_gpio haptics_enable = {
-		.direction      = PM_GPIO_DIR_OUT,
-		.pull           = PM_GPIO_PULL_NO,
-		.out_strength   = PM_GPIO_STRENGTH_HIGH,
-		.function       = PM_GPIO_FUNC_NORMAL,
-		.inv_int_pol    = 0,
-		.vin_sel        = 2,
-		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
-		.output_value   = 0,
+	struct pm8xxx_gpio_init_info haptics_enable = {
+		PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_HAP_ENABLE),
+		{
+			.direction      = PM_GPIO_DIR_OUT,
+			.pull           = PM_GPIO_PULL_NO,
+			.out_strength   = PM_GPIO_STRENGTH_HIGH,
+			.function       = PM_GPIO_FUNC_NORMAL,
+			.inv_int_pol    = 0,
+			.vin_sel        = 2,
+			.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
+			.output_value   = 0,
+		},
 	};
 
-	struct pm8058_gpio hdmi_5V_en = {
-		.direction      = PM_GPIO_DIR_OUT,
-		.pull           = PM_GPIO_PULL_NO,
-		.vin_sel        = PM_GPIO_VIN_VPH,
-		.function       = PM_GPIO_FUNC_NORMAL,
-		.out_strength   = PM_GPIO_STRENGTH_LOW,
-		.output_value   = 0,
+	struct pm8xxx_gpio_init_info hdmi_5V_en = {
+		PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_HDMI_5V_EN_V3),
+		{
+			.direction      = PM_GPIO_DIR_OUT,
+			.pull           = PM_GPIO_PULL_NO,
+			.vin_sel        = PM8058_GPIO_VIN_VPH,
+			.function       = PM_GPIO_FUNC_NORMAL,
+			.out_strength   = PM_GPIO_STRENGTH_LOW,
+			.output_value   = 0,
+		},
 	};
 
-	struct pm8058_gpio flash_boost_enable = {
-		.direction      = PM_GPIO_DIR_OUT,
-		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
-		.output_value   = 0,
-		.pull           = PM_GPIO_PULL_NO,
-		.vin_sel        = PM_GPIO_VIN_S3,
-		.out_strength   = PM_GPIO_STRENGTH_HIGH,
-		.function       = PM_GPIO_FUNC_2,
+	struct pm8xxx_gpio_init_info flash_boost_enable = {
+		PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_FLASH_BOOST_ENABLE),
+		{
+			.direction      = PM_GPIO_DIR_OUT,
+			.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
+			.output_value   = 0,
+			.pull           = PM_GPIO_PULL_NO,
+			.vin_sel        = PM8058_GPIO_VIN_S3,
+			.out_strength   = PM_GPIO_STRENGTH_HIGH,
+			.function        = PM_GPIO_FUNC_2,
+		},
 	};
 
-	struct pm8058_gpio gpio23 = {
+	struct pm8xxx_gpio_init_info gpio23 = {
+		PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_WLAN_EXT_POR),
+		{
 			.direction      = PM_GPIO_DIR_OUT,
 			.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
 			.output_value   = 0,
@@ -198,71 +208,83 @@
 			.vin_sel        = 2,
 			.out_strength   = PM_GPIO_STRENGTH_LOW,
 			.function       = PM_GPIO_FUNC_NORMAL,
+		}
 	};
 
-
-	if (machine_is_msm8x55_svlte_surf() || machine_is_msm8x55_svlte_ffa() ||
-						machine_is_msm7x30_fluid())
-		pmic_gpio_hdmi_5v_en = PMIC_GPIO_HDMI_5V_EN_V2 ;
-	else
-		pmic_gpio_hdmi_5v_en = PMIC_GPIO_HDMI_5V_EN_V3 ;
-
-	if (machine_is_msm7x30_fluid()) {
-		rc = pm8058_gpio_config(PMIC_GPIO_HAP_ENABLE, &haptics_enable);
-		if (rc) {
-			pr_err("%s: PMIC GPIO %d write failed\n", __func__,
-				(PMIC_GPIO_HAP_ENABLE + 1));
-			return rc;
-		}
-		rc = pm8058_gpio_config(PMIC_GPIO_FLASH_BOOST_ENABLE,
-			&flash_boost_enable);
-		if (rc) {
-			pr_err("%s: PMIC GPIO %d write failed\n", __func__,
-				(PMIC_GPIO_FLASH_BOOST_ENABLE + 1));
-			return rc;
-		}
-	}
-
 #ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
-	if (machine_is_msm7x30_fluid())
-		sdcc_det.inv_int_pol = 1;
+	struct pm8xxx_gpio_init_info sdcc_det = {
+		PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SD_DET - 1),
+		{
+			.direction      = PM_GPIO_DIR_IN,
+			.pull           = PM_GPIO_PULL_UP_1P5,
+			.vin_sel        = 2,
+			.function       = PM_GPIO_FUNC_NORMAL,
+			.inv_int_pol    = 0,
+		},
+	};
 
-	rc = pm8058_gpio_config(PMIC_GPIO_SD_DET - 1, &sdcc_det);
+	if (machine_is_msm7x30_fluid())
+		sdcc_det.config.inv_int_pol = 1;
+
+	rc = pm8xxx_gpio_config(sdcc_det.gpio, &sdcc_det.config);
 	if (rc) {
 		pr_err("%s PMIC_GPIO_SD_DET config failed\n", __func__);
 		return rc;
 	}
 #endif
 
-	rc = pm8058_gpio_config(pmic_gpio_hdmi_5v_en, &hdmi_5V_en);
+	if (machine_is_msm8x55_svlte_surf() || machine_is_msm8x55_svlte_ffa() ||
+						machine_is_msm7x30_fluid())
+		hdmi_5V_en.gpio = PMIC_GPIO_HDMI_5V_EN_V2;
+	else
+		hdmi_5V_en.gpio = PMIC_GPIO_HDMI_5V_EN_V3;
+
+	hdmi_5V_en.gpio = PM8058_GPIO_PM_TO_SYS(hdmi_5V_en.gpio);
+
+	rc = pm8xxx_gpio_config(hdmi_5V_en.gpio, &hdmi_5V_en.config);
 	if (rc) {
 		pr_err("%s PMIC_GPIO_HDMI_5V_EN config failed\n", __func__);
 		return rc;
 	}
 
 	/* Deassert GPIO#23 (source for Ext_POR on WLAN-Volans) */
-	rc = pm8058_gpio_config(PMIC_GPIO_WLAN_EXT_POR, &gpio23);
+	rc = pm8xxx_gpio_config(gpio23.gpio, &gpio23.config);
 	if (rc) {
 		pr_err("%s PMIC_GPIO_WLAN_EXT_POR config failed\n", __func__);
 		return rc;
 	}
 
 	if (machine_is_msm7x30_fluid()) {
-		rc = pm8058_gpio_config(PMIC_GPIO_SDC4_EN_N, &sdc4_en);
+		/* Haptics gpio */
+		rc = pm8xxx_gpio_config(haptics_enable.gpio,
+						&haptics_enable.config);
+		if (rc) {
+			pr_err("%s: PMIC GPIO %d write failed\n", __func__,
+							haptics_enable.gpio);
+			return rc;
+		}
+		/* Flash boost gpio */
+		rc = pm8xxx_gpio_config(flash_boost_enable.gpio,
+						&flash_boost_enable.config);
+		if (rc) {
+			pr_err("%s: PMIC GPIO %d write failed\n", __func__,
+						flash_boost_enable.gpio);
+			return rc;
+		}
+		/* SCD4 gpio */
+		rc = pm8xxx_gpio_config(sdc4_en.gpio, &sdc4_en.config);
 		if (rc) {
 			pr_err("%s PMIC_GPIO_SDC4_EN_N config failed\n",
 								 __func__);
 			return rc;
 		}
-		rc = gpio_request(PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SDC4_EN_N),
-				  "sdc4_en");
+		rc = gpio_request(sdc4_en.gpio, "sdc4_en");
 		if (rc) {
 			pr_err("%s PMIC_GPIO_SDC4_EN_N gpio_request failed\n",
 				__func__);
 			return rc;
 		}
-		gpio_set_value_cansleep(
-			PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SDC4_EN_N), 0);
+		gpio_set_value_cansleep(sdc4_en.gpio, 0);
 	}
 
 	return 0;
@@ -450,12 +472,12 @@
 
 static int pm8058_pwm_config(struct pwm_device *pwm, int ch, int on)
 {
-	struct pm8058_gpio pwm_gpio_config = {
+	struct pm_gpio pwm_gpio_config = {
 		.direction      = PM_GPIO_DIR_OUT,
 		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
 		.output_value   = 0,
 		.pull           = PM_GPIO_PULL_NO,
-		.vin_sel        = PM_GPIO_VIN_S3,
+		.vin_sel        = PM8058_GPIO_VIN_S3,
 		.out_strength   = PM_GPIO_STRENGTH_HIGH,
 		.function       = PM_GPIO_FUNC_2,
 	};
@@ -469,9 +491,10 @@
 	case 2:
 		if (on) {
 			id = 24 + ch;
-			rc = pm8058_gpio_config(id - 1, &pwm_gpio_config);
+			rc = pm8xxx_gpio_config(PM8058_GPIO_PM_TO_SYS(id - 1),
+							&pwm_gpio_config);
 			if (rc)
-				pr_err("%s: pm8058_gpio_config(%d): rc=%d\n",
+				pr_err("%s: pm8xxx_gpio_config(%d): rc=%d\n",
 				       __func__, id, rc);
 		}
 		break;
@@ -660,78 +683,47 @@
 	KEY(11, 7, KEY_RIGHTSHIFT),
 };
 
-static struct resource resources_keypad[] = {
-	{
-		.start	= PM8058_KEYPAD_IRQ(PMIC8058_IRQ_BASE),
-		.end	= PM8058_KEYPAD_IRQ(PMIC8058_IRQ_BASE),
-		.flags	= IORESOURCE_IRQ,
-	},
-	{
-		.start	= PM8058_KEYSTUCK_IRQ(PMIC8058_IRQ_BASE),
-		.end	= PM8058_KEYSTUCK_IRQ(PMIC8058_IRQ_BASE),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
 static struct matrix_keymap_data surf_keymap_data = {
-        .keymap_size    = ARRAY_SIZE(surf_keymap),
-        .keymap         = surf_keymap,
+	.keymap_size    = ARRAY_SIZE(surf_keymap),
+	.keymap		= surf_keymap,
 };
 
-
-static struct pmic8058_keypad_data surf_keypad_data = {
+static struct pm8xxx_keypad_platform_data surf_keypad_data = {
 	.input_name		= "surf_keypad",
 	.input_phys_device	= "surf_keypad/input0",
 	.num_rows		= 12,
 	.num_cols		= 8,
-	.rows_gpio_start	= 8,
-	.cols_gpio_start	= 0,
-	.debounce_ms		= {8, 10},
+	.rows_gpio_start	= PM8058_GPIO_PM_TO_SYS(8),
+	.cols_gpio_start	= PM8058_GPIO_PM_TO_SYS(0),
+	.debounce_ms		= 15,
 	.scan_delay_ms		= 32,
 	.row_hold_ns		= 91500,
 	.wakeup			= 1,
-	.keymap_data            = &surf_keymap_data,
+	.keymap_data		= &surf_keymap_data,
 };
 
 static struct matrix_keymap_data fluid_keymap_data = {
-        .keymap_size    = ARRAY_SIZE(fluid_keymap),
-        .keymap         = fluid_keymap,
+	.keymap_size	= ARRAY_SIZE(fluid_keymap),
+	.keymap		= fluid_keymap,
 };
 
-
-
-static struct pmic8058_keypad_data fluid_keypad_data = {
+static struct pm8xxx_keypad_platform_data fluid_keypad_data = {
 	.input_name		= "fluid-keypad",
 	.input_phys_device	= "fluid-keypad/input0",
 	.num_rows		= 5,
 	.num_cols		= 5,
-	.rows_gpio_start	= 8,
-	.cols_gpio_start	= 0,
-	.debounce_ms		= {8, 10},
+	.rows_gpio_start	= PM8058_GPIO_PM_TO_SYS(8),
+	.cols_gpio_start	= PM8058_GPIO_PM_TO_SYS(0),
+	.debounce_ms		= 15,
 	.scan_delay_ms		= 32,
 	.row_hold_ns		= 91500,
 	.wakeup			= 1,
-	.keymap_data            = &fluid_keymap_data,
+	.keymap_data		= &fluid_keymap_data,
 };
 
 static struct pm8058_pwm_pdata pm8058_pwm_data = {
-	.config		= pm8058_pwm_config,
-	.enable		= pm8058_pwm_enable,
-};
-
-/* Put sub devices with fixed location first in sub_devices array */
-#define	PM8058_SUBDEV_KPD	0
-#define	PM8058_SUBDEV_LED	1
-
-static struct pm8058_gpio_platform_data pm8058_gpio_data = {
-	.gpio_base	= PM8058_GPIO_PM_TO_SYS(0),
-	.irq_base	= PM8058_GPIO_IRQ(PMIC8058_IRQ_BASE, 0),
-	.init		= pm8058_gpios_init,
-};
-
-static struct pm8058_gpio_platform_data pm8058_mpp_data = {
-	.gpio_base	= PM8058_GPIO_PM_TO_SYS(PM8058_GPIOS),
-	.irq_base	= PM8058_MPP_IRQ(PMIC8058_IRQ_BASE, 0),
+	.config         = pm8058_pwm_config,
+	.enable         = pm8058_pwm_enable,
 };
 
 static struct pmic8058_led pmic8058_ffa_leds[] = {
@@ -765,38 +757,6 @@
 	},
 };
 
-static struct mfd_cell pm8058_subdevs[] = {
-	{	.name = "pm8058-keypad",
-		.id		= -1,
-		.num_resources	= ARRAY_SIZE(resources_keypad),
-		.resources	= resources_keypad,
-	},
-	{	.name = "pm8058-led",
-		.id		= -1,
-	},
-	{	.name = "pm8058-gpio",
-		.id		= -1,
-		.platform_data	= &pm8058_gpio_data,
-		.pdata_size	= sizeof(pm8058_gpio_data),
-	},
-	{	.name = "pm8058-mpp",
-		.id		= -1,
-		.platform_data	= &pm8058_mpp_data,
-		.pdata_size	= sizeof(pm8058_mpp_data),
-	},
-	{	.name = "pm8058-pwm",
-		.id		= -1,
-		.platform_data	= &pm8058_pwm_data,
-		.pdata_size	= sizeof(pm8058_pwm_data),
-	},
-	{	.name = "pm8058-nfc",
-		.id		= -1,
-	},
-	{	.name = "pm8058-upl",
-		.id		= -1,
-	},
-};
-
 static struct pmic8058_leds_platform_data pm8058_surf_leds_data = {
 	.num_leds = ARRAY_SIZE(pmic8058_surf_leds),
 	.leds	= pmic8058_surf_leds,
@@ -825,13 +785,25 @@
 	.leds	= pmic8058_fluid_leds,
 };
 
-static struct pm8058_platform_data pm8058_7x30_data = {
-	.irq_base = PMIC8058_IRQ_BASE,
-	.irq = MSM_GPIO_TO_INT(PMIC_GPIO_INT),
+static struct pm8xxx_irq_platform_data pm8xxx_irq_pdata = {
+	.irq_base		= PMIC8058_IRQ_BASE,
+	.devirq			= MSM_GPIO_TO_INT(PMIC_GPIO_INT),
+	.irq_trigger_flag       = IRQF_TRIGGER_LOW,
+};
 
-	.num_subdevs = ARRAY_SIZE(pm8058_subdevs),
-	.sub_devices = pm8058_subdevs,
-	.irq_trigger_flags = IRQF_TRIGGER_LOW,
+static struct pm8xxx_gpio_platform_data pm8xxx_gpio_pdata = {
+	.gpio_base		= PM8058_GPIO_PM_TO_SYS(0),
+};
+
+static struct pm8xxx_mpp_platform_data pm8xxx_mpp_pdata = {
+	.mpp_base	= PM8058_MPP_PM_TO_SYS(0),
+};
+
+static struct pm8058_platform_data pm8058_7x30_data = {
+	.irq_pdata		= &pm8xxx_irq_pdata,
+	.gpio_pdata		= &pm8xxx_gpio_pdata,
+	.mpp_pdata		= &pm8xxx_mpp_pdata,
+	.pwm_pdata		= &pm8058_pwm_data,
 };
 
 #ifdef CONFIG_MSM_SSBI
@@ -1611,15 +1583,10 @@
 		pr_err("%s: gpio_tlmm_config (gpio=%d) failed\n",
 		       __func__, PMIC_GPIO_INT);
 
-	if (machine_is_msm7x30_fluid()) {
-		pm8058_7x30_data.sub_devices[PM8058_SUBDEV_KPD].platform_data
-			= &fluid_keypad_data;
-	} else {
-		pm8058_7x30_data.sub_devices[PM8058_SUBDEV_KPD].platform_data
-			= &surf_keypad_data;
-		pm8058_7x30_data.sub_devices[PM8058_SUBDEV_KPD].pdata_size
-                        = sizeof(surf_keypad_data);
-	}
+	if (machine_is_msm8x60_fluid())
+		pm8058_7x30_data.keypad_pdata = &fluid_keypad_data;
+	else
+		pm8058_7x30_data.keypad_pdata = &surf_keypad_data;
 
 	return 0;
 }
@@ -3246,24 +3213,27 @@
 {
         int rc;
         static int vbus_is_on;
-        struct pm8058_gpio usb_vbus = {
-                .direction      = PM_GPIO_DIR_OUT,
-                .pull           = PM_GPIO_PULL_NO,
-                .output_buffer  = PM_GPIO_OUT_BUF_CMOS,
-                .output_value   = 1,
-                .vin_sel        = 2,
-                .out_strength   = PM_GPIO_STRENGTH_MED,
-                .function       = PM_GPIO_FUNC_NORMAL,
-                .inv_int_pol    = 0,
-        };
+	struct pm8xxx_gpio_init_info usb_vbus = {
+		PM8058_GPIO_PM_TO_SYS(36),
+		{
+			.direction      = PM_GPIO_DIR_OUT,
+			.pull           = PM_GPIO_PULL_NO,
+			.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
+			.output_value   = 1,
+			.vin_sel        = 2,
+			.out_strength   = PM_GPIO_STRENGTH_MED,
+			.function       = PM_GPIO_FUNC_NORMAL,
+			.inv_int_pol    = 0,
+		},
+	};
 
         /* If VBUS is already on (or off), do nothing. */
         if (unlikely(on == vbus_is_on))
                 return;
 
         if (on) {
-                rc = pm8058_gpio_config(36, &usb_vbus);
-                if (rc) {
+		rc = pm8xxx_gpio_config(usb_vbus.gpio, &usb_vbus.config);
+		if (rc) {
                         pr_err("%s PMIC GPIO 36 write failed\n", __func__);
                         return;
                 }
@@ -4041,14 +4011,17 @@
 static unsigned quickvx_vlp_gpio =
 	GPIO_CFG(97, 0, GPIO_CFG_OUTPUT,  GPIO_CFG_NO_PULL,	GPIO_CFG_2MA);
 
-static struct pm8058_gpio pmic_quickvx_clk_gpio = {
-	.direction      = PM_GPIO_DIR_OUT,
-	.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
-	.output_value   = 1,
-	.pull           = PM_GPIO_PULL_NO,
-	.vin_sel        = PM_GPIO_VIN_S3,
-	.out_strength   = PM_GPIO_STRENGTH_HIGH,
-	.function       = PM_GPIO_FUNC_2,
+static struct pm8xxx_gpio_init_info pmic_quickvx_clk_gpio = {
+	PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_QUICKVX_CLK),
+	{
+		.direction      = PM_GPIO_DIR_OUT,
+		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
+		.output_value   = 1,
+		.pull           = PM_GPIO_PULL_NO,
+		.vin_sel        = PM8058_GPIO_VIN_S3,
+		.out_strength   = PM_GPIO_STRENGTH_HIGH,
+		.function       = PM_GPIO_FUNC_2,
+	},
 };
 
 static int display_common_power(int on)
@@ -4088,11 +4061,11 @@
 			/* bring QuickVX VLP line low */
 			gpio_set_value(97, 0);
 
-			rc = pm8058_gpio_config(PMIC_GPIO_QUICKVX_CLK,
-				&pmic_quickvx_clk_gpio);
+			rc = pm8xxx_gpio_config(pmic_quickvx_clk_gpio.gpio,
+						&pmic_quickvx_clk_gpio.config);
 			if (rc) {
-				pr_err("%s: pm8058_gpio_config(%#x)=%d\n",
-					__func__, PMIC_GPIO_QUICKVX_CLK + 1,
+				pr_err("%s: pm8xxx_gpio_config(%#x)=%d\n",
+					__func__, pmic_quickvx_clk_gpio.gpio,
 					rc);
 				return rc;
 			}
@@ -6452,16 +6425,12 @@
 
 static void __init pmic8058_leds_init(void)
 {
-	if (machine_is_msm7x30_surf()) {
-		pm8058_7x30_data.sub_devices[PM8058_SUBDEV_LED].platform_data
-			= &pm8058_surf_leds_data;
-	} else if (!machine_is_msm7x30_fluid()) {
-		pm8058_7x30_data.sub_devices[PM8058_SUBDEV_LED].platform_data
-			= &pm8058_ffa_leds_data;
-	} else if (machine_is_msm7x30_fluid()) {
-		pm8058_7x30_data.sub_devices[PM8058_SUBDEV_LED].platform_data
-			= &pm8058_fluid_leds_data;
-	}
+	if (machine_is_msm7x30_surf())
+		pm8058_7x30_data.leds_pdata = &pm8058_surf_leds_data;
+	else if (!machine_is_msm7x30_fluid())
+		pm8058_7x30_data.leds_pdata = &pm8058_ffa_leds_data;
+	else if (machine_is_msm7x30_fluid())
+		pm8058_7x30_data.leds_pdata = &pm8058_fluid_leds_data;
 }
 
 static struct msm_spm_platform_data msm_spm_data __initdata = {
@@ -6780,8 +6749,14 @@
 
 static int kp_flip_mpp_config(void)
 {
-	return pm8058_mpp_config_digital_in(PM_FLIP_MPP,
-		PM8058_MPP_DIG_LEVEL_S3, PM_MPP_DIN_TO_INT);
+	struct pm8xxx_mpp_config_data kp_flip_mpp = {
+		.type = PM8XXX_MPP_TYPE_D_INPUT,
+		.level = PM8018_MPP_DIG_LEVEL_S3,
+		.control = PM8XXX_MPP_DIN_TO_INT,
+	};
+
+	return pm8xxx_mpp_config(PM8058_MPP_PM_TO_SYS(PM_FLIP_MPP),
+						&kp_flip_mpp);
 }
 
 static struct flip_switch_pdata flip_switch_data = {
@@ -6992,6 +6967,10 @@
 		msm_adc_pdata.num_adc = ARRAY_SIZE(msm_adc_surf_device_names);
 	}
 
+	pmic8058_leds_init();
+
+	buses_init();
+
 #ifdef CONFIG_MSM_SSBI
 	msm_device_ssbi_pmic1.dev.platform_data =
 				&msm7x30_ssbi_pm8058_pdata;
@@ -7023,7 +7002,6 @@
 	msm_device_i2c_init();
 	msm_device_i2c_2_init();
 	qup_device_i2c_init();
-	buses_init();
 	msm7x30_init_marimba();
 #ifdef CONFIG_MSM7KV2_AUDIO
 	snddev_poweramp_gpio_init();
@@ -7071,7 +7049,8 @@
 
 	if (machine_is_msm7x30_surf())
 		platform_device_register(&flip_switch_device);
-	pmic8058_leds_init();
+
+	pm8058_gpios_init();
 
 	if (machine_is_msm7x30_fluid()) {
 		/* Initialize platform data for fluid v2 hardware */
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index b394710..090605f 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -19,21 +19,11 @@
 #include <linux/msm_ssbi.h>
 #include <linux/mfd/pmic8058.h>
 
-#include <linux/input/pmic8058-keypad.h>
-#include <linux/pmic8058-batt-alarm.h>
-#include <linux/pmic8058-pwrkey.h>
-#include <linux/rtc/rtc-pm8058.h>
-#include <linux/pmic8058-vibrator.h>
 #include <linux/leds.h>
 #include <linux/pmic8058-othc.h>
 #include <linux/mfd/pmic8901.h>
-#include <linux/regulator/pmic8058-regulator.h>
 #include <linux/regulator/pmic8901-regulator.h>
 #include <linux/bootmem.h>
-#include <linux/pwm.h>
-#include <linux/pmic8058-pwm.h>
-#include <linux/leds-pmic8058.h>
-#include <linux/pmic8058-xoadc.h>
 #include <linux/msm_adc.h>
 #include <linux/m_adcproc.h>
 #include <linux/mfd/marimba.h>
@@ -274,6 +264,21 @@
 	GPIO_EPM_EXPANDER_IO15,
 };
 
+struct pm8xxx_mpp_init_info {
+	unsigned			mpp;
+	struct pm8xxx_mpp_config_data	config;
+};
+
+#define PM8XXX_MPP_INIT(_mpp, _type, _level, _control) \
+{ \
+	.mpp	= PM8058_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.
@@ -1054,14 +1059,14 @@
 {
 	unsigned ret = -ENODEV;
 
-	struct pm8058_gpio pmic_id_cfg = {
+	struct pm_gpio pmic_id_cfg = {
 		.direction	= PM_GPIO_DIR_IN,
 		.pull		= PM_GPIO_PULL_UP_1P5,
 		.function	= PM_GPIO_FUNC_NORMAL,
 		.vin_sel	= 2,
 		.inv_int_pol	= 0,
 	};
-	struct pm8058_gpio pmic_id_uncfg = {
+	struct pm_gpio pmic_id_uncfg = {
 		.direction	= PM_GPIO_DIR_IN,
 		.pull		= PM_GPIO_PULL_NO,
 		.function	= PM_GPIO_FUNC_NORMAL,
@@ -1092,9 +1097,10 @@
 	if (init) {
 		notify_vbus_state_func_ptr = callback;
 		INIT_DELAYED_WORK(&pmic_id_det, pmic_id_detect);
-		ret = pm8058_gpio_config(PMIC_ID_GPIO, &pmic_id_cfg);
+		ret = pm8xxx_gpio_config(PM8058_GPIO_PM_TO_SYS(PMIC_ID_GPIO),
+							&pmic_id_cfg);
 		if (ret) {
-			pr_err("%s:return val of pm8058_gpio_config: %d\n",
+			pr_err("%s:return val of pm8xxx_gpio_config: %d\n",
 						__func__,  ret);
 			return ret;
 		}
@@ -1110,9 +1116,10 @@
 	} else {
 		usb_phy_susp_dig_vol = 750000;
 		free_irq(PMICID_INT, 0);
-		ret = pm8058_gpio_config(PMIC_ID_GPIO, &pmic_id_uncfg);
+		ret = pm8xxx_gpio_config(PM8058_GPIO_PM_TO_SYS(PMIC_ID_GPIO),
+							&pmic_id_uncfg);
 		if (ret) {
-			pr_err("%s: return val of pm8058_gpio_config: %d\n",
+			pr_err("%s: return val of pm8xxx_gpio_config: %d\n",
 						__func__,  ret);
 			return ret;
 		}
@@ -4482,13 +4489,6 @@
 #endif
 
 #ifdef CONFIG_SENSORS_MSM_ADC
-static struct resource resources_adc[] = {
-	{
-		.start = PM8058_ADC_IRQ(PM8058_IRQ_BASE),
-		.end   = PM8058_ADC_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-};
 
 static struct adc_access_fn xoadc_fn = {
 	pm8058_xoadc_select_chan_and_start_conv,
@@ -4837,37 +4837,33 @@
 
 static void pmic8058_xoadc_mpp_config(void)
 {
-	int rc;
+	int rc, i;
+	struct pm8xxx_mpp_init_info xoadc_mpps[] = {
+		PM8XXX_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,
+							AOUT_CTRL_DISABLE),
+		PM8XXX_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,
+							AOUT_CTRL_DISABLE),
+		PM8XXX_MPP_INIT(XOADC_MPP_10, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH7,
+							AOUT_CTRL_DISABLE),
+	};
 
 	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__);
 
-	rc = pm8058_mpp_config_analog_input(XOADC_MPP_3,
-			PM_MPP_AIN_AMUX_CH5, PM_MPP_AOUT_CTL_DISABLE);
-	if (rc)
-		pr_err("%s: Config mpp3 on pmic 8058 failed\n", __func__);
-
-	rc = pm8058_mpp_config_analog_input(XOADC_MPP_5,
-			PM_MPP_AIN_AMUX_CH9, PM_MPP_AOUT_CTL_DISABLE);
-	if (rc)
-		pr_err("%s: Config mpp5 on pmic 8058 failed\n", __func__);
-
-	rc = pm8058_mpp_config_analog_input(XOADC_MPP_7,
-			PM_MPP_AIN_AMUX_CH6, PM_MPP_AOUT_CTL_DISABLE);
-	if (rc)
-		pr_err("%s: Config mpp7 on pmic 8058 failed\n", __func__);
-
-	rc = pm8058_mpp_config_analog_input(XOADC_MPP_8,
-			PM_MPP_AIN_AMUX_CH8, PM_MPP_AOUT_CTL_DISABLE);
-	if (rc)
-		pr_err("%s: Config mpp8 on pmic 8058 failed\n", __func__);
-
-	rc = pm8058_mpp_config_analog_input(XOADC_MPP_10,
-			PM_MPP_AIN_AMUX_CH7, PM_MPP_AOUT_CTL_DISABLE);
-	if (rc)
-		pr_err("%s: Config mpp10 on pmic 8058 failed\n", __func__);
+	for (i = 0; i < ARRAY_SIZE(xoadc_mpps); i++) {
+		rc = pm8xxx_mpp_config(xoadc_mpps[i].mpp,
+					&xoadc_mpps[i].config);
+		if (rc) {
+			pr_err("%s: Config MPP %d of PM8058 failed\n",
+					__func__, xoadc_mpps[i].mpp);
+		}
+	}
 }
 
 static struct regulator *vreg_ldo18_adc;
@@ -4932,7 +4928,7 @@
 	.conversiontime         = 54,
 };
 
-static struct xoadc_platform_data xoadc_pdata = {
+static struct xoadc_platform_data pm8058_xoadc_pdata = {
 	.xoadc_prop = &pm8058_xoadc_data,
 	.xoadc_mpp_config = pmic8058_xoadc_mpp_config,
 	.xoadc_vreg_set = pmic8058_xoadc_vreg_config,
@@ -5314,18 +5310,28 @@
 #define EXT_CHG_VALID_MPP 10
 #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_DIG_LEVEL_S3, DIN_TO_INT),
+	PM8XXX_MPP_INIT(EXT_CHG_VALID_MPP_2, D_BI_DIR,
+		PM8058_MPP_DIG_LEVEL_S3, BI_PULLUP_10KOHM),
+};
+
 #ifdef CONFIG_ISL9519_CHARGER
 static int isl_detection_setup(void)
 {
-	int ret = 0;
+	int ret = 0, i;
 
-	ret = pm8058_mpp_config_digital_in(EXT_CHG_VALID_MPP,
-					   PM8058_MPP_DIG_LEVEL_S3,
-					   PM_MPP_DIN_TO_INT);
-	ret |=  pm8058_mpp_config_bi_dir(EXT_CHG_VALID_MPP_2,
-					   PM8058_MPP_DIG_LEVEL_S3,
-					   PM_MPP_BI_PULLUP_10KOHM
-					   );
+	for (i = 0; i < ARRAY_SIZE(isl_mpp); i++) {
+		ret = pm8xxx_mpp_config(isl_mpp[i].mpp,
+					&isl_mpp[i].config);
+		if (ret) {
+			pr_err("%s: Config MPP %d of PM8058 failed\n",
+						 __func__, isl_mpp[i].mpp);
+			return ret;
+		}
+	}
+
 	return ret;
 }
 
@@ -5342,7 +5348,7 @@
 static struct i2c_board_info isl_charger_i2c_info[] __initdata = {
 	{
 		I2C_BOARD_INFO("isl9519q", 0x9),
-		.irq = PM8058_CBLPWR_IRQ(PM8058_IRQ_BASE),
+		.irq = PM8058_IRQ_BASE + PM8058_CBLPWR_IRQ,
 		.platform_data = &isl_data,
 	},
 };
@@ -5351,14 +5357,18 @@
 #if defined(CONFIG_SMB137B_CHARGER) || defined(CONFIG_SMB137B_CHARGER_MODULE)
 static int smb137b_detection_setup(void)
 {
-	int ret = 0;
+	int ret = 0, i;
 
-	ret = pm8058_mpp_config_digital_in(EXT_CHG_VALID_MPP,
-					PM8058_MPP_DIG_LEVEL_S3,
-					PM_MPP_DIN_TO_INT);
-	ret |=  pm8058_mpp_config_bi_dir(EXT_CHG_VALID_MPP_2,
-					PM8058_MPP_DIG_LEVEL_S3,
-					PM_MPP_BI_PULLUP_10KOHM);
+	for (i = 0; i < ARRAY_SIZE(isl_mpp); i++) {
+		ret = pm8xxx_mpp_config(isl_mpp[i].mpp,
+					&isl_mpp[i].config);
+		if (ret) {
+			pr_err("%s: Config MPP %d of PM8058 failed\n",
+						 __func__, isl_mpp[i].mpp);
+			return ret;
+		}
+	}
+
 	return ret;
 }
 
@@ -5371,7 +5381,7 @@
 static struct i2c_board_info smb137b_charger_i2c_info[] __initdata = {
 	{
 		I2C_BOARD_INFO("smb137b", 0x08),
-		.irq = PM8058_CBLPWR_IRQ(PM8058_IRQ_BASE),
+		.irq = PM8058_IRQ_BASE + PM8058_CBLPWR_IRQ,
 		.platform_data = &smb137b_data,
 	},
 };
@@ -5387,12 +5397,12 @@
 	int rc;
 	struct pm8058_gpio_cfg {
 		int                gpio;
-		struct pm8058_gpio cfg;
+		struct pm_gpio	   cfg;
 	};
 
 	struct pm8058_gpio_cfg gpio_cfgs[] = {
 		{ /* FFA ethernet */
-			6,
+			PM8058_GPIO_PM_TO_SYS(6),
 			{
 				.direction      = PM_GPIO_DIR_IN,
 				.pull           = PM_GPIO_PULL_DN,
@@ -5403,7 +5413,7 @@
 		},
 #ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
 		{
-			PMIC_GPIO_SDC3_DET - 1,
+			PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SDC3_DET - 1),
 			{
 				.direction      = PM_GPIO_DIR_IN,
 				.pull           = PM_GPIO_PULL_UP_30,
@@ -5414,37 +5424,37 @@
 		},
 #endif
 		{ /* core&surf gpio expander */
-			UI_INT1_N,
+			PM8058_GPIO_PM_TO_SYS(UI_INT1_N),
 			{
 				.direction      = PM_GPIO_DIR_IN,
 				.pull           = PM_GPIO_PULL_NO,
-				.vin_sel        = PM_GPIO_VIN_S3,
+				.vin_sel        = PM8058_GPIO_VIN_S3,
 				.function       = PM_GPIO_FUNC_NORMAL,
 				.inv_int_pol    = 0,
 			},
 		},
 		{ /* docking gpio expander */
-			UI_INT2_N,
+			PM8058_GPIO_PM_TO_SYS(UI_INT2_N),
 			{
 				.direction      = PM_GPIO_DIR_IN,
 				.pull           = PM_GPIO_PULL_NO,
-				.vin_sel        = PM_GPIO_VIN_S3,
+				.vin_sel        = PM8058_GPIO_VIN_S3,
 				.function       = PM_GPIO_FUNC_NORMAL,
 				.inv_int_pol    = 0,
 			},
 		},
 		{ /* FHA/keypad gpio expanders */
-			UI_INT3_N,
+			PM8058_GPIO_PM_TO_SYS(UI_INT3_N),
 			{
 				.direction      = PM_GPIO_DIR_IN,
 				.pull           = PM_GPIO_PULL_NO,
-				.vin_sel        = PM_GPIO_VIN_S3,
+				.vin_sel        = PM8058_GPIO_VIN_S3,
 				.function       = PM_GPIO_FUNC_NORMAL,
 				.inv_int_pol    = 0,
 			},
 		},
 		{ /* Timpani Reset */
-			20,
+			PM8058_GPIO_PM_TO_SYS(20),
 			{
 				.direction	= PM_GPIO_DIR_OUT,
 				.output_value	= 1,
@@ -5457,7 +5467,7 @@
 			}
 		},
 		{ /* PMIC ID interrupt */
-			36,
+			PM8058_GPIO_PM_TO_SYS(36),
 			{
 				.direction	= PM_GPIO_DIR_IN,
 				.pull		= PM_GPIO_PULL_NO,
@@ -5470,7 +5480,7 @@
 
 #if defined(CONFIG_TOUCHDISC_VTD518_SHINETSU) || \
 		defined(CONFIG_TOUCHDISC_VTD518_SHINETSU_MODULE)
-	struct pm8058_gpio touchdisc_intr_gpio_cfg = {
+	struct pm_gpio touchdisc_intr_gpio_cfg = {
 		.direction      = PM_GPIO_DIR_IN,
 		.pull           = PM_GPIO_PULL_UP_1P5,
 		.vin_sel        = 2,
@@ -5480,7 +5490,7 @@
 
 #if defined(CONFIG_HAPTIC_ISA1200) || \
 			defined(CONFIG_HAPTIC_ISA1200_MODULE)
-	struct pm8058_gpio en_hap_gpio_cfg = {
+	struct pm_gpio en_hap_gpio_cfg = {
 		.direction      = PM_GPIO_DIR_OUT,
 		.pull           = PM_GPIO_PULL_NO,
 		.out_strength   = PM_GPIO_STRENGTH_HIGH,
@@ -5494,7 +5504,7 @@
 
 #if defined(CONFIG_PMIC8058_OTHC) || defined(CONFIG_PMIC8058_OTHC_MODULE)
 	struct pm8058_gpio_cfg line_in_gpio_cfg = {
-			18,
+			PM8058_GPIO_PM_TO_SYS(18),
 			{
 				.direction	= PM_GPIO_DIR_IN,
 				.pull           = PM_GPIO_PULL_UP_1P5,
@@ -5508,7 +5518,7 @@
 #if defined(CONFIG_QS_S5K4E1)
 		{
 			struct pm8058_gpio_cfg qs_hc37_cam_pd_gpio_cfg = {
-			26,
+			PM8058_GPIO_PM_TO_SYS(26),
 			{
 				.direction		= PM_GPIO_DIR_OUT,
 				.output_value	= 0,
@@ -5523,32 +5533,33 @@
 #endif
 #ifdef CONFIG_FB_MSM_LCDC_NT35582_WVGA
 	struct pm8058_gpio_cfg pmic_lcdc_nt35582_gpio_cfg = {
-		GPIO_NT35582_BL_EN_HW_PIN - 1,
+		PM8058_GPIO_PM_TO_SYS(GPIO_NT35582_BL_EN_HW_PIN - 1),
 		{
 			.direction		= PM_GPIO_DIR_OUT,
 			.output_buffer	= PM_GPIO_OUT_BUF_CMOS,
 			.output_value	= 1,
 			.pull			= PM_GPIO_PULL_UP_30,
 			/* 2.9V  PM_GPIO_VIN_L2, which gives 2.6V */
-			.vin_sel		= PM_GPIO_VIN_L5,
+			.vin_sel		= PM8058_GPIO_VIN_L5,
 			.out_strength	= PM_GPIO_STRENGTH_HIGH,
 			.function		= PM_GPIO_FUNC_NORMAL,
 			.inv_int_pol	= 0,
 		}
 	};
 #endif
-
 #if defined(CONFIG_HAPTIC_ISA1200) || \
 			defined(CONFIG_HAPTIC_ISA1200_MODULE)
 	if (machine_is_msm8x60_fluid()) {
-		rc = pm8058_gpio_config(PMIC_GPIO_HAP_ENABLE,
-				&en_hap_gpio_cfg);
+		rc = pm8xxx_gpio_config(
+			PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_HAP_ENABLE),
+			&en_hap_gpio_cfg);
 		if (rc < 0) {
 			pr_err("%s: pmic haptics gpio config failed\n",
 							__func__);
 		}
-		rc = pm8058_gpio_config(PMIC_GPIO_HAP_LDO_ENABLE,
-				&en_hap_gpio_cfg);
+		rc = pm8xxx_gpio_config(
+			PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_HAP_LDO_ENABLE),
+			&en_hap_gpio_cfg);
 		if (rc < 0) {
 			pr_err("%s: pmic haptics ldo gpio config failed\n",
 							__func__);
@@ -5561,8 +5572,9 @@
 		defined(CONFIG_TOUCHDISC_VTD518_SHINETSU_MODULE)
 	if (machine_is_msm8x60_ffa() || machine_is_msm8x60_surf() ||
 		machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa()) {
-		rc = pm8058_gpio_config(PMIC_GPIO_TOUCH_DISC_INTR,
-				&touchdisc_intr_gpio_cfg);
+		rc = pm8xxx_gpio_config(
+			PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_TOUCH_DISC_INTR),
+			&touchdisc_intr_gpio_cfg);
 		if (rc < 0) {
 			pr_err("%s: Touchdisc interrupt gpio config failed\n",
 							__func__);
@@ -5575,7 +5587,7 @@
 	if (machine_is_msm8x60_ffa() || machine_is_msm8x60_surf() ||
 		machine_is_msm8x60_fusion() || machine_is_msm8x60_dragon() ||
 		machine_is_msm8x60_fusn_ffa()) {
-		rc = pm8058_gpio_config(line_in_gpio_cfg.gpio,
+		rc = pm8xxx_gpio_config(line_in_gpio_cfg.gpio,
 				&line_in_gpio_cfg.cfg);
 		if (rc < 0) {
 			pr_err("%s pmic line_in gpio config failed\n",
@@ -5587,7 +5599,7 @@
 
 #ifdef CONFIG_FB_MSM_LCDC_NT35582_WVGA
 	if (machine_is_msm8x60_dragon()) {
-		rc = pm8058_gpio_config(pmic_lcdc_nt35582_gpio_cfg.gpio,
+		rc = pm8xxx_gpio_config(pmic_lcdc_nt35582_gpio_cfg.gpio,
 				&pmic_lcdc_nt35582_gpio_cfg.cfg);
 		if (rc < 0) {
 			pr_err("%s pmic gpio config failed\n", __func__);
@@ -5599,7 +5611,7 @@
 #if defined(CONFIG_QS_S5K4E1)
 		/* qs_cam_hc37_cam_pd only for 8660 fluid qs camera*/
 		if (machine_is_msm8x60_fluid()) {
-			rc = pm8058_gpio_config(qs_hc37_cam_pd_gpio_cfg.gpio,
+			rc = pm8xxx_gpio_config(qs_hc37_cam_pd_gpio_cfg.gpio,
 					&qs_hc37_cam_pd_gpio_cfg.cfg);
 			if (rc < 0) {
 				pr_err("%s pmic qs_hc37_cam_pd gpio config failed\n",
@@ -5611,7 +5623,7 @@
 #endif
 
 	for (i = 0; i < ARRAY_SIZE(gpio_cfgs); ++i) {
-		rc = pm8058_gpio_config(gpio_cfgs[i].gpio,
+		rc = pm8xxx_gpio_config(gpio_cfgs[i].gpio,
 				&gpio_cfgs[i].cfg);
 		if (rc < 0) {
 			pr_err("%s pmic gpio config failed\n",
@@ -5679,32 +5691,19 @@
 	KEY(4, 3, KEY_KBDILLUMTOGGLE),
 };
 
-static struct resource resources_keypad[] = {
-	{
-		.start	= PM8058_KEYPAD_IRQ(PM8058_IRQ_BASE),
-		.end	= PM8058_KEYPAD_IRQ(PM8058_IRQ_BASE),
-		.flags	= IORESOURCE_IRQ,
-	},
-	{
-		.start	= PM8058_KEYSTUCK_IRQ(PM8058_IRQ_BASE),
-		.end	= PM8058_KEYSTUCK_IRQ(PM8058_IRQ_BASE),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
 static struct matrix_keymap_data ffa_keymap_data = {
 	.keymap_size	= ARRAY_SIZE(ffa_keymap),
 	.keymap		= ffa_keymap,
 };
 
-static struct pmic8058_keypad_data ffa_keypad_data = {
+static struct pm8xxx_keypad_platform_data ffa_keypad_data = {
 	.input_name		= "ffa-keypad",
 	.input_phys_device	= "ffa-keypad/input0",
 	.num_rows		= 6,
 	.num_cols		= 5,
-	.rows_gpio_start	= 8,
-	.cols_gpio_start	= 0,
-	.debounce_ms		= {8, 10},
+	.rows_gpio_start	= PM8058_GPIO_PM_TO_SYS(8),
+	.cols_gpio_start	= PM8058_GPIO_PM_TO_SYS(0),
+	.debounce_ms		= 15,
 	.scan_delay_ms		= 32,
 	.row_hold_ns            = 91500,
 	.wakeup			= 1,
@@ -5716,19 +5715,20 @@
 	.keymap = dragon_keymap,
 };
 
-static struct pmic8058_keypad_data dragon_keypad_data = {
+static struct pm8xxx_keypad_platform_data dragon_keypad_data = {
 	.input_name = "dragon-keypad",
 	.input_phys_device = "dragon-keypad/input0",
 	.num_rows = 6,
 	.num_cols = 5,
-	.rows_gpio_start = 8,
-	.cols_gpio_start = 0,
-	.debounce_ms = {8, 10},
+	.rows_gpio_start	= PM8058_GPIO_PM_TO_SYS(8),
+	.cols_gpio_start	= PM8058_GPIO_PM_TO_SYS(0),
+	.debounce_ms		= 15,
 	.scan_delay_ms = 32,
 	.row_hold_ns = 91500,
 	.wakeup = 1,
 	.keymap_data = &dragon_keymap_data,
 };
+
 static const unsigned int fluid_keymap[] = {
 	KEY(0, 0, KEY_FN_F1),	 /* LS - PUSH1 */
 	KEY(0, 1, KEY_UP),	 /* NAV - UP */
@@ -5760,50 +5760,37 @@
 	.keymap		= fluid_keymap,
 };
 
-static struct pmic8058_keypad_data fluid_keypad_data = {
+static struct pm8xxx_keypad_platform_data fluid_keypad_data = {
 	.input_name		= "fluid-keypad",
 	.input_phys_device	= "fluid-keypad/input0",
 	.num_rows		= 6,
 	.num_cols		= 5,
-	.rows_gpio_start	= 8,
-	.cols_gpio_start	= 0,
-	.debounce_ms		= {8, 10},
+	.rows_gpio_start	= PM8058_GPIO_PM_TO_SYS(8),
+	.cols_gpio_start	= PM8058_GPIO_PM_TO_SYS(0),
+	.debounce_ms		= 15,
 	.scan_delay_ms		= 32,
 	.row_hold_ns            = 91500,
 	.wakeup			= 1,
 	.keymap_data		= &fluid_keymap_data,
 };
 
-static struct resource resources_pwrkey[] = {
-	{
-		.start	= PM8058_PWRKEY_REL_IRQ(PM8058_IRQ_BASE),
-		.end	= PM8058_PWRKEY_REL_IRQ(PM8058_IRQ_BASE),
-		.flags	= IORESOURCE_IRQ,
-	},
-	{
-		.start	= PM8058_PWRKEY_PRESS_IRQ(PM8058_IRQ_BASE),
-		.end	= PM8058_PWRKEY_PRESS_IRQ(PM8058_IRQ_BASE),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct pmic8058_pwrkey_pdata pwrkey_pdata = {
-	.pull_up		= 1,
-	.kpd_trigger_delay_us   = 970,
-	.wakeup			= 1,
-	.pwrkey_time_ms		= 500,
-};
-
-static struct pmic8058_vibrator_pdata pmic_vib_pdata = {
+static struct pm8xxx_vibrator_platform_data pm8058_vib_pdata = {
 	.initial_vibrate_ms  = 500,
 	.level_mV = 3000,
 	.max_timeout_ms = 15000,
 };
 
-#if defined(CONFIG_PMIC8058_OTHC) || defined(CONFIG_PMIC8058_OTHC_MODULE)
-#define PM8058_OTHC_CNTR_BASE0	0xA0
-#define PM8058_OTHC_CNTR_BASE1	0x134
-#define PM8058_OTHC_CNTR_BASE2	0x137
+static struct pm8xxx_rtc_platform_data pm8058_rtc_pdata = {
+	.rtc_write_enable       = false,
+	.rtc_alarm_powerup	= false,
+};
+
+static struct pm8xxx_pwrkey_platform_data pm8058_pwrkey_pdata = {
+	.pull_up		= 1,
+	.kpd_trigger_delay_us   = 970,
+	.wakeup			= 1,
+};
+
 #define PM8058_LINE_IN_DET_GPIO	PM8058_GPIO_PM_TO_SYS(18)
 
 static struct othc_accessory_info othc_accessories[]  = {
@@ -5950,42 +5937,6 @@
 	.micbias_regulator = &othc_reg,
 };
 
-static struct resource resources_othc_0[] = {
-	{
-		.name = "othc_base",
-		.start = PM8058_OTHC_CNTR_BASE0,
-		.end   = PM8058_OTHC_CNTR_BASE0,
-		.flags = IORESOURCE_IO,
-	},
-};
-
-static struct resource resources_othc_1[] = {
-	{
-		.start = PM8058_SW_1_IRQ(PM8058_IRQ_BASE),
-		.end   = PM8058_SW_1_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = PM8058_IR_1_IRQ(PM8058_IRQ_BASE),
-		.end   = PM8058_IR_1_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "othc_base",
-		.start = PM8058_OTHC_CNTR_BASE1,
-		.end   = PM8058_OTHC_CNTR_BASE1,
-		.flags = IORESOURCE_IO,
-	},
-};
-
-static struct resource resources_othc_2[] = {
-	{
-		.name = "othc_base",
-		.start = PM8058_OTHC_CNTR_BASE2,
-		.end   = PM8058_OTHC_CNTR_BASE2,
-		.flags = IORESOURCE_IO,
-	},
-};
 
 static void __init msm8x60_init_pm8058_othc(void)
 {
@@ -6023,143 +5974,16 @@
 		}
 	}
 }
-#endif
 
-static struct resource resources_pm8058_charger[] = {
-	{	.name = "CHGVAL",
-		.start = PM8058_CHGVAL_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_CHGVAL_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{	.name = "CHGINVAL",
-		.start = PM8058_CHGINVAL_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_CHGINVAL_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "CHGILIM",
-		.start = PM8058_CHGILIM_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_CHGILIM_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "VCP",
-		.start = PM8058_VCP_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_VCP_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-		{
-		.name = "ATC_DONE",
-		.start = PM8058_ATC_DONE_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_ATC_DONE_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "ATCFAIL",
-		.start = PM8058_ATCFAIL_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_ATCFAIL_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "AUTO_CHGDONE",
-		 .start = PM8058_AUTO_CHGDONE_IRQ(PM8058_IRQ_BASE),
-		 .end = PM8058_AUTO_CHGDONE_IRQ(PM8058_IRQ_BASE),
-		 .flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "AUTO_CHGFAIL",
-		.start = PM8058_AUTO_CHGFAIL_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_AUTO_CHGFAIL_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "CHGSTATE",
-		.start = PM8058_CHGSTATE_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_CHGSTATE_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "FASTCHG",
-		.start = PM8058_FASTCHG_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_FASTCHG_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "CHG_END",
-		 .start = PM8058_CHG_END_IRQ(PM8058_IRQ_BASE),
-		 .end = PM8058_CHG_END_IRQ(PM8058_IRQ_BASE),
-		 .flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "BATTTEMP",
-		.start = PM8058_BATTTEMP_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_BATTTEMP_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "CHGHOT",
-		.start = PM8058_CHGHOT_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_CHGHOT_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "CHGTLIMIT",
-		.start = PM8058_CHGTLIMIT_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_CHGTLIMIT_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "CHG_GONE",
-		 .start = PM8058_CHG_GONE_IRQ(PM8058_IRQ_BASE),
-		 .end = PM8058_CHG_GONE_IRQ(PM8058_IRQ_BASE),
-		 .flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "VCPMAJOR",
-		 .start = PM8058_VCPMAJOR_IRQ(PM8058_IRQ_BASE),
-		 .end = PM8058_VCPMAJOR_IRQ(PM8058_IRQ_BASE),
-		 .flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "VBATDET",
-		 .start = PM8058_VBATDET_IRQ(PM8058_IRQ_BASE),
-		 .end = PM8058_VBATDET_IRQ(PM8058_IRQ_BASE),
-		 .flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "BATFET",
-		 .start = PM8058_BATFET_IRQ(PM8058_IRQ_BASE),
-		 .end = PM8058_BATFET_IRQ(PM8058_IRQ_BASE),
-		 .flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "BATT_REPLACE",
-		.start = PM8058_BATT_REPLACE_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_BATT_REPLACE_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "BATTCONNECT",
-		.start = PM8058_BATTCONNECT_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_BATTCONNECT_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "VBATDET_LOW",
-		.start = PM8058_VBATDET_LOW_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_VBATDET_LOW_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-};
 
 static int pm8058_pwm_config(struct pwm_device *pwm, int ch, int on)
 {
-	struct pm8058_gpio pwm_gpio_config = {
+	struct pm_gpio pwm_gpio_config = {
 		.direction      = PM_GPIO_DIR_OUT,
 		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
 		.output_value   = 0,
 		.pull           = PM_GPIO_PULL_NO,
-		.vin_sel        = PM_GPIO_VIN_VPH,
+		.vin_sel        = PM8058_GPIO_VIN_VPH,
 		.out_strength   = PM_GPIO_STRENGTH_HIGH,
 		.function       = PM_GPIO_FUNC_2,
 	};
@@ -6174,9 +5998,10 @@
 	case 2:
 		if (on) {
 			id = 24 + ch;
-			rc = pm8058_gpio_config(id - 1, &pwm_gpio_config);
+			rc = pm8xxx_gpio_config(PM8058_GPIO_PM_TO_SYS(id - 1),
+							&pwm_gpio_config);
 			if (rc)
-				pr_err("%s: pm8058_gpio_config(%d): rc=%d\n",
+				pr_err("%s: pm8xxx_gpio_config(%d): rc=%d\n",
 					__func__, id, rc);
 		}
 		break;
@@ -6217,34 +6042,6 @@
 
 #define PM8058_GPIO_INT           88
 
-static struct pm8058_gpio_platform_data pm8058_gpio_data = {
-	.gpio_base	= PM8058_GPIO_PM_TO_SYS(0),
-	.irq_base	= PM8058_GPIO_IRQ(PM8058_IRQ_BASE, 0),
-	.init		= pm8058_gpios_init,
-};
-
-static struct pm8058_gpio_platform_data pm8058_mpp_data = {
-	.gpio_base	= PM8058_GPIO_PM_TO_SYS(PM8058_GPIOS),
-	.irq_base	= PM8058_MPP_IRQ(PM8058_IRQ_BASE, 0),
-};
-
-static struct resource resources_rtc[] = {
-       {
-		.start  = PM8058_RTC_IRQ(PM8058_IRQ_BASE),
-		.end    = PM8058_RTC_IRQ(PM8058_IRQ_BASE),
-		.flags  = IORESOURCE_IRQ,
-       },
-       {
-		.start  = PM8058_RTC_ALARM_IRQ(PM8058_IRQ_BASE),
-		.end    = PM8058_RTC_ALARM_IRQ(PM8058_IRQ_BASE),
-		.flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct pm8058_rtc_platform_data pm8058_rtc_pdata = {
-	.rtc_alarm_powerup	= false,
-};
-
 static struct pmic8058_led pmic8058_flash_leds[] = {
 	[0] = {
 		.name		= "camera:flash0",
@@ -6322,156 +6119,48 @@
 	.leds	= pmic8058_fluid_flash_leds,
 };
 
-static struct resource resources_temp_alarm[] = {
-	{
-		.start  = PM8058_TEMP_ALARM_IRQ(PM8058_IRQ_BASE),
-		.end    = PM8058_TEMP_ALARM_IRQ(PM8058_IRQ_BASE),
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static struct resource resources_pm8058_misc[] = {
-	{
-		.start  = PM8058_OSCHALT_IRQ(PM8058_IRQ_BASE),
-		.end    = PM8058_OSCHALT_IRQ(PM8058_IRQ_BASE),
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static struct resource resources_pm8058_batt_alarm[] = {
-	{
-		.start  = PM8058_BATT_ALARM_IRQ(PM8058_IRQ_BASE),
-		.end    = PM8058_BATT_ALARM_IRQ(PM8058_IRQ_BASE),
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-#define PM8058_SUBDEV_KPD 0
-#define PM8058_SUBDEV_LED 1
-#define PM8058_SUBDEV_VIB 2
-
-static struct mfd_cell pm8058_subdevs[] = {
-	{
-		.name = "pm8058-keypad",
-		.id		= -1,
-		.num_resources	= ARRAY_SIZE(resources_keypad),
-		.resources	= resources_keypad,
-	},
-	{	.name = "pm8058-led",
-		.id		= -1,
-	},
-	{
-		.name = "pm8058-vib",
-		.id = -1,
-	},
-	{	.name = "pm8058-gpio",
-		.id		= -1,
-		.platform_data	= &pm8058_gpio_data,
-		.pdata_size = sizeof(pm8058_gpio_data),
-	},
-	{	.name = "pm8058-mpp",
-		.id		= -1,
-		.platform_data	= &pm8058_mpp_data,
-		.pdata_size = sizeof(pm8058_mpp_data),
-	},
-	{	.name = "pm8058-pwrkey",
-		.id	= -1,
-		.resources = resources_pwrkey,
-		.num_resources = ARRAY_SIZE(resources_pwrkey),
-		.platform_data = &pwrkey_pdata,
-		.pdata_size = sizeof(pwrkey_pdata),
-	},
-	{
-		.name = "pm8058-pwm",
-		.id = -1,
-		.platform_data = &pm8058_pwm_data,
-		.pdata_size = sizeof(pm8058_pwm_data),
-	},
-#ifdef CONFIG_SENSORS_MSM_ADC
-	{
-		.name = "pm8058-xoadc",
-		.id = -1,
-		.num_resources = ARRAY_SIZE(resources_adc),
-		.resources = resources_adc,
-		.platform_data = &xoadc_pdata,
-		.pdata_size = sizeof(xoadc_pdata),
-	},
-#endif
-#if defined(CONFIG_PMIC8058_OTHC) || defined(CONFIG_PMIC8058_OTHC_MODULE)
-	{
-		.name = "pm8058-othc",
-		.id = 0,
-		.platform_data = &othc_config_pdata_0,
-		.pdata_size = sizeof(othc_config_pdata_0),
-		.num_resources = ARRAY_SIZE(resources_othc_0),
-		.resources = resources_othc_0,
-	},
-	{
-		/* OTHC1 module has headset/switch dection */
-		.name = "pm8058-othc",
-		.id = 1,
-		.num_resources = ARRAY_SIZE(resources_othc_1),
-		.resources = resources_othc_1,
-		.platform_data = &othc_config_pdata_1,
-		.pdata_size = sizeof(othc_config_pdata_1),
-	},
-	{
-		.name = "pm8058-othc",
-		.id = 2,
-		.platform_data = &othc_config_pdata_2,
-		.pdata_size = sizeof(othc_config_pdata_2),
-		.num_resources = ARRAY_SIZE(resources_othc_2),
-		.resources = resources_othc_2,
-	},
-#endif
-	{
-		.name = "pm8058-rtc",
-		.id = -1,
-		.num_resources  = ARRAY_SIZE(resources_rtc),
-		.resources      = resources_rtc,
-		.platform_data = &pm8058_rtc_pdata,
-	},
-	{
-		.name = "pm8058-tm",
-		.id = -1,
-		.num_resources  = ARRAY_SIZE(resources_temp_alarm),
-		.resources      = resources_temp_alarm,
-	},
-	{	.name = "pm8058-upl",
-		.id		= -1,
-	},
-	{
-		.name = "pm8058-misc",
-		.id = -1,
-		.num_resources  = ARRAY_SIZE(resources_pm8058_misc),
-		.resources      = resources_pm8058_misc,
-	},
-	{	.name = "pm8058-batt-alarm",
-		.id		= -1,
-		.num_resources  = ARRAY_SIZE(resources_pm8058_batt_alarm),
-		.resources      = resources_pm8058_batt_alarm,
-	},
-};
-
 static struct pmic8058_charger_data pmic8058_charger_dragon = {
+		.charger_data_valid = true,
 		.max_source_current = 1800,
 		.charger_type = CHG_TYPE_AC,
 };
 
-static struct mfd_cell pm8058_charger_sub_dev = {
-		.name = "pm8058-charger",
-		.id = -1,
-		.num_resources = ARRAY_SIZE(resources_pm8058_charger),
-		.resources = resources_pm8058_charger,
+static struct pmic8058_charger_data pmic8058_charger_ffa_surf = {
+		.charger_data_valid = false,
+};
+
+static struct pm8xxx_misc_platform_data pm8058_misc_pdata = {
+	.priority		= 0,
+};
+
+static struct pm8xxx_irq_platform_data pm8058_irq_pdata = {
+	.irq_base		= PM8058_IRQ_BASE,
+	.devirq			= MSM_GPIO_TO_INT(PM8058_GPIO_INT),
+	.irq_trigger_flag	= IRQF_TRIGGER_LOW,
+};
+
+static struct pm8xxx_gpio_platform_data pm8058_gpio_pdata = {
+	.gpio_base	= PM8058_GPIO_PM_TO_SYS(0),
+};
+
+static struct pm8xxx_mpp_platform_data pm8058_mpp_pdata = {
+	.mpp_base	= PM8058_MPP_PM_TO_SYS(0),
 };
 
 static struct pm8058_platform_data pm8058_platform_data = {
-	.irq_base = PM8058_IRQ_BASE,
-	.irq = MSM_GPIO_TO_INT(PM8058_GPIO_INT),
-
-	.num_subdevs = ARRAY_SIZE(pm8058_subdevs),
-	.sub_devices = pm8058_subdevs,
-	.irq_trigger_flags = IRQF_TRIGGER_LOW,
+	.irq_pdata		= &pm8058_irq_pdata,
+	.gpio_pdata		= &pm8058_gpio_pdata,
+	.mpp_pdata		= &pm8058_mpp_pdata,
+	.rtc_pdata		= &pm8058_rtc_pdata,
+	.pwrkey_pdata		= &pm8058_pwrkey_pdata,
+	.othc0_pdata		= &othc_config_pdata_0,
+	.othc1_pdata		= &othc_config_pdata_1,
+	.othc2_pdata		= &othc_config_pdata_2,
+	.pwm_pdata		= &pm8058_pwm_data,
+	.misc_pdata		= &pm8058_misc_pdata,
+#ifdef CONFIG_SENSORS_MSM_ADC
+	.xoadc_pdata		= &pm8058_xoadc_pdata,
+#endif
 };
 
 #ifdef CONFIG_MSM_SSBI
@@ -7108,10 +6797,10 @@
 static int fm_radio_setup(struct marimba_fm_platform_data *pdata)
 {
 	int rc = 0;
-	struct pm8058_gpio cfg = {
+	struct pm_gpio cfg = {
 				.direction      = PM_GPIO_DIR_IN,
 				.pull           = PM_GPIO_PULL_NO,
-				.vin_sel        = PM_GPIO_VIN_S3,
+				.vin_sel        = PM8058_GPIO_VIN_S3,
 				.function       = PM_GPIO_FUNC_NORMAL,
 				.inv_int_pol    = 0,
 				};
@@ -7159,9 +6848,9 @@
 	}
 
 	/*GPIO 18 on PMIC is FM_IRQ*/
-	rc = pm8058_gpio_config(FM_GPIO, &cfg);
+	rc = pm8xxx_gpio_config(PM8058_GPIO_PM_TO_SYS(FM_GPIO), &cfg);
 	if (rc) {
-		printk(KERN_ERR "%s: return val of pm8058_gpio_config: %d\n",
+		printk(KERN_ERR "%s: return val of pm8xxx_gpio_config: %d\n",
 						__func__,  rc);
 		goto fm_fail_clock;
 	}
@@ -10226,7 +9915,7 @@
 {
 	uint32_t soc_platform_version;
 
-	pmic_reset_irq = PM8058_RESOUT_IRQ(PM8058_IRQ_BASE);
+	pmic_reset_irq = PM8058_IRQ_BASE + PM8058_RESOUT_IRQ;
 
 	/*
 	 * Initialize RPM first as other drivers and devices may need
@@ -10322,28 +10011,12 @@
 	msm8x60_init_pm8058_othc();
 #endif
 
-	if (machine_is_msm8x60_fluid()) {
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].
-			platform_data = &fluid_keypad_data;
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].pdata_size
-			= sizeof(fluid_keypad_data);
-	} else if (machine_is_msm8x60_dragon()) {
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].
-			platform_data = &dragon_keypad_data;
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].pdata_size
-			= sizeof(dragon_keypad_data);
-	} else {
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].
-			platform_data = &ffa_keypad_data;
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].pdata_size
-			= sizeof(ffa_keypad_data);
-
-	}
-
-	/* Disable END_CALL simulation function of powerkey on fluid */
-	if (machine_is_msm8x60_fluid()) {
-		pwrkey_pdata.pwrkey_time_ms = 0;
-	}
+	if (machine_is_msm8x60_fluid())
+		pm8058_platform_data.keypad_pdata = &fluid_keypad_data;
+	else if (machine_is_msm8x60_dragon())
+		pm8058_platform_data.keypad_pdata = &dragon_keypad_data;
+	else
+		pm8058_platform_data.keypad_pdata = &ffa_keypad_data;
 
 	/* Specify reset pin for OV9726 */
 	if (machine_is_msm8x60_dragon()) {
@@ -10351,6 +10024,31 @@
 		ov9726_sensor_8660_info.mount_angle = 270;
 	}
 
+#ifdef CONFIG_BATTERY_MSM8X60
+	if (machine_is_msm8x60_surf() || machine_is_msm8x60_ffa() ||
+		machine_is_msm8x60_fusion() || machine_is_msm8x60_dragon() ||
+		machine_is_msm8x60_fusn_ffa() || machine_is_msm8x60_fluid())
+		platform_device_register(&msm_charger_device);
+#endif
+
+	if (machine_is_msm8x60_dragon())
+		pm8058_platform_data.charger_pdata = &pmic8058_charger_dragon;
+	if (!machine_is_msm8x60_fluid())
+		pm8058_platform_data.charger_pdata = &pmic8058_charger_ffa_surf;
+
+	/* configure pmic leds */
+	if (machine_is_msm8x60_fluid())
+		pm8058_platform_data.leds_pdata = &pm8058_fluid_flash_leds_data;
+	else if (machine_is_msm8x60_dragon())
+		pm8058_platform_data.leds_pdata = &pm8058_dragon_leds_data;
+	else
+		pm8058_platform_data.leds_pdata = &pm8058_flash_leds_data;
+
+	if (machine_is_msm8x60_ffa() || machine_is_msm8x60_fusn_ffa() ||
+		machine_is_msm8x60_dragon()) {
+		pm8058_platform_data.vibrator_pdata = &pm8058_vib_pdata;
+	}
+
 	if (machine_is_msm8x60_surf() || machine_is_msm8x60_ffa() ||
 	    machine_is_msm8x60_fluid() || machine_is_msm8x60_fusion() ||
 	    machine_is_msm8x60_fusn_ffa() || machine_is_msm8x60_dragon()) {
@@ -10398,25 +10096,10 @@
 		machine_is_msm8x60_dragon())
 		msm8x60_cfg_isp1763();
 #endif
-#ifdef CONFIG_BATTERY_MSM8X60
-	if (machine_is_msm8x60_surf() || machine_is_msm8x60_ffa() ||
-		machine_is_msm8x60_fusion() || machine_is_msm8x60_dragon() ||
-		machine_is_msm8x60_fusn_ffa() || machine_is_msm8x60_fluid())
-		platform_device_register(&msm_charger_device);
-#endif
 
 	if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())
 		platform_add_devices(charm_devices, ARRAY_SIZE(charm_devices));
 
-	if (machine_is_msm8x60_dragon()) {
-		pm8058_charger_sub_dev.platform_data
-			= &pmic8058_charger_dragon;
-		pm8058_charger_sub_dev.pdata_size
-			= sizeof(pmic8058_charger_dragon);
-	}
-	if (!machine_is_msm8x60_fluid())
-		pm8058_platform_data.charger_sub_device
-			= &pm8058_charger_sub_dev;
 
 #if defined(CONFIG_SPI_QUP) || defined(CONFIG_SPI_QUP_MODULE)
 	if (machine_is_msm8x60_fluid())
@@ -10473,6 +10156,8 @@
 				msm_pm_data);
 	BUG_ON(msm_pm_boot_init(MSM_PM_BOOT_CONFIG_TZ, NULL));
 
+	pm8058_gpios_init();
+
 #ifdef CONFIG_SENSORS_MSM_ADC
 	if (machine_is_msm8x60_fluid()) {
 		msm_adc_pdata.dev_names = msm_adc_fluid_device_names;
@@ -10494,32 +10179,6 @@
 		platform_device_register(&gpio_leds);
 #endif
 
-	/* configure pmic leds */
-	if (machine_is_msm8x60_fluid()) {
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].
-			platform_data = &pm8058_fluid_flash_leds_data;
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].pdata_size
-			= sizeof(pm8058_fluid_flash_leds_data);
-	} else if (machine_is_msm8x60_dragon()) {
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].
-			platform_data = &pm8058_dragon_leds_data;
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].pdata_size
-			= sizeof(pm8058_dragon_leds_data);
-	} else {
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].
-			platform_data = &pm8058_flash_leds_data;
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].pdata_size
-			= sizeof(pm8058_flash_leds_data);
-	}
-
-	if (machine_is_msm8x60_ffa() || machine_is_msm8x60_fusn_ffa() ||
-		machine_is_msm8x60_dragon()) {
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_VIB].
-					platform_data = &pmic_vib_pdata;
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_VIB].
-					pdata_size = sizeof(pmic_vib_pdata);
-	}
-
 	msm8x60_multi_sdio_init();
 
 	if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index 2a39e3c..017eed9 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -548,8 +548,8 @@
 	},
 	{
 		.name	= "vbus_on",
-		.start	= PM8058_CHGVAL_IRQ(PMIC8058_IRQ_BASE),
-		.end	= PM8058_CHGVAL_IRQ(PMIC8058_IRQ_BASE),
+		.start	= PMIC8058_IRQ_BASE + PM8058_CHGVAL_IRQ,
+		.end	= PMIC8058_IRQ_BASE + PM8058_CHGVAL_IRQ,
 		.flags	= IORESOURCE_IRQ,
 	},
 };
diff --git a/arch/arm/mach-msm/restart.c b/arch/arm/mach-msm/restart.c
index 00be696..28bf064 100644
--- a/arch/arm/mach-msm/restart.c
+++ b/arch/arm/mach-msm/restart.c
@@ -120,11 +120,11 @@
 #ifdef CONFIG_MSM_DLOAD_MODE
 	set_dload_mode(0);
 #endif
-	if (cpu_is_msm8x60()) {
-		pm8058_reset_pwr_off(0);
-		pm8901_reset_pwr_off(0);
-	}
 	pm8xxx_reset_pwr_off(0);
+
+	if (cpu_is_msm8x60())
+		pm8901_reset_pwr_off(0);
+
 	if (lower_pshold) {
 		__raw_writel(0, PSHOLD_CTL_SU);
 		mdelay(10000);
@@ -202,8 +202,6 @@
 
 	printk(KERN_NOTICE "Going down for restart now\n");
 
-	if (cpu_is_msm8x60())
-		pm8058_reset_pwr_off(1);
 	pm8xxx_reset_pwr_off(1);
 
 	if (cmd != NULL) {
diff --git a/drivers/gpio/pm8xxx-gpio.c b/drivers/gpio/pm8xxx-gpio.c
index 377510f..53305e3 100644
--- a/drivers/gpio/pm8xxx-gpio.c
+++ b/drivers/gpio/pm8xxx-gpio.c
@@ -432,7 +432,7 @@
 
 	return rc;
 }
-EXPORT_SYMBOL_GPL(pm8xxx_gpio_config);
+EXPORT_SYMBOL(pm8xxx_gpio_config);
 
 static struct platform_driver pm_gpio_driver = {
 	.probe		= pm_gpio_probe,
diff --git a/drivers/input/keyboard/Kconfig b/drivers/input/keyboard/Kconfig
index 0822866..6db0da1 100644
--- a/drivers/input/keyboard/Kconfig
+++ b/drivers/input/keyboard/Kconfig
@@ -401,17 +401,6 @@
 	  Say Y here to enable the driver for the keypad matrix interface
 	  on the Qualcomm PM8058 power management I/C device.
 
-config KEYBOARD_PMIC8XXX
-	tristate "Qualcomm PMIC8XXX keypad support"
-	depends on MFD_PM8XXX
-	help
-	  Say Y here if you want to enable the driver for the PMIC8XXX
-	  keypad provided as a reference design from Qualcomm. This is intended
-	  to support upto 18x8 matrix based keypad design.
-
-	  To compile this driver as a module, choose M here: the module will
-	  be called pmic8xxx-keypad.
-
 config KEYBOARD_PXA27x
 	tristate "PXA27x/PXA3xx keypad support"
 	depends on PXA27x || PXA3xx || ARCH_MMP
diff --git a/drivers/input/misc/pmic8058-othc.c b/drivers/input/misc/pmic8058-othc.c
index c6be119..a28e8e1 100644
--- a/drivers/input/misc/pmic8058-othc.c
+++ b/drivers/input/misc/pmic8058-othc.c
@@ -27,7 +27,7 @@
 #include <linux/delay.h>
 #include <linux/regulator/consumer.h>
 
-#include <linux/mfd/pmic8058.h>
+#include <linux/mfd/pm8xxx/core.h>
 #include <linux/pmic8058-othc.h>
 #include <linux/msm_adc.h>
 
@@ -68,6 +68,7 @@
 	void *adc_handle;
 	void *accessory_adc_handle;
 	spinlock_t lock;
+	struct device *dev;
 	struct regulator *othc_vreg;
 	struct input_dev *othc_ipd;
 	struct switch_dev othc_sdev;
@@ -75,7 +76,6 @@
 	struct othc_accessory_info *accessory_info;
 	struct hrtimer timer;
 	struct othc_n_switch_config *switch_config;
-	struct pm8058_chip *pm_chip;
 	struct work_struct switch_work;
 	struct delayed_work detect_work;
 	struct delayed_work hs_work;
@@ -149,7 +149,7 @@
 		return -EINVAL;
 	}
 
-	rc = pm8058_read(dd->pm_chip, dd->othc_base + 1, &reg, 1);
+	rc = pm8xxx_readb(dd->dev->parent, dd->othc_base + 1, &reg);
 	if (rc < 0) {
 		pr_err("PM8058 read failed\n");
 		return rc;
@@ -158,7 +158,7 @@
 	reg &= PM8058_OTHC_EN_SIG_MASK;
 	reg |= (enable << PM8058_OTHC_EN_SIG_SHIFT);
 
-	rc = pm8058_write(dd->pm_chip, dd->othc_base + 1, &reg, 1);
+	rc = pm8xxx_writeb(dd->dev->parent, dd->othc_base + 1, reg);
 	if (rc < 0) {
 		pr_err("PM8058 write failed\n");
 		return rc;
@@ -446,7 +446,7 @@
 
 	if (dd->ir_gpio < 0) {
 		/* Check the MIC_BIAS status */
-		rc = pm8058_irq_get_rt_status(dd->pm_chip, dd->othc_irq_ir);
+		rc = pm8xxx_read_irq_stat(dd->dev->parent, dd->othc_irq_ir);
 		if (rc < 0) {
 			pr_err("Unable to read IR status from PMIC\n");
 			goto fail_ir_accessory;
@@ -462,7 +462,7 @@
 	}
 
 	/* Check the switch status */
-	rc = pm8058_irq_get_rt_status(dd->pm_chip, dd->othc_irq_sw);
+	rc = pm8xxx_read_irq_stat(dd->dev->parent, dd->othc_irq_sw);
 	if (rc < 0) {
 		pr_err("Unable to read SWITCH status\n");
 		goto fail_ir_accessory;
@@ -576,7 +576,7 @@
 	}
 	spin_unlock_irqrestore(&dd->lock, flags);
 
-	level = pm8058_irq_get_rt_status(dd->pm_chip, dd->othc_irq_sw);
+	level = pm8xxx_read_irq_stat(dd->dev->parent, dd->othc_irq_sw);
 	if (level < 0) {
 		pr_err("Unable to read IRQ status register\n");
 		return IRQ_HANDLED;
@@ -641,7 +641,7 @@
 	disable_irq_nosync(dd->othc_irq_ir);
 
 	/* Check the MIC_BIAS status, to check if inserted or removed */
-	rc = pm8058_irq_get_rt_status(dd->pm_chip, dd->othc_irq_ir);
+	rc = pm8xxx_read_irq_stat(dd->dev->parent, dd->othc_irq_ir);
 	if (rc < 0) {
 		pr_err("Unable to read IR status\n");
 		goto fail_ir;
@@ -666,7 +666,7 @@
 
 	/* Intialize the OTHC module */
 	/* Control Register 1*/
-	rc = pm8058_read(dd->pm_chip, base_addr, &reg, 1);
+	rc = pm8xxx_readb(dd->dev->parent, base_addr, &reg);
 	if (rc < 0) {
 		pr_err("PM8058 read failed\n");
 		return rc;
@@ -676,14 +676,14 @@
 	value = (hsed_config->othc_highcurr_thresh_uA / 100) - 2;
 	reg =  (reg & PM8058_OTHC_HIGH_CURR_MASK) | value;
 
-	rc = pm8058_write(dd->pm_chip, base_addr, &reg, 1);
+	rc = pm8xxx_writeb(dd->dev->parent, base_addr, reg);
 	if (rc < 0) {
 		pr_err("PM8058 read failed\n");
 		return rc;
 	}
 
 	/* Control register 2*/
-	rc = pm8058_read(dd->pm_chip, base_addr + 1, &reg, 1);
+	rc = pm8xxx_readb(dd->dev->parent, base_addr + 1, &reg);
 	if (rc < 0) {
 		pr_err("PM8058 read failed\n");
 		return rc;
@@ -718,14 +718,14 @@
 	}
 	reg = (reg &  PM8058_OTHC_CLK_PREDIV_MASK) | (value - 1);
 
-	rc = pm8058_write(dd->pm_chip, base_addr + 1, &reg, 1);
+	rc = pm8xxx_writeb(dd->dev->parent, base_addr + 1, reg);
 	if (rc < 0) {
 		pr_err("PM8058 read failed\n");
 		return rc;
 	}
 
 	/* Control register 3 */
-	rc = pm8058_read(dd->pm_chip, base_addr + 2 , &reg, 1);
+	rc = pm8xxx_readb(dd->dev->parent, base_addr + 2 , &reg);
 	if (rc < 0) {
 		pr_err("PM8058 read failed\n");
 		return rc;
@@ -748,7 +748,7 @@
 	}
 	reg = (reg & PM8058_OTHC_PERIOD_CLK_MASK) | value;
 
-	rc = pm8058_write(dd->pm_chip, base_addr + 2, &reg, 1);
+	rc = pm8xxx_writeb(dd->dev->parent, base_addr + 2, reg);
 	if (rc < 0) {
 		pr_err("PM8058 read failed\n");
 		return rc;
@@ -1006,7 +1006,7 @@
 
 	/* Check if the accessory is already inserted during boot up */
 	if (dd->ir_gpio < 0) {
-		rc = pm8058_irq_get_rt_status(dd->pm_chip, dd->othc_irq_ir);
+		rc = pm8xxx_read_irq_stat(dd->dev->parent, dd->othc_irq_ir);
 		if (rc < 0) {
 			pr_err("Unable to get accessory status at boot\n");
 			goto fail_ir_status;
@@ -1061,22 +1061,9 @@
 {
 	int rc;
 	struct pm8058_othc *dd;
-	struct pm8058_chip *chip;
 	struct resource *res;
 	struct pmic8058_othc_config_pdata *pdata = pd->dev.platform_data;
 
-	chip = dev_get_drvdata(pd->dev.parent);
-	if (chip == NULL) {
-		pr_err("Invalid driver information\n");
-		return  -EINVAL;
-	}
-
-	/* Check PMIC8058 version. A0 version is not supported */
-	if (pm8058_rev(chip) == PM_8058_REV_1p0) {
-		pr_err("PMIC8058 version not supported\n");
-		return -ENODEV;
-	}
-
 	if (pdata == NULL) {
 		pr_err("Platform data not present\n");
 		return -EINVAL;
@@ -1101,8 +1088,8 @@
 		goto fail_get_res;
 	}
 
+	dd->dev = &pd->dev;
 	dd->othc_pdata = pdata;
-	dd->pm_chip = chip;
 	dd->othc_base = res->start;
 	if (pdata->micbias_regulator == NULL) {
 		pr_err("OTHC regulator not specified\n");
diff --git a/drivers/leds/leds-pmic8058.c b/drivers/leds/leds-pmic8058.c
index d1aed3f..3b3a24a 100644
--- a/drivers/leds/leds-pmic8058.c
+++ b/drivers/leds/leds-pmic8058.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010, 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
@@ -15,7 +15,7 @@
 #include <linux/leds.h>
 #include <linux/workqueue.h>
 #include <linux/spinlock.h>
-#include <linux/mfd/pmic8058.h>
+#include <linux/mfd/pm8xxx/core.h>
 #include <linux/leds-pmic8058.h>
 
 #define SSBI_REG_ADDR_DRV_KEYPAD	0x48
@@ -41,11 +41,11 @@
 #define PMIC8058_LED_OFFSET(id) ((id) - PMIC8058_ID_LED_0)
 
 struct pmic8058_led_data {
+	struct device		*dev;
 	struct led_classdev	cdev;
 	int			id;
 	enum led_brightness	brightness;
 	u8			flags;
-	struct pm8058_chip	*pm_chip;
 	struct work_struct	work;
 	struct mutex		lock;
 	spinlock_t		value_lock;
@@ -72,8 +72,8 @@
 	led->reg_kp |= level;
 	spin_unlock_irqrestore(&led->value_lock, flags);
 
-	rc = pm8058_write(led->pm_chip, SSBI_REG_ADDR_DRV_KEYPAD,
-				 &led->reg_kp, 1);
+	rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_DRV_KEYPAD,
+						led->reg_kp);
 	if (rc)
 		pr_err("%s: can't set keypad backlight level\n", __func__);
 }
@@ -105,8 +105,8 @@
 	tmp |= level;
 	spin_unlock_irqrestore(&led->value_lock, flags);
 
-	rc = pm8058_write(led->pm_chip,	SSBI_REG_ADDR_LED_CTRL(offset),
-			&tmp, 1);
+	rc = pm8xxx_writeb(led->dev->parent, SSBI_REG_ADDR_LED_CTRL(offset),
+								tmp);
 	if (rc) {
 		dev_err(led->cdev.dev, "can't set (%d) led value\n",
 				led->id);
@@ -159,7 +159,7 @@
 	}
 	spin_unlock_irqrestore(&led->value_lock, flags);
 
-	rc = pm8058_write(led->pm_chip, reg_addr, &reg_flash_led, 1);
+	rc = pm8xxx_writeb(led->dev->parent, reg_addr, reg_flash_led);
 	if (rc)
 		pr_err("%s: can't set flash led%d level %d\n", __func__,
 			led->id, rc);
@@ -294,46 +294,38 @@
 	struct pmic8058_led_data *led_dat;
 	struct pmic8058_led *curr_led;
 	int rc, i = 0;
-	struct pm8058_chip	*pm_chip;
 	u8			reg_kp;
 	u8			reg_led_ctrl[3];
 	u8			reg_flash_led0;
 	u8			reg_flash_led1;
 
-	pm_chip = dev_get_drvdata(pdev->dev.parent);
-	if (pm_chip == NULL) {
-		dev_err(&pdev->dev, "no parent data passed in\n");
-		return -EFAULT;
-	}
-
 	if (pdata == NULL) {
 		dev_err(&pdev->dev, "platform data not supplied\n");
 		return -EINVAL;
 	}
 
-	rc = pm8058_read(pm_chip, SSBI_REG_ADDR_DRV_KEYPAD, &reg_kp,
-				1);
+	rc = pm8xxx_readb(pdev->dev.parent, SSBI_REG_ADDR_DRV_KEYPAD, &reg_kp);
 	if (rc) {
 		dev_err(&pdev->dev, "can't get keypad backlight level\n");
 		goto err_reg_read;
 	}
 
-	rc = pm8058_read(pm_chip, SSBI_REG_ADDR_LED_CTRL_BASE,
-			reg_led_ctrl, 3);
+	rc = pm8xxx_read_buf(pdev->dev.parent, SSBI_REG_ADDR_LED_CTRL_BASE,
+							reg_led_ctrl, 3);
 	if (rc) {
 		dev_err(&pdev->dev, "can't get led levels\n");
 		goto err_reg_read;
 	}
 
-	rc = pm8058_read(pm_chip, SSBI_REG_ADDR_FLASH_DRV0,
-			&reg_flash_led0, 1);
+	rc = pm8xxx_readb(pdev->dev.parent, SSBI_REG_ADDR_FLASH_DRV0,
+						&reg_flash_led0);
 	if (rc) {
 		dev_err(&pdev->dev, "can't read flash led0\n");
 		goto err_reg_read;
 	}
 
-	rc = pm8058_read(pm_chip, SSBI_REG_ADDR_FLASH_DRV1,
-			&reg_flash_led1, 1);
+	rc = pm8xxx_readb(pdev->dev.parent, SSBI_REG_ADDR_FLASH_DRV1,
+						&reg_flash_led1);
 	if (rc) {
 		dev_err(&pdev->dev, "can't get flash led1\n");
 		goto err_reg_read;
@@ -366,7 +358,7 @@
 			goto fail_id_check;
 		}
 
-		led_dat->pm_chip		= pm_chip;
+		led_dat->dev			= &pdev->dev;
 
 		mutex_init(&led_dat->lock);
 		spin_lock_init(&led_dat->value_lock);
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index a4feb838..c27fea6 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -157,6 +157,7 @@
 	tristate "PMIC8058 Power Management chip"
 	depends on MSM_SSBI
 	select MFD_CORE
+	select MFD_PM8XXX
 	select MSM_SHOW_RESUME_IRQ
 	help
 	  Say yes here for Qualcomm PM8058 chip.
diff --git a/drivers/mfd/pmic8058.c b/drivers/mfd/pmic8058.c
index 85c8a9d..77e393e 100644
--- a/drivers/mfd/pmic8058.c
+++ b/drivers/mfd/pmic8058.c
@@ -14,55 +14,32 @@
  * Qualcomm PMIC8058 driver
  *
  */
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/ratelimit.h>
-#include <linux/kthread.h>
+#include <linux/irq.h>
 #include <linux/msm_ssbi.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/pmic8058.h>
-#include <linux/platform_device.h>
-#include <linux/ratelimit.h>
-#include <linux/slab.h>
-#include <linux/debugfs.h>
-#include <linux/irq.h>
-#include <linux/syscore_ops.h>
-#include <linux/gpio.h>
+#include <linux/mfd/pm8xxx/core.h>
+#include <linux/msm_adc.h>
+
+#define REG_MPP_BASE			0x50
 
 /* PMIC8058 Revision */
-#define SSBI_REG_REV			0x002  /* PMIC4 revision */
+#define PM8058_REG_REV			0x002  /* PMIC4 revision */
+#define PM8058_VERSION_MASK		0xF0
+#define PM8058_REVISION_MASK		0x0F
+#define PM8058_VERSION_VALUE		0xE0
 
-/* PMIC8058 IRQ */
-#define	SSBI_REG_ADDR_IRQ_BASE		0x1BB
+/* PMIC 8058 Battery Alarm SSBI registers */
+#define REG_BATT_ALARM_THRESH		0x023
+#define REG_BATT_ALARM_CTRL1		0x024
+#define REG_BATT_ALARM_CTRL2		0x0AA
+#define REG_BATT_ALARM_PWM_CTRL		0x0A3
 
-#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	PM8058_IRQF_LVL_SEL		0x01	/* level select */
-#define	PM8058_IRQF_MASK_FE		0x02	/* mask falling edge */
-#define	PM8058_IRQF_MASK_RE		0x04	/* mask rising edge */
-#define	PM8058_IRQF_CLR			0x08	/* clear interrupt */
-#define	PM8058_IRQF_BITS_MASK		0x70
-#define	PM8058_IRQF_BITS_SHIFT		4
-#define	PM8058_IRQF_WRITE		0x80
-
-#define	PM8058_IRQF_MASK_ALL		(PM8058_IRQF_MASK_FE | \
-					PM8058_IRQF_MASK_RE)
-#define PM8058_IRQF_W_C_M		(PM8058_IRQF_WRITE |	\
-					PM8058_IRQF_CLR |	\
-					PM8058_IRQF_MASK_ALL)
-
-/* MISC register */
-#define	SSBI_REG_ADDR_MISC		0x1CC
+#define REG_TEMP_ALRM_CTRL		0x1B
+#define REG_TEMP_ALRM_PWM		0x9B
 
 /* PON CNTL 1 register */
 #define SSBI_REG_ADDR_PON_CNTL_1	0x01C
@@ -138,53 +115,32 @@
 /* GP_TEST1 register */
 #define SSBI_REG_ADDR_GP_TEST_1		0x07A
 
-/* IRQ */
-#define	MAX_PM_IRQ		256
-#define	MAX_PM_BLOCKS		(MAX_PM_IRQ / 8 + 1)
-#define	MAX_PM_MASTERS		(MAX_PM_BLOCKS / 8 + 1)
+#define PM8058_RTC_BASE			0x1E8
+#define PM8058_OTHC_CNTR_BASE0		0xA0
+#define PM8058_OTHC_CNTR_BASE1		0x134
+#define PM8058_OTHC_CNTR_BASE2		0x137
+
+#define SINGLE_IRQ_RESOURCE(_name, _irq) \
+{ \
+	.name	= _name, \
+	.start	= _irq, \
+	.end	= _irq, \
+	.flags	= IORESOURCE_IRQ, \
+}
 
 struct pm8058_chip {
 	struct pm8058_platform_data	pdata;
 	struct device		*dev;
+	struct pm_irq_chip	*irq_chip;
+	struct mfd_cell         *mfd_regulators, *mfd_xo_buffers;
 
-	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	bus_unlock_config[MAX_PM_IRQ];
-	u8	wake_enable[MAX_PM_IRQ];
-	u16	count_wakeable;
-
-	u8	revision;
+	u8		revision;
 
 	struct mutex	pm_lock;
 };
 
-#if defined(CONFIG_DEBUG_FS)
-struct pm8058_dbg_device {
-	struct mutex		dbg_mutex;
-	struct pm8058_chip	*pm_chip;
-	struct dentry		*dent;
-	int			addr;
-};
-
-static struct pm8058_dbg_device *pmic_dbg_device;
-#endif
-
 static struct pm8058_chip *pmic_chip;
 
-/* Helper Functions */
-DEFINE_RATELIMIT_STATE(pm8058_msg_ratelimit, 60 * HZ, 10);
-
-static inline int pm8058_can_print(void)
-{
-	return __ratelimit(&pm8058_msg_ratelimit);
-}
-
 static inline int
 ssbi_read(struct device *dev, u16 addr, u8 *buf, size_t len)
 {
@@ -223,111 +179,6 @@
 	return rc;
 }
 
-/* External APIs */
-int pm8058_rev(struct pm8058_chip *chip)
-{
-	if (chip == NULL)
-		return -EINVAL;
-
-	return chip->revision;
-}
-EXPORT_SYMBOL(pm8058_rev);
-
-int pm8058_irq_get_rt_status(struct pm8058_chip *chip, int irq)
-{
-	int     rc;
-	u8      block, bits, bit;
-
-	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;
-
-	mutex_lock(&chip->pm_lock);
-
-	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:
-	mutex_unlock(&chip->pm_lock);
-
-	return rc;
-}
-EXPORT_SYMBOL(pm8058_irq_get_rt_status);
-
-int pm8058_read(struct pm8058_chip *chip, u16 addr, u8 *values,
-		unsigned int len)
-{
-	if (chip == NULL)
-		return -EINVAL;
-
-	return ssbi_read(chip->dev, addr, values, len);
-}
-EXPORT_SYMBOL(pm8058_read);
-
-int pm8058_write(struct pm8058_chip *chip, u16 addr, u8 *values,
-		 unsigned int len)
-{
-	if (chip == NULL)
-		return -EINVAL;
-
-	return ssbi_write(chip->dev, addr, values, len);
-}
-EXPORT_SYMBOL(pm8058_write);
-
-int pm8058_misc_control(struct pm8058_chip *chip, int mask, int flag)
-{
-	int		rc;
-	u8		misc;
-
-	if (chip == NULL)
-		chip = pmic_chip;	/* for calls from non child */
-	if (chip == NULL)
-		return -ENODEV;
-
-	mutex_lock(&chip->pm_lock);
-
-	rc = ssbi_read(chip->dev, SSBI_REG_ADDR_MISC, &misc, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n",
-		       __func__, SSBI_REG_ADDR_MISC, rc);
-		goto get_out;
-	}
-
-	misc &= ~mask;
-	misc |= flag;
-
-	rc = ssbi_write(chip->dev, SSBI_REG_ADDR_MISC, &misc, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n",
-		       __func__, SSBI_REG_ADDR_MISC, misc, rc);
-		goto get_out;
-	}
-
-get_out:
-	mutex_unlock(&chip->pm_lock);
-
-	return rc;
-}
-EXPORT_SYMBOL(pm8058_misc_control);
-
 /**
  * pm8058_smpl_control - enables/disables SMPL detection
  * @enable: 0 = shutdown PMIC on power loss, 1 = reset PMIC on power loss
@@ -713,765 +564,694 @@
 }
 EXPORT_SYMBOL(pm8058_hard_reset_config);
 
-/* Internal functions */
-static inline int
-pm8058_config_irq(struct pm8058_chip *chip, u8 *bp, u8 *cp)
+static int pm8058_readb(const struct device *dev, u16 addr, u8 *val)
 {
-	int	rc;
+	const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+	const struct pm8058_chip *pmic = pm8058_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 pm8058_irq_mask(struct irq_data *data)
+static int pm8058_writeb(const struct device *dev, u16 addr, u8 val)
 {
-	int	master, irq_bit;
-	struct	pm8058_chip *chip = irq_data_get_irq_chip_data(data);
-	u8	block, config;
-	unsigned int irq = data->irq;
+	const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+	const struct pm8058_chip *pmic = pm8058_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 = PM8058_IRQF_WRITE | chip->config[irq] |
-		PM8058_IRQF_MASK_FE | PM8058_IRQF_MASK_RE;
-	chip->bus_unlock_config[irq] = config;
+	return msm_ssbi_write(pmic->dev->parent, addr, &val, 1);
 }
 
-static void pm8058_irq_unmask(struct irq_data *data)
+static int pm8058_read_buf(const struct device *dev, u16 addr, u8 *buf,
+								int cnt)
 {
-	int	master, irq_bit;
-	struct	pm8058_chip *chip = irq_data_get_irq_chip_data(data);
-	u8	block, config, old_irqs_allowed, old_blocks_allowed;
-	unsigned int irq = data->irq;
+	const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+	const struct pm8058_chip *pmic = pm8058_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];
-	if (old_irqs_allowed & (1 << irq_bit)) {
-		pr_debug("%s: no need to enable an already enabled irq=%d\n",
-					__func__, irq + chip->pdata.irq_base);
-		return;
-	}
-
-	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 = PM8058_IRQF_WRITE | chip->config[irq];
-	chip->bus_unlock_config[irq] = config;
+	return msm_ssbi_read(pmic->dev->parent, addr, buf, cnt);
 }
 
-static void pm8058_irq_ack(struct irq_data *data)
+static int pm8058_write_buf(const struct device *dev, u16 addr, u8 *buf,
+								int cnt)
 {
-	struct	pm8058_chip *chip = irq_data_get_irq_chip_data(data);
-	u8	block, config;
-	unsigned int irq = data->irq;
+	const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+	const struct pm8058_chip *pmic = pm8058_drvdata->pm_chip_data;
 
-	irq -= chip->pdata.irq_base;
-	block = irq / 8;
-
-	config = PM8058_IRQF_WRITE | chip->config[irq] | PM8058_IRQF_CLR;
-	/* Keep the mask */
-	if (!(chip->irqs_allowed[block] & (1 << (irq % 8))))
-		config |= PM8058_IRQF_MASK_FE | PM8058_IRQF_MASK_RE;
-	chip->bus_unlock_config[irq] = config;
+	return msm_ssbi_write(pmic->dev->parent, addr, buf, cnt);
 }
 
-static int pm8058_irq_set_type(struct irq_data *data, unsigned int flow_type)
+static int pm8058_read_irq_stat(const struct device *dev, int irq)
 {
-	int	master, irq_bit;
-	struct	pm8058_chip *chip = irq_data_get_irq_chip_data(data);
-	u8	block, config;
-	unsigned int irq = data->irq;
+	const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+	const struct pm8058_chip *pmic = pm8058_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 << PM8058_IRQF_BITS_SHIFT) |
-			PM8058_IRQF_MASK_RE | PM8058_IRQF_MASK_FE;
-	if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
-		if (flow_type & IRQF_TRIGGER_RISING)
-			chip->config[irq] &= ~PM8058_IRQF_MASK_RE;
-		if (flow_type & IRQF_TRIGGER_FALLING)
-			chip->config[irq] &= ~PM8058_IRQF_MASK_FE;
-	} else {
-		chip->config[irq] |= PM8058_IRQF_LVL_SEL;
-
-		if (flow_type & IRQF_TRIGGER_HIGH)
-			chip->config[irq] &= ~PM8058_IRQF_MASK_RE;
-		else
-			chip->config[irq] &= ~PM8058_IRQF_MASK_FE;
-	}
-
-	config = PM8058_IRQF_WRITE | chip->config[irq] | PM8058_IRQF_CLR;
-	chip->bus_unlock_config[irq] = config;
-	return 0;
-}
-
-static int pm8058_irq_set_wake(struct irq_data *data, unsigned int on)
-{
-	struct	pm8058_chip *chip = irq_data_get_irq_chip_data(data);
-	unsigned int irq = data->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 void pm8058_irq_bus_lock(struct irq_data *data)
+static enum pm8xxx_version pm8058_get_version(const struct device *dev)
 {
-	u8	block;
-	struct	pm8058_chip *chip = irq_data_get_irq_chip_data(data);
-	unsigned int irq = data->irq;
+	const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+	const struct pm8058_chip *pmic = pm8058_drvdata->pm_chip_data;
+	enum pm8xxx_version version = -ENODEV;
 
-	irq -= chip->pdata.irq_base;
-	block = irq / 8;
-	chip->bus_unlock_config[irq] = 0;
+	if ((pmic->revision & PM8058_VERSION_MASK) == PM8058_VERSION_VALUE)
+		version = PM8XXX_VERSION_8058;
 
-	mutex_lock(&chip->pm_lock);
+	return version;
 }
 
-static void pm8058_irq_bus_sync_unlock(struct irq_data *data)
+static int pm8058_get_revision(const struct device *dev)
 {
-	u8	block, config;
-	struct	pm8058_chip *chip = irq_data_get_irq_chip_data(data);
-	unsigned int irq = data->irq;
+	const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+	const struct pm8058_chip *pmic = pm8058_drvdata->pm_chip_data;
 
-	irq -= chip->pdata.irq_base;
-	block = irq / 8;
-	config = chip->bus_unlock_config[irq];
-	/* dont waste cpu cycles if we dont have data to write */
-	if (config)
-		pm8058_config_irq(chip, &block, &config);
-	mutex_unlock(&chip->pm_lock);
+	return pmic->revision & PM8058_REVISION_MASK;
 }
 
-static inline int
-pm8058_read_root(struct pm8058_chip *chip, u8 *rp)
-{
-	int	rc;
-
-	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;
-	}
-
-	return rc;
-}
-
-static inline int
-pm8058_read_master(struct pm8058_chip *chip, u8 m, u8 *bp)
-{
-	int	rc;
-
-	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;
-}
-
-static inline int
-pm8058_read_block(struct pm8058_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 pm8058_isr_thread(int irq_requested, void *data)
-{
-	struct pm8058_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];
-
-	mutex_lock(&chip->pm_lock);
-
-	/* Read root for masters */
-	if (pm8058_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 (pm8058_read_master(chip, i, &blocks[i]))
-				goto bail_out;
-
-			if (!blocks[i]) {
-				if (pm8058_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 (pm8058_read_block(chip, &block, &bits))
-				goto bail_out;
-
-			if (!bits) {
-				if (pm8058_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 = PM8058_IRQF_W_C_M |
-						(k << PM8058_IRQF_BITS_SHIFT);
-
-					pm8058_config_irq(chip,
-							  &block, &config);
-
-					if (pm8058_can_print())
-						pr_err("%s: Spurious IRQ: "
-						       "[master, block, bit]="
-						       "[%d, %d (%d), %d]\n",
-							__func__,
-						       i, j, block, k);
-					spurious++;
-				}
-			}
-		}
-
-	}
-
-bail_out:
-
-	mutex_unlock(&chip->pm_lock);
-
-	for (i = 0; i < handled; i++) {
-		int pmic_irq = irqs_to_handle[i] - chip->pdata.irq_base;
-
-		/* ack the interrupt first */
-		block  = pmic_irq / 8 ;
-		config = PM8058_IRQF_WRITE | chip->config[pmic_irq]
-				| PM8058_IRQF_CLR;
-		pm8058_config_irq(chip, &block, &config);
-
-		/* calle the action handler */
-		handle_nested_irq(irqs_to_handle[i]);
-	}
-
-	if (spurious) {
-		if (!pm8058_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 8058 register address is invalid: %d\n",
-			func_name, addr);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int data_set(void *data, u64 val)
-{
-	struct pm8058_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 = pm8058_write(dbgdev->pm_chip, dbgdev->addr, &reg, 1);
-
-	if (rc)
-		pr_err("%s: FAIL pm8058_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 pm8058_dbg_device *dbgdev = data;
-	int rc;
-	u8 reg;
-
-	mutex_lock(&dbgdev->dbg_mutex);
-
-	rc = check_addr(dbgdev->addr, __func__);
-	if (rc)
-		goto done;
-
-	rc = pm8058_read(dbgdev->pm_chip, dbgdev->addr, &reg, 1);
-
-	if (rc) {
-		pr_err("%s: FAIL pm8058_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 pm8058_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 pm8058_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 pmic8058_dbg_probe(struct pm8058_chip *chip)
-{
-	struct pm8058_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("pm8058-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 pmic8058_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 pmic8058_dbg_probe(struct pm8058_chip *chip)
-{
-	return 0;
-}
-
-static int __devexit pmic8058_dbg_remove(void)
-{
-	return 0;
-}
-
-#endif
-
-static struct irq_chip pm8058_irq_chip = {
-	.name      = "pm8058",
-	.irq_ack	= pm8058_irq_ack,
-	.irq_mask	= pm8058_irq_mask,
-	.irq_unmask	= pm8058_irq_unmask,
-	.irq_set_type	= pm8058_irq_set_type,
-	.irq_set_wake	= pm8058_irq_set_wake,
-	.irq_bus_lock	= pm8058_irq_bus_lock,
-	.irq_bus_sync_unlock	= pm8058_irq_bus_sync_unlock,
+static struct pm8xxx_drvdata pm8058_drvdata = {
+	.pmic_readb		= pm8058_readb,
+	.pmic_writeb		= pm8058_writeb,
+	.pmic_read_buf		= pm8058_read_buf,
+	.pmic_write_buf		= pm8058_write_buf,
+	.pmic_read_irq_stat	= pm8058_read_irq_stat,
+	.pmic_get_version	= pm8058_get_version,
+	.pmic_get_revision	= pm8058_get_revision,
 };
 
-static int pm8058_suspend(void)
-{
-	struct	pm8058_chip *chip = pmic_chip;
-	struct irq_data *data;
-	int	i;
-
-	for (i = 0; i < MAX_PM_IRQ; i++) {
-		if (chip->config[i] && !chip->wake_enable[i]) {
-			if (!((chip->config[i] & PM8058_IRQF_MASK_ALL)
-			      == PM8058_IRQF_MASK_ALL)) {
-				data = irq_get_irq_data(i +
-						chip->pdata.irq_base);
-				pm8058_irq_bus_lock(data);
-				pm8058_irq_mask(data);
-				pm8058_irq_bus_sync_unlock(data);
-			}
-		}
-	}
-
-	if (!chip->count_wakeable)
-		disable_irq(chip->pdata.irq);
-
-	return 0;
-}
-
-extern int msm_show_resume_irq_mask;
-
-static void pm8058_show_resume_irq(void)
-{
-	u8	block, bits;
-	int i;
-	struct pm8058_chip *chip = pmic_chip;
-
-	if (!msm_show_resume_irq_mask)
-		return;
-
-	for (i = 0; i < MAX_PM_IRQ; i++) {
-		if (chip->wake_enable[i]) {
-			block = i / 8;
-			if (!pm8058_read_block(chip, &block, &bits)) {
-				if (bits & (1 << (i & 0x7)))
-					pr_warning("%s:%d triggered\n",
-					__func__, i + chip->pdata.irq_base);
-			}
-		}
-	}
-}
-
-static void pm8058_resume(void)
-{
-	struct	pm8058_chip *chip = pmic_chip;
-	struct irq_data *data;
-	int	i;
-
-	pm8058_show_resume_irq();
-
-	for (i = 0; i < MAX_PM_IRQ; i++) {
-		if (chip->config[i] && !chip->wake_enable[i]) {
-			if (!((chip->config[i] & PM8058_IRQF_MASK_ALL)
-			      == PM8058_IRQF_MASK_ALL)) {
-				data = irq_get_irq_data(i +
-						chip->pdata.irq_base);
-				pm8058_irq_bus_lock(data);
-				pm8058_irq_unmask(data);
-				pm8058_irq_bus_sync_unlock(data);
-			}
-		}
-	}
-
-	if (!chip->count_wakeable)
-		enable_irq(chip->pdata.irq);
-}
-
-static struct syscore_ops pm8058_pm = {
-	.suspend = pm8058_suspend,
-	.resume = pm8058_resume,
+static const struct resource pm8058_charger_resources[] __devinitconst = {
+	SINGLE_IRQ_RESOURCE("CHGVAL",		PM8058_CHGVAL_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGINVAL",		PM8058_CHGINVAL_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGILIM",		PM8058_CHGILIM_IRQ),
+	SINGLE_IRQ_RESOURCE("VCP",		PM8058_VCP_IRQ),
+	SINGLE_IRQ_RESOURCE("ATC_DONE",		PM8058_ATC_DONE_IRQ),
+	SINGLE_IRQ_RESOURCE("ATCFAIL",		PM8058_ATCFAIL_IRQ),
+	SINGLE_IRQ_RESOURCE("AUTO_CHGDONE",	PM8058_AUTO_CHGDONE_IRQ),
+	SINGLE_IRQ_RESOURCE("AUTO_CHGFAIL",	PM8058_AUTO_CHGFAIL_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGSTATE",		PM8058_CHGSTATE_IRQ),
+	SINGLE_IRQ_RESOURCE("FASTCHG",		PM8058_FASTCHG_IRQ),
+	SINGLE_IRQ_RESOURCE("CHG_END",		PM8058_CHG_END_IRQ),
+	SINGLE_IRQ_RESOURCE("BATTTEMP",		PM8058_BATTTEMP_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGHOT",		PM8058_CHGHOT_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGTLIMIT",	PM8058_CHGTLIMIT_IRQ),
+	SINGLE_IRQ_RESOURCE("CHG_GONE",		PM8058_CHG_GONE_IRQ),
+	SINGLE_IRQ_RESOURCE("VCPMAJOR",		PM8058_VCPMAJOR_IRQ),
+	SINGLE_IRQ_RESOURCE("VBATDET",		PM8058_VBATDET_IRQ),
+	SINGLE_IRQ_RESOURCE("BATFET",		PM8058_BATFET_IRQ),
+	SINGLE_IRQ_RESOURCE("BATT_REPLACE",	PM8058_BATT_REPLACE_IRQ),
+	SINGLE_IRQ_RESOURCE("BATTCONNECT",	PM8058_BATTCONNECT_IRQ),
+	SINGLE_IRQ_RESOURCE("VBATDET_LOW",	PM8058_VBATDET_LOW_IRQ),
 };
 
+static struct mfd_cell pm8058_charger_cell __devinitdata = {
+	.name		= "pm8058-charger",
+	.id		= -1,
+	.resources	= pm8058_charger_resources,
+	.num_resources	= ARRAY_SIZE(pm8058_charger_resources),
+};
+
+static const struct resource misc_cell_resources[] __devinitconst = {
+	SINGLE_IRQ_RESOURCE("pm8xxx_osc_halt_irq", PM8058_OSCHALT_IRQ),
+};
+
+static struct mfd_cell misc_cell __devinitdata = {
+	.name		= PM8XXX_MISC_DEV_NAME,
+	.id		= -1,
+	.resources	= misc_cell_resources,
+	.num_resources	= ARRAY_SIZE(misc_cell_resources),
+};
+
+static struct mfd_cell pm8058_pwm_cell __devinitdata = {
+	.name		= "pm8058-pwm",
+	.id		= -1,
+};
+
+static struct resource xoadc_resources[] = {
+	SINGLE_IRQ_RESOURCE(NULL, PM8058_ADC_IRQ),
+};
+
+static struct mfd_cell xoadc_cell __devinitdata = {
+	.name		= "pm8058-xoadc",
+	.id		= -1,
+	.resources	= xoadc_resources,
+	.num_resources	= ARRAY_SIZE(xoadc_resources),
+};
+
+static const struct resource thermal_alarm_cell_resources[] __devinitconst = {
+	SINGLE_IRQ_RESOURCE("pm8058_tempstat_irq", PM8058_TEMPSTAT_IRQ),
+	SINGLE_IRQ_RESOURCE("pm8058_overtemp_irq", PM8058_OVERTEMP_IRQ),
+};
+
+static struct pm8xxx_tm_core_data thermal_alarm_cdata = {
+	.adc_channel			= CHANNEL_ADC_DIE_TEMP,
+	.adc_type			= PM8XXX_TM_ADC_PM8058_ADC,
+	.reg_addr_temp_alarm_ctrl	= REG_TEMP_ALRM_CTRL,
+	.reg_addr_temp_alarm_pwm	= REG_TEMP_ALRM_PWM,
+	.tm_name			= "pm8058_tz",
+	.irq_name_temp_stat		= "pm8058_tempstat_irq",
+	.irq_name_over_temp		= "pm8058_overtemp_irq",
+};
+
+static struct mfd_cell thermal_alarm_cell __devinitdata = {
+	.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 struct mfd_cell debugfs_cell __devinitdata = {
+	.name		= "pm8xxx-debug",
+	.id		= -1,
+	.platform_data	= "pm8058-dbg",
+	.pdata_size	= sizeof("pm8058-dbg"),
+};
+
+static const struct resource othc0_cell_resources[] __devinitconst = {
+	{
+		.name	= "othc_base",
+		.start	= PM8058_OTHC_CNTR_BASE0,
+		.end	= PM8058_OTHC_CNTR_BASE0,
+		.flags	= IORESOURCE_IO,
+	},
+};
+
+static const struct resource othc1_cell_resources[] __devinitconst = {
+	SINGLE_IRQ_RESOURCE(NULL, PM8058_SW_1_IRQ),
+	SINGLE_IRQ_RESOURCE(NULL, PM8058_IR_1_IRQ),
+	{
+		.name	= "othc_base",
+		.start	= PM8058_OTHC_CNTR_BASE1,
+		.end	= PM8058_OTHC_CNTR_BASE1,
+		.flags	= IORESOURCE_IO,
+	},
+};
+
+static const struct resource othc2_cell_resources[] __devinitconst = {
+	{
+		.name	= "othc_base",
+		.start	= PM8058_OTHC_CNTR_BASE2,
+		.end	= PM8058_OTHC_CNTR_BASE2,
+		.flags	= IORESOURCE_IO,
+	},
+};
+
+static const struct resource batt_alarm_cell_resources[] __devinitconst = {
+	SINGLE_IRQ_RESOURCE("pm8058_batt_alarm_irq", PM8058_BATT_ALARM_IRQ),
+};
+
+static struct mfd_cell leds_cell __devinitdata = {
+	.name		= "pm8058-led",
+	.id		= -1,
+};
+
+static struct mfd_cell othc0_cell __devinitdata = {
+	.name		= "pm8058-othc",
+	.id		= 0,
+	.resources	= othc0_cell_resources,
+	.num_resources  = ARRAY_SIZE(othc0_cell_resources),
+};
+
+static struct mfd_cell othc1_cell __devinitdata = {
+	.name		= "pm8058-othc",
+	.id		= 1,
+	.resources	= othc1_cell_resources,
+	.num_resources  = ARRAY_SIZE(othc1_cell_resources),
+};
+
+static struct mfd_cell othc2_cell __devinitdata = {
+	.name		= "pm8058-othc",
+	.id		= 2,
+	.resources	= othc2_cell_resources,
+	.num_resources  = ARRAY_SIZE(othc2_cell_resources),
+};
+
+static struct pm8xxx_batt_alarm_core_data batt_alarm_cdata = {
+	.irq_name		= "pm8058_batt_alarm_irq",
+	.reg_addr_threshold	= REG_BATT_ALARM_THRESH,
+	.reg_addr_ctrl1		= REG_BATT_ALARM_CTRL1,
+	.reg_addr_ctrl2		= REG_BATT_ALARM_CTRL2,
+	.reg_addr_pwm_ctrl	= REG_BATT_ALARM_PWM_CTRL,
+};
+
+static struct mfd_cell batt_alarm_cell __devinitdata = {
+	.name		= PM8XXX_BATT_ALARM_DEV_NAME,
+	.id		= -1,
+	.resources	= batt_alarm_cell_resources,
+	.num_resources	= ARRAY_SIZE(batt_alarm_cell_resources),
+	.platform_data	= &batt_alarm_cdata,
+	.pdata_size	= sizeof(struct pm8xxx_batt_alarm_core_data),
+};
+
+static struct mfd_cell upl_cell __devinitdata = {
+	.name		= PM8XXX_UPL_DEV_NAME,
+	.id		= -1,
+};
+
+static struct mfd_cell nfc_cell __devinitdata = {
+	.name		= PM8XXX_NFC_DEV_NAME,
+	.id		= -1,
+};
+
+static const struct resource rtc_cell_resources[] __devinitconst = {
+	[0] = SINGLE_IRQ_RESOURCE(NULL, PM8058_RTC_ALARM_IRQ),
+	[1] = {
+		.name   = "pmic_rtc_base",
+		.start  = PM8058_RTC_BASE,
+		.end    = PM8058_RTC_BASE,
+		.flags  = IORESOURCE_IO,
+	},
+};
+
+static struct mfd_cell rtc_cell __devinitdata = {
+	.name		= PM8XXX_RTC_DEV_NAME,
+	.id		= -1,
+	.resources	= rtc_cell_resources,
+	.num_resources  = ARRAY_SIZE(rtc_cell_resources),
+};
+
+static const struct resource resources_pwrkey[] __devinitconst = {
+	SINGLE_IRQ_RESOURCE(NULL, PM8058_PWRKEY_REL_IRQ),
+	SINGLE_IRQ_RESOURCE(NULL, PM8058_PWRKEY_PRESS_IRQ),
+};
+
+static struct mfd_cell vibrator_cell __devinitdata = {
+	.name		= PM8XXX_VIBRATOR_DEV_NAME,
+	.id		= -1,
+};
+
+static struct mfd_cell pwrkey_cell __devinitdata = {
+	.name		= PM8XXX_PWRKEY_DEV_NAME,
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(resources_pwrkey),
+	.resources	= resources_pwrkey,
+};
+
+static const struct resource resources_keypad[] = {
+	SINGLE_IRQ_RESOURCE(NULL, PM8058_KEYPAD_IRQ),
+	SINGLE_IRQ_RESOURCE(NULL, PM8058_KEYSTUCK_IRQ),
+};
+
+static struct mfd_cell keypad_cell __devinitdata = {
+	.name		= PM8XXX_KEYPAD_DEV_NAME,
+	.id		= -1,
+	.num_resources  = ARRAY_SIZE(resources_keypad),
+	.resources	= resources_keypad,
+};
+
+static const struct resource mpp_cell_resources[] __devinitconst = {
+	{
+		.start	= PM8058_IRQ_BLOCK_BIT(PM8058_MPP_BLOCK_START, 0),
+		.end	= PM8058_IRQ_BLOCK_BIT(PM8058_MPP_BLOCK_START, 0)
+			  + PM8058_MPPS - 1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mfd_cell mpp_cell __devinitdata = {
+	.name		= PM8XXX_MPP_DEV_NAME,
+	.id		= 0,
+	.resources	= mpp_cell_resources,
+	.num_resources	= ARRAY_SIZE(mpp_cell_resources),
+};
+
+static const struct resource gpio_cell_resources[] __devinitconst = {
+	[0] = {
+		.start = PM8058_IRQ_BLOCK_BIT(PM8058_GPIO_BLOCK_START, 0),
+		.end   = PM8058_IRQ_BLOCK_BIT(PM8058_GPIO_BLOCK_START, 0)
+			+ PM8058_GPIOS - 1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct mfd_cell gpio_cell __devinitdata = {
+	.name		= PM8XXX_GPIO_DEV_NAME,
+	.id		= -1,
+	.resources	= gpio_cell_resources,
+	.num_resources	= ARRAY_SIZE(gpio_cell_resources),
+};
+
+static int __devinit
+pm8058_add_subdevices(const struct pm8058_platform_data *pdata,
+				struct pm8058_chip *pmic)
+{
+	int rc = 0, irq_base = 0, i;
+	struct pm_irq_chip *irq_chip;
+	static struct mfd_cell *mfd_regulators, *mfd_xo_buffers;
+
+	if (pdata->irq_pdata) {
+		pdata->irq_pdata->irq_cdata.nirqs = PM8058_NR_IRQS;
+		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->gpio_pdata) {
+		pdata->gpio_pdata->gpio_cdata.ngpios = PM8058_GPIOS;
+		gpio_cell.platform_data = pdata->gpio_pdata;
+		gpio_cell.pdata_size = sizeof(struct pm8xxx_gpio_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &gpio_cell, 1,
+					NULL, irq_base);
+		if (rc) {
+			pr_err("Failed to add  gpio subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->mpp_pdata) {
+		pdata->mpp_pdata->core_data.nmpps = PM8058_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 pm8058 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 = "pm8058-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 pm8058_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;
+	}
+
+	if (pdata->num_xo_buffers > 0 && pdata->xo_buffer_pdata) {
+		mfd_xo_buffers = kzalloc(sizeof(struct mfd_cell)
+					 * (pdata->num_xo_buffers), GFP_KERNEL);
+		if (!mfd_xo_buffers) {
+			pr_err("Cannot allocate %d bytes for pm8058 XO buffer "
+				"mfd cells\n", sizeof(struct mfd_cell)
+						* (pdata->num_xo_buffers));
+			rc = -ENOMEM;
+			goto bail;
+		}
+		for (i = 0; i < pdata->num_xo_buffers; i++) {
+			mfd_xo_buffers[i].name = PM8058_XO_BUFFER_DEV_NAME;
+			mfd_xo_buffers[i].id = pdata->xo_buffer_pdata[i].id;
+			mfd_xo_buffers[i].platform_data =
+				&(pdata->xo_buffer_pdata[i]);
+			mfd_xo_buffers[i].pdata_size =
+					sizeof(struct pm8058_xo_pdata);
+		}
+		rc = mfd_add_devices(pmic->dev, 0, mfd_xo_buffers,
+				pdata->num_xo_buffers, NULL, irq_base);
+		if (rc) {
+			pr_err("Failed to add XO buffer subdevices ret=%d\n",
+				rc);
+			kfree(mfd_xo_buffers);
+			goto bail;
+		}
+		pmic->mfd_xo_buffers = mfd_xo_buffers;
+	}
+
+	if (pdata->keypad_pdata) {
+		keypad_cell.platform_data = pdata->keypad_pdata;
+		keypad_cell.pdata_size =
+			sizeof(struct pm8xxx_keypad_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &keypad_cell, 1, NULL,
+					irq_base);
+		if (rc) {
+			pr_err("Failed to add keypad subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->rtc_pdata) {
+		rtc_cell.platform_data = pdata->rtc_pdata;
+		rtc_cell.pdata_size = sizeof(struct pm8xxx_rtc_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &rtc_cell, 1, NULL,
+						irq_base);
+		if (rc) {
+			pr_err("Failed to add rtc subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->pwrkey_pdata) {
+		pwrkey_cell.platform_data = pdata->pwrkey_pdata;
+		pwrkey_cell.pdata_size =
+			sizeof(struct pm8xxx_pwrkey_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &pwrkey_cell, 1, NULL,
+							irq_base);
+		if (rc) {
+			pr_err("Failed to add pwrkey subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->vibrator_pdata) {
+		vibrator_cell.platform_data = pdata->vibrator_pdata;
+		vibrator_cell.pdata_size =
+				sizeof(struct pm8xxx_vibrator_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &vibrator_cell, 1, NULL,
+								irq_base);
+		if (rc) {
+			pr_err("Failed to add vibrator subdevice ret=%d\n",
+									rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->leds_pdata) {
+		leds_cell.platform_data = pdata->leds_pdata;
+		leds_cell.pdata_size =
+			sizeof(struct pmic8058_leds_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &leds_cell, 1, NULL,
+								irq_base);
+		if (rc) {
+			pr_err("Failed to add leds subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->xoadc_pdata) {
+		xoadc_cell.platform_data = pdata->xoadc_pdata;
+		xoadc_cell.pdata_size =
+			sizeof(struct xoadc_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &xoadc_cell, 1, NULL,
+								irq_base);
+		if (rc) {
+			pr_err("Failed to add leds subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->othc0_pdata) {
+		othc0_cell.platform_data = pdata->othc0_pdata;
+		othc0_cell.pdata_size =
+			sizeof(struct pmic8058_othc_config_pdata);
+		rc = mfd_add_devices(pmic->dev, 0, &othc0_cell, 1, NULL, 0);
+		if (rc) {
+			pr_err("Failed to add othc0 subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->othc1_pdata) {
+		othc1_cell.platform_data = pdata->othc1_pdata;
+		othc1_cell.pdata_size =
+			sizeof(struct pmic8058_othc_config_pdata);
+		rc = mfd_add_devices(pmic->dev, 0, &othc1_cell, 1, NULL,
+								irq_base);
+		if (rc) {
+			pr_err("Failed to add othc1 subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->othc2_pdata) {
+		othc2_cell.platform_data = pdata->othc2_pdata;
+		othc2_cell.pdata_size =
+			sizeof(struct pmic8058_othc_config_pdata);
+		rc = mfd_add_devices(pmic->dev, 0, &othc2_cell, 1, NULL, 0);
+		if (rc) {
+			pr_err("Failed to add othc2 subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->pwm_pdata) {
+		pm8058_pwm_cell.platform_data = pdata->pwm_pdata;
+		pm8058_pwm_cell.pdata_size = sizeof(struct pm8058_pwm_pdata);
+		rc = mfd_add_devices(pmic->dev, 0, &pm8058_pwm_cell, 1, NULL,
+								irq_base);
+		if (rc) {
+			pr_err("Failed to add pwm subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->misc_pdata) {
+		misc_cell.platform_data = pdata->misc_pdata;
+		misc_cell.pdata_size = sizeof(struct pm8xxx_misc_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &misc_cell, 1, NULL,
+				      irq_base);
+		if (rc) {
+			pr_err("Failed to add  misc subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	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, &batt_alarm_cell, 1, NULL,
+				irq_base);
+	if (rc) {
+		pr_err("Failed to add battery alarm subdevice ret=%d\n",
+			rc);
+		goto bail;
+	}
+
+	rc = mfd_add_devices(pmic->dev, 0, &upl_cell, 1, NULL, 0);
+	if (rc) {
+		pr_err("Failed to add upl subdevice ret=%d\n", rc);
+		goto bail;
+	}
+
+	rc = mfd_add_devices(pmic->dev, 0, &nfc_cell, 1, NULL, 0);
+	if (rc) {
+		pr_err("Failed to add upl subdevice ret=%d\n", rc);
+		goto bail;
+	}
+
+	if (pdata->charger_pdata) {
+		pm8058_charger_cell.platform_data = pdata->charger_pdata;
+		pm8058_charger_cell.pdata_size = sizeof(struct
+						pmic8058_charger_data);
+		rc = mfd_add_devices(pmic->dev, 0, &pm8058_charger_cell,
+						1, NULL, irq_base);
+		if (rc) {
+			pr_err("Failed to add charger 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 __devinit pm8058_probe(struct platform_device *pdev)
 {
-	int	i, rc;
-	struct	pm8058_platform_data *pdata = pdev->dev.platform_data;
-	struct	pm8058_chip *chip;
+	int rc;
+	struct pm8058_platform_data *pdata = pdev->dev.platform_data;
+	struct pm8058_chip *pmic;
 
-	if (pdata == NULL || !gpio_is_valid(pdata->irq)) {
+	if (pdata == NULL) {
 		pr_err("%s: No platform_data or IRQ.\n", __func__);
 		return -ENODEV;
 	}
 
-	if (pdata->num_subdevs == 0) {
-		pr_err("%s: No sub devices to support.\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;
+
+	pm8058_drvdata.pm_chip_data = pmic;
+	platform_set_drvdata(pdev, &pm8058_drvdata);
+
+	mutex_init(&pmic->pm_lock);
+	pmic_chip = pmic;
 
 	/* Read PMIC chip revision */
-	rc = ssbi_read(chip->dev, SSBI_REG_REV, &chip->revision, 1);
+	rc = pm8058_readb(pmic->dev, PM8058_REG_REV, &pmic->revision);
 	if (rc)
-		pr_err("%s: Failed on ssbi_read for revision: rc=%d.\n",
+		pr_err("%s: Failed on pm8058_readb for revision: 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);
 
-	mutex_init(&chip->pm_lock);
-	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;
-
-	/* Register for all reserved IRQs */
-	for (i = pdata->irq_base; i < (pdata->irq_base + MAX_PM_IRQ); i++) {
-		irq_set_chip(i, &pm8058_irq_chip);
-		irq_set_chip_data(i, (void *)chip);
-		irq_set_handler(i, handle_edge_irq);
-		set_irq_flags(i, IRQF_VALID);
-		irq_set_nested_thread(i, 1);
+	rc = pm8058_add_subdevices(pdata, pmic);
+	if (rc) {
+		pr_err("Cannot add subdevices rc=%d\n", rc);
+		goto err;
 	}
 
-	rc = mfd_add_devices(chip->dev, 0, pdata->sub_devices,
-			     pdata->num_subdevs, NULL, 0);
-
-	/* Add charger sub device with the chip parameter as driver data */
-	if (pdata->charger_sub_device) {
-		rc = mfd_add_devices(chip->dev, 0,
-					pdata->charger_sub_device,
-					1, NULL, 0);
-	}
-
-	if (pdata->init) {
-		rc = pdata->init(chip);
-		if (rc != 0) {
-			pr_err("%s: board init failed\n", __func__);
-			chip->dev = NULL;
-			kfree(chip);
-			return -ENODEV;
-		}
-	}
-
-	rc = request_threaded_irq(pdata->irq, NULL, pm8058_isr_thread,
-			IRQF_ONESHOT | IRQF_DISABLED | pdata->irq_trigger_flags,
-			"pm8058-irq", chip);
-	if (rc < 0)
-		pr_err("%s: could not request irq %d: %d\n", __func__,
-				pdata->irq, rc);
-
-	rc = pmic8058_dbg_probe(chip);
-	if (rc < 0)
-		pr_err("%s: could not set up debugfs: %d\n", __func__, rc);
-
 	rc = pm8058_hard_reset_config(SHUTDOWN_ON_HARD_RESET);
 	if (rc < 0)
 		pr_err("%s: failed to config shutdown on hard reset: %d\n",
 								__func__, rc);
 
-	register_syscore_ops(&pm8058_pm);
-
 	return 0;
+
+err:
+	mfd_remove_devices(pmic->dev);
+	platform_set_drvdata(pdev, NULL);
+	kfree(pmic);
+	return rc;
 }
 
 static int __devexit pm8058_remove(struct platform_device *pdev)
 {
-	struct	pm8058_chip *chip;
+	struct pm8xxx_drvdata *drvdata;
+	struct pm8058_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);
-		}
-		mutex_destroy(&chip->pm_lock);
-		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);
+		mutex_destroy(&pmic->pm_lock);
+		kfree(pmic->mfd_regulators);
+		kfree(pmic);
 	}
-
-	pmic8058_dbg_remove();
+	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
@@ -1489,7 +1269,7 @@
 {
 	return platform_driver_register(&pm8058_driver);
 }
-arch_initcall(pm8058_init);
+postcore_initcall(pm8058_init);
 
 static void __exit pm8058_exit(void)
 {
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index dfbf345..3d7738e 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -601,21 +601,19 @@
 	  on the PM8XXX chips. The vibrator is controlled using the
 	  timed output class.
 
-config PMIC8058_NFC
-	tristate "Qualcomm PM8058 support for Near Field Communication"
-	depends on PMIC8058
-	default y
+config PMIC8XXX_NFC
+	tristate "Qualcomm PM8XXX support for Near Field Communication"
+	depends on MFD_PM8XXX
 	help
-	  Qualcomm PM8058 chip has a module to support NFC (Near Field
+	  Qualcomm PM8XXX chips have a module to support NFC (Near Field
 	  Communication). This option enables the driver to support it.
 
-config PMIC8058_UPL
-	tristate "Qualcomm PM8058 support for User Programmable Logic"
-	depends on PMIC8058
-	default n
+config PMIC8XXX_UPL
+	tristate "Qualcomm PM8XXX support for User Programmable Logic"
+	depends on MFD_PM8XXX
 	help
 	  This option enables device driver support for User Programmable Logic
-	  on Qualcomm PM8058 chip.  The UPL module provides a means to implement
+	  on Qualcomm PM8XXX chips. The UPL module provides a means to implement
 	  simple truth table based logic via a set of control registers. I/O may
 	  be routed in and out of the UPL module via GPIO or DTEST pins.
 
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index a38ccfd..b7f23c8 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -59,8 +59,8 @@
 obj-$(CONFIG_PMIC8058_PWM) += pmic8058-pwm.o
 obj-$(CONFIG_PMIC8058_VIBRATOR) += pmic8058-vibrator.o
 obj-$(CONFIG_PMIC8XXX_VIBRATOR) += pm8xxx-vibrator.o
-obj-$(CONFIG_PMIC8058_NFC) += pmic8058-nfc.o
-obj-$(CONFIG_PMIC8058_UPL) += pmic8058-upl.o
+obj-$(CONFIG_PMIC8XXX_NFC) += pm8xxx-nfc.o
+obj-$(CONFIG_PMIC8XXX_UPL) += pm8xxx-upl.o
 obj-$(CONFIG_MSM_MEMORY_LOW_POWER_MODE_SUSPEND_DEEP_POWER_DOWN) \
 	+= msm_migrate_pages.o
 obj-$(CONFIG_PMIC8058_XOADC) += pmic8058-xoadc.o
diff --git a/drivers/misc/pm8xxx-nfc.c b/drivers/misc/pm8xxx-nfc.c
new file mode 100644
index 0000000..1aaa3e3
--- /dev/null
+++ b/drivers/misc/pm8xxx-nfc.c
@@ -0,0 +1,311 @@
+/* Copyright (c) 2010,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.
+ *
+ */
+/*
+ * Qualcomm PMIC8XXX NFC driver
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <linux/mfd/pm8xxx/core.h>
+#include <linux/mfd/pm8xxx/nfc.h>
+
+/* PM8XXX NFC */
+#define SSBI_REG_NFC_CTRL	0x14D
+#define SSBI_REG_NFC_TEST	0x14E
+
+/* NFC_CTRL */
+#define PM8XXX_NFC_SUPPORT_EN		0x80
+#define PM8XXX_NFC_LDO_EN		0x40
+#define PM8XXX_NFC_EN			0x20
+#define PM8XXX_NFC_EXT_VDDLDO_EN	0x10
+#define PM8XXX_NFC_VPH_PWR_EN		0x08
+#define PM8XXX_NFC_RESERVED		0x04
+#define PM8XXX_NFC_VDDLDO_LEVEL		0x03
+
+/* NFC_TEST */
+#define PM8XXX_NFC_VDDLDO_MON_EN	0x80
+#define PM8XXX_NFC_ATEST_EN		0x40
+#define PM8XXX_NFC_DTEST1_EN		0x20
+#define PM8XXX_NFC_RESERVED2		0x18
+#define PM8XXX_NFC_VDDLDO_OK_S		0x04
+#define PM8XXX_NFC_MBG_EN_S		0x02
+#define PM8XXX_NFC_EXT_EN_S		0x01
+
+struct pm8xxx_nfc_device {
+	struct device *dev;
+	struct mutex		nfc_mutex;
+#if defined(CONFIG_DEBUG_FS)
+	struct dentry		*dent;
+#endif
+};
+static struct pm8xxx_nfc_device	*nfc_dev;
+
+/* APIs */
+/*
+ * pm8xxx_nfc_request - request a handle to access NFC device
+ */
+struct pm8xxx_nfc_device *pm8xxx_nfc_request(void)
+{
+	return nfc_dev;
+}
+EXPORT_SYMBOL(pm8xxx_nfc_request);
+
+/*
+ * pm8xxx_nfc_config - configure NFC signals
+ *
+ * @nfcdev: the NFC device
+ * @mask: signal mask to configure
+ * @flags: control flags
+ */
+int pm8xxx_nfc_config(struct pm8xxx_nfc_device *nfcdev, u32 mask, u32 flags)
+{
+	u8	nfc_ctrl, nfc_test, m, f;
+	int	rc;
+
+	if (nfcdev == NULL || IS_ERR(nfcdev) || !mask)
+		return -EINVAL;
+
+	mutex_lock(&nfcdev->nfc_mutex);
+
+	if (!(mask & PM_NFC_CTRL_REQ))
+		goto config_test;
+
+	rc = pm8xxx_readb(nfcdev->dev->parent, SSBI_REG_NFC_CTRL, &nfc_ctrl);
+	if (rc) {
+		pr_err("%s: FAIL pm8xxx_readb(): rc=%d (nfc_ctrl=0x%x)\n",
+		       __func__, rc, nfc_ctrl);
+		goto config_done;
+	}
+
+	m = mask & 0x00ff;
+	f = flags & 0x00ff;
+	nfc_ctrl &= ~m;
+	nfc_ctrl |= m & f;
+
+	rc = pm8xxx_writeb(nfcdev->dev->parent, SSBI_REG_NFC_CTRL, nfc_ctrl);
+	if (rc) {
+		pr_err("%s: FAIL pm8xxx_writeb(): rc=%d (nfc_ctrl=0x%x)\n",
+		       __func__, rc, nfc_ctrl);
+		goto config_done;
+	}
+
+config_test:
+	if (!(mask & PM_NFC_TEST_REQ))
+		goto config_done;
+
+	rc = pm8xxx_readb(nfcdev->dev->parent, SSBI_REG_NFC_TEST, &nfc_test);
+	if (rc) {
+		pr_err("%s: FAIL pm8xxx_readb(): rc=%d (nfc_test=0x%x)\n",
+		       __func__, rc, nfc_test);
+		goto config_done;
+	}
+
+	m = (mask >> 8) & 0x00ff;
+	f = (flags >> 8) & 0x00ff;
+	nfc_test &= ~m;
+	nfc_test |= m & f;
+
+	rc = pm8xxx_writeb(nfcdev->dev->parent, SSBI_REG_NFC_TEST, nfc_test);
+	if (rc) {
+		pr_err("%s: FAIL pm8xxx_writeb(): rc=%d (nfc_test=0x%x)\n",
+		       __func__, rc, nfc_test);
+		goto config_done;
+	}
+
+config_done:
+	mutex_unlock(&nfcdev->nfc_mutex);
+	return 0;
+}
+EXPORT_SYMBOL(pm8xxx_nfc_config);
+
+/*
+ * pm8xxx_nfc_get_status - get NFC status
+ *
+ * @nfcdev: the NFC device
+ * @mask: of status mask to read
+ * @status: pointer to the status variable
+ */
+int pm8xxx_nfc_get_status(struct pm8xxx_nfc_device *nfcdev,
+			  u32 mask, u32 *status)
+{
+	u8	nfc_ctrl, nfc_test;
+	u32	st;
+	int	rc;
+
+	if (nfcdev == NULL || IS_ERR(nfcdev) || status == NULL)
+		return -EINVAL;
+
+	st = 0;
+	mutex_lock(&nfcdev->nfc_mutex);
+
+	if (!(mask & PM_NFC_CTRL_REQ))
+		goto read_test;
+
+	rc = pm8xxx_readb(nfcdev->dev->parent, SSBI_REG_NFC_CTRL, &nfc_ctrl);
+	if (rc) {
+		pr_err("%s: FAIL pm8xxx_readb(): rc=%d (nfc_ctrl=0x%x)\n",
+		       __func__, rc, nfc_ctrl);
+		goto get_status_done;
+	}
+
+read_test:
+	if (!(mask & (PM_NFC_TEST_REQ | PM_NFC_TEST_STATUS)))
+		goto get_status_done;
+
+	rc = pm8xxx_readb(nfcdev->dev->parent, SSBI_REG_NFC_TEST, &nfc_test);
+	if (rc)
+		pr_err("%s: FAIL pm8xxx_readb(): rc=%d (nfc_test=0x%x)\n",
+		       __func__, rc, nfc_test);
+
+get_status_done:
+	st = nfc_ctrl;
+	st |= nfc_test << 8;
+	*status = st;
+
+	mutex_unlock(&nfcdev->nfc_mutex);
+	return 0;
+}
+EXPORT_SYMBOL(pm8xxx_nfc_get_status);
+
+/*
+ * pm8xxx_nfc_free - free the NFC device
+ */
+void pm8xxx_nfc_free(struct pm8xxx_nfc_device *nfcdev)
+{
+	/* Disable all signals */
+	pm8xxx_nfc_config(nfcdev, PM_NFC_CTRL_REQ, 0);
+}
+EXPORT_SYMBOL(pm8xxx_nfc_free);
+
+#if defined(CONFIG_DEBUG_FS)
+static int pm8xxx_nfc_debug_set(void *data, u64 val)
+{
+	struct pm8xxx_nfc_device *nfcdev;
+	u32	mask, control;
+	int	rc;
+
+	nfcdev = (struct pm8xxx_nfc_device *)data;
+	control = (u32)val & 0xffff;
+	mask = ((u32)val >> 16) & 0xffff;
+	rc = pm8xxx_nfc_config(nfcdev, mask, control);
+	if (rc)
+		pr_err("%s: ERR pm8xxx_nfc_config: rc=%d, "
+		       "[mask, control]=[0x%x, 0x%x]\n",
+		       __func__, rc, mask, control);
+
+	return 0;
+}
+
+static int pm8xxx_nfc_debug_get(void *data, u64 *val)
+{
+	struct pm8xxx_nfc_device *nfcdev;
+	u32	status;
+	int	rc;
+
+	nfcdev = (struct pm8xxx_nfc_device *)data;
+	rc = pm8xxx_nfc_get_status(nfcdev, (u32)-1, &status);
+	if (rc)
+		pr_err("%s: ERR pm8xxx_nfc_get_status: rc=%d, status=0x%x\n",
+		       __func__, rc, status);
+
+	if (val)
+		*val = (u64)status;
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(pm8xxx_nfc_fops, pm8xxx_nfc_debug_get,
+			pm8xxx_nfc_debug_set, "%llu\n");
+
+static int pm8xxx_nfc_debug_init(struct pm8xxx_nfc_device *nfcdev)
+{
+	struct dentry *dent;
+
+	dent = debugfs_create_file("pm8xxx-nfc", 0644, NULL,
+				   (void *)nfcdev, &pm8xxx_nfc_fops);
+
+	if (dent == NULL || IS_ERR(dent))
+		pr_err("%s: ERR debugfs_create_file: dent=0x%x\n",
+		       __func__, (unsigned)dent);
+
+	nfcdev->dent = dent;
+	return 0;
+}
+#endif
+
+static int __devinit pm8xxx_nfc_probe(struct platform_device *pdev)
+{
+	struct pm8xxx_nfc_device	*nfcdev;
+
+	nfcdev = kzalloc(sizeof *nfcdev, GFP_KERNEL);
+	if (nfcdev == NULL) {
+		pr_err("%s: kzalloc() failed.\n", __func__);
+		return -ENOMEM;
+	}
+
+	mutex_init(&nfcdev->nfc_mutex);
+
+	nfcdev->dev = &pdev->dev;
+	nfc_dev = nfcdev;
+	platform_set_drvdata(pdev, nfcdev);
+
+#if defined(CONFIG_DEBUG_FS)
+	pm8xxx_nfc_debug_init(nfc_dev);
+#endif
+
+	pr_notice("%s: OK\n", __func__);
+	return 0;
+}
+
+static int __devexit pm8xxx_nfc_remove(struct platform_device *pdev)
+{
+	struct pm8xxx_nfc_device *nfcdev = platform_get_drvdata(pdev);
+
+#if defined(CONFIG_DEBUG_FS)
+	debugfs_remove(nfcdev->dent);
+#endif
+
+	platform_set_drvdata(pdev, NULL);
+	kfree(nfcdev);
+	return 0;
+}
+
+static struct platform_driver pm8xxx_nfc_driver = {
+	.probe		= pm8xxx_nfc_probe,
+	.remove		= __devexit_p(pm8xxx_nfc_remove),
+	.driver		= {
+		.name = PM8XXX_NFC_DEV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init pm8xxx_nfc_init(void)
+{
+	return platform_driver_register(&pm8xxx_nfc_driver);
+}
+
+static void __exit pm8xxx_nfc_exit(void)
+{
+	platform_driver_unregister(&pm8xxx_nfc_driver);
+}
+
+module_init(pm8xxx_nfc_init);
+module_exit(pm8xxx_nfc_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("PM8XXX NFC driver");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("platform:" PM8XXX_NFC_DEV_NAME);
diff --git a/drivers/misc/pm8xxx-upl.c b/drivers/misc/pm8xxx-upl.c
new file mode 100644
index 0000000..d3d9746f
--- /dev/null
+++ b/drivers/misc/pm8xxx-upl.c
@@ -0,0 +1,350 @@
+/* Copyright (c) 2010,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.
+ *
+ */
+/*
+ * Qualcomm PM8XXX UPL driver
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <linux/mfd/pm8xxx/core.h>
+#include <linux/mfd/pm8xxx/upl.h>
+
+/* PMIC8XXX UPL registers */
+#define SSBI_REG_UPL_CTRL		0x17B
+#define SSBI_REG_UPL_TRUTHTABLE1	0x17C
+#define SSBI_REG_UPL_TRUTHTABLE2	0x17D
+
+struct pm8xxx_upl_device {
+	struct device		*dev;
+	struct mutex		upl_mutex;
+#if defined(CONFIG_DEBUG_FS)
+	struct dentry		*dent;
+#endif
+};
+static struct pm8xxx_upl_device *upl_dev;
+
+/* APIs */
+
+/*
+ * pm8xxx_upl_request - request a handle to access UPL device
+ */
+struct pm8xxx_upl_device *pm8xxx_upl_request(void)
+{
+	return upl_dev;
+}
+EXPORT_SYMBOL(pm8xxx_upl_request);
+
+/*
+ * pm8xxx_upl_read_truthtable - read value currently stored in UPL truth table
+ *
+ * @upldev: the UPL device
+ * @truthtable: value read from UPL truth table
+ */
+int pm8xxx_upl_read_truthtable(struct pm8xxx_upl_device *upldev,
+				u16 *truthtable)
+{
+	int rc = 0;
+	u8 table[2];
+
+	if (upldev == NULL || IS_ERR(upldev))
+		return -EINVAL;
+
+	mutex_lock(&upldev->upl_mutex);
+
+	rc = pm8xxx_readb(upldev->dev->parent, SSBI_REG_UPL_TRUTHTABLE1,
+							&(table[0]));
+	if (rc) {
+		pr_err("%s: FAIL pm8xxx_readb(0x%X)=0x%02X: rc=%d\n",
+			__func__, SSBI_REG_UPL_TRUTHTABLE1, table[0], rc);
+		goto upl_read_done;
+	}
+
+	rc = pm8xxx_readb(upldev->dev->parent, SSBI_REG_UPL_TRUTHTABLE2,
+							&(table[1]));
+	if (rc)
+		pr_err("%s: FAIL pm8xxx_readb(0x%X)=0x%02X: rc=%d\n",
+			__func__, SSBI_REG_UPL_TRUTHTABLE2, table[1], rc);
+upl_read_done:
+	mutex_unlock(&upldev->upl_mutex);
+	*truthtable = (((u16)table[1]) << 8) | table[0];
+	return rc;
+}
+EXPORT_SYMBOL(pm8xxx_upl_read_truthtable);
+
+/*
+ * pm8xxx_upl_writes_truthtable - write value into UPL truth table
+ *
+ * @upldev: the UPL device
+ * @truthtable: value written to UPL truth table
+ *
+ * Each bit in parameter "truthtable" corresponds to the UPL output for a given
+ * set of input pin values. For example, if the input pins have the following
+ * values: A=1, B=1, C=1, D=0, then the UPL would output the value of bit 14
+ * (0b1110) in parameter "truthtable".
+ */
+int pm8xxx_upl_write_truthtable(struct pm8xxx_upl_device *upldev,
+				u16 truthtable)
+{
+	int rc = 0;
+	u8 table[2];
+
+	if (upldev == NULL || IS_ERR(upldev))
+		return -EINVAL;
+
+	table[0] = truthtable & 0xFF;
+	table[1] = (truthtable >> 8) & 0xFF;
+
+	mutex_lock(&upldev->upl_mutex);
+
+	rc = pm8xxx_writeb(upldev->dev->parent, SSBI_REG_UPL_TRUTHTABLE1,
+								table[0]);
+	if (rc) {
+		pr_err("%s: FAIL pm8xxx_writeb(0x%X)=0x%04X: rc=%d\n",
+			__func__, SSBI_REG_UPL_TRUTHTABLE1, table[0], rc);
+		goto upl_write_done;
+	}
+
+	rc = pm8xxx_writeb(upldev->dev->parent, SSBI_REG_UPL_TRUTHTABLE2,
+								table[1]);
+	if (rc)
+		pr_err("%s: FAIL pm8xxx_writeb(0x%X)=0x%04X: rc=%d\n",
+			__func__, SSBI_REG_UPL_TRUTHTABLE2, table[1], rc);
+upl_write_done:
+	mutex_unlock(&upldev->upl_mutex);
+	return rc;
+}
+EXPORT_SYMBOL(pm8xxx_upl_write_truthtable);
+
+/*
+ * pm8xxx_upl_config - configure UPL I/O settings and UPL enable/disable
+ *
+ * @upldev: the UPL device
+ * @mask: setting mask to configure
+ * @flags: setting flags
+ */
+int pm8xxx_upl_config(struct pm8xxx_upl_device *upldev, u32 mask, u32 flags)
+{
+	int rc;
+	u8 upl_ctrl, m, f;
+
+	if (upldev == NULL || IS_ERR(upldev))
+		return -EINVAL;
+
+	mutex_lock(&upldev->upl_mutex);
+
+	rc = pm8xxx_readb(upldev->dev->parent, SSBI_REG_UPL_CTRL, &upl_ctrl);
+	if (rc) {
+		pr_err("%s: FAIL pm8xxx_readb(0x%X)=0x%02X: rc=%d\n",
+			__func__, SSBI_REG_UPL_CTRL, upl_ctrl, rc);
+		goto upl_config_done;
+	}
+
+	m = mask & 0x00ff;
+	f = flags & 0x00ff;
+	upl_ctrl &= ~m;
+	upl_ctrl |= m & f;
+
+	rc = pm8xxx_writeb(upldev->dev->parent, SSBI_REG_UPL_CTRL, upl_ctrl);
+	if (rc)
+		pr_err("%s: FAIL pm8xxx_writeb(0x%X)=0x%02X: rc=%d\n",
+			__func__, SSBI_REG_UPL_CTRL, upl_ctrl, rc);
+upl_config_done:
+	mutex_unlock(&upldev->upl_mutex);
+	return rc;
+}
+EXPORT_SYMBOL(pm8xxx_upl_config);
+
+#if defined(CONFIG_DEBUG_FS)
+
+static int truthtable_set(void *data, u64 val)
+{
+	int rc;
+
+	rc = pm8xxx_upl_write_truthtable(data, val);
+	if (rc)
+		pr_err("%s: pm8xxx_upl_write_truthtable: rc=%d, "
+			"truthtable=0x%llX\n", __func__, rc, val);
+	return rc;
+}
+
+static int truthtable_get(void *data, u64 *val)
+{
+	int rc;
+	u16 truthtable;
+
+	rc = pm8xxx_upl_read_truthtable(data, &truthtable);
+	if (rc)
+		pr_err("%s: pm8xxx_upl_read_truthtable: rc=%d, "
+			"truthtable=0x%X\n", __func__, rc, truthtable);
+	if (val)
+		*val = truthtable;
+
+	return rc;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(upl_truthtable_fops, truthtable_get,
+			truthtable_set, "0x%04llX\n");
+
+/* enter values as 0xMMMMFFFF where MMMM is the mask and FFFF is the flags */
+static int control_set(void *data, u64 val)
+{
+	u8 mask, flags;
+	int rc;
+
+	flags = val & 0xFFFF;
+	mask = (val >> 16) & 0xFFFF;
+
+	rc = pm8xxx_upl_config(data, mask, flags);
+	if (rc)
+		pr_err("%s: pm8xxx_upl_config: rc=%d, mask = 0x%X, "
+			"flags = 0x%X\n", __func__, rc, mask, flags);
+	return rc;
+}
+
+static int control_get(void *data, u64 *val)
+{
+	struct pm8xxx_upl_device *upldev;
+	int rc = 0;
+	u8 ctrl;
+
+	upldev = data;
+
+	mutex_lock(&upldev->upl_mutex);
+
+	rc = pm8xxx_readb(upldev->dev->parent, SSBI_REG_UPL_CTRL, &ctrl);
+	if (rc)
+		pr_err("%s: FAIL pm8xxx_readb(): rc=%d (ctrl=0x%02X)\n",
+		       __func__, rc, ctrl);
+
+	mutex_unlock(&upldev->upl_mutex);
+
+	*val = ctrl;
+
+	return rc;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(upl_control_fops, control_get,
+			control_set, "0x%02llX\n");
+
+static int pm8xxx_upl_debug_init(struct pm8xxx_upl_device *upldev)
+{
+	struct dentry *dent;
+	struct dentry *temp;
+
+	dent = debugfs_create_dir("pm8xxx-upl", NULL);
+	if (dent == NULL || IS_ERR(dent)) {
+		pr_err("%s: ERR debugfs_create_dir: dent=0x%X\n",
+					__func__, (unsigned)dent);
+		return -ENOMEM;
+	}
+
+	temp = debugfs_create_file("truthtable", S_IRUSR | S_IWUSR, dent,
+					upldev, &upl_truthtable_fops);
+	if (temp == NULL || IS_ERR(temp)) {
+		pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
+					__func__, (unsigned)dent);
+		goto debug_error;
+	}
+
+	temp = debugfs_create_file("control", S_IRUSR | S_IWUSR, dent,
+					upldev, &upl_control_fops);
+	if (temp == NULL || IS_ERR(temp)) {
+		pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
+					__func__, (unsigned)dent);
+		goto debug_error;
+	}
+
+	upldev->dent = dent;
+	return 0;
+
+debug_error:
+	debugfs_remove_recursive(dent);
+	return -ENOMEM;
+}
+
+static int __devexit pm8xxx_upl_debug_remove(struct pm8xxx_upl_device *upldev)
+{
+	debugfs_remove_recursive(upldev->dent);
+	return 0;
+}
+
+#endif /* CONFIG_DEBUG_FS */
+
+static int __devinit pm8xxx_upl_probe(struct platform_device *pdev)
+{
+	struct pm8xxx_upl_device	*upldev;
+
+	upldev = kzalloc(sizeof *upldev, GFP_KERNEL);
+	if (upldev == NULL) {
+		pr_err("%s: kzalloc() failed.\n", __func__);
+		return -ENOMEM;
+	}
+
+	mutex_init(&upldev->upl_mutex);
+
+	upl_dev = upldev;
+	upldev->dev = &pdev->dev;
+	platform_set_drvdata(pdev, upldev);
+
+#if defined(CONFIG_DEBUG_FS)
+	pm8xxx_upl_debug_init(upl_dev);
+#endif
+	pr_notice("%s: OK\n", __func__);
+	return 0;
+}
+
+static int __devexit pm8xxx_upl_remove(struct platform_device *pdev)
+{
+	struct pm8xxx_upl_device *upldev = platform_get_drvdata(pdev);
+
+#if defined(CONFIG_DEBUG_FS)
+	pm8xxx_upl_debug_remove(upldev);
+#endif
+
+	platform_set_drvdata(pdev, NULL);
+	kfree(upldev);
+	pr_notice("%s: OK\n", __func__);
+
+	return 0;
+}
+
+static struct platform_driver pm8xxx_upl_driver = {
+	.probe		= pm8xxx_upl_probe,
+	.remove		= __devexit_p(pm8xxx_upl_remove),
+	.driver		= {
+		.name = PM8XXX_UPL_DEV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init pm8xxx_upl_init(void)
+{
+	return platform_driver_register(&pm8xxx_upl_driver);
+}
+
+static void __exit pm8xxx_upl_exit(void)
+{
+	platform_driver_unregister(&pm8xxx_upl_driver);
+}
+
+module_init(pm8xxx_upl_init);
+module_exit(pm8xxx_upl_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("PM8XXX UPL driver");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("platform:" PM8XXX_UPL_DEV_NAME);
diff --git a/drivers/misc/pm8xxx-vibrator.c b/drivers/misc/pm8xxx-vibrator.c
index 8aa7f72..4f22efe 100644
--- a/drivers/misc/pm8xxx-vibrator.c
+++ b/drivers/misc/pm8xxx-vibrator.c
@@ -27,6 +27,7 @@
 #define VIB_DRV_SEL_MASK	0xf8
 #define VIB_DRV_SEL_SHIFT	0x03
 #define VIB_DRV_EN_MANUAL_MASK	0xfc
+#define VIB_DRV_LOGIC_SHIFT	0x2
 
 #define VIB_MAX_LEVEL_mV	3100
 #define VIB_MIN_LEVEL_mV	1200
@@ -43,6 +44,40 @@
 	u8  reg_vib_drv;
 };
 
+static struct pm8xxx_vib *vib_dev;
+
+int pm8xxx_vibrator_config(struct pm8xxx_vib_config *vib_config)
+{
+	u8 reg = 0;
+	int rc;
+
+	if (vib_dev == NULL) {
+		pr_err("%s: vib_dev is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	if (vib_config->drive_mV) {
+		if ((vib_config->drive_mV < VIB_MIN_LEVEL_mV) ||
+			(vib_config->drive_mV > VIB_MAX_LEVEL_mV)) {
+			pr_err("Invalid vibrator drive strength\n");
+			return -EINVAL;
+		}
+	}
+
+	reg = (vib_config->drive_mV / 100) << VIB_DRV_SEL_SHIFT;
+
+	reg |= (!!vib_config->active_low) << VIB_DRV_LOGIC_SHIFT;
+
+	reg |= vib_config->enable_mode;
+
+	rc = pm8xxx_writeb(vib_dev->dev->parent, VIB_DRV, reg);
+	if (rc)
+		pr_err("%s: pm8xxx write failed: rc=%d\n", __func__, rc);
+
+	return rc;
+}
+EXPORT_SYMBOL(pm8xxx_vibrator_config);
+
 /* REVISIT: just for debugging, will be removed in final working version */
 static void __dump_vib_regs(struct pm8xxx_vib *vib, char *msg)
 {
@@ -240,6 +275,8 @@
 
 	platform_set_drvdata(pdev, vib);
 
+	vib_dev = vib;
+
 	return 0;
 
 err_read_vib:
diff --git a/drivers/misc/pmic8058-nfc.c b/drivers/misc/pmic8058-nfc.c
deleted file mode 100644
index 76a19f4..0000000
--- a/drivers/misc/pmic8058-nfc.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/* Copyright (c) 2010, 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.
- *
- */
-/*
- * Qualcomm PMIC8058 NFC driver
- *
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/mfd/pmic8058.h>
-#include <linux/pmic8058-nfc.h>
-#include <linux/debugfs.h>
-#include <linux/slab.h>
-
-/* PMIC8058 NFC */
-#define	SSBI_REG_NFC_CTRL	0x14D
-#define	SSBI_REG_NFC_TEST	0x14E
-
-/* NFC_CTRL */
-#define	PM8058_NFC_SUPPORT_EN		0x80
-#define	PM8058_NFC_LDO_EN		0x40
-#define	PM8058_NFC_EN			0x20
-#define	PM8058_NFC_EXT_VDDLDO_EN	0x10
-#define	PM8058_NFC_VPH_PWR_EN		0x08
-#define	PM8058_NFC_RESERVED		0x04
-#define	PM8058_NFC_VDDLDO_LEVEL		0x03
-
-/* NFC_TEST */
-#define	PM8058_NFC_VDDLDO_MON_EN	0x80
-#define	PM8058_NFC_ATEST_EN		0x40
-#define	PM8058_NFC_DTEST1_EN		0x20
-#define	PM8058_NFC_RESERVED2		0x18
-#define	PM8058_NFC_VDDLDO_OK_S		0x04
-#define	PM8058_NFC_MBG_EN_S		0x02
-#define	PM8058_NFC_EXT_EN_S		0x01
-
-struct pm8058_nfc_device {
-	struct mutex		nfc_mutex;
-	struct pm8058_chip	*pm_chip;
-#if defined(CONFIG_DEBUG_FS)
-	struct dentry 		*dent;
-#endif
-};
-static struct pm8058_nfc_device	*nfc_dev;
-
-/* APIs */
-/*
- * pm8058_nfc_request - request a handle to access NFC device
- */
-struct pm8058_nfc_device *pm8058_nfc_request(void)
-{
-	return nfc_dev;
-}
-EXPORT_SYMBOL(pm8058_nfc_request);
-
-/*
- * pm8058_nfc_config - configure NFC signals
- *
- * @nfcdev: the NFC device
- * @mask: signal mask to configure
- * @flags: control flags
- */
-int pm8058_nfc_config(struct pm8058_nfc_device *nfcdev, u32 mask, u32 flags)
-{
-	u8	nfc_ctrl, nfc_test, m, f;
-	int	rc;
-
-	if (nfcdev == NULL || IS_ERR(nfcdev) || !mask)
-		return -EINVAL;
-	if (nfcdev->pm_chip == NULL)
-		return -ENODEV;
-
-	mutex_lock(&nfcdev->nfc_mutex);
-
-	if (!(mask & PM_NFC_CTRL_REQ))
-		goto config_test;
-
-	rc = pm8058_read(nfcdev->pm_chip, SSBI_REG_NFC_CTRL, &nfc_ctrl, 1);
-	if (rc) {
-		pr_err("%s: FAIL pm8058_read(): rc=%d (nfc_ctrl=0x%x)\n",
-		       __func__, rc, nfc_ctrl);
-		goto config_done;
-	}
-
-	m = mask & 0x00ff;
-	f = flags & 0x00ff;
-	nfc_ctrl &= ~m;
-	nfc_ctrl |= m & f;
-
-	rc = pm8058_write(nfcdev->pm_chip, SSBI_REG_NFC_CTRL, &nfc_ctrl, 1);
-	if (rc) {
-		pr_err("%s: FAIL pm8058_write(): rc=%d (nfc_ctrl=0x%x)\n",
-		       __func__, rc, nfc_ctrl);
-		goto config_done;
-	}
-
-config_test:
-	if (!(mask & PM_NFC_TEST_REQ))
-		goto config_done;
-
-	rc = pm8058_read(nfcdev->pm_chip, SSBI_REG_NFC_TEST, &nfc_test, 1);
-	if (rc) {
-		pr_err("%s: FAIL pm8058_read(): rc=%d (nfc_test=0x%x)\n",
-		       __func__, rc, nfc_test);
-		goto config_done;
-	}
-
-	m = (mask >> 8) & 0x00ff;
-	f = (flags >> 8) & 0x00ff;
-	nfc_test &= ~m;
-	nfc_test |= m & f;
-
-	rc = pm8058_write(nfcdev->pm_chip, SSBI_REG_NFC_TEST, &nfc_test, 1);
-	if (rc) {
-		pr_err("%s: FAIL pm8058_write(): rc=%d (nfc_test=0x%x)\n",
-		       __func__, rc, nfc_test);
-		goto config_done;
-	}
-
-config_done:
-	mutex_unlock(&nfcdev->nfc_mutex);
-	return 0;
-}
-EXPORT_SYMBOL(pm8058_nfc_config);
-
-/*
- * pm8058_nfc_get_status - get NFC status
- *
- * @nfcdev: the NFC device
- * @mask: of status mask to read
- * @status: pointer to the status variable
- */
-int pm8058_nfc_get_status(struct pm8058_nfc_device *nfcdev,
-			  u32 mask, u32 *status)
-{
-	u8	nfc_ctrl, nfc_test;
-	u32	st;
-	int	rc;
-
-	if (nfcdev == NULL || IS_ERR(nfcdev) || status == NULL)
-		return -EINVAL;
-	if (nfcdev->pm_chip == NULL)
-		return -ENODEV;
-
-	st = 0;
-	mutex_lock(&nfcdev->nfc_mutex);
-
-	if (!(mask & PM_NFC_CTRL_REQ))
-		goto read_test;
-
-	rc = pm8058_read(nfcdev->pm_chip, SSBI_REG_NFC_CTRL, &nfc_ctrl, 1);
-	if (rc) {
-		pr_err("%s: FAIL pm8058_read(): rc=%d (nfc_ctrl=0x%x)\n",
-		       __func__, rc, nfc_ctrl);
-		goto get_status_done;
-	}
-
-read_test:
-	if (!(mask & (PM_NFC_TEST_REQ | PM_NFC_TEST_STATUS)))
-		goto get_status_done;
-
-	rc = pm8058_read(nfcdev->pm_chip, SSBI_REG_NFC_TEST, &nfc_test, 1);
-	if (rc)
-		pr_err("%s: FAIL pm8058_read(): rc=%d (nfc_test=0x%x)\n",
-		       __func__, rc, nfc_test);
-
-get_status_done:
-	st = nfc_ctrl;
-	st |= nfc_test << 8;
-	*status = st;
-
-	mutex_unlock(&nfcdev->nfc_mutex);
-	return 0;
-}
-EXPORT_SYMBOL(pm8058_nfc_get_status);
-
-/*
- * pm8058_nfc_free - free the NFC device
- */
-void pm8058_nfc_free(struct pm8058_nfc_device *nfcdev)
-{
-	/* Disable all signals */
-	pm8058_nfc_config(nfcdev, PM_NFC_CTRL_REQ, 0);
-}
-EXPORT_SYMBOL(pm8058_nfc_free);
-
-#if defined(CONFIG_DEBUG_FS)
-static int pm8058_nfc_debug_set(void *data, u64 val)
-{
-	struct pm8058_nfc_device *nfcdev;
-	u32	mask, control;
-	int	rc;
-
-	nfcdev = (struct pm8058_nfc_device *)data;
-	control = (u32)val & 0xffff;
-	mask = ((u32)val >> 16) & 0xffff;
-	rc = pm8058_nfc_config(nfcdev, mask, control);
-	if (rc)
-		pr_err("%s: ERR pm8058_nfc_config: rc=%d, "
-		       "[mask, control]=[0x%x, 0x%x]\n",
-		       __func__, rc, mask, control);
-
-	return 0;
-}
-
-static int pm8058_nfc_debug_get(void *data, u64 *val)
-{
-	struct pm8058_nfc_device *nfcdev;
-	u32	status;
-	int	rc;
-
-	nfcdev = (struct pm8058_nfc_device *)data;
-	rc = pm8058_nfc_get_status(nfcdev, (u32)-1, &status);
-	if (rc)
-		pr_err("%s: ERR pm8058_nfc_get_status: rc=%d, status=0x%x\n",
-		       __func__, rc, status);
-
-	if (val)
-		*val = (u64)status;
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(pm8058_nfc_fops, pm8058_nfc_debug_get,
-			pm8058_nfc_debug_set, "%llu\n");
-
-static int pm8058_nfc_debug_init(struct pm8058_nfc_device *nfcdev)
-{
-	struct dentry *dent;
-
-	dent = debugfs_create_file("pm8058-nfc", 0644, NULL,
-				   (void *)nfcdev, &pm8058_nfc_fops);
-
-	if (dent == NULL || IS_ERR(dent))
-		pr_err("%s: ERR debugfs_create_file: dent=0x%x\n",
-		       __func__, (unsigned)dent);
-
-	nfcdev->dent = dent;
-	return 0;
-}
-#endif
-
-static int __devinit pmic8058_nfc_probe(struct platform_device *pdev)
-{
-	struct pm8058_chip		*pm_chip;
-	struct pm8058_nfc_device	*nfcdev;
-
-	pm_chip = dev_get_drvdata(pdev->dev.parent);
-	if (pm_chip == NULL) {
-		pr_err("%s: no parent data passed in.\n", __func__);
-		return -EFAULT;
-	}
-
-	nfcdev = kzalloc(sizeof *nfcdev, GFP_KERNEL);
-	if (nfcdev == NULL) {
-		pr_err("%s: kzalloc() failed.\n", __func__);
-		return -ENOMEM;
-	}
-
-	mutex_init(&nfcdev->nfc_mutex);
-
-	nfcdev->pm_chip = pm_chip;
-	nfc_dev = nfcdev;
-	platform_set_drvdata(pdev, nfcdev);
-
-#if defined(CONFIG_DEBUG_FS)
-	pm8058_nfc_debug_init(nfc_dev);
-#endif
-
-	pr_notice("%s: OK\n", __func__);
-	return 0;
-}
-
-static int __devexit pmic8058_nfc_remove(struct platform_device *pdev)
-{
-	struct pm8058_nfc_device *nfcdev = platform_get_drvdata(pdev);
-
-#if defined(CONFIG_DEBUG_FS)
-	debugfs_remove(nfcdev->dent);
-#endif
-
-	platform_set_drvdata(pdev, nfcdev->pm_chip);
-	kfree(nfcdev);
-	return 0;
-}
-
-static struct platform_driver pmic8058_nfc_driver = {
-	.probe		= pmic8058_nfc_probe,
-	.remove		= __devexit_p(pmic8058_nfc_remove),
-	.driver		= {
-		.name = "pm8058-nfc",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init pm8058_nfc_init(void)
-{
-	return platform_driver_register(&pmic8058_nfc_driver);
-}
-
-static void __exit pm8058_nfc_exit(void)
-{
-	platform_driver_unregister(&pmic8058_nfc_driver);
-}
-
-module_init(pm8058_nfc_init);
-module_exit(pm8058_nfc_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("PMIC8058 NFC driver");
-MODULE_VERSION("1.0");
-MODULE_ALIAS("platform:pmic8058-nfc");
diff --git a/drivers/misc/pmic8058-pwm.c b/drivers/misc/pmic8058-pwm.c
index ad03b88..33407b7 100644
--- a/drivers/misc/pmic8058-pwm.c
+++ b/drivers/misc/pmic8058-pwm.c
@@ -19,11 +19,11 @@
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/pwm.h>
-#include <linux/mfd/pmic8058.h>
+#include <linux/mfd/pm8xxx/core.h>
 #include <linux/pmic8058-pwm.h>
-#include <linux/slab.h>
 
 #define	PM8058_LPG_BANKS		8
 #define	PM8058_PWM_CHANNELS		PM8058_LPG_BANKS	/* MAX=8 */
@@ -179,6 +179,7 @@
 struct pm8058_pwm_chip;
 
 struct pwm_device {
+	struct device		*dev;
 	int			pwm_id;		/* = bank/channel id */
 	int			in_use;
 	const char		*label;
@@ -188,14 +189,13 @@
 	int			use_lut;	/* Use LUT to output PWM */
 	u8			pwm_ctl[PM8058_LPG_CTL_REGS];
 	int			irq;
-	struct pm8058_pwm_chip	*chip;
+	struct pm8058_pwm_chip  *chip;
 };
 
 struct pm8058_pwm_chip {
 	struct pwm_device	pwm_dev[PM8058_PWM_CHANNELS];
 	u8			bank_mask;
 	struct mutex		pwm_mutex;
-	struct pm8058_chip	*pm_chip;
 	struct pm8058_pwm_pdata	*pdata;
 };
 
@@ -244,9 +244,10 @@
 	else
 		reg = chip->bank_mask & ~(1 << pwm->pwm_id);
 
-	rc = pm8058_write(chip->pm_chip, SSBI_REG_ADDR_LPG_BANK_EN, &reg, 1);
+	rc = pm8xxx_writeb(pwm->dev->parent,
+				SSBI_REG_ADDR_LPG_BANK_EN, reg);
 	if (rc) {
-		pr_err("pm8058_write(): rc=%d (Enable LPG Bank)\n", rc);
+		pr_err("pm8xxx_write(): rc=%d (Enable LPG Bank)\n", rc);
 		goto bail_out;
 	}
 	chip->bank_mask = reg;
@@ -261,10 +262,10 @@
 	u8	reg;
 
 	reg = pwm->pwm_id;
-	rc = pm8058_write(pwm->chip->pm_chip, SSBI_REG_ADDR_LPG_BANK_SEL,
-			     &reg, 1);
+	rc = pm8xxx_writeb(pwm->dev->parent,
+			SSBI_REG_ADDR_LPG_BANK_SEL, reg);
 	if (rc)
-		pr_err("pm8058_write(): rc=%d (Select PWM Bank)\n", rc);
+		pr_err("pm8xxx_write(): rc=%d (Select PWM Bank)\n", rc);
 	return rc;
 }
 
@@ -284,10 +285,10 @@
 		reg &= ~PM8058_PWM_RAMP_GEN_START;
 	}
 
-	rc = pm8058_write(pwm->chip->pm_chip, SSBI_REG_ADDR_LPG_CTL(0),
-			  &reg, 1);
+	rc = pm8xxx_writeb(pwm->dev->parent, SSBI_REG_ADDR_LPG_CTL(0),
+									reg);
 	if (rc)
-		pr_err("pm8058_write(): rc=%d (Enable PWM Ctl 0)\n", rc);
+		pr_err("pm8xxx_write(): rc=%d (Enable PWM Ctl 0)\n", rc);
 	else
 		pwm->pwm_ctl[0] = reg;
 	return rc;
@@ -415,15 +416,13 @@
 		cfg1 = (pwm_value >> 1) & 0x80;
 		cfg1 |= start_idx + i;
 
-		rc = pm8058_write(pwm->chip->pm_chip,
-			     SSBI_REG_ADDR_LPG_LUT_CFG0,
-			     &cfg0, 1);
+		rc = pm8xxx_writeb(pwm->dev->parent,
+			     SSBI_REG_ADDR_LPG_LUT_CFG0, cfg0);
 		if (rc)
 			break;
 
-		rc = pm8058_write(pwm->chip->pm_chip,
-			     SSBI_REG_ADDR_LPG_LUT_CFG1,
-			     &cfg1, 1);
+		rc = pm8xxx_writeb(pwm->dev->parent,
+			     SSBI_REG_ADDR_LPG_LUT_CFG1, cfg1);
 		if (rc)
 			break;
 	}
@@ -539,11 +538,11 @@
 
 	/* Write in reverse way so 0 would be the last */
 	for (i = end - 1; i >= start; i--) {
-		rc = pm8058_write(pwm->chip->pm_chip,
+		rc = pm8xxx_writeb(pwm->dev->parent,
 				  SSBI_REG_ADDR_LPG_CTL(i),
-				  &pwm->pwm_ctl[i], 1);
+				  pwm->pwm_ctl[i]);
 		if (rc) {
-			pr_err("pm8058_write(): rc=%d (PWM Ctl[%d])\n", rc, i);
+			pr_err("pm8xxx_write(): rc=%d (PWM Ctl[%d])\n", rc, i);
 			return rc;
 		}
 	}
@@ -957,8 +956,8 @@
 	case PM_PWM_LED_2:
 		conf = mode & PM8058_LED_MODE_MASK;
 		conf |= (max_current / 2) << PM8058_LED_CURRENT_SHIFT;
-		rc = pm8058_write(pwm->chip->pm_chip,
-				  SSBI_REG_ADDR_LED(id), &conf, 1);
+		rc = pm8xxx_writeb(pwm->dev->parent,
+				  SSBI_REG_ADDR_LED(id), conf);
 		break;
 
 	case PM_PWM_LED_KPD:
@@ -982,8 +981,8 @@
 		}
 		conf |= (max_current / 20) << PM8058_FLASH_CURRENT_SHIFT;
 		id -= PM_PWM_LED_KPD;
-		rc = pm8058_write(pwm->chip->pm_chip,
-				  SSBI_REG_ADDR_FLASH(id), &conf, 1);
+		rc = pm8xxx_writeb(pwm->dev->parent,
+				  SSBI_REG_ADDR_FLASH(id), conf);
 		break;
 	default:
 		rc = -EINVAL;
@@ -1012,10 +1011,10 @@
 			/* Only Test 1 available */
 			reg |= (1 << PM8058_PWM_DTEST_SHIFT) &
 				PM8058_PWM_DTEST_MASK;
-		rc = pm8058_write(pwm->chip->pm_chip, SSBI_REG_ADDR_LPG_TEST,
-				  &reg, 1);
+		rc = pm8xxx_writeb(pwm->dev->parent,
+			SSBI_REG_ADDR_LPG_TEST, reg);
 		if (rc)
-			pr_err("pm8058_write(DTEST=0x%x): rc=%d\n", reg, rc);
+			pr_err("pm8xxx_write(DTEST=0x%x): rc=%d\n", reg, rc);
 
 	}
 	return rc;
@@ -1024,16 +1023,9 @@
 
 static int __devinit pmic8058_pwm_probe(struct platform_device *pdev)
 {
-	struct pm8058_chip	*pm_chip;
 	struct pm8058_pwm_chip	*chip;
 	int	i;
 
-	pm_chip = dev_get_drvdata(pdev->dev.parent);
-	if (pm_chip == NULL) {
-		pr_err("no parent data passed in.\n");
-		return -EFAULT;
-	}
-
 	chip = kzalloc(sizeof *chip, GFP_KERNEL);
 	if (chip == NULL) {
 		pr_err("kzalloc() failed.\n");
@@ -1043,12 +1035,12 @@
 	for (i = 0; i < PM8058_PWM_CHANNELS; i++) {
 		chip->pwm_dev[i].pwm_id = i;
 		chip->pwm_dev[i].chip = chip;
+		chip->pwm_dev[i].dev = &pdev->dev;
 	}
 
 	mutex_init(&chip->pwm_mutex);
 
 	chip->pdata = pdev->dev.platform_data;
-	chip->pm_chip = pm_chip;
 	pwm_chip = chip;
 	platform_set_drvdata(pdev, chip);
 
diff --git a/drivers/misc/pmic8058-upl.c b/drivers/misc/pmic8058-upl.c
deleted file mode 100644
index ae0abd8..0000000
--- a/drivers/misc/pmic8058-upl.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/* Copyright (c) 2010, 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.
- *
- */
-/*
- * Qualcomm PMIC8058 UPL driver
- *
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/mfd/pmic8058.h>
-#include <linux/pmic8058-upl.h>
-#include <linux/debugfs.h>
-#include <linux/slab.h>
-
-/* PMIC8058 UPL registers */
-#define	SSBI_REG_UPL_CTRL		0x17B
-#define	SSBI_REG_UPL_TRUTHTABLE1	0x17C
-#define	SSBI_REG_UPL_TRUTHTABLE2	0x17D
-
-struct pm8058_upl_device {
-	struct mutex		upl_mutex;
-	struct pm8058_chip	*pm_chip;
-#if defined(CONFIG_DEBUG_FS)
-	struct dentry		*dent;
-#endif
-};
-static struct pm8058_upl_device *upl_dev;
-
-/* APIs */
-
-/*
- * pm8058_upl_request - request a handle to access UPL device
- */
-struct pm8058_upl_device *pm8058_upl_request(void)
-{
-	return upl_dev;
-}
-EXPORT_SYMBOL(pm8058_upl_request);
-
-/*
- * pm8058_upl_read_truthtable - read value currently stored in UPL truth table
- *
- * @upldev: the UPL device
- * @truthtable: value read from UPL truth table
- */
-int pm8058_upl_read_truthtable(struct pm8058_upl_device *upldev,
-				u16 *truthtable)
-{
-	int rc = 0;
-	u8 table[2];
-
-	if (upldev == NULL || IS_ERR(upldev))
-		return -EINVAL;
-	if (upldev->pm_chip == NULL)
-		return -ENODEV;
-
-	mutex_lock(&upldev->upl_mutex);
-
-	rc = pm8058_read(upldev->pm_chip, SSBI_REG_UPL_TRUTHTABLE1,
-			&(table[0]), 1);
-	if (rc) {
-		pr_err("%s: FAIL pm8058_read(0x%X)=0x%02X: rc=%d\n",
-			__func__, SSBI_REG_UPL_TRUTHTABLE1, table[0], rc);
-		goto upl_read_done;
-	}
-
-	rc = pm8058_read(upldev->pm_chip, SSBI_REG_UPL_TRUTHTABLE2,
-			&(table[1]), 1);
-	if (rc)
-		pr_err("%s: FAIL pm8058_read(0x%X)=0x%02X: rc=%d\n",
-			__func__, SSBI_REG_UPL_TRUTHTABLE2, table[1], rc);
-upl_read_done:
-	mutex_unlock(&upldev->upl_mutex);
-	*truthtable = (((u16)table[1]) << 8) | table[0];
-	return rc;
-}
-EXPORT_SYMBOL(pm8058_upl_read_truthtable);
-
-/*
- * pm8058_upl_writes_truthtable - write value into UPL truth table
- *
- * @upldev: the UPL device
- * @truthtable: value written to UPL truth table
- *
- * Each bit in parameter "truthtable" corresponds to the UPL output for a given
- * set of input pin values. For example, if the input pins have the following
- * values: A=1, B=1, C=1, D=0, then the UPL would output the value of bit 14
- * (0b1110) in parameter "truthtable".
- */
-int pm8058_upl_write_truthtable(struct pm8058_upl_device *upldev,
-				u16 truthtable)
-{
-	int rc = 0;
-	u8 table[2];
-
-	if (upldev == NULL || IS_ERR(upldev))
-		return -EINVAL;
-	if (upldev->pm_chip == NULL)
-		return -ENODEV;
-
-	table[0] = truthtable & 0xFF;
-	table[1] = (truthtable >> 8) & 0xFF;
-
-	mutex_lock(&upldev->upl_mutex);
-
-	rc = pm8058_write(upldev->pm_chip, SSBI_REG_UPL_TRUTHTABLE1,
-				&(table[0]), 1);
-	if (rc) {
-		pr_err("%s: FAIL pm8058_write(0x%X)=0x%04X: rc=%d\n",
-			__func__, SSBI_REG_UPL_TRUTHTABLE1, table[0], rc);
-		goto upl_write_done;
-	}
-
-	rc = pm8058_write(upldev->pm_chip, SSBI_REG_UPL_TRUTHTABLE2,
-				&(table[1]), 1);
-	if (rc)
-		pr_err("%s: FAIL pm8058_write(0x%X)=0x%04X: rc=%d\n",
-			__func__, SSBI_REG_UPL_TRUTHTABLE2, table[1], rc);
-upl_write_done:
-	mutex_unlock(&upldev->upl_mutex);
-	return rc;
-}
-EXPORT_SYMBOL(pm8058_upl_write_truthtable);
-
-/*
- * pm8058_upl_config - configure UPL I/O settings and UPL enable/disable
- *
- * @upldev: the UPL device
- * @mask: setting mask to configure
- * @flags: setting flags
- */
-int pm8058_upl_config(struct pm8058_upl_device *upldev, u32 mask, u32 flags)
-{
-	int rc;
-	u8 upl_ctrl, m, f;
-
-	if (upldev == NULL || IS_ERR(upldev))
-		return -EINVAL;
-	if (upldev->pm_chip == NULL)
-		return -ENODEV;
-
-	mutex_lock(&upldev->upl_mutex);
-
-	rc = pm8058_read(upldev->pm_chip, SSBI_REG_UPL_CTRL, &upl_ctrl, 1);
-	if (rc) {
-		pr_err("%s: FAIL pm8058_read(0x%X)=0x%02X: rc=%d\n",
-			__func__, SSBI_REG_UPL_CTRL, upl_ctrl, rc);
-		goto upl_config_done;
-	}
-
-	m = mask & 0x00ff;
-	f = flags & 0x00ff;
-	upl_ctrl &= ~m;
-	upl_ctrl |= m & f;
-
-	rc = pm8058_write(upldev->pm_chip, SSBI_REG_UPL_CTRL, &upl_ctrl, 1);
-	if (rc)
-		pr_err("%s: FAIL pm8058_write(0x%X)=0x%02X: rc=%d\n",
-			__func__, SSBI_REG_UPL_CTRL, upl_ctrl, rc);
-upl_config_done:
-	mutex_unlock(&upldev->upl_mutex);
-	return rc;
-}
-EXPORT_SYMBOL(pm8058_upl_config);
-
-#if defined(CONFIG_DEBUG_FS)
-
-static int truthtable_set(void *data, u64 val)
-{
-	int rc;
-
-	rc = pm8058_upl_write_truthtable(data, val);
-	if (rc)
-		pr_err("%s: pm8058_upl_write_truthtable: rc=%d, "
-			"truthtable=0x%llX\n", __func__, rc, val);
-	return rc;
-}
-
-static int truthtable_get(void *data, u64 *val)
-{
-	int rc;
-	u16 truthtable;
-
-	rc = pm8058_upl_read_truthtable(data, &truthtable);
-	if (rc)
-		pr_err("%s: pm8058_upl_read_truthtable: rc=%d, "
-			"truthtable=0x%X\n", __func__, rc, truthtable);
-	if (val)
-		*val = truthtable;
-
-	return rc;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(upl_truthtable_fops, truthtable_get,
-			truthtable_set, "0x%04llX\n");
-
-/* enter values as 0xMMMMFFFF where MMMM is the mask and FFFF is the flags */
-static int control_set(void *data, u64 val)
-{
-	u8 mask, flags;
-	int rc;
-
-	flags = val & 0xFFFF;
-	mask = (val >> 16) & 0xFFFF;
-
-	rc = pm8058_upl_config(data, mask, flags);
-	if (rc)
-		pr_err("%s: pm8058_upl_config: rc=%d, mask = 0x%X, "
-			"flags = 0x%X\n", __func__, rc, mask, flags);
-	return rc;
-}
-
-static int control_get(void *data, u64 *val)
-{
-	struct pm8058_upl_device *upldev;
-	int rc = 0;
-	u8 ctrl;
-
-	upldev = data;
-
-	mutex_lock(&upldev->upl_mutex);
-
-	rc = pm8058_read(upldev->pm_chip, SSBI_REG_UPL_CTRL, &ctrl, 1);
-	if (rc)
-		pr_err("%s: FAIL pm8058_read(): rc=%d (ctrl=0x%02X)\n",
-		       __func__, rc, ctrl);
-
-	mutex_unlock(&upldev->upl_mutex);
-
-	*val = ctrl;
-
-	return rc;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(upl_control_fops, control_get,
-			control_set, "0x%02llX\n");
-
-static int pm8058_upl_debug_init(struct pm8058_upl_device *upldev)
-{
-	struct dentry *dent;
-	struct dentry *temp;
-
-	dent = debugfs_create_dir("pm8058-upl", NULL);
-	if (dent == NULL || IS_ERR(dent)) {
-		pr_err("%s: ERR debugfs_create_dir: dent=0x%X\n",
-					__func__, (unsigned)dent);
-		return -ENOMEM;
-	}
-
-	temp = debugfs_create_file("truthtable", S_IRUSR | S_IWUSR, dent,
-					upldev, &upl_truthtable_fops);
-	if (temp == NULL || IS_ERR(temp)) {
-		pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
-					__func__, (unsigned)dent);
-		goto debug_error;
-	}
-
-	temp = debugfs_create_file("control", S_IRUSR | S_IWUSR, dent,
-					upldev, &upl_control_fops);
-	if (temp == NULL || IS_ERR(temp)) {
-		pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
-					__func__, (unsigned)dent);
-		goto debug_error;
-	}
-
-	upldev->dent = dent;
-	return 0;
-
-debug_error:
-	debugfs_remove_recursive(dent);
-	return -ENOMEM;
-}
-
-static int __devexit pm8058_upl_debug_remove(struct pm8058_upl_device *upldev)
-{
-	debugfs_remove_recursive(upldev->dent);
-	return 0;
-}
-
-#endif /* CONFIG_DEBUG_FS */
-
-static int __devinit pmic8058_upl_probe(struct platform_device *pdev)
-{
-	struct pm8058_chip		*pm_chip;
-	struct pm8058_upl_device	*upldev;
-
-	pm_chip = dev_get_drvdata(pdev->dev.parent);
-	if (pm_chip == NULL) {
-		pr_err("%s: no parent data passed in.\n", __func__);
-		return -EFAULT;
-	}
-
-	upldev = kzalloc(sizeof *upldev, GFP_KERNEL);
-	if (upldev == NULL) {
-		pr_err("%s: kzalloc() failed.\n", __func__);
-		return -ENOMEM;
-	}
-
-	mutex_init(&upldev->upl_mutex);
-
-	upldev->pm_chip = pm_chip;
-	upl_dev = upldev;
-	platform_set_drvdata(pdev, upldev);
-
-#if defined(CONFIG_DEBUG_FS)
-	pm8058_upl_debug_init(upl_dev);
-#endif
-	pr_notice("%s: OK\n", __func__);
-	return 0;
-}
-
-static int __devexit pmic8058_upl_remove(struct platform_device *pdev)
-{
-	struct pm8058_upl_device *upldev = platform_get_drvdata(pdev);
-
-#if defined(CONFIG_DEBUG_FS)
-	pm8058_upl_debug_remove(upldev);
-#endif
-
-	platform_set_drvdata(pdev, upldev->pm_chip);
-	kfree(upldev);
-	pr_notice("%s: OK\n", __func__);
-
-	return 0;
-}
-
-static struct platform_driver pmic8058_upl_driver = {
-	.probe		= pmic8058_upl_probe,
-	.remove		= __devexit_p(pmic8058_upl_remove),
-	.driver		= {
-		.name = "pm8058-upl",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init pm8058_upl_init(void)
-{
-	return platform_driver_register(&pmic8058_upl_driver);
-}
-
-static void __exit pm8058_upl_exit(void)
-{
-	platform_driver_unregister(&pmic8058_upl_driver);
-}
-
-module_init(pm8058_upl_init);
-module_exit(pm8058_upl_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("PMIC8058 UPL driver");
-MODULE_VERSION("1.0");
-MODULE_ALIAS("platform:pmic8058-upl");
diff --git a/drivers/misc/pmic8058-xoadc.c b/drivers/misc/pmic8058-xoadc.c
index b63800c..14b790f 100644
--- a/drivers/misc/pmic8058-xoadc.c
+++ b/drivers/misc/pmic8058-xoadc.c
@@ -17,7 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/err.h>
 #include <linux/msm_adc.h>
-#include <linux/pmic8058-xoadc.h>
+#include <linux/mfd/pm8xxx/core.h>
 #include <linux/mfd/pmic8058.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
@@ -54,8 +54,8 @@
 #define ADC_ARB_USRP_DATA1                      0x19C
 
 struct pmic8058_adc {
+	struct device *dev;
 	struct xoadc_platform_data *pdata;
-	struct pm8058_chip *pm_chip;
 	struct adc_properties *adc_prop;
 	struct xoadc_conv_state	conv[2];
 	int xoadc_queue_count;
@@ -144,8 +144,8 @@
 	/* Write twice to the CNTRL register for the arbiter settings
 	   to take into effect */
 	for (i = 0; i < 2; i++) {
-		rc = pm8058_write(adc_pmic->pm_chip, ADC_ARB_USRP_CNTRL,
-					&data_arb_cntrl, 1);
+		rc = pm8xxx_writeb(adc_pmic->dev->parent, ADC_ARB_USRP_CNTRL,
+							data_arb_cntrl);
 		if (rc < 0) {
 			pr_debug("%s: PM8058 write failed\n", __func__);
 			return rc;
@@ -165,8 +165,8 @@
 {
 
 	struct pmic8058_adc *adc_pmic = pmic_adc[adc_instance];
-	u8 data_arb_cntrl, data_amux_chan, data_arb_rsv, data_ana_param;
-	u8 data_dig_param, data_ana_param2;
+	u8 data_arb_cntrl = 0, data_amux_chan = 0, data_arb_rsv = 0;
+	u8 data_dig_param = 0, data_ana_param2 = 0, data_ana_param = 0;
 	int rc;
 
 	rc = pm8058_xoadc_arb_cntrl(1, adc_instance, slot->chan_path);
@@ -307,15 +307,15 @@
 		break;
 	}
 
-	rc = pm8058_write(adc_pmic->pm_chip,
-			ADC_ARB_USRP_AMUX_CNTRL, &data_amux_chan, 1);
+	rc = pm8xxx_writeb(adc_pmic->dev->parent,
+			ADC_ARB_USRP_AMUX_CNTRL, data_amux_chan);
 	if (rc < 0) {
 		pr_debug("%s: PM8058 write failed\n", __func__);
 		return rc;
 	}
 
-	rc = pm8058_write(adc_pmic->pm_chip,
-			ADC_ARB_USRP_RSV, &data_arb_rsv, 1);
+	rc = pm8xxx_writeb(adc_pmic->dev->parent,
+			ADC_ARB_USRP_RSV, data_arb_rsv);
 	if (rc < 0) {
 		pr_debug("%s: PM8058 write failed\n", __func__);
 		return rc;
@@ -341,22 +341,22 @@
 		break;
 	}
 
-	rc = pm8058_write(adc_pmic->pm_chip,
-				ADC_ARB_USRP_ANA_PARAM, &data_ana_param, 1);
+	rc = pm8xxx_writeb(adc_pmic->dev->parent,
+				ADC_ARB_USRP_ANA_PARAM, data_ana_param);
 	if (rc < 0) {
 		pr_debug("%s: PM8058 write failed\n", __func__);
 		return rc;
 	}
 
-	rc = pm8058_write(adc_pmic->pm_chip,
-				ADC_ARB_USRP_DIG_PARAM, &data_dig_param, 1);
+	rc = pm8xxx_writeb(adc_pmic->dev->parent,
+			ADC_ARB_USRP_DIG_PARAM, data_dig_param);
 	if (rc < 0) {
 		pr_debug("%s: PM8058 write failed\n", __func__);
 		return rc;
 	}
 
-	rc = pm8058_write(adc_pmic->pm_chip,
-				ADC_ARB_USRP_ANA_PARAM, &data_ana_param2, 1);
+	rc = pm8xxx_writeb(adc_pmic->dev->parent,
+			ADC_ARB_USRP_ANA_PARAM, data_ana_param2);
 	if (rc < 0) {
 		pr_debug("%s: PM8058 write failed\n", __func__);
 		return rc;
@@ -364,8 +364,8 @@
 
 	enable_irq(adc_pmic->adc_irq);
 
-	rc = pm8058_write(adc_pmic->pm_chip,
-				ADC_ARB_USRP_CNTRL, &data_arb_cntrl, 1);
+	rc = pm8xxx_writeb(adc_pmic->dev->parent,
+				ADC_ARB_USRP_CNTRL, data_arb_cntrl);
 	if (rc < 0) {
 		pr_debug("%s: PM8058 write failed\n", __func__);
 		return rc;
@@ -434,13 +434,15 @@
 	if (!xoadc_initialized)
 		return -ENODEV;
 
-	rc = pm8058_read(adc_pmic->pm_chip, ADC_ARB_USRP_DATA0, &rslt_lsb, 1);
+	rc = pm8xxx_readb(adc_pmic->dev->parent, ADC_ARB_USRP_DATA0,
+							&rslt_lsb);
 	if (rc < 0) {
 		pr_debug("%s: PM8058 read failed\n", __func__);
 		return rc;
 	}
 
-	rc = pm8058_read(adc_pmic->pm_chip, ADC_ARB_USRP_DATA1, &rslt_msb, 1);
+	rc = pm8xxx_readb(adc_pmic->dev->parent, ADC_ARB_USRP_DATA1,
+							&rslt_msb);
 	if (rc < 0) {
 		pr_debug("%s: PM8058 read failed\n", __func__);
 		return rc;
@@ -657,7 +659,7 @@
 
 	wake_lock_destroy(&adc_pmic->adc_wakelock);
 	msm_xo_put(adc_pmic->adc_voter);
-	platform_set_drvdata(pdev, adc_pmic->pm_chip);
+	platform_set_drvdata(pdev, NULL);
 	device_init_wakeup(&pdev->dev, 0);
 	kfree(adc_pmic);
 	xoadc_initialized = false;
@@ -668,16 +670,9 @@
 static int __devinit pm8058_xoadc_probe(struct platform_device *pdev)
 {
 	struct xoadc_platform_data *pdata = pdev->dev.platform_data;
-	struct pm8058_chip *pm_chip;
 	struct pmic8058_adc *adc_pmic;
 	int i, rc = 0;
 
-	pm_chip = dev_get_drvdata(pdev->dev.parent);
-	if (pm_chip == NULL) {
-		dev_err(&pdev->dev, "no parent data passed in\n");
-		return -EFAULT;
-	}
-
 	if (!pdata) {
 		dev_err(&pdev->dev, "no platform data?\n");
 		return -EINVAL;
@@ -689,7 +684,7 @@
 		return -ENOMEM;
 	}
 
-	adc_pmic->pm_chip = pm_chip;
+	adc_pmic->dev = &pdev->dev;
 	adc_pmic->adc_prop = pdata->xoadc_prop;
 	adc_pmic->xoadc_num = pdata->xoadc_num;
 	adc_pmic->xoadc_queue_count = 0;
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index cca1035..3590e6d 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -244,7 +244,7 @@
 
 config BATTERY_MSM8X60
 	tristate "MSM8X60 battery"
-	select PMIC8058_BATTALARM
+	select PMIC8XXX_BATTALARM
 	help
 	  Some MSM boards have dual charging paths to charge the battery.
 	  Say Y to enable support for the battery charging in
diff --git a/drivers/power/pmic8058-charger.c b/drivers/power/pmic8058-charger.c
index a3ce54d..70b5d59 100644
--- a/drivers/power/pmic8058-charger.c
+++ b/drivers/power/pmic8058-charger.c
@@ -15,7 +15,6 @@
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
 #include <linux/errno.h>
-#include <linux/mfd/pmic8058.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/bitops.h>
@@ -25,8 +24,10 @@
 #include <linux/slab.h>
 #include <linux/msm_adc.h>
 #include <linux/notifier.h>
-#include <linux/pmic8058-batt-alarm.h>
+#include <linux/mfd/pm8xxx/core.h>
+#include <linux/mfd/pmic8058.h>
 #include <linux/pmic8058-charger.h>
+#include <linux/mfd/pm8xxx/batt-alarm.h>
 
 #include <mach/msm_xo.h>
 #include <mach/msm_hsusb.h>
@@ -177,7 +178,6 @@
 
 struct pm8058_charger {
 	struct pmic_charger_pdata *pdata;
-	struct pm8058_chip *pm_chip;
 	struct device *dev;
 
 	int pmic_chg_irq[PMIC_CHG_MAX_INTS];
@@ -228,7 +228,11 @@
 	if (rc)
 		goto out;
 
-	rc = pm8058_batt_alarm_threshold_set(resume_mv, 4300);
+	rc = pm8xxx_batt_alarm_threshold_set(
+			PM8XXX_BATT_ALARM_LOWER_COMPARATOR, resume_mv);
+	if (!rc)
+		rc = pm8xxx_batt_alarm_threshold_set(
+			PM8XXX_BATT_ALARM_UPPER_COMPARATOR, 4300);
 
 out:
 	mutex_unlock(&batt_alarm_lock);
@@ -255,15 +259,9 @@
 
 static int pm_chg_get_rt_status(int irq)
 {
-	int count = 3;
 	int ret;
 
-	while ((ret =
-		pm8058_irq_get_rt_status(pm8058_chg.pm_chip, irq)) == -EAGAIN
-	       && count--) {
-		dev_info(pm8058_chg.dev, "%s trycount=%d\n", __func__, count);
-		cpu_relax();
-	}
+	ret = pm8xxx_read_irq_stat(pm8058_chg.dev->parent, irq);
 	if (ret == -EAGAIN)
 		return 0;
 	else
@@ -281,53 +279,53 @@
 	u8 temp;
 	int temp2;
 
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_CNTRL = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_CNTRL_2 = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_VMAX_SEL, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_VMAX_SEL, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_VMAX_SEL = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_VBAT_DET, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_VBAT_DET, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_VBAT_DET = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_IMAX, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_IMAX, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_IMAX = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TRICKLE, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TRICKLE, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_TRICKLE = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_ITERM, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_ITERM, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_ITERM = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TTRKL_MAX, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TTRKL_MAX, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_TTRKL_MAX = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TCHG_MAX, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TCHG_MAX, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_TCHG_MAX = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEMP_THRESH, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEMP_THRESH, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_TEMP_THRESH = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEMP_REG, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEMP_REG, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_TEMP_REG = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_PULSE, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_PULSE, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_PULSE = 0x%x\n", temp);
 
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_STATUS_CLEAR_IRQ_1,
-		    &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_STATUS_CLEAR_IRQ_1,
+		    &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_1 = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_STATUS_CLEAR_IRQ_3,
-		    &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_STATUS_CLEAR_IRQ_3,
+		    &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_3 = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_STATUS_CLEAR_IRQ_10,
-		    &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_STATUS_CLEAR_IRQ_10,
+		    &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_10 = 0x%x\n",
 		temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_STATUS_CLEAR_IRQ_11,
-		    &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_STATUS_CLEAR_IRQ_11,
+		    &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_11 = 0x%x\n",
 		temp);
 
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_MASK_IRQ_1, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_MASK_IRQ_1, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_1 = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_MASK_IRQ_3, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_MASK_IRQ_3, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_3 = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_MASK_IRQ_10, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_MASK_IRQ_10, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_10 = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_MASK_IRQ_11, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_MASK_IRQ_11, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_11 = 0x%x\n", temp);
 
 	temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHGVAL_IRQ]);
@@ -405,7 +403,7 @@
 	u8 temp;
 	int ret;
 
-	ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+	ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
 	if (ret)
 		return ret;
 	if (value)
@@ -413,7 +411,7 @@
 	else
 		temp &= ~BIT(CHG_USB_SUSPEND);
 
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, temp);
 }
 
 static int pm_chg_auto_disable(int value)
@@ -421,7 +419,7 @@
 	u8 temp;
 	int ret;
 
-	ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
 	if (ret)
 		return ret;
 	if (value)
@@ -429,7 +427,7 @@
 	else
 		temp &= ~BIT(CHARGE_AUTO_DIS);
 
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, temp);
 }
 
 static int pm_chg_batt_temp_disable(int value)
@@ -437,7 +435,7 @@
 	u8 temp;
 	int ret;
 
-	ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
 	if (ret)
 		return ret;
 	if (value)
@@ -445,7 +443,7 @@
 	else
 		temp &= ~BIT(CHG_BATT_TEMP_DIS);
 
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, temp);
 }
 
 static int pm_chg_vbatdet_set(int voltage)
@@ -463,7 +461,7 @@
 	temp = diff / PM8058_CHG_V_STEP_MV;
 	dev_dbg(pm8058_chg.dev, "%s voltage=%d setting %02x\n", __func__,
 		voltage, temp);
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_VBAT_DET, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_VBAT_DET, temp);
 }
 
 static int pm_chg_imaxsel_set(int chg_current)
@@ -484,7 +482,7 @@
 			__func__, chg_current);
 		temp = 31;
 	}
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_IMAX, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_IMAX, temp);
 }
 
 #define PM8058_CHG_VMAX_MIN  3300
@@ -501,7 +499,7 @@
 	temp = (voltage - PM8058_CHG_V_MIN_MV) / PM8058_CHG_V_STEP_MV;
 	dev_dbg(pm8058_chg.dev, "%s mV=%d setting %02x\n", __func__, voltage,
 		temp);
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_VMAX_SEL, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_VMAX_SEL, temp);
 }
 
 static int pm_chg_failed_clear(int value)
@@ -509,14 +507,14 @@
 	u8 temp;
 	int ret;
 
-	ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
 	if (ret)
 		return ret;
 	if (value)
 		temp |= BIT(CHG_FAILED_CLEAR);
 	else
 		temp &= ~BIT(CHG_FAILED_CLEAR);
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, temp);
 }
 
 static int pm_chg_iterm_set(int chg_current)
@@ -524,7 +522,7 @@
 	u8 temp;
 
 	temp = (chg_current / PM8058_CHG_I_TERM_STEP_MA) - 1;
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_ITERM, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_ITERM, temp);
 }
 
 static int pm_chg_tchg_set(int minutes)
@@ -532,7 +530,7 @@
 	u8 temp;
 
 	temp = (minutes >> PM8058_CHG_T_TCHG_SHIFT) - 1;
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TCHG_MAX, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TCHG_MAX, temp);
 }
 
 static int pm_chg_ttrkl_set(int minutes)
@@ -540,7 +538,8 @@
 	u8 temp;
 
 	temp = minutes - 1;
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TTRKL_MAX, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TTRKL_MAX,
+									temp);
 }
 
 static int pm_chg_enum_done_enable(int value)
@@ -548,7 +547,7 @@
 	u8 temp;
 	int ret;
 
-	ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
 	if (ret)
 		return ret;
 	if (value)
@@ -556,7 +555,7 @@
 	else
 		temp &= ~BIT(ENUM_DONE);
 
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, temp);
 }
 
 static uint32_t get_fsm_state(void)
@@ -564,8 +563,8 @@
 	u8 temp;
 
 	temp = 0x00;
-	pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_3, &temp, 1);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEST_3, &temp, 1);
+	pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_3, temp);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEST_3, &temp);
 	return (uint32_t)temp;
 }
 
@@ -590,7 +589,7 @@
 	u8 temp;
 	int ret;
 
-	ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+	ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
 	if (ret)
 		return ret;
 	if (value)
@@ -598,7 +597,7 @@
 	else
 		temp &= ~BIT(CHG_CHARGE_DIS);
 
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, temp);
 }
 
 static void pm8058_start_system_current(struct msm_hardware_charger *hw_chg,
@@ -734,7 +733,11 @@
 	case PMIC8058_CHG_STATE_ATC:
 	case PMIC8058_CHG_STATE_FAST_CHG:
 	case PMIC8058_CHG_STATE_TRKL_CHG:
-		rc = pm8058_batt_alarm_state_set(0, 0);
+		rc = pm8xxx_batt_alarm_disable(
+				PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+		if (!rc)
+			rc = pm8xxx_batt_alarm_disable(
+				PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
 		if (rc)
 			dev_err(pm8058_chg.dev,
 				"%s: unable to set alarm state\n", __func__);
@@ -863,25 +866,25 @@
 		}
 	} else {
 		if (pm8058_chg.present) {
-			ret = pm8058_read(pm8058_chg.pm_chip,
+			ret = pm8xxx_readb(pm8058_chg.dev->parent,
 						PM8058_OVP_TEST_REG,
-						&old, 1);
+						&old);
 			temp = old | BIT(FORCE_OVP_OFF);
-			ret = pm8058_write(pm8058_chg.pm_chip,
+			ret = pm8xxx_writeb(pm8058_chg.dev->parent,
 						PM8058_OVP_TEST_REG,
-						&temp, 1);
+						temp);
 			temp = 0xFC;
-			ret = pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST,
-						&temp, 1);
+			ret = pm8xxx_writeb(pm8058_chg.dev->parent,
+					PM8058_CHG_TEST, temp);
 			/* 10 ms sleep is for the VCHG to discharge */
 			msleep(10);
 			temp = 0xF0;
-			ret = pm8058_write(pm8058_chg.pm_chip,
+			ret = pm8xxx_writeb(pm8058_chg.dev->parent,
 						PM8058_CHG_TEST,
-						&temp, 1);
-			ret = pm8058_write(pm8058_chg.pm_chip,
+						temp);
+			ret = pm8xxx_writeb(pm8058_chg.dev->parent,
 						PM8058_OVP_TEST_REG,
-						&old, 1);
+						old);
 
 			pm_chg_enum_done_enable(0);
 			pm_chg_auto_disable(1);
@@ -904,21 +907,21 @@
 
 		pm_chg_enum_done_enable(0);
 		pm_chg_auto_disable(1);
-		ret = pm8058_read(pm8058_chg.pm_chip,
-				PM8058_OVP_TEST_REG, &old, 1);
+		ret = pm8xxx_readb(pm8058_chg.dev->parent,
+				PM8058_OVP_TEST_REG, &old);
 		temp = old | BIT(FORCE_OVP_OFF);
-		ret = pm8058_write(pm8058_chg.pm_chip,
-				PM8058_OVP_TEST_REG, &temp, 1);
+		ret = pm8xxx_writeb(pm8058_chg.dev->parent,
+				PM8058_OVP_TEST_REG, temp);
 		temp = 0xFC;
-		ret = pm8058_write(pm8058_chg.pm_chip,
-				PM8058_CHG_TEST, &temp, 1);
+		ret = pm8xxx_writeb(pm8058_chg.dev->parent,
+				PM8058_CHG_TEST, temp);
 		/* 10 ms sleep is for the VCHG to discharge */
 		msleep(10);
 		temp = 0xF0;
-		ret = pm8058_write(pm8058_chg.pm_chip,
-				PM8058_CHG_TEST, &temp, 1);
-		ret = pm8058_write(pm8058_chg.pm_chip,
-				PM8058_OVP_TEST_REG, &old, 1);
+		ret = pm8xxx_writeb(pm8058_chg.dev->parent,
+				PM8058_CHG_TEST, temp);
+		ret = pm8xxx_writeb(pm8058_chg.dev->parent,
+				PM8058_OVP_TEST_REG, old);
 
 		if (!is_chg_plugged_in()) {
 			msm_charger_notify_event(&usb_hw_chg,
@@ -983,8 +986,8 @@
 	u8 temp;
 
 	temp = 0x00;
-	if (!pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_3, &temp, 1)) {
-		pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEST_3, &temp, 1);
+	if (!pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_3, temp)) {
+		pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEST_3, &temp);
 		dev_dbg(pm8058_chg.dev, "%s state=%d\n", __func__, temp);
 	}
 	return IRQ_HANDLED;
@@ -1187,7 +1190,7 @@
 			"%s:couldnt find resource AUTO_CHGDONE\n", __func__);
 		goto err_out;
 	} else {
-		ret = request_threaded_irq(res->start, NULL,
+		ret = request_irq(res->start,
 				  pm8058_chg_auto_chgdone_handler,
 				  IRQF_TRIGGER_RISING,
 				  res->name, NULL);
@@ -1208,7 +1211,7 @@
 			"%s:couldnt find resource AUTO_CHGFAIL\n", __func__);
 		goto err_out;
 	} else {
-		ret = request_threaded_irq(res->start, NULL,
+		ret = request_irq(res->start,
 				  pm8058_chg_auto_chgfail_handler,
 				  IRQF_TRIGGER_RISING, res->name, NULL);
 		if (ret < 0) {
@@ -1227,7 +1230,7 @@
 			"%s:couldnt find resource CHGSTATE\n", __func__);
 		goto err_out;
 	} else {
-		ret = request_threaded_irq(res->start, NULL,
+		ret = request_irq(res->start,
 				  pm8058_chg_chgstate_handler,
 				  IRQF_TRIGGER_RISING, res->name, NULL);
 		if (ret < 0) {
@@ -1246,7 +1249,7 @@
 			"%s:couldnt find resource FASTCHG\n", __func__);
 		goto err_out;
 	} else {
-		ret = request_threaded_irq(res->start, NULL,
+		ret = request_irq(res->start,
 				  pm8058_chg_fastchg_handler,
 				  IRQF_TRIGGER_RISING, res->name, NULL);
 		if (ret < 0) {
@@ -1265,7 +1268,7 @@
 			"%s:couldnt find resource CHG_END\n", __func__);
 		goto err_out;
 	} else {
-		ret = request_threaded_irq(res->start, NULL,
+		ret = request_irq(res->start,
 				  pm8058_chg_batttemp_handler,
 				  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 				  res->name, NULL);
@@ -1286,7 +1289,7 @@
 			"%s:couldnt find resource BATT_REPLACE\n", __func__);
 		goto err_out;
 	} else {
-		ret = request_threaded_irq(res->start, NULL,
+		ret = request_irq(res->start,
 				  pm8058_chg_batt_replace_handler,
 				  IRQF_TRIGGER_RISING, res->name, NULL);
 		if (ret < 0) {
@@ -1305,7 +1308,7 @@
 			"%s:couldnt find resource BATTCONNECT\n", __func__);
 		goto err_out;
 	} else {
-		ret = request_threaded_irq(res->start, NULL,
+		ret = request_irq(res->start,
 				  pm8058_chg_battconnect_handler,
 				  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 				  res->name, NULL);
@@ -1351,7 +1354,7 @@
 	u8 temp;
 	int rc;
 
-	rc = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+	rc = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
 	if (rc)
 		return rc;
 
@@ -1367,7 +1370,7 @@
 	u8 temp;
 	int rc;
 
-	rc = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+	rc = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
 	if (rc)
 		return rc;
 	if (on)
@@ -1375,7 +1378,7 @@
 	else
 		temp &= ~BIT(CHG_CHARGE_BAT);
 
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, temp);
 
 }
 EXPORT_SYMBOL(pm8058_set_charge_batt);
@@ -1496,12 +1499,12 @@
 	u8 temp;
 
 	temp = 0xA3;
-	pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_2, &temp, 1);
+	pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_2, temp);
 	temp = 0x84;
-	pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_2, &temp, 1);
+	pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_2, temp);
 	msleep(2);
 	temp = 0x80;
-	pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_2, &temp, 1);
+	pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_2, temp);
 	return 0;
 }
 
@@ -1511,7 +1514,7 @@
 	int ret;
 	u8 temp;
 
-	ret = pm8058_read(pm8058_chg.pm_chip, i, &temp, 1);
+	ret = pm8xxx_readb(pm8058_chg.dev->parent, i, &temp);
 	if (ret)
 		return -EAGAIN;
 	*val = temp;
@@ -1525,7 +1528,7 @@
 	u8 temp;
 
 	temp = (u8) val;
-	ret = pm8058_write(pm8058_chg.pm_chip, i, &temp, 1);
+	ret = pm8xxx_writeb(pm8058_chg.dev->parent, i, temp);
 	mb();
 	if (ret)
 		return -EAGAIN;
@@ -1821,7 +1824,11 @@
 		break;
 	/* expected case - trip of low threshold */
 	case 1:
-		rc = pm8058_batt_alarm_state_set(0, 0);
+		rc = pm8xxx_batt_alarm_disable(
+				PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+		if (!rc)
+			rc = pm8xxx_batt_alarm_disable(
+				PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
 		if (rc)
 			dev_err(pm8058_chg.dev,
 				"%s: unable to set alarm state\n", __func__);
@@ -1841,8 +1848,15 @@
 
 static int pm8058_monitor_for_recharging(void)
 {
+	int rc;
 	/* enable low comparator */
-	return pm8058_batt_alarm_state_set(1, 0);
+	rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+	if (!rc)
+		return pm8xxx_batt_alarm_enable(
+				PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
+
+	return rc;
+
 }
 
 static struct msm_battery_gauge pm8058_batt_gauge = {
@@ -1860,33 +1874,30 @@
 	int ret = 0;
 
 	temp = 0x10;
-	ret |= pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST, &temp, 1);
-	ret |= pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEST, &old, 1);
+	ret |= pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST, temp);
+	ret |= pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEST, &old);
 	old = old & ~BIT(IGNORE_LL);
 	temp = 0x90  | (0xF & old);
-	ret |= pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST, &temp, 1);
+	ret |= pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST, temp);
 
 	return ret;
 }
 
 static int __devinit pm8058_charger_probe(struct platform_device *pdev)
 {
-	struct pm8058_chip *pm_chip;
 	struct pmic8058_charger_data *pdata;
 	int rc = 0;
 
-	pm_chip = dev_get_drvdata(pdev->dev.parent);
-	if (pm_chip == NULL) {
-		pr_err("%s:no parent data passed in.\n", __func__);
-		return -EFAULT;
-	}
-
-	pm8058_chg.pm_chip = pm_chip;
 	pm8058_chg.pdata = pdev->dev.platform_data;
 	pm8058_chg.dev = &pdev->dev;
 	pdata = (struct pmic8058_charger_data *) pm8058_chg.pdata;
 
-	if (pdata) {
+	if (pdata == NULL) {
+		pr_err("%s: pdata not present\n", __func__);
+		return -EINVAL;
+	}
+
+	if (pdata->charger_data_valid) {
 		usb_hw_chg.type = pdata->charger_type;
 		chg_data.charger_type = pdata->charger_type;
 		chg_data.max_source_current = pdata->max_source_current;
@@ -1928,7 +1939,10 @@
 	pm8058_chg_enable_irq(BATTTEMP_IRQ);
 	pm8058_chg_enable_irq(BATTCONNECT_IRQ);
 
-	rc = pm8058_batt_alarm_state_set(0, 0);
+	rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+	if (!rc)
+		rc = pm8xxx_batt_alarm_disable(
+			PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
 	if (rc) {
 		pr_err("%s: unable to set batt alarm state\n", __func__);
 		goto free_irq;
@@ -1938,26 +1952,31 @@
 	 * The batt-alarm driver requires sane values for both min / max,
 	 * regardless of whether they're both activated.
 	 */
-	rc = pm8058_batt_alarm_threshold_set(resume_mv, 4300);
+	rc = pm8xxx_batt_alarm_threshold_set(
+			PM8XXX_BATT_ALARM_LOWER_COMPARATOR, resume_mv);
+	if (!rc)
+		rc = pm8xxx_batt_alarm_threshold_set(
+			PM8XXX_BATT_ALARM_UPPER_COMPARATOR, 4300);
 	if (rc) {
 		pr_err("%s: unable to set batt alarm threshold\n", __func__);
 		goto free_irq;
 	}
 
-	rc = pm8058_batt_alarm_hold_time_set(PM8058_BATT_ALARM_HOLD_TIME_16_MS);
+	rc = pm8xxx_batt_alarm_hold_time_set(
+				PM8XXX_BATT_ALARM_HOLD_TIME_16_MS);
 	if (rc) {
 		pr_err("%s: unable to set batt alarm hold time\n", __func__);
 		goto free_irq;
 	}
 
 	/* PWM enabled at 2Hz */
-	rc = pm8058_batt_alarm_pwm_rate_set(1, 7, 4);
+	rc = pm8xxx_batt_alarm_pwm_rate_set(1, 7, 4);
 	if (rc) {
 		pr_err("%s: unable to set batt alarm pwm rate\n", __func__);
 		goto free_irq;
 	}
 
-	rc = pm8058_batt_alarm_register_notifier(&alarm_notifier);
+	rc = pm8xxx_batt_alarm_register_notifier(&alarm_notifier);
 	if (rc) {
 		pr_err("%s: unable to register alarm notifier\n", __func__);
 		goto free_irq;
@@ -1987,11 +2006,14 @@
 	remove_debugfs_entries();
 	kfree(chip);
 
-	rc = pm8058_batt_alarm_state_set(0, 0);
+	rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+	if (!rc)
+		rc = pm8xxx_batt_alarm_disable(
+			PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
 	if (rc)
 		pr_err("%s: unable to set batt alarm state\n", __func__);
 
-	rc |= pm8058_batt_alarm_unregister_notifier(&alarm_notifier);
+	rc |= pm8xxx_batt_alarm_unregister_notifier(&alarm_notifier);
 	if (rc)
 		pr_err("%s: unable to register alarm notifier\n", __func__);
 	return rc;
diff --git a/drivers/regulator/pm8058-xo.c b/drivers/regulator/pm8058-xo.c
index 581e228..b778660 100644
--- a/drivers/regulator/pm8058-xo.c
+++ b/drivers/regulator/pm8058-xo.c
@@ -19,6 +19,7 @@
 #include <linux/bitops.h>
 #include <linux/mfd/pmic8058.h>
 #include <linux/regulator/driver.h>
+#include <linux/mfd/pm8xxx/core.h>
 #include <linux/regulator/pm8058-xo.h>
 
 /* XO buffer masks and values */
@@ -39,6 +40,7 @@
 #define XO_DISABLE		(XO_MODE_MANUAL | XO_BUFFER_DISABLE)
 
 struct pm8058_xo_buffer {
+	struct device			*dev;
 	struct pm8058_xo_pdata		*pdata;
 	struct regulator_dev		*rdev;
 	u16				ctrl_addr;
@@ -55,7 +57,7 @@
 	XO_BUFFER(A1, 0x186),
 };
 
-static int pm8058_xo_buffer_write(struct pm8058_chip *chip,
+static int pm8058_xo_buffer_write(struct pm8058_xo_buffer *xo,
 		u16 addr, u8 val, u8 mask, u8 *reg_save)
 {
 	u8	reg;
@@ -63,10 +65,10 @@
 
 	reg = (*reg_save & ~mask) | (val & mask);
 	if (reg != *reg_save)
-		rc = pm8058_write(chip, addr, &reg, 1);
+		rc = pm8xxx_writeb(xo->dev->parent, addr, reg);
 
 	if (rc)
-		pr_err("FAIL: pm8058_write: rc=%d\n", rc);
+		pr_err("FAIL: pm8xxx_write: rc=%d\n", rc);
 	else
 		*reg_save = reg;
 	return rc;
@@ -75,10 +77,9 @@
 static int pm8058_xo_buffer_enable(struct regulator_dev *dev)
 {
 	struct pm8058_xo_buffer *xo = rdev_get_drvdata(dev);
-	struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
 	int rc;
 
-	rc = pm8058_xo_buffer_write(chip, xo->ctrl_addr, XO_ENABLE,
+	rc = pm8058_xo_buffer_write(xo, xo->ctrl_addr, XO_ENABLE,
 				    XO_ENABLE_MASK, &xo->ctrl_reg);
 	if (rc)
 		pr_err("FAIL: pm8058_xo_buffer_write: rc=%d\n", rc);
@@ -99,10 +100,9 @@
 static int pm8058_xo_buffer_disable(struct regulator_dev *dev)
 {
 	struct pm8058_xo_buffer *xo = rdev_get_drvdata(dev);
-	struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
 	int rc;
 
-	rc = pm8058_xo_buffer_write(chip, xo->ctrl_addr, XO_DISABLE,
+	rc = pm8058_xo_buffer_write(xo, xo->ctrl_addr, XO_DISABLE,
 				    XO_ENABLE_MASK, &xo->ctrl_reg);
 	if (rc)
 		pr_err("FAIL: pm8058_xo_buffer_write: rc=%d\n", rc);
@@ -130,23 +130,21 @@
 	VREG_DESCRIP(PM8058_XO_ID_A1, "8058_xo_a1", &pm8058_xo_ops),
 };
 
-static int pm8058_init_xo_buffer(struct pm8058_chip *chip,
-				 struct pm8058_xo_buffer *xo)
+static int pm8058_init_xo_buffer(struct pm8058_xo_buffer *xo)
 {
 	int	rc;
 
 	/* Save the current control register state */
-	rc = pm8058_read(chip, xo->ctrl_addr, &xo->ctrl_reg, 1);
+	rc = pm8xxx_readb(xo->dev->parent, xo->ctrl_addr, &xo->ctrl_reg);
 
 	if (rc)
-		pr_err("FAIL: pm8058_read: rc=%d\n", rc);
+		pr_err("FAIL: pm8xxx_read: rc=%d\n", rc);
 	return rc;
 }
 
 static int __devinit pm8058_xo_buffer_probe(struct platform_device *pdev)
 {
 	struct regulator_desc *rdesc;
-	struct pm8058_chip *chip;
 	struct pm8058_xo_buffer *xo;
 	int rc = 0;
 
@@ -154,16 +152,15 @@
 		return -EINVAL;
 
 	if (pdev->id >= 0 && pdev->id < PM8058_XO_ID_MAX) {
-		chip = dev_get_drvdata(pdev->dev.parent);
 		rdesc = &pm8058_xo_buffer_desc[pdev->id];
 		xo = &pm8058_xo_buffer[pdev->id];
 		xo->pdata = pdev->dev.platform_data;
+		xo->dev  = &pdev->dev;
 
-		rc = pm8058_init_xo_buffer(chip, xo);
+		rc = pm8058_init_xo_buffer(xo);
 		if (rc)
 			goto bail;
 
-		platform_set_drvdata(pdev, chip);
 		xo->rdev = regulator_register(rdesc, &pdev->dev,
 					&xo->pdata->init_data, xo);
 		if (IS_ERR(xo->rdev)) {
diff --git a/drivers/regulator/pmic8058-regulator.c b/drivers/regulator/pmic8058-regulator.c
index c11f32b..e137b0f 100644
--- a/drivers/regulator/pmic8058-regulator.c
+++ b/drivers/regulator/pmic8058-regulator.c
@@ -18,6 +18,7 @@
 #include <linux/mfd/pmic8058.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
+#include <linux/mfd/pm8xxx/core.h>
 #include <linux/regulator/pmic8058-regulator.h>
 
 /* Regulator types */
@@ -205,6 +206,7 @@
 };
 
 struct pm8058_vreg {
+	struct device			*dev;
 	struct pm8058_vreg_pdata	*pdata;
 	struct regulator_dev		*rdev;
 	struct pm8058_enable		*global_enable[GLOBAL_ENABLE_MAX];
@@ -375,11 +377,9 @@
 	NCP(NCP, 0x090, 0x0EC),
 };
 
-static int pm8058_smps_set_voltage_advanced(struct pm8058_vreg *vreg,
-					struct pm8058_chip *chip, int uV,
+static int pm8058_smps_set_voltage_advanced(struct pm8058_vreg *vreg, int uV,
 					int force_on);
-static int pm8058_smps_set_voltage_legacy(struct pm8058_vreg *vreg,
-					struct pm8058_chip *chip, int uV);
+static int pm8058_smps_set_voltage_legacy(struct pm8058_vreg *vreg, int uV);
 static int _pm8058_vreg_is_enabled(struct pm8058_vreg *vreg);
 
 static unsigned int pm8058_vreg_get_mode(struct regulator_dev *dev);
@@ -387,7 +387,7 @@
 static void print_write_error(struct pm8058_vreg *vreg, int rc,
 				const char *func);
 
-static int pm8058_vreg_write(struct pm8058_chip *chip,
+static int pm8058_vreg_write(struct pm8058_vreg *vreg,
 		u16 addr, u8 val, u8 mask, u8 *reg_save)
 {
 	int rc = 0;
@@ -395,9 +395,9 @@
 
 	reg = (*reg_save & ~mask) | (val & mask);
 	if (reg != *reg_save)
-		rc = pm8058_write(chip, addr, &reg, 1);
+		rc = pm8xxx_writeb(vreg->dev->parent, addr, reg);
 	if (rc)
-		pr_err("%s: pm8058_write failed, rc=%d\n", __func__, rc);
+		pr_err("%s: pm8xxx_write failed, rc=%d\n", __func__, rc);
 	else
 		*reg_save = reg;
 	return rc;
@@ -416,14 +416,13 @@
 }
 
 
-static int pm8058_vreg_set_global_enable(struct pm8058_vreg *vreg,
-					 struct pm8058_chip *chip, int on)
+static int pm8058_vreg_set_global_enable(struct pm8058_vreg *vreg, int on)
 {
 	int rc = 0, i;
 
 	for (i = 0;
 	     (i < GLOBAL_ENABLE_MAX) && !rc && vreg->global_enable[i]; i++)
-		rc = pm8058_vreg_write(chip, vreg->global_enable[i]->addr,
+		rc = pm8058_vreg_write(vreg, vreg->global_enable[i]->addr,
 					(on ? vreg->global_enable_mask[i] : 0),
 					vreg->global_enable_mask[i],
 					&vreg->global_enable[i]->reg);
@@ -452,8 +451,7 @@
 	return ret;
 }
 
-static int pm8058_vreg_set_pin_ctrl(struct pm8058_vreg *vreg,
-		struct pm8058_chip *chip, int on)
+static int pm8058_vreg_set_pin_ctrl(struct pm8058_vreg *vreg, int on)
 {
 	int rc = 0, bank;
 	u8 val = 0, mask;
@@ -473,7 +471,7 @@
 				val |= LDO_TEST_PIN_CTRL_EN3;
 
 			bank = (pf == PM8058_VREG_PIN_FN_ENABLE ? 5 : 6);
-			rc = pm8058_vreg_write(chip, vreg->test_addr,
+			rc = pm8058_vreg_write(vreg, vreg->test_addr,
 				val | REGULATOR_BANK_SEL(bank)
 				  | REGULATOR_BANK_WRITE,
 				LDO_TEST_PIN_CTRL_MASK | REGULATOR_BANK_MASK,
@@ -484,26 +482,25 @@
 			val = LDO_TEST_LPM_SEL_CTRL | REGULATOR_BANK_WRITE
 				| REGULATOR_BANK_SEL(0);
 			mask = LDO_TEST_LPM_MASK | REGULATOR_BANK_MASK;
-			rc = pm8058_vreg_write(chip, vreg->test_addr, val, mask,
+			rc = pm8058_vreg_write(vreg, vreg->test_addr, val, mask,
 						&vreg->test_reg[0]);
 			if (rc)
 				goto bail;
 
 			if (pf == PM8058_VREG_PIN_FN_ENABLE) {
 				/* Pin control ON/OFF */
-				rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+				rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
 					LDO_CTRL_PM_HPM,
 					LDO_ENABLE_MASK | LDO_CTRL_PM_MASK,
 					&vreg->ctrl_reg);
 				if (rc)
 					goto bail;
-				rc = pm8058_vreg_set_global_enable(vreg, chip,
-								   0);
+				rc = pm8058_vreg_set_global_enable(vreg, 0);
 				if (rc)
 					goto bail;
 			} else {
 				/* Pin control LPM/HPM */
-				rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+				rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
 					LDO_ENABLE | LDO_CTRL_PM_LPM,
 					LDO_ENABLE_MASK | LDO_CTRL_PM_MASK,
 					&vreg->ctrl_reg);
@@ -512,14 +509,14 @@
 			}
 		} else {
 			/* Pin control off */
-			rc = pm8058_vreg_write(chip, vreg->test_addr,
+			rc = pm8058_vreg_write(vreg, vreg->test_addr,
 				REGULATOR_BANK_SEL(5) | REGULATOR_BANK_WRITE,
 				LDO_TEST_PIN_CTRL_MASK | REGULATOR_BANK_MASK,
 				&vreg->test_reg[5]);
 			if (rc)
 				goto bail;
 
-			rc = pm8058_vreg_write(chip, vreg->test_addr,
+			rc = pm8058_vreg_write(vreg, vreg->test_addr,
 				REGULATOR_BANK_SEL(6) | REGULATOR_BANK_WRITE,
 				LDO_TEST_PIN_CTRL_MASK | REGULATOR_BANK_MASK,
 				&vreg->test_reg[6]);
@@ -551,29 +548,29 @@
 				if (pc & PM8058_VREG_PIN_CTRL_A1)
 					val |= SMPS_PIN_CTRL_LPM_A1;
 			}
-			rc = pm8058_vreg_set_global_enable(vreg, chip, 0);
+			rc = pm8058_vreg_set_global_enable(vreg, 0);
 			if (rc)
 				goto bail;
 
-			rc = pm8058_smps_set_voltage_legacy(vreg, chip,
+			rc = pm8058_smps_set_voltage_legacy(vreg,
 							vreg->save_uV);
 			if (rc)
 				goto bail;
 
-			rc = pm8058_vreg_write(chip, vreg->sleep_ctrl_addr, val,
+			rc = pm8058_vreg_write(vreg, vreg->sleep_ctrl_addr, val,
 				SMPS_PIN_CTRL_MASK | SMPS_PIN_CTRL_LPM_MASK,
 				&vreg->sleep_ctrl_reg);
 			if (rc)
 				goto bail;
 
-			rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+			rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
 				(pf == PM8058_VREG_PIN_FN_ENABLE
 				       ? 0 : SMPS_LEGACY_ENABLE),
 				SMPS_LEGACY_ENABLE, &vreg->ctrl_reg);
 			if (rc)
 				goto bail;
 
-			rc = pm8058_vreg_write(chip, vreg->clk_ctrl_addr,
+			rc = pm8058_vreg_write(vreg, vreg->clk_ctrl_addr,
 				(pf == PM8058_VREG_PIN_FN_ENABLE
 				       ? SMPS_CLK_CTRL_PWM : SMPS_CLK_CTRL_PFM),
 				SMPS_CLK_CTRL_MASK, &vreg->clk_ctrl_reg);
@@ -584,20 +581,20 @@
 			if (!SMPS_IN_ADVANCED_MODE(vreg)) {
 				if (_pm8058_vreg_is_enabled(vreg))
 					val = SMPS_LEGACY_ENABLE;
-				rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+				rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
 					val, SMPS_LEGACY_ENABLE,
 					&vreg->ctrl_reg);
 				if (rc)
 					goto bail;
 			}
 
-			rc = pm8058_vreg_write(chip, vreg->sleep_ctrl_addr, 0,
+			rc = pm8058_vreg_write(vreg, vreg->sleep_ctrl_addr, 0,
 				SMPS_PIN_CTRL_MASK | SMPS_PIN_CTRL_LPM_MASK,
 				&vreg->sleep_ctrl_reg);
 			if (rc)
 				goto bail;
 
-			rc = pm8058_smps_set_voltage_advanced(vreg, chip,
+			rc = pm8058_smps_set_voltage_advanced(vreg,
 							 vreg->save_uV, 0);
 			if (rc)
 				goto bail;
@@ -615,13 +612,13 @@
 			if (pc & PM8058_VREG_PIN_CTRL_A1)
 				val |= LVS_PIN_CTRL_EN3;
 
-			rc = pm8058_vreg_write(chip, vreg->ctrl_addr, val,
+			rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, val,
 					LVS_PIN_CTRL_MASK | LVS_ENABLE_MASK,
 					&vreg->ctrl_reg);
 			if (rc)
 				goto bail;
 
-			rc = pm8058_vreg_set_global_enable(vreg, chip, 0);
+			rc = pm8058_vreg_set_global_enable(vreg, 0);
 			if (rc)
 				goto bail;
 		} else {
@@ -629,7 +626,7 @@
 			if (_pm8058_vreg_is_enabled(vreg))
 				val = LVS_ENABLE;
 
-			rc = pm8058_vreg_write(chip, vreg->ctrl_addr, val,
+			rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, val,
 					LVS_ENABLE_MASK | LVS_PIN_CTRL_MASK,
 					&vreg->ctrl_reg);
 			if (rc)
@@ -649,7 +646,6 @@
 static int pm8058_vreg_enable(struct regulator_dev *dev)
 {
 	struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
 	int mode;
 	int rc = 0;
 
@@ -657,16 +653,15 @@
 
 	if (mode == REGULATOR_MODE_IDLE) {
 		/* Turn on pin control. */
-		rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 1);
+		rc = pm8058_vreg_set_pin_ctrl(vreg, 1);
 		if (rc)
 			goto bail;
 		return rc;
 	}
 	if (vreg->type == REGULATOR_TYPE_SMPS && SMPS_IN_ADVANCED_MODE(vreg))
-		rc = pm8058_smps_set_voltage_advanced(vreg, chip,
-							vreg->save_uV, 1);
+		rc = pm8058_smps_set_voltage_advanced(vreg, vreg->save_uV, 1);
 	else
-		rc = pm8058_vreg_write(chip, vreg->ctrl_addr, REGULATOR_EN_MASK,
+		rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, REGULATOR_EN_MASK,
 			REGULATOR_EN_MASK, &vreg->ctrl_reg);
 bail:
 	if (rc)
@@ -706,26 +701,25 @@
 static int pm8058_vreg_disable(struct regulator_dev *dev)
 {
 	struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
 	int rc = 0;
 
 	/* Disable in global control register. */
-	rc = pm8058_vreg_set_global_enable(vreg, chip, 0);
+	rc = pm8058_vreg_set_global_enable(vreg, 0);
 	if (rc)
 		goto bail;
 
 	/* Turn off pin control. */
-	rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+	rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
 	if (rc)
 		goto bail;
 
 	/* Disable in local control register. */
 	if (vreg->type == REGULATOR_TYPE_SMPS && SMPS_IN_ADVANCED_MODE(vreg))
-		rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+		rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
 			SMPS_ADVANCED_BAND_OFF, SMPS_ADVANCED_BAND_MASK,
 			&vreg->ctrl_reg);
 	else
-		rc = pm8058_vreg_write(chip, vreg->ctrl_addr, 0,
+		rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, 0,
 			REGULATOR_EN_MASK, &vreg->ctrl_reg);
 
 bail:
@@ -735,8 +729,7 @@
 	return rc;
 }
 
-static int pm8058_pldo_set_voltage(struct pm8058_chip *chip,
-		struct pm8058_vreg *vreg, int uV)
+static int pm8058_pldo_set_voltage(struct pm8058_vreg *vreg, int uV)
 {
 	int vmin, rc = 0;
 	unsigned vprog, fine_step;
@@ -775,7 +768,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 = pm8058_vreg_write(chip, vreg->test_addr,
+		rc = pm8058_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]);
@@ -784,13 +777,13 @@
 	}
 
 	/* Write new voltage. */
-	rc = pm8058_vreg_write(chip, vreg->ctrl_addr, vprog,
+	rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, vprog,
 				LDO_CTRL_VPROG_MASK, &vreg->ctrl_reg);
 	if (rc)
 		goto bail;
 
 	/* Write range extension. */
-	rc = pm8058_vreg_write(chip, vreg->test_addr,
+	rc = pm8058_vreg_write(vreg, vreg->test_addr,
 			range_ext | REGULATOR_BANK_SEL(4)
 			 | REGULATOR_BANK_WRITE,
 			LDO_TEST_RANGE_EXT_MASK | REGULATOR_BANK_MASK,
@@ -799,7 +792,7 @@
 		goto bail;
 
 	/* Write fine step, range select and program voltage update. */
-	rc = pm8058_vreg_write(chip, vreg->test_addr,
+	rc = pm8058_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
@@ -812,8 +805,7 @@
 	return rc;
 }
 
-static int pm8058_nldo_set_voltage(struct pm8058_chip *chip,
-		struct pm8058_vreg *vreg, int uV)
+static int pm8058_nldo_set_voltage(struct pm8058_vreg *vreg, int uV)
 {
 	unsigned vprog, fine_step_reg;
 	int rc;
@@ -826,13 +818,13 @@
 	vprog >>= 1;
 
 	/* Write new voltage. */
-	rc = pm8058_vreg_write(chip, vreg->ctrl_addr, vprog,
+	rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, vprog,
 				LDO_CTRL_VPROG_MASK, &vreg->ctrl_reg);
 	if (rc)
 		goto bail;
 
 	/* Write fine step. */
-	rc = pm8058_vreg_write(chip, vreg->test_addr,
+	rc = pm8058_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
@@ -849,12 +841,11 @@
 		int min_uV, int max_uV, unsigned *selector)
 {
 	struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
 
 	if (vreg->is_nmos)
-		return pm8058_nldo_set_voltage(chip, vreg, min_uV);
+		return pm8058_nldo_set_voltage(vreg, min_uV);
 	else
-		return pm8058_pldo_set_voltage(chip, vreg, min_uV);
+		return pm8058_pldo_set_voltage(vreg, min_uV);
 }
 
 static int pm8058_pldo_get_voltage(struct pm8058_vreg *vreg)
@@ -967,8 +958,7 @@
 }
 
 static int pm8058_smps_set_voltage_advanced(struct pm8058_vreg *vreg,
-					struct pm8058_chip *chip, int uV,
-					int force_on)
+					int uV,	int force_on)
 {
 	u8 vprog, band;
 	int rc, new_uV;
@@ -992,7 +982,7 @@
 		band = SMPS_ADVANCED_BAND_OFF;
 
 	/* Set advanced mode bit to 1. */
-	rc = pm8058_vreg_write(chip, vreg->test_addr, SMPS_ADVANCED_MODE
+	rc = pm8058_vreg_write(vreg, vreg->test_addr, SMPS_ADVANCED_MODE
 		| REGULATOR_BANK_WRITE | REGULATOR_BANK_SEL(7),
 		SMPS_ADVANCED_MODE_MASK | REGULATOR_BANK_MASK,
 		&vreg->test_reg[7]);
@@ -1000,7 +990,7 @@
 		goto bail;
 
 	/* Set voltage and voltage band. */
-	rc = pm8058_vreg_write(chip, vreg->ctrl_addr, band | vprog,
+	rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, band | vprog,
 			SMPS_ADVANCED_BAND_MASK | SMPS_ADVANCED_VPROG_MASK,
 			&vreg->ctrl_reg);
 	if (rc)
@@ -1012,8 +1002,7 @@
 	return rc;
 }
 
-static int pm8058_smps_set_voltage_legacy(struct pm8058_vreg *vreg,
-					struct pm8058_chip *chip, int uV)
+static int pm8058_smps_set_voltage_legacy(struct pm8058_vreg *vreg, int uV)
 {
 	u8 vlow, vref, vprog, pd, en;
 	int rc;
@@ -1033,7 +1022,7 @@
 	}
 
 	/* set vlow bit for ultra low voltage mode */
-	rc = pm8058_vreg_write(chip, vreg->test_addr,
+	rc = pm8058_vreg_write(vreg, vreg->test_addr,
 		vlow | REGULATOR_BANK_WRITE | REGULATOR_BANK_SEL(1),
 		REGULATOR_BANK_MASK | SMPS_LEGACY_VLOW_SEL_MASK,
 		&vreg->test_reg[1]);
@@ -1041,7 +1030,7 @@
 		goto bail;
 
 	/* Set advanced mode bit to 0. */
-	rc = pm8058_vreg_write(chip, vreg->test_addr, SMPS_LEGACY_MODE
+	rc = pm8058_vreg_write(vreg, vreg->test_addr, SMPS_LEGACY_MODE
 		| REGULATOR_BANK_WRITE | REGULATOR_BANK_SEL(7),
 		SMPS_ADVANCED_MODE_MASK | REGULATOR_BANK_MASK,
 		&vreg->test_reg[7]);
@@ -1052,7 +1041,7 @@
 	pd = (vreg->pdata->pull_down_enable ? SMPS_LEGACY_PULL_DOWN_ENABLE : 0);
 
 	/* Set voltage (and the rest of the control register). */
-	rc = pm8058_vreg_write(chip, vreg->ctrl_addr, en | pd | vref | vprog,
+	rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, en | pd | vref | vprog,
 		SMPS_LEGACY_ENABLE | SMPS_LEGACY_PULL_DOWN_ENABLE
 		| SMPS_LEGACY_VREF_SEL_MASK | SMPS_LEGACY_VPROG_MASK,
 		&vreg->ctrl_reg);
@@ -1067,16 +1056,15 @@
 		int min_uV, int max_uV, unsigned *selector)
 {
 	struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
 	int rc = 0;
 
 	if (min_uV < SMPS_UV_MIN || min_uV > SMPS_UV_MAX)
 		return -EINVAL;
 
 	if (SMPS_IN_ADVANCED_MODE(vreg))
-		rc = pm8058_smps_set_voltage_advanced(vreg, chip, min_uV, 0);
+		rc = pm8058_smps_set_voltage_advanced(vreg, min_uV, 0);
 	else
-		rc = pm8058_smps_set_voltage_legacy(vreg, chip, min_uV);
+		rc = pm8058_smps_set_voltage_legacy(vreg, min_uV);
 
 	if (rc)
 		print_write_error(vreg, rc, __func__);
@@ -1088,7 +1076,6 @@
 		int min_uV, int max_uV, unsigned *selector)
 {
 	struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
 	int rc;
 	u8 val;
 
@@ -1098,7 +1085,7 @@
 	val = (min_uV - NCP_UV_MIN) / NCP_UV_STEP;
 
 	/* voltage setting */
-	rc = pm8058_vreg_write(chip, vreg->ctrl_addr, val, NCP_VPROG_MASK,
+	rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, val, NCP_VPROG_MASK,
 			&vreg->ctrl_reg);
 	if (rc)
 		print_write_error(vreg, rc, __func__);
@@ -1113,8 +1100,7 @@
 	return NCP_UV_MIN + vprog * NCP_UV_STEP;
 }
 
-static int pm8058_ldo_set_mode(struct pm8058_vreg *vreg,
-		struct pm8058_chip *chip, unsigned int mode)
+static int pm8058_ldo_set_mode(struct pm8058_vreg *vreg, unsigned int mode)
 {
 	int rc = 0;
 	u8 mask, val;
@@ -1125,13 +1111,13 @@
 		val = (_pm8058_vreg_is_enabled(vreg) ? LDO_ENABLE : 0)
 			| LDO_CTRL_PM_HPM;
 		mask = LDO_ENABLE_MASK | LDO_CTRL_PM_MASK;
-		rc = pm8058_vreg_write(chip, vreg->ctrl_addr, val, mask,
+		rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, val, mask,
 					&vreg->ctrl_reg);
 		if (rc)
 			goto bail;
 
 		if (pm8058_vreg_using_pin_ctrl(vreg))
-			rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+			rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
 		if (rc)
 			goto bail;
 		break;
@@ -1141,7 +1127,7 @@
 		val = (_pm8058_vreg_is_enabled(vreg) ? LDO_ENABLE : 0)
 			| LDO_CTRL_PM_LPM;
 		mask = LDO_ENABLE_MASK | LDO_CTRL_PM_MASK;
-		rc = pm8058_vreg_write(chip, vreg->ctrl_addr, val, mask,
+		rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, val, mask,
 					&vreg->ctrl_reg);
 		if (rc)
 			goto bail;
@@ -1149,13 +1135,13 @@
 		val = LDO_TEST_LPM_SEL_CTRL | REGULATOR_BANK_WRITE
 			| REGULATOR_BANK_SEL(0);
 		mask = LDO_TEST_LPM_MASK | REGULATOR_BANK_MASK;
-		rc = pm8058_vreg_write(chip, vreg->test_addr, val, mask,
+		rc = pm8058_vreg_write(vreg, vreg->test_addr, val, mask,
 					&vreg->test_reg[0]);
 		if (rc)
 			goto bail;
 
 		if (pm8058_vreg_using_pin_ctrl(vreg))
-			rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+			rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
 		if (rc)
 			goto bail;
 		break;
@@ -1163,7 +1149,7 @@
 	case REGULATOR_MODE_IDLE:
 		/* Pin Control */
 		if (_pm8058_vreg_is_enabled(vreg))
-			rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 1);
+			rc = pm8058_vreg_set_pin_ctrl(vreg, 1);
 		if (rc)
 			goto bail;
 		break;
@@ -1180,8 +1166,7 @@
 	return rc;
 }
 
-static int pm8058_smps_set_mode(struct pm8058_vreg *vreg,
-		struct pm8058_chip *chip, unsigned int mode)
+static int pm8058_smps_set_mode(struct pm8058_vreg *vreg, unsigned int mode)
 {
 	int rc = 0;
 	u8 mask, val;
@@ -1191,13 +1176,13 @@
 		/* HPM */
 		val = SMPS_CLK_CTRL_PWM;
 		mask = SMPS_CLK_CTRL_MASK;
-		rc = pm8058_vreg_write(chip, vreg->clk_ctrl_addr, val, mask,
+		rc = pm8058_vreg_write(vreg, vreg->clk_ctrl_addr, val, mask,
 					&vreg->clk_ctrl_reg);
 		if (rc)
 			goto bail;
 
 		if (pm8058_vreg_using_pin_ctrl(vreg))
-			rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+			rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
 		if (rc)
 			goto bail;
 		break;
@@ -1206,13 +1191,13 @@
 		/* LPM */
 		val = SMPS_CLK_CTRL_PFM;
 		mask = SMPS_CLK_CTRL_MASK;
-		rc = pm8058_vreg_write(chip, vreg->clk_ctrl_addr, val, mask,
+		rc = pm8058_vreg_write(vreg, vreg->clk_ctrl_addr, val, mask,
 					&vreg->clk_ctrl_reg);
 		if (rc)
 			goto bail;
 
 		if (pm8058_vreg_using_pin_ctrl(vreg))
-			rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+			rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
 		if (rc)
 			goto bail;
 		break;
@@ -1220,7 +1205,7 @@
 	case REGULATOR_MODE_IDLE:
 		/* Pin Control */
 		if (_pm8058_vreg_is_enabled(vreg))
-			rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 1);
+			rc = pm8058_vreg_set_pin_ctrl(vreg, 1);
 		if (rc)
 			goto bail;
 		break;
@@ -1237,18 +1222,17 @@
 	return rc;
 }
 
-static int pm8058_lvs_set_mode(struct pm8058_vreg *vreg,
-		struct pm8058_chip *chip, unsigned int mode)
+static int pm8058_lvs_set_mode(struct pm8058_vreg *vreg, unsigned int mode)
 {
 	int rc = 0;
 
 	if (mode == REGULATOR_MODE_IDLE) {
 		/* Use pin control. */
 		if (_pm8058_vreg_is_enabled(vreg))
-			rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 1);
+			rc = pm8058_vreg_set_pin_ctrl(vreg, 1);
 	} else {
 		/* Turn off pin control. */
-		rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+		rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
 	}
 
 	return rc;
@@ -1268,7 +1252,6 @@
 static int pm8058_vreg_set_mode(struct regulator_dev *dev, unsigned int mode)
 {
 	struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
 	unsigned prev_optimum = vreg->optimum;
 	unsigned prev_pc_vote = vreg->pc_vote;
 	unsigned prev_mode_initialized = vreg->mode_initialized;
@@ -1320,13 +1303,13 @@
 
 	switch (vreg->type) {
 	case REGULATOR_TYPE_LDO:
-		rc = pm8058_ldo_set_mode(vreg, chip, new_mode);
+		rc = pm8058_ldo_set_mode(vreg, new_mode);
 		break;
 	case REGULATOR_TYPE_SMPS:
-		rc = pm8058_smps_set_mode(vreg, chip, new_mode);
+		rc = pm8058_smps_set_mode(vreg, new_mode);
 		break;
 	case REGULATOR_TYPE_LVS:
-		rc = pm8058_lvs_set_mode(vreg, chip, new_mode);
+		rc = pm8058_lvs_set_mode(vreg, new_mode);
 		break;
 	}
 
@@ -1499,24 +1482,25 @@
 	VREG_DESCRIP(PM8058_VREG_ID_NCP, "8058_ncp", &pm8058_ncp_ops),
 };
 
-static int pm8058_master_enable_init(struct pm8058_chip *chip)
+static int pm8058_master_enable_init(struct pm8058_vreg *vreg)
 {
 	int rc = 0, i;
 
 	for (i = 0; i < MASTER_ENABLE_COUNT; i++) {
-		rc = pm8058_read(chip, m_en[i].addr, &(m_en[i].reg), 1);
+		rc = pm8xxx_readb(vreg->dev->parent, m_en[i].addr,
+							&(m_en[i].reg));
 		if (rc)
 			goto bail;
 	}
 
 bail:
 	if (rc)
-		pr_err("%s: pm8058_read failed, rc=%d\n", __func__, rc);
+		pr_err("%s: pm8xxx_read failed, rc=%d\n", __func__, rc);
 
 	return rc;
 }
 
-static int pm8058_init_ldo(struct pm8058_chip *chip, struct pm8058_vreg *vreg)
+static int pm8058_init_ldo(struct pm8058_vreg *vreg)
 {
 	int rc = 0, i;
 	u8 bank;
@@ -1524,11 +1508,12 @@
 	/* Save the current test register state. */
 	for (i = 0; i < LDO_TEST_BANKS; i++) {
 		bank = REGULATOR_BANK_SEL(i);
-		rc = pm8058_write(chip, vreg->test_addr, &bank, 1);
+		rc = pm8xxx_writeb(vreg->dev->parent, vreg->test_addr, bank);
 		if (rc)
 			goto bail;
 
-		rc = pm8058_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;
 		vreg->test_reg[i] |= REGULATOR_BANK_WRITE;
@@ -1540,14 +1525,14 @@
 		vreg->optimum = REGULATOR_MODE_FAST;
 
 	/* Set pull down enable based on platform data. */
-	rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+	rc = pm8058_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 pm8058_init_smps(struct pm8058_chip *chip, struct pm8058_vreg *vreg)
+static int pm8058_init_smps(struct pm8058_vreg *vreg)
 {
 	int rc = 0, i;
 	u8 bank;
@@ -1555,24 +1540,26 @@
 	/* Save the current test2 register state. */
 	for (i = 0; i < SMPS_TEST_BANKS; i++) {
 		bank = REGULATOR_BANK_SEL(i);
-		rc = pm8058_write(chip, vreg->test_addr, &bank, 1);
+		rc = pm8xxx_writeb(vreg->dev->parent, vreg->test_addr, bank);
 		if (rc)
 			goto bail;
 
-		rc = pm8058_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;
 		vreg->test_reg[i] |= REGULATOR_BANK_WRITE;
 	}
 
 	/* Save the current clock control register state. */
-	rc = pm8058_read(chip, vreg->clk_ctrl_addr, &vreg->clk_ctrl_reg, 1);
+	rc = pm8xxx_readb(vreg->dev->parent, vreg->clk_ctrl_addr,
+						&vreg->clk_ctrl_reg);
 	if (rc)
 		goto bail;
 
 	/* Save the current sleep control register state. */
-	rc = pm8058_read(chip, vreg->sleep_ctrl_addr, &vreg->sleep_ctrl_reg, 1);
+	rc = pm8xxx_readb(vreg->dev->parent, vreg->sleep_ctrl_addr,
+						&vreg->sleep_ctrl_reg);
 	if (rc)
 		goto bail;
 
@@ -1585,7 +1572,7 @@
 		vreg->optimum = REGULATOR_MODE_FAST;
 
 	/* Set advanced mode pull down enable based on platform data. */
-	rc = pm8058_vreg_write(chip, vreg->test_addr,
+	rc = pm8058_vreg_write(vreg, vreg->test_addr,
 		(vreg->pdata->pull_down_enable
 			? SMPS_ADVANCED_PULL_DOWN_ENABLE : 0)
 		| REGULATOR_BANK_SEL(6) | REGULATOR_BANK_WRITE,
@@ -1596,7 +1583,7 @@
 
 	if (!SMPS_IN_ADVANCED_MODE(vreg)) {
 		/* Set legacy mode pull down enable based on platform data. */
-		rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+		rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
 			(vreg->pdata->pull_down_enable
 				? SMPS_LEGACY_PULL_DOWN_ENABLE : 0),
 			SMPS_LEGACY_PULL_DOWN_ENABLE, &vreg->ctrl_reg);
@@ -1608,26 +1595,27 @@
 	return rc;
 }
 
-static int pm8058_init_lvs(struct pm8058_chip *chip, struct pm8058_vreg *vreg)
+static int pm8058_init_lvs(struct pm8058_vreg *vreg)
 {
 	int rc = 0;
 
 	vreg->optimum = REGULATOR_MODE_FAST;
 
 	/* Set pull down enable based on platform data. */
-	rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+	rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
 		(vreg->pdata->pull_down_enable
 			? LVS_PULL_DOWN_ENABLE : LVS_PULL_DOWN_DISABLE),
 		LVS_PULL_DOWN_ENABLE_MASK, &vreg->ctrl_reg);
 	return rc;
 }
 
-static int pm8058_init_ncp(struct pm8058_chip *chip, struct pm8058_vreg *vreg)
+static int pm8058_init_ncp(struct pm8058_vreg *vreg)
 {
 	int rc = 0;
 
 	/* Save the current test1 register state. */
-	rc = pm8058_read(chip, vreg->test_addr, &vreg->test_reg[0], 1);
+	rc = pm8xxx_readb(vreg->dev->parent, vreg->test_addr,
+					&vreg->test_reg[0]);
 	if (rc)
 		goto bail;
 
@@ -1637,8 +1625,7 @@
 	return rc;
 }
 
-static int pm8058_init_regulator(struct pm8058_chip *chip,
-		struct pm8058_vreg *vreg)
+static int pm8058_init_regulator(struct pm8058_vreg *vreg)
 {
 	static int master_enable_inited;
 	int rc = 0;
@@ -1646,28 +1633,28 @@
 	vreg->mode_initialized = 0;
 
 	if (!master_enable_inited) {
-		rc = pm8058_master_enable_init(chip);
+		rc = pm8058_master_enable_init(vreg);
 		if (!rc)
 			master_enable_inited = 1;
 	}
 
 	/* save the current control register state */
-	rc = pm8058_read(chip, vreg->ctrl_addr, &vreg->ctrl_reg, 1);
+	rc = pm8xxx_readb(vreg->dev->parent, vreg->ctrl_addr, &vreg->ctrl_reg);
 	if (rc)
 		goto bail;
 
 	switch (vreg->type) {
 	case REGULATOR_TYPE_LDO:
-		rc = pm8058_init_ldo(chip, vreg);
+		rc = pm8058_init_ldo(vreg);
 		break;
 	case REGULATOR_TYPE_SMPS:
-		rc = pm8058_init_smps(chip, vreg);
+		rc = pm8058_init_smps(vreg);
 		break;
 	case REGULATOR_TYPE_LVS:
-		rc = pm8058_init_lvs(chip, vreg);
+		rc = pm8058_init_lvs(vreg);
 		break;
 	case REGULATOR_TYPE_NCP:
-		rc = pm8058_init_ncp(chip, vreg);
+		rc = pm8058_init_ncp(vreg);
 		break;
 	}
 
@@ -1681,7 +1668,6 @@
 static int __devinit pm8058_vreg_probe(struct platform_device *pdev)
 {
 	struct regulator_desc *rdesc;
-	struct pm8058_chip *chip;
 	struct pm8058_vreg *vreg;
 	const char *reg_name = NULL;
 	int rc = 0;
@@ -1690,13 +1676,13 @@
 		return -EINVAL;
 
 	if (pdev->id >= 0 && pdev->id < PM8058_VREG_MAX) {
-		chip = dev_get_drvdata(pdev->dev.parent);
 		rdesc = &pm8058_vreg_descrip[pdev->id];
 		vreg = &pm8058_vreg[pdev->id];
 		vreg->pdata = pdev->dev.platform_data;
 		reg_name = pm8058_vreg_descrip[pdev->id].name;
+		vreg->dev = &pdev->dev;
 
-		rc = pm8058_init_regulator(chip, vreg);
+		rc = pm8058_init_regulator(vreg);
 		if (rc)
 			goto bail;
 
@@ -1705,7 +1691,6 @@
 			vreg->pdata->init_data.constraints.valid_modes_mask
 			      &= ~(REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE);
 
-		platform_set_drvdata(pdev, chip);
 		vreg->rdev = regulator_register(rdesc, &pdev->dev,
 				&vreg->pdata->init_data, vreg);
 		if (IS_ERR(vreg->rdev)) {
diff --git a/drivers/thermal/pm8xxx-tm.c b/drivers/thermal/pm8xxx-tm.c
index d9f9c9e..1d518e3 100644
--- a/drivers/thermal/pm8xxx-tm.c
+++ b/drivers/thermal/pm8xxx-tm.c
@@ -30,6 +30,7 @@
 #include <linux/mfd/pm8xxx/tm.h>
 #include <linux/completion.h>
 #include <linux/mfd/pm8xxx/pm8921-adc.h>
+#include <linux/msm_adc.h>
 
 /* Register TEMP_ALARM_CTRL bits */
 #define	TEMP_ALARM_CTRL_ST3_SD		0x80
@@ -226,6 +227,43 @@
 	return 0;
 }
 
+static int pm8xxx_tz_get_temp_pm8058_adc(struct thermal_zone_device *thermal,
+			      unsigned long *temp)
+{
+	struct pm8xxx_tm_chip *chip = thermal->devdata;
+	DECLARE_COMPLETION_ONSTACK(wait);
+	struct adc_chan_result adc_result = {
+		.physical = 0lu,
+	};
+	int rc;
+
+	if (!chip || !temp)
+		return -EINVAL;
+
+	*temp = chip->temp;
+
+	rc = adc_channel_request_conv(chip->adc_handle, &wait);
+	if (rc < 0) {
+		pr_err("%s: adc_channel_request_conv() failed, rc = %d\n",
+			__func__, rc);
+		return rc;
+	}
+
+	wait_for_completion(&wait);
+
+	rc = adc_channel_read_result(chip->adc_handle, &adc_result);
+	if (rc < 0) {
+		pr_err("%s: adc_channel_read_result() failed, rc = %d\n",
+			__func__, rc);
+		return rc;
+	}
+
+	*temp = adc_result.physical;
+	chip->temp = adc_result.physical;
+
+	return 0;
+}
+
 static int pm8xxx_tz_get_temp_pm8921_adc(struct thermal_zone_device *thermal,
 				      unsigned long *temp)
 {
@@ -372,6 +410,15 @@
 	.get_crit_temp = pm8xxx_tz_get_crit_temp,
 };
 
+static struct thermal_zone_device_ops pm8xxx_thermal_zone_ops_pm8058_adc = {
+	.get_temp = pm8xxx_tz_get_temp_pm8058_adc,
+	.get_mode = pm8xxx_tz_get_mode,
+	.set_mode = pm8xxx_tz_set_mode,
+	.get_trip_type = pm8xxx_tz_get_trip_type,
+	.get_trip_temp = pm8xxx_tz_get_trip_temp,
+	.get_crit_temp = pm8xxx_tz_get_crit_temp,
+};
+
 static void pm8xxx_tm_work(struct work_struct *work)
 {
 	struct pm8xxx_tm_chip *chip
@@ -465,6 +512,24 @@
 	return rc;
 }
 
+static int pm8xxx_init_adc(struct pm8xxx_tm_chip *chip, bool enable)
+{
+	int rc = 0;
+
+	if (chip->cdata.adc_type == PM8XXX_TM_ADC_PM8058_ADC) {
+		if (enable) {
+			rc = adc_channel_open(chip->cdata.adc_channel,
+						&(chip->adc_handle));
+			if (rc < 0)
+				pr_err("adc_channel_open() failed.\n");
+		} else {
+			adc_channel_close(chip->adc_handle);
+		}
+	}
+
+	return rc;
+}
+
 static int __devinit pm8xxx_tm_probe(struct platform_device *pdev)
 {
 	const struct pm8xxx_tm_core_data *cdata = pdev->dev.platform_data;
@@ -505,18 +570,27 @@
 		goto err_free_chip;
 	}
 
+	rc = pm8xxx_init_adc(chip, true);
+	if (rc < 0) {
+		pr_err("Unable to initialize adc\n");
+		goto err_free_chip;
+	}
+
 	/* Select proper thermal zone ops functions based on ADC type. */
 	if (chip->cdata.adc_type == PM8XXX_TM_ADC_PM8921_ADC)
 		tz_ops = &pm8xxx_thermal_zone_ops_pm8921_adc;
+	else if (chip->cdata.adc_type == PM8XXX_TM_ADC_PM8058_ADC)
+		tz_ops = &pm8xxx_thermal_zone_ops_pm8058_adc;
 	else
 		tz_ops = &pm8xxx_thermal_zone_ops_no_adc;
 
 	chip->tz_dev = thermal_zone_device_register(chip->cdata.tm_name,
 			TRIP_NUM, chip, tz_ops, 0, 0, 0, 0);
+
 	if (chip->tz_dev == NULL) {
 		pr_err("thermal_zone_device_register() failed.\n");
 		rc = -ENODEV;
-		goto err_free_chip;
+		goto err_fail_adc;
 	}
 
 	rc = pm8xxx_tm_init_reg(chip);
@@ -564,6 +638,8 @@
 	cancel_work_sync(&chip->irq_work);
 err_free_tz:
 	thermal_zone_device_unregister(chip->tz_dev);
+err_fail_adc:
+	pm8xxx_init_adc(chip, false);
 err_free_chip:
 	kfree(chip);
 	return rc;
@@ -579,6 +655,7 @@
 		free_irq(chip->overtemp_irq, chip);
 		free_irq(chip->tempstat_irq, chip);
 		pm8xxx_tm_shutdown_override(chip, SOFTWARE_OVERRIDE_DISABLED);
+		pm8xxx_init_adc(chip, false);
 		thermal_zone_device_unregister(chip->tz_dev);
 		kfree(chip);
 	}
diff --git a/include/linux/mfd/pm8xxx/gpio.h b/include/linux/mfd/pm8xxx/gpio.h
index 0a9c95d..f2e4a21 100644
--- a/include/linux/mfd/pm8xxx/gpio.h
+++ b/include/linux/mfd/pm8xxx/gpio.h
@@ -59,6 +59,16 @@
 #define	PM_GPIO_VIN_L3			5
 #define	PM_GPIO_VIN_L17			6
 
+/* vin_sel: Voltage Input select on PM8058 */
+#define PM8058_GPIO_VIN_VPH		0
+#define PM8058_GPIO_VIN_BB		1
+#define PM8058_GPIO_VIN_S3		2
+#define PM8058_GPIO_VIN_L3		3
+#define PM8058_GPIO_VIN_L7		4
+#define PM8058_GPIO_VIN_L6		5
+#define PM8058_GPIO_VIN_L5		6
+#define PM8058_GPIO_VIN_L2		7
+
 /* out_strength */
 #define	PM_GPIO_STRENGTH_NO		0
 #define	PM_GPIO_STRENGTH_HIGH		1
diff --git a/include/linux/pmic8058-nfc.h b/include/linux/mfd/pm8xxx/nfc.h
similarity index 70%
rename from include/linux/pmic8058-nfc.h
rename to include/linux/mfd/pm8xxx/nfc.h
index 5b2d6cf..e58e0a9 100644
--- a/include/linux/pmic8058-nfc.h
+++ b/include/linux/mfd/pm8xxx/nfc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010,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
@@ -10,10 +10,12 @@
  * GNU General Public License for more details.
  *
  */
-#ifndef __PMIC8058_NFC_H__
-#define __PMIC8058_NFC_H__
+#ifndef __PM8XXX_NFC_H__
+#define __PM8XXX_NFC_H__
 
-struct pm8058_nfc_device;
+struct pm8xxx_nfc_device;
+
+#define PM8XXX_NFC_DEV_NAME		"pm8xxx-nfc"
 
 /* masks, flags and status */
 #define	PM_NFC_VDDLDO_MON_LEVEL		0x0003
@@ -46,32 +48,32 @@
 					PM_NFC_VDDLDO_OK_HIGH)
 
 /*
- * pm8058_nfc_request - request a handle to access NFC device
+ * pm8xxx_nfc_request - request a handle to access NFC device
  */
-struct pm8058_nfc_device *pm8058_nfc_request(void);
+struct pm8xxx_nfc_device *pm8xxx_nfc_request(void);
 
 /*
- * pm8058_nfc_config - configure NFC signals
+ * pm8xxx_nfc_config - configure NFC signals
  *
  * @nfcdev: the NFC device
  * @mask: signal mask to configure
  * @flags: control flags
  */
-int pm8058_nfc_config(struct pm8058_nfc_device *nfcdev, u32 mask, u32 flags);
+int pm8xxx_nfc_config(struct pm8xxx_nfc_device *nfcdev, u32 mask, u32 flags);
 
 /*
- * pm8058_nfc_get_status - get NFC status
+ * pm8xxx_nfc_get_status - get NFC status
  *
  * @nfcdev: the NFC device
  * @mask: of status mask to read
  * @status: pointer to the status variable
  */
-int pm8058_nfc_get_status(struct pm8058_nfc_device *nfcdev,
+int pm8xxx_nfc_get_status(struct pm8xxx_nfc_device *nfcdev,
 			  u32 mask, u32 *status);
 
 /*
- * pm8058_nfc_free - free the NFC device
+ * pm8xxx_nfc_free - free the NFC device
  */
-void pm8058_nfc_free(struct pm8058_nfc_device *nfcdev);
+void pm8xxx_nfc_free(struct pm8xxx_nfc_device *nfcdev);
 
-#endif /* __PMIC8058_NFC_H__ */
+#endif /* __PM8XXX_NFC_H__ */
diff --git a/include/linux/mfd/pm8xxx/tm.h b/include/linux/mfd/pm8xxx/tm.h
index 01edb97..5eeefd9 100644
--- a/include/linux/mfd/pm8xxx/tm.h
+++ b/include/linux/mfd/pm8xxx/tm.h
@@ -24,6 +24,7 @@
 
 enum pm8xxx_tm_adc_type {
 	PM8XXX_TM_ADC_NONE,	/* Estimates temp based on overload level. */
+	PM8XXX_TM_ADC_PM8058_ADC,
 	PM8XXX_TM_ADC_PM8921_ADC,
 };
 
diff --git a/include/linux/mfd/pm8xxx/upl.h b/include/linux/mfd/pm8xxx/upl.h
new file mode 100644
index 0000000..b0e94a9
--- /dev/null
+++ b/include/linux/mfd/pm8xxx/upl.h
@@ -0,0 +1,65 @@
+/* Copyright (c) 2010,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 __PM8XXX_UPL_H__
+#define __PM8XXX_UPL_H__
+
+struct pm8xxx_upl_device;
+
+#define PM8XXX_UPL_DEV_NAME		"pm8xxx-upl"
+
+/* control masks and flags */
+#define PM8XXX_UPL_MOD_ENABLE_MASK	(0x10)
+#define PM8XXX_UPL_MOD_ENABLE		(0x10)
+#define PM8XXX_UPL_MOD_DISABLE		(0x00)
+
+#define PM8XXX_UPL_OUT_DTEST_MASK	(0xE0)
+#define PM8XXX_UPL_OUT_GPIO_ONLY	(0x00)
+#define PM8XXX_UPL_OUT_DTEST_1		(0x80)
+#define PM8XXX_UPL_OUT_DTEST_2		(0xA0)
+#define PM8XXX_UPL_OUT_DTEST_3		(0xC0)
+#define PM8XXX_UPL_OUT_DTEST_4		(0xE0)
+
+#define PM8XXX_UPL_IN_A_MASK		(0x01)
+#define PM8XXX_UPL_IN_A_GPIO		(0x00)
+#define PM8XXX_UPL_IN_A_DTEST		(0x01)
+#define PM8XXX_UPL_IN_B_MASK		(0x02)
+#define PM8XXX_UPL_IN_B_GPIO		(0x00)
+#define PM8XXX_UPL_IN_B_DTEST		(0x02)
+#define PM8XXX_UPL_IN_C_MASK		(0x04)
+#define PM8XXX_UPL_IN_C_GPIO		(0x00)
+#define PM8XXX_UPL_IN_C_DTEST		(0x04)
+#define PM8XXX_UPL_IN_D_MASK		(0x08)
+#define PM8XXX_UPL_IN_D_GPIO		(0x00)
+#define PM8XXX_UPL_IN_D_DTEST		(0x08)
+
+/*
+ * pm8xxx_upl_request - request a handle to access UPL device
+ */
+struct pm8xxx_upl_device *pm8xxx_upl_request(void);
+
+int pm8xxx_upl_read_truthtable(struct pm8xxx_upl_device *upldev,
+				u16 *truthtable);
+
+int pm8xxx_upl_write_truthtable(struct pm8xxx_upl_device *upldev,
+				u16 truthtable);
+
+/*
+ * pm8xxx_upl_config - configure UPL I/O settings and UPL enable/disable
+ *
+ * @upldev: the UPL device
+ * @mask: setting mask to configure
+ * @flags: setting flags
+ */
+int pm8xxx_upl_config(struct pm8xxx_upl_device *upldev, u32 mask, u32 flags);
+
+#endif /* __PM8XXX_UPL_H__ */
diff --git a/include/linux/mfd/pm8xxx/vibrator.h b/include/linux/mfd/pm8xxx/vibrator.h
index 3a269a0..cfea1c9 100644
--- a/include/linux/mfd/pm8xxx/vibrator.h
+++ b/include/linux/mfd/pm8xxx/vibrator.h
@@ -15,10 +15,25 @@
 
 #define PM8XXX_VIBRATOR_DEV_NAME "pm8xxx-vib"
 
+enum pm8xxx_vib_en_mode {
+	PM8XXX_VIB_MANUAL,
+	PM8XXX_VIB_DTEST1,
+	PM8XXX_VIB_DTEST2,
+	PM8XXX_VIB_DTEST3
+};
+
+struct pm8xxx_vib_config {
+	u16			drive_mV;
+	u8			active_low;
+	enum pm8xxx_vib_en_mode	enable_mode;
+};
+
 struct pm8xxx_vibrator_platform_data {
 	int initial_vibrate_ms;
 	int max_timeout_ms;
 	int level_mV;
 };
 
+int pm8xxx_vibrator_config(struct pm8xxx_vib_config *vib_config);
+
 #endif /* __PMIC8XXX_VIBRATOR_H__ */
diff --git a/include/linux/mfd/pmic8058.h b/include/linux/mfd/pmic8058.h
index 4d9f257..cf753b5d 100644
--- a/include/linux/mfd/pmic8058.h
+++ b/include/linux/mfd/pmic8058.h
@@ -15,12 +15,39 @@
  *
  */
 
+#ifndef __MFD_PMIC8058_H__
+#define __MFD_PMIC8058_H__
+
 #include <linux/irq.h>
 #include <linux/mfd/core.h>
+#include <linux/mfd/pm8xxx/irq.h>
+#include <linux/mfd/pm8xxx/gpio.h>
+#include <linux/mfd/pm8xxx/mpp.h>
+#include <linux/mfd/pm8xxx/rtc.h>
+#include <linux/input/pmic8xxx-pwrkey.h>
+#include <linux/input/pmic8xxx-keypad.h>
+#include <linux/mfd/pm8xxx/vibrator.h>
+#include <linux/mfd/pm8xxx/nfc.h>
+#include <linux/mfd/pm8xxx/upl.h>
+#include <linux/mfd/pm8xxx/misc.h>
+#include <linux/mfd/pm8xxx/batt-alarm.h>
+#include <linux/leds-pmic8058.h>
+#include <linux/pmic8058-othc.h>
+#include <linux/mfd/pm8xxx/tm.h>
+#include <linux/pmic8058-xoadc.h>
+#include <linux/regulator/pmic8058-regulator.h>
+#include <linux/regulator/pm8058-xo.h>
+#include <linux/pwm.h>
+#include <linux/pmic8058-pwm.h>
 
 #define PM8058_GPIOS		40
 #define PM8058_MPPS		12
 
+#define PM8058_GPIO_BLOCK_START	24
+#define PM8058_MPP_BLOCK_START	16
+
+#define PM8058_NR_IRQS		256
+
 #define PM8058_IRQ_BLOCK_BIT(block, bit) ((block) * 8 + (bit))
 
 /* MPPs and GPIOs [0,N) */
@@ -29,146 +56,58 @@
 #define PM8058_GPIO_IRQ(base, gpio)	((base) + \
 					PM8058_IRQ_BLOCK_BIT(24, (gpio)))
 
-#define PM8058_KEYPAD_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(9, 2))
-#define PM8058_KEYSTUCK_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(9, 3))
+/* PM8058 IRQ's */
+#define PM8058_VCP_IRQ			PM8058_IRQ_BLOCK_BIT(1, 0)
+#define PM8058_CHGILIM_IRQ		PM8058_IRQ_BLOCK_BIT(1, 3)
+#define PM8058_VBATDET_LOW_IRQ		PM8058_IRQ_BLOCK_BIT(1, 4)
+#define PM8058_BATT_REPLACE_IRQ		PM8058_IRQ_BLOCK_BIT(1, 5)
+#define PM8058_CHGINVAL_IRQ		PM8058_IRQ_BLOCK_BIT(1, 6)
+#define PM8058_CHGVAL_IRQ		PM8058_IRQ_BLOCK_BIT(1, 7)
+#define PM8058_CHG_END_IRQ		PM8058_IRQ_BLOCK_BIT(2, 0)
+#define PM8058_FASTCHG_IRQ		PM8058_IRQ_BLOCK_BIT(2, 1)
+#define PM8058_CHGSTATE_IRQ		PM8058_IRQ_BLOCK_BIT(2, 3)
+#define PM8058_AUTO_CHGFAIL_IRQ		PM8058_IRQ_BLOCK_BIT(2, 4)
+#define PM8058_AUTO_CHGDONE_IRQ		PM8058_IRQ_BLOCK_BIT(2, 5)
+#define PM8058_ATCFAIL_IRQ		PM8058_IRQ_BLOCK_BIT(2, 6)
+#define PM8058_ATC_DONE_IRQ		PM8058_IRQ_BLOCK_BIT(2, 7)
+#define PM8058_OVP_OK_IRQ		PM8058_IRQ_BLOCK_BIT(3, 0)
+#define PM8058_COARSE_DET_OVP_IRQ	PM8058_IRQ_BLOCK_BIT(3, 1)
+#define PM8058_VCPMAJOR_IRQ		PM8058_IRQ_BLOCK_BIT(3, 2)
+#define PM8058_CHG_GONE_IRQ		PM8058_IRQ_BLOCK_BIT(3, 3)
+#define PM8058_CHGTLIMIT_IRQ		PM8058_IRQ_BLOCK_BIT(3, 4)
+#define PM8058_CHGHOT_IRQ		PM8058_IRQ_BLOCK_BIT(3, 5)
+#define PM8058_BATTTEMP_IRQ		PM8058_IRQ_BLOCK_BIT(3, 6)
+#define PM8058_BATTCONNECT_IRQ		PM8058_IRQ_BLOCK_BIT(3, 7)
+#define PM8058_BATFET_IRQ		PM8058_IRQ_BLOCK_BIT(5, 4)
+#define PM8058_VBATDET_IRQ		PM8058_IRQ_BLOCK_BIT(5, 5)
+#define PM8058_VBAT_IRQ			PM8058_IRQ_BLOCK_BIT(5, 6)
 
-#define PM8058_VCP_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(1, 0))
-#define PM8058_CHGILIM_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(1, 3))
-#define PM8058_VBATDET_LOW_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(1, 4))
-#define PM8058_BATT_REPLACE_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(1, 5))
-#define PM8058_CHGINVAL_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(1, 6))
-#define PM8058_CHGVAL_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(1, 7))
-#define PM8058_CHG_END_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(2, 0))
-#define PM8058_FASTCHG_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(2, 1))
-#define PM8058_CHGSTATE_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(2, 3))
-#define PM8058_AUTO_CHGFAIL_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(2, 4))
-#define PM8058_AUTO_CHGDONE_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(2, 5))
-#define PM8058_ATCFAIL_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(2, 6))
-#define PM8058_ATC_DONE_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(2, 7))
-#define PM8058_OVP_OK_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(3, 0))
-#define PM8058_COARSE_DET_OVP_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(3, 1))
-#define PM8058_VCPMAJOR_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(3, 2))
-#define PM8058_CHG_GONE_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(3, 3))
-#define PM8058_CHGTLIMIT_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(3, 4))
-#define PM8058_CHGHOT_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(3, 5))
-#define PM8058_BATTTEMP_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(3, 6))
-#define PM8058_BATTCONNECT_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(3, 7))
-#define PM8058_BATFET_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(5, 4))
-#define PM8058_VBATDET_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(5, 5))
-#define PM8058_VBAT_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(5, 6))
-
-#define PM8058_CBLPWR_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(4, 3))
-
-#define PM8058_PWRKEY_REL_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(6, 2))
-#define PM8058_PWRKEY_PRESS_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(6, 3))
-#define PM8058_SW_0_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(7, 1))
-#define PM8058_IR_0_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(7, 0))
-#define PM8058_SW_1_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(7, 3))
-#define PM8058_IR_1_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(7, 2))
-#define PM8058_SW_2_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(7, 5))
-#define PM8058_IR_2_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(7, 4))
-#define PM8058_RTC_IRQ(base) 		((base) + PM8058_IRQ_BLOCK_BIT(6, 5))
-#define PM8058_RTC_ALARM_IRQ(base) 	((base) + PM8058_IRQ_BLOCK_BIT(4, 7))
-#define PM8058_ADC_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(9, 4))
-#define PM8058_TEMP_ALARM_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(6, 7))
-#define PM8058_OSCHALT_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(4, 6))
-#define PM8058_BATT_ALARM_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(5, 6))
-#define PM8058_RESOUT_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(6, 4))
-
-struct pm8058_chip;
-
-struct pm8058_platform_data {
-	/* This table is only needed for misc interrupts. */
-	int		irq_base;
-	int		irq;
-	int 		(*init)(struct pm8058_chip *pm_chip);
-
-	int		num_subdevs;
-	struct mfd_cell *sub_devices;
-	int		irq_trigger_flags;
-	struct mfd_cell *charger_sub_device;
-};
-
-struct pm8058_gpio_platform_data {
-	int	gpio_base;
-	int	irq_base;
-	int	(*init)(void);
-};
-
-/* GPIO parameters */
-/* direction */
-#define	PM_GPIO_DIR_OUT			0x01
-#define	PM_GPIO_DIR_IN			0x02
-#define	PM_GPIO_DIR_BOTH		(PM_GPIO_DIR_OUT | PM_GPIO_DIR_IN)
-
-/* output_buffer */
-#define	PM_GPIO_OUT_BUF_OPEN_DRAIN	1
-#define	PM_GPIO_OUT_BUF_CMOS		0
-
-/* pull */
-#define	PM_GPIO_PULL_UP_30		0
-#define	PM_GPIO_PULL_UP_1P5		1
-#define	PM_GPIO_PULL_UP_31P5		2
-#define	PM_GPIO_PULL_UP_1P5_30		3
-#define	PM_GPIO_PULL_DN			4
-#define	PM_GPIO_PULL_NO			5
-
-/* vin_sel: Voltage Input Select */
-#define	PM_GPIO_VIN_VPH			0
-#define	PM_GPIO_VIN_BB			1
-#define	PM_GPIO_VIN_S3			2
-#define	PM_GPIO_VIN_L3			3
-#define	PM_GPIO_VIN_L7			4
-#define	PM_GPIO_VIN_L6			5
-#define	PM_GPIO_VIN_L5			6
-#define	PM_GPIO_VIN_L2			7
-
-/* out_strength */
-#define	PM_GPIO_STRENGTH_NO		0
-#define	PM_GPIO_STRENGTH_HIGH		1
-#define	PM_GPIO_STRENGTH_MED		2
-#define	PM_GPIO_STRENGTH_LOW		3
-
-/* function */
-#define	PM_GPIO_FUNC_NORMAL		0
-#define	PM_GPIO_FUNC_PAIRED		1
-#define	PM_GPIO_FUNC_1			2
-#define	PM_GPIO_FUNC_2			3
-#define	PM_GPIO_DTEST1			4
-#define	PM_GPIO_DTEST2			5
-#define	PM_GPIO_DTEST3			6
-#define	PM_GPIO_DTEST4			7
-
-struct pm8058_gpio {
-	int		direction;
-	int		output_buffer;
-	int		output_value;
-	int		pull;
-	int		vin_sel;	/* 0..7 */
-	int		out_strength;
-	int		function;
-	int		inv_int_pol;	/* invert interrupt polarity */
-	int		disable_pin;	/* disable pin and tri-state its pad */
-};
+#define PM8058_RTC_IRQ			PM8058_IRQ_BLOCK_BIT(6, 5)
+#define PM8058_RTC_ALARM_IRQ		PM8058_IRQ_BLOCK_BIT(4, 7)
+#define PM8058_PWRKEY_REL_IRQ		PM8058_IRQ_BLOCK_BIT(6, 2)
+#define PM8058_PWRKEY_PRESS_IRQ		PM8058_IRQ_BLOCK_BIT(6, 3)
+#define PM8058_KEYPAD_IRQ		PM8058_IRQ_BLOCK_BIT(9, 2)
+#define PM8058_KEYSTUCK_IRQ		PM8058_IRQ_BLOCK_BIT(9, 3)
+#define PM8058_BATT_ALARM_IRQ		PM8058_IRQ_BLOCK_BIT(5, 6)
+#define PM8058_SW_0_IRQ			PM8058_IRQ_BLOCK_BIT(7, 1)
+#define PM8058_IR_0_IRQ			PM8058_IRQ_BLOCK_BIT(7, 0)
+#define PM8058_SW_1_IRQ			PM8058_IRQ_BLOCK_BIT(7, 3)
+#define PM8058_IR_1_IRQ			PM8058_IRQ_BLOCK_BIT(7, 2)
+#define PM8058_SW_2_IRQ			PM8058_IRQ_BLOCK_BIT(7, 5)
+#define PM8058_IR_2_IRQ			PM8058_IRQ_BLOCK_BIT(7, 4)
+#define PM8058_TEMPSTAT_IRQ		PM8058_IRQ_BLOCK_BIT(6, 7)
+#define PM8058_OVERTEMP_IRQ		PM8058_IRQ_BLOCK_BIT(4, 2)
+#define PM8058_ADC_IRQ			PM8058_IRQ_BLOCK_BIT(9, 4)
+#define PM8058_OSCHALT_IRQ		PM8058_IRQ_BLOCK_BIT(4, 6)
+#define PM8058_CBLPWR_IRQ		PM8058_IRQ_BLOCK_BIT(4, 3)
+#define PM8058_RESOUT_IRQ		PM8058_IRQ_BLOCK_BIT(6, 4)
 
 struct pmic8058_charger_data {
 	unsigned int max_source_current;
 	int charger_type;
+	bool charger_data_valid;
 };
 
-/* chip revision */
-#define PM_8058_REV_1p0			0xE1
-#define PM_8058_REV_2p0			0xE2
-#define PM_8058_REV_2p1			0xE3
-
-/* misc: control mask and flag */
-#define	PM8058_UART_MUX_MASK		0x60
-
-#define PM8058_UART_MUX_NO		0x0
-#define PM8058_UART_MUX_1		0x20
-#define PM8058_UART_MUX_2		0x40
-#define PM8058_UART_MUX_3		0x60
-
 enum pon_config{
 	DISABLE_HARD_RESET = 0,
 	SHUTDOWN_ON_HARD_RESET,
@@ -183,19 +122,27 @@
 	PM8058_SMPL_DELAY_2p0,
 };
 
-/* Note -do not call pm8058_read and pm8058_write in an atomic context */
-int pm8058_read(struct pm8058_chip *pm_chip, u16 addr, u8 *values,
-		unsigned int len);
-int pm8058_write(struct pm8058_chip *pm_chip, u16 addr, u8 *values,
-		 unsigned int len);
-
-int pm8058_gpio_config(int gpio, struct pm8058_gpio *param);
-
-int pm8058_rev(struct pm8058_chip *pm_chip);
-
-int pm8058_irq_get_rt_status(struct pm8058_chip *pm_chip, int irq);
-
-int pm8058_misc_control(struct pm8058_chip *pm_chip, int mask, int flag);
+struct pm8058_platform_data {
+	struct pm8xxx_mpp_platform_data		*mpp_pdata;
+	struct pm8xxx_keypad_platform_data      *keypad_pdata;
+	struct pm8xxx_gpio_platform_data	*gpio_pdata;
+	struct pm8xxx_irq_platform_data		*irq_pdata;
+	struct pm8xxx_rtc_platform_data		*rtc_pdata;
+	struct pm8xxx_pwrkey_platform_data	*pwrkey_pdata;
+	struct pm8xxx_vibrator_platform_data	*vibrator_pdata;
+	struct pm8xxx_misc_platform_data	*misc_pdata;
+	struct pmic8058_leds_platform_data	*leds_pdata;
+	struct pmic8058_othc_config_pdata	*othc0_pdata;
+	struct pmic8058_othc_config_pdata	*othc1_pdata;
+	struct pmic8058_othc_config_pdata	*othc2_pdata;
+	struct xoadc_platform_data		*xoadc_pdata;
+	struct pm8058_pwm_pdata			*pwm_pdata;
+	struct pm8058_vreg_pdata		*regulator_pdatas;
+	int					num_regulators;
+	struct pm8058_xo_pdata			*xo_buffer_pdata;
+	int					num_xo_buffers;
+	struct pmic8058_charger_data		*charger_pdata;
+};
 
 #ifdef CONFIG_PMIC8058
 int pm8058_reset_pwr_off(int reset);
@@ -256,3 +203,5 @@
  * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
  */
 int pm8058_stay_on(void);
+
+#endif  /* __MFD_PMIC8058_H__ */
diff --git a/include/linux/msm_adc.h b/include/linux/msm_adc.h
index 5d5fb1b..51371a6 100644
--- a/include/linux/msm_adc.h
+++ b/include/linux/msm_adc.h
@@ -344,22 +344,24 @@
 int32_t adc_channel_request_conv(void *h, struct completion *conv_complete_evt);
 int32_t adc_channel_read_result(void *h, struct adc_chan_result *chan_result);
 #else
-int32_t adc_channel_open(uint32_t channel, void **h)
+static int32_t adc_channel_open(uint32_t channel, void **h)
 {
 	pr_err("%s.not supported.\n", __func__);
 	return -ENODEV;
 }
-int32_t adc_channel_close(void *h)
+static int32_t adc_channel_close(void *h)
 {
 	pr_err("%s.not supported.\n", __func__);
 	return -ENODEV;
 }
-int32_t adc_channel_request_conv(void *h, struct completion *conv_complete_evt)
+static int32_t
+adc_channel_request_conv(void *h, struct completion *conv_complete_evt)
 {
 	pr_err("%s.not supported.\n", __func__);
 	return -ENODEV;
 }
-int32_t adc_channel_read_result(void *h, struct adc_chan_result *chan_result)
+static int32_t
+adc_channel_read_result(void *h, struct adc_chan_result *chan_result)
 {
 	pr_err("%s.not supported.\n", __func__);
 	return -ENODEV;
diff --git a/include/linux/pmic8058-upl.h b/include/linux/pmic8058-upl.h
deleted file mode 100644
index a8979f4..0000000
--- a/include/linux/pmic8058-upl.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Copyright (c) 2010, 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 __PMIC8058_UPL_H__
-#define __PMIC8058_UPL_H__
-
-struct pm8058_upl_device;
-
-/* control masks and flags */
-#define PM8058_UPL_MOD_ENABLE_MASK	(0x10)
-#define PM8058_UPL_MOD_ENABLE		(0x10)
-#define PM8058_UPL_MOD_DISABLE		(0x00)
-
-#define PM8058_UPL_OUT_DTEST_MASK	(0xE0)
-#define PM8058_UPL_OUT_GPIO_ONLY	(0x00)
-#define PM8058_UPL_OUT_DTEST_1		(0x80)
-#define PM8058_UPL_OUT_DTEST_2		(0xA0)
-#define PM8058_UPL_OUT_DTEST_3		(0xC0)
-#define PM8058_UPL_OUT_DTEST_4		(0xE0)
-
-#define PM8058_UPL_IN_A_MASK		(0x01)
-#define PM8058_UPL_IN_A_GPIO		(0x00)
-#define PM8058_UPL_IN_A_DTEST		(0x01)
-#define PM8058_UPL_IN_B_MASK		(0x02)
-#define PM8058_UPL_IN_B_GPIO		(0x00)
-#define PM8058_UPL_IN_B_DTEST		(0x02)
-#define PM8058_UPL_IN_C_MASK		(0x04)
-#define PM8058_UPL_IN_C_GPIO		(0x00)
-#define PM8058_UPL_IN_C_DTEST		(0x04)
-#define PM8058_UPL_IN_D_MASK		(0x08)
-#define PM8058_UPL_IN_D_GPIO		(0x00)
-#define PM8058_UPL_IN_D_DTEST		(0x08)
-
-/*
- * pm8058_upl_request - request a handle to access UPL device
- */
-struct pm8058_upl_device *pm8058_upl_request(void);
-
-int pm8058_upl_read_truthtable(struct pm8058_upl_device *upldev,
-				u16 *truthtable);
-
-int pm8058_upl_write_truthtable(struct pm8058_upl_device *upldev,
-				u16 truthtable);
-
-/*
- * pm8058_upl_config - configure UPL I/O settings and UPL enable/disable
- *
- * @upldev: the UPL device
- * @mask: setting mask to configure
- * @flags: setting flags
- */
-int pm8058_upl_config(struct pm8058_upl_device *upldev, u32 mask, u32 flags);
-
-#endif /* __PMIC8058_UPL_H__ */
diff --git a/include/linux/regulator/pm8058-xo.h b/include/linux/regulator/pm8058-xo.h
index 9b363c4..a2b8aeb 100644
--- a/include/linux/regulator/pm8058-xo.h
+++ b/include/linux/regulator/pm8058-xo.h
@@ -25,6 +25,7 @@
 
 struct pm8058_xo_pdata {
 	struct regulator_init_data	init_data;
+	int id;
 };
 
 #endif
diff --git a/include/linux/regulator/pmic8058-regulator.h b/include/linux/regulator/pmic8058-regulator.h
index 83d4412..3eeaa61 100644
--- a/include/linux/regulator/pmic8058-regulator.h
+++ b/include/linux/regulator/pmic8058-regulator.h
@@ -80,6 +80,7 @@
 
 struct pm8058_vreg_pdata {
 	struct regulator_init_data	init_data;
+	int				id;
 	unsigned			pull_down_enable;
 	unsigned			pin_ctrl;
 	enum pm8058_vreg_pin_fn		pin_fn;