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/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);
 	}