Merge changes Ia7ca43fa,Icd62a876,I6d157b44,I482a9398 into msm-3.0

* changes:
  msm: qdsp5: Replace use of clk_set_min_rate() with clk_set_rate()
  msm: iommu: Discontinue use of clk_set_min_rate()
  msm: clock-local: Use clk_set_rate() to request bus clock rates
  msm: clock: Add 'gp' clocks for 8660, 8960, 8064, and 9615
diff --git a/Documentation/devicetree/bindings/usb/msm-hsusb.txt b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
new file mode 100644
index 0000000..c1399ae
--- /dev/null
+++ b/Documentation/devicetree/bindings/usb/msm-hsusb.txt
@@ -0,0 +1,51 @@
+MSM SoC HSUSB controllers
+
+OTG:
+
+Required properties :
+- compatible : should be "qcom,hsusb-otg"
+- regs : offset and length of the register set in the memory map
+- interrupts: IRQ line
+- qcom,hsusb-otg-phy-type: PHY type can be one of
+            1 - Chipidea 45nm PHY
+	    2 - Synopsis 28nm PHY
+- qcom,hsusb-otg-mode: Operational mode. Can be one of
+            1 - Peripheral only mode
+	    2 - Host only mode
+	    3 - OTG mode
+	    Based on the mode, OTG driver registers platform devices for
+	    gadget and host.
+- qcom,hsusb-otg-control: OTG control (VBUS and ID notifications)
+  can be one of
+            1 - PHY control
+	    2 - PMIC control
+	    3 - User control (via debugfs)
+
+Optional properties :
+- qcom,hsusb-otg-default-mode: The default USB mode after boot-up.
+  Applicable only when OTG is controlled by user. Can be one of
+            0 - None. Low power mode
+            1 - Peripheral
+	    2 - Host
+- qcom,hsusb-otg-phy-init-seq: PHY configuration sequence. val, reg pairs
+  terminate with -1
+- qcom,hsusb-otg-power-budget: VBUS power budget in mA
+  0 will be treated as 500mA
+- qcom,hsusb-otg-pclk-src-name: The source of pclk
+- qcom,hsusb-otg-pmic-id-irq: ID, routed to PMIC IRQ number
+
+Example HSUSB OTG controller device node :
+	usb@F9690000 {
+		compatible = "qcom,hsusb-otg";
+		reg = <0xF9690000 0x400>;
+		interrupts = <134>;
+
+		qcom,hsusb-otg-phy-type = <2>;
+		qcom,hsusb-otg-mode = <1>;
+		qcom,hsusb-otg-otg-control = <1>;
+		qcom,hsusb-otg-default-mode = <2>;
+		qcom,hsusb-otg-phy-init-seq = <0x01 0x90 0xFFFFFFFF>;
+		qcom,hsusb-otg-power-budget = <500>;
+		qcom,hsusb-otg-pclk-src-name = "dfab_usb_clk";
+		qcom,hsusb-otg-pmic-id-irq = <47>
+	};
diff --git a/arch/arm/boot/dts/msmcopper.dts b/arch/arm/boot/dts/msmcopper.dts
index 52c0b66..74fc5a9 100644
--- a/arch/arm/boot/dts/msmcopper.dts
+++ b/arch/arm/boot/dts/msmcopper.dts
@@ -20,4 +20,14 @@
 		reg = <0xF9684000 0x1000>;
 		interrupts = <109>;
 	};
+
+	usb@F9690000 {
+		compatible = "qcom,hsusb-otg";
+		reg = <0xF9690000 0x400>;
+		interrupts = <134>;
+
+		qcom,hsusb-otg-phy-type = <2>;
+		qcom,hsusb-otg-mode = <1>;
+		qcom,hsusb-otg-otg-control = <1>;
+	};
 };
diff --git a/arch/arm/configs/fsm9xxx-perf_defconfig b/arch/arm/configs/fsm9xxx-perf_defconfig
index b6bc4f1..5717577 100644
--- a/arch/arm/configs/fsm9xxx-perf_defconfig
+++ b/arch/arm/configs/fsm9xxx-perf_defconfig
@@ -134,6 +134,8 @@
 CONFIG_POWER_SUPPLY=y
 CONFIG_SENSORS_MSM_ADC=y
 CONFIG_PMIC8058=y
+# CONFIG_MFD_PM8XXX_PWM is not set
+# CONFIG_MFD_PM8XXX_MISC is not set
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_PM8058_XO=y
 # CONFIG_USB_SUPPORT is not set
diff --git a/arch/arm/configs/fsm9xxx_defconfig b/arch/arm/configs/fsm9xxx_defconfig
index dd9797a..ebff2d2 100644
--- a/arch/arm/configs/fsm9xxx_defconfig
+++ b/arch/arm/configs/fsm9xxx_defconfig
@@ -132,6 +132,8 @@
 CONFIG_POWER_SUPPLY=y
 CONFIG_SENSORS_MSM_ADC=y
 CONFIG_PMIC8058=y
+# CONFIG_MFD_PM8XXX_PWM is not set
+# CONFIG_MFD_PM8XXX_MISC is not set
 CONFIG_REGULATOR=y
 CONFIG_REGULATOR_PM8058_XO=y
 # CONFIG_USB_SUPPORT is not set
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index 9fb4615..6c50ae9 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -95,7 +95,9 @@
 # CONFIG_HWMON is not set
 # CONFIG_MFD_SUPPORT is not set
 # CONFIG_HID_SUPPORT is not set
-# CONFIG_USB_SUPPORT is not set
+CONFIG_USB_GADGET=y
+CONFIG_USB_GADGET_CI13XXX_MSM=y
+CONFIG_USB_G_ANDROID=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 # CONFIG_LEDS_MSM_PMIC is not set
diff --git a/arch/arm/configs/msm7630-perf_defconfig b/arch/arm/configs/msm7630-perf_defconfig
index 56710d7..042d751 100644
--- a/arch/arm/configs/msm7630-perf_defconfig
+++ b/arch/arm/configs/msm7630-perf_defconfig
@@ -187,7 +187,7 @@
 CONFIG_BLK_DEV_RAM_SIZE=16384
 CONFIG_MISC_DEVICES=y
 CONFIG_HAPTIC_ISA1200=y
-CONFIG_PMIC8058_UPL=y
+CONFIG_PMIC8XXX_UPL=y
 CONFIG_SCSI=y
 CONFIG_SCSI_TGT=y
 CONFIG_BLK_DEV_SD=y
@@ -216,6 +216,8 @@
 CONFIG_INPUT_EVDEV=y
 CONFIG_INPUT_EVBUG=m
 # CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_PMIC8XXX=y
+# CONFIG_KEYBOARD_PMIC8058 is not set
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_MSM=y
@@ -249,6 +251,9 @@
 CONFIG_MARIMBA_CORE=y
 CONFIG_MARIMBA_CODEC=y
 CONFIG_TIMPANI_CODEC=y
+# CONFIG_MFD_PM8XXX_DEBUG is not set
+# CONFIG_MFD_PM8XXX_PWM is not set
+# CONFIG_MFD_PM8XXX_MISC is not set
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_VIDEO_DEV=y
 # CONFIG_MEDIA_TUNER_CUSTOMISE is not set
diff --git a/arch/arm/configs/msm7630_defconfig b/arch/arm/configs/msm7630_defconfig
index 115ce98..362babe 100644
--- a/arch/arm/configs/msm7630_defconfig
+++ b/arch/arm/configs/msm7630_defconfig
@@ -186,7 +186,7 @@
 CONFIG_BLK_DEV_RAM_SIZE=16384
 CONFIG_MISC_DEVICES=y
 CONFIG_HAPTIC_ISA1200=y
-CONFIG_PMIC8058_UPL=y
+CONFIG_PMIC8XXX_UPL=y
 CONFIG_SCSI=y
 CONFIG_SCSI_TGT=y
 CONFIG_BLK_DEV_SD=y
@@ -215,6 +215,8 @@
 CONFIG_INPUT_EVDEV=y
 CONFIG_INPUT_EVBUG=m
 # CONFIG_KEYBOARD_ATKBD is not set
+CONFIG_KEYBOARD_PMIC8XXX=y
+# CONFIG_KEYBOARD_PMIC8058 is not set
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_MSM=y
@@ -248,6 +250,9 @@
 CONFIG_MARIMBA_CORE=y
 CONFIG_MARIMBA_CODEC=y
 CONFIG_TIMPANI_CODEC=y
+# CONFIG_MFD_PM8XXX_DEBUG is not set
+# CONFIG_MFD_PM8XXX_PWM is not set
+# CONFIG_MFD_PM8XXX_MISC is not set
 CONFIG_MSM_KGSL=y
 CONFIG_VIDEO_OUTPUT_CONTROL=y
 CONFIG_FB=y
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index de58931..dcdf9e5 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -222,10 +222,9 @@
 CONFIG_TSIF=m
 CONFIG_TSIF_CHRDEV=m
 CONFIG_HAPTIC_ISA1200=y
-CONFIG_PMIC8058_VIBRATOR=y
-CONFIG_PMIC8058_UPL=y
+CONFIG_PMIC8XXX_VIBRATOR=y
+CONFIG_PMIC8XXX_UPL=y
 CONFIG_PMIC8058_XOADC=y
-CONFIG_PMIC8058_MISC=y
 CONFIG_TZCOM=y
 CONFIG_SCSI=y
 CONFIG_SCSI_TGT=y
@@ -262,6 +261,8 @@
 CONFIG_INPUT_KEYRESET=y
 CONFIG_KEYBOARD_GPIO=y
 CONFIG_KEYBOARD_MATRIX=y
+CONFIG_KEYBOARD_PMIC8XXX=y
+# CONFIG_KEYBOARD_PMIC8058 is not set
 CONFIG_INPUT_JOYSTICK=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
@@ -269,7 +270,7 @@
 CONFIG_TOUCHSCREEN_CYTTSP_I2C=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
-CONFIG_PMIC8058_PWRKEY=y
+CONFIG_INPUT_PMIC8XXX_PWRKEY=y
 CONFIG_PMIC8058_OTHC=y
 CONFIG_SERIAL_MSM_HS=y
 CONFIG_SERIAL_MSM_HSL=y
@@ -300,11 +301,13 @@
 CONFIG_THERMAL=y
 CONFIG_THERMAL_HWMON=y
 CONFIG_THERMAL_PM8901=y
-CONFIG_THERMAL_PM8058=y
 CONFIG_THERMAL_TSENS=y
+CONFIG_THERMAL_PM8XXX=y
 CONFIG_PMIC8058=y
 CONFIG_MARIMBA_CORE=y
 CONFIG_TIMPANI_CODEC=y
+# CONFIG_MFD_PM8XXX_PWM is not set
+CONFIG_MFD_PM8XXX_BATT_ALARM=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_VIDEO_DEV=y
 # CONFIG_MEDIA_TUNER_CUSTOMISE is not set
@@ -387,7 +390,7 @@
 CONFIG_SWITCH_GPIO=y
 CONFIG_RTC_CLASS=y
 # CONFIG_RTC_DRV_MSM is not set
-CONFIG_RTC_PM8058=y
+CONFIG_RTC_DRV_PM8XXX=y
 CONFIG_STAGING=y
 CONFIG_ANDROID=y
 CONFIG_ANDROID_BINDER_IPC=y
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index 6d99df7..8f049a5 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -214,10 +214,9 @@
 CONFIG_TSIF=m
 CONFIG_TSIF_CHRDEV=m
 CONFIG_HAPTIC_ISA1200=y
-CONFIG_PMIC8058_VIBRATOR=y
-CONFIG_PMIC8058_UPL=y
+CONFIG_PMIC8XXX_VIBRATOR=y
+CONFIG_PMIC8XXX_UPL=y
 CONFIG_PMIC8058_XOADC=y
-CONFIG_PMIC8058_MISC=y
 CONFIG_TZCOM=y
 CONFIG_SCSI=y
 CONFIG_SCSI_TGT=y
@@ -254,6 +253,8 @@
 CONFIG_INPUT_KEYRESET=y
 CONFIG_KEYBOARD_GPIO=y
 CONFIG_KEYBOARD_MATRIX=y
+CONFIG_KEYBOARD_PMIC8XXX=y
+# CONFIG_KEYBOARD_PMIC8058 is not set
 CONFIG_INPUT_JOYSTICK=y
 CONFIG_INPUT_TOUCHSCREEN=y
 CONFIG_TOUCHSCREEN_ATMEL_MAXTOUCH=y
@@ -261,7 +262,7 @@
 CONFIG_TOUCHSCREEN_CYTTSP_I2C=y
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
-CONFIG_PMIC8058_PWRKEY=y
+CONFIG_INPUT_PMIC8XXX_PWRKEY=y
 CONFIG_PMIC8058_OTHC=y
 CONFIG_SERIAL_MSM_HS=y
 CONFIG_SERIAL_MSM_HSL=y
@@ -291,11 +292,13 @@
 CONFIG_SENSORS_MSM_ADC=y
 CONFIG_THERMAL=y
 CONFIG_THERMAL_PM8901=y
-CONFIG_THERMAL_PM8058=y
 CONFIG_THERMAL_TSENS=y
+CONFIG_THERMAL_PM8XXX=y
 CONFIG_PMIC8058=y
 CONFIG_MARIMBA_CORE=y
 CONFIG_TIMPANI_CODEC=y
+# CONFIG_MFD_PM8XXX_PWM is not set
+CONFIG_MFD_PM8XXX_BATT_ALARM=y
 CONFIG_MEDIA_SUPPORT=y
 CONFIG_VIDEO_DEV=y
 # CONFIG_MEDIA_TUNER_CUSTOMISE is not set
@@ -374,7 +377,7 @@
 CONFIG_SWITCH_GPIO=y
 CONFIG_RTC_CLASS=y
 # CONFIG_RTC_DRV_MSM is not set
-CONFIG_RTC_PM8058=y
+CONFIG_RTC_DRV_PM8XXX=y
 CONFIG_STAGING=y
 CONFIG_ANDROID=y
 CONFIG_ANDROID_BINDER_IPC=y
diff --git a/arch/arm/include/asm/perf_event.h b/arch/arm/include/asm/perf_event.h
index 0e1fd19..87d1bed 100644
--- a/arch/arm/include/asm/perf_event.h
+++ b/arch/arm/include/asm/perf_event.h
@@ -24,6 +24,8 @@
 	ARM_PERF_PMU_ID_V6MP,
 	ARM_PERF_PMU_ID_CA8,
 	ARM_PERF_PMU_ID_CA9,
+	ARM_PERF_PMU_ID_CA5,
+	ARM_PERF_PMU_ID_CA15,
 	ARM_PERF_PMU_ID_SCORPION,
 	ARM_PERF_PMU_ID_SCORPIONMP,
 	ARM_PERF_PMU_ID_KRAIT,
diff --git a/arch/arm/kernel/perf_event.c b/arch/arm/kernel/perf_event.c
index c9982829..c8f963c 100644
--- a/arch/arm/kernel/perf_event.c
+++ b/arch/arm/kernel/perf_event.c
@@ -680,6 +680,12 @@
 		case 0xC090:	/* Cortex-A9 */
 			armpmu = armv7_a9_pmu_init();
 			break;
+		case 0xC050:	/* Cortex-A5 */
+			armpmu = armv7_a5_pmu_init();
+			break;
+		case 0xC0F0:	/* Cortex-A15 */
+			armpmu = armv7_a15_pmu_init();
+			break;
 		}
 	/* Intel CPUs [xscale]. */
 	} else if (0x69 == implementor) {
diff --git a/arch/arm/kernel/perf_event_v7.c b/arch/arm/kernel/perf_event_v7.c
index 01b1145..9633178 100644
--- a/arch/arm/kernel/perf_event_v7.c
+++ b/arch/arm/kernel/perf_event_v7.c
@@ -153,6 +153,39 @@
 	ARMV7_PERFCTR_PLE_RQST_PROG		= 0xA5
 };
 
+/* ARMv7 Cortex-A5 specific event types */
+enum armv7_a5_perf_types {
+	ARMV7_PERFCTR_IRQ_TAKEN			= 0x86,
+	ARMV7_PERFCTR_FIQ_TAKEN			= 0x87,
+
+	ARMV7_PERFCTR_EXT_MEM_RQST		= 0xc0,
+	ARMV7_PERFCTR_NC_EXT_MEM_RQST		= 0xc1,
+	ARMV7_PERFCTR_PREFETCH_LINEFILL		= 0xc2,
+	ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP	= 0xc3,
+	ARMV7_PERFCTR_ENTER_READ_ALLOC		= 0xc4,
+	ARMV7_PERFCTR_READ_ALLOC		= 0xc5,
+
+	ARMV7_PERFCTR_STALL_SB_FULL		= 0xc9,
+};
+
+/* ARMv7 Cortex-A15 specific event types */
+enum armv7_a15_perf_types {
+	ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS	= 0x40,
+	ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS	= 0x41,
+	ARMV7_PERFCTR_L1_DCACHE_READ_REFILL	= 0x42,
+	ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL	= 0x43,
+
+	ARMV7_PERFCTR_L1_DTLB_READ_REFILL	= 0x4C,
+	ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL	= 0x4D,
+
+	ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS	= 0x50,
+	ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS	= 0x51,
+	ARMV7_PERFCTR_L2_DCACHE_READ_REFILL	= 0x52,
+	ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL	= 0x53,
+
+	ARMV7_PERFCTR_SPEC_PC_WRITE		= 0x76,
+};
+
 /*
  * Cortex-A8 HW events mapping
  *
@@ -379,6 +412,242 @@
 };
 
 /*
+ * Cortex-A5 HW events mapping
+ */
+static const unsigned armv7_a5_perf_map[PERF_COUNT_HW_MAX] = {
+	[PERF_COUNT_HW_CPU_CYCLES]	    = ARMV7_PERFCTR_CPU_CYCLES,
+	[PERF_COUNT_HW_INSTRUCTIONS]	    = ARMV7_PERFCTR_INSTR_EXECUTED,
+	[PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
+	[PERF_COUNT_HW_CACHE_MISSES]	    = HW_OP_UNSUPPORTED,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_PC_WRITE,
+	[PERF_COUNT_HW_BRANCH_MISSES]	    = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+	[PERF_COUNT_HW_BUS_CYCLES]	    = HW_OP_UNSUPPORTED,
+};
+
+static const unsigned armv7_a5_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+					[PERF_COUNT_HW_CACHE_OP_MAX]
+					[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+	[C(L1D)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]
+					= ARMV7_PERFCTR_DCACHE_ACCESS,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_DCACHE_REFILL,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]
+					= ARMV7_PERFCTR_DCACHE_ACCESS,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_DCACHE_REFILL,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]
+					= ARMV7_PERFCTR_PREFETCH_LINEFILL,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP,
+		},
+	},
+	[C(L1I)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_IFETCH_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_IFETCH_MISS,
+		},
+		/*
+		 * The prefetch counters don't differentiate between the I
+		 * side and the D side.
+		 */
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]
+					= ARMV7_PERFCTR_PREFETCH_LINEFILL,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_PREFETCH_LINEFILL_DROP,
+		},
+	},
+	[C(LL)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(DTLB)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DTLB_REFILL,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_DTLB_REFILL,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(ITLB)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(BPU)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_BRANCH_PRED,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_BRANCH_PRED,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+};
+
+/*
+ * Cortex-A15 HW events mapping
+ */
+static const unsigned armv7_a15_perf_map[PERF_COUNT_HW_MAX] = {
+	[PERF_COUNT_HW_CPU_CYCLES]	    = ARMV7_PERFCTR_CPU_CYCLES,
+	[PERF_COUNT_HW_INSTRUCTIONS]	    = ARMV7_PERFCTR_INSTR_EXECUTED,
+	[PERF_COUNT_HW_CACHE_REFERENCES]    = HW_OP_UNSUPPORTED,
+	[PERF_COUNT_HW_CACHE_MISSES]	    = HW_OP_UNSUPPORTED,
+	[PERF_COUNT_HW_BRANCH_INSTRUCTIONS] = ARMV7_PERFCTR_SPEC_PC_WRITE,
+	[PERF_COUNT_HW_BRANCH_MISSES]	    = ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+	[PERF_COUNT_HW_BUS_CYCLES]	    = ARMV7_PERFCTR_BUS_CYCLES,
+};
+
+static const unsigned armv7_a15_perf_cache_map[PERF_COUNT_HW_CACHE_MAX]
+					[PERF_COUNT_HW_CACHE_OP_MAX]
+					[PERF_COUNT_HW_CACHE_RESULT_MAX] = {
+	[C(L1D)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]
+					= ARMV7_PERFCTR_L1_DCACHE_READ_ACCESS,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_L1_DCACHE_READ_REFILL,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]
+					= ARMV7_PERFCTR_L1_DCACHE_WRITE_ACCESS,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_L1_DCACHE_WRITE_REFILL,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(L1I)] = {
+		/*
+		 * Not all performance counters differentiate between read
+		 * and write accesses/misses so we're not always strictly
+		 * correct, but it's the best we can do. Writes and reads get
+		 * combined in these cases.
+		 */
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_IFETCH_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_L1_ICACHE_ACCESS,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_IFETCH_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(LL)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]
+					= ARMV7_PERFCTR_L2_DCACHE_READ_ACCESS,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_L2_DCACHE_READ_REFILL,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]
+					= ARMV7_PERFCTR_L2_DCACHE_WRITE_ACCESS,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_L2_DCACHE_WRITE_REFILL,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(DTLB)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_L1_DTLB_READ_REFILL,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_L1_DTLB_WRITE_REFILL,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(ITLB)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_MISS,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= ARMV7_PERFCTR_ITLB_MISS,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+	[C(BPU)] = {
+		[C(OP_READ)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_BRANCH_PRED,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+		},
+		[C(OP_WRITE)] = {
+			[C(RESULT_ACCESS)]	= ARMV7_PERFCTR_PC_BRANCH_PRED,
+			[C(RESULT_MISS)]
+					= ARMV7_PERFCTR_PC_BRANCH_MIS_PRED,
+		},
+		[C(OP_PREFETCH)] = {
+			[C(RESULT_ACCESS)]	= CACHE_OP_UNSUPPORTED,
+			[C(RESULT_MISS)]	= CACHE_OP_UNSUPPORTED,
+		},
+	},
+};
+
+/*
  * Perf Events counters
  */
 enum armv7_counters {
@@ -910,6 +1179,26 @@
 	armv7pmu.num_events	= armv7_read_num_pmnc_events();
 	return &armv7pmu;
 }
+
+static const struct arm_pmu *__init armv7_a5_pmu_init(void)
+{
+	armv7pmu.id		= ARM_PERF_PMU_ID_CA5;
+	armv7pmu.name		= "ARMv7 Cortex-A5";
+	armv7pmu.cache_map	= &armv7_a5_perf_cache_map;
+	armv7pmu.event_map	= &armv7_a5_perf_map;
+	armv7pmu.num_events	= armv7_read_num_pmnc_events();
+	return &armv7pmu;
+}
+
+static const struct arm_pmu *__init armv7_a15_pmu_init(void)
+{
+	armv7pmu.id		= ARM_PERF_PMU_ID_CA15;
+	armv7pmu.name		= "ARMv7 Cortex-A15";
+	armv7pmu.cache_map	= &armv7_a15_perf_cache_map;
+	armv7pmu.event_map	= &armv7_a15_perf_map;
+	armv7pmu.num_events	= armv7_read_num_pmnc_events();
+	return &armv7pmu;
+}
 #else
 static const struct arm_pmu *__init armv7_a8_pmu_init(void)
 {
@@ -920,4 +1209,14 @@
 {
 	return NULL;
 }
+
+static const struct arm_pmu *__init armv7_a5_pmu_init(void)
+{
+	return NULL;
+}
+
+static const struct arm_pmu *__init armv7_a15_pmu_init(void)
+{
+	return NULL;
+}
 #endif	/* CONFIG_CPU_V7 */
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 60259ca..604989d 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -253,7 +253,6 @@
 obj-$(CONFIG_HTC_HEADSET) += htc_headset.o
 obj-$(CONFIG_MSM_RMT_STORAGE_CLIENT) += rmt_storage_client.o
 obj-$(CONFIG_MSM_SDIO_SMEM) += sdio_smem.o
-obj-$(CONFIG_PMIC8058) += pmic8058-gpio.o pmic8058-mpp.o
 obj-$(CONFIG_MSM_RPM) += rpm.o rpm_resources.o
 obj-$(CONFIG_MSM_MPM) += mpm.o
 obj-$(CONFIG_MSM_RPM_STATS_LOG) += rpm_stats.o
diff --git a/arch/arm/mach-msm/board-copper.c b/arch/arm/mach-msm/board-copper.c
index 9ddcc78..a2ddeb4 100644
--- a/arch/arm/mach-msm/board-copper.c
+++ b/arch/arm/mach-msm/board-copper.c
@@ -80,6 +80,9 @@
 	CLK_DUMMY("iface_clk",	SDC1_P_CLK,	NULL,			OFF),
 	CLK_DUMMY("core_clk",	SDC3_CLK,	NULL,			OFF),
 	CLK_DUMMY("iface_clk",	SDC3_P_CLK,	NULL,			OFF),
+	CLK_DUMMY("usb_phy_clk", NULL, NULL, OFF),
+	CLK_DUMMY("usb_hs_clk", NULL, NULL, OFF),
+	CLK_DUMMY("usb_hs_pclk", NULL, NULL, OFF),
 };
 
 struct clock_init_data msm_dummy_clock_init_data __initdata = {
diff --git a/arch/arm/mach-msm/board-fsm9xxx.c b/arch/arm/mach-msm/board-fsm9xxx.c
index eb936e4..333d366 100644
--- a/arch/arm/mach-msm/board-fsm9xxx.c
+++ b/arch/arm/mach-msm/board-fsm9xxx.c
@@ -28,15 +28,12 @@
 #include <asm/mach/arch.h>
 #include <asm/setup.h>
 
-#include <mach/mpp.h>
 #include <mach/board.h>
 #include <mach/memory.h>
 #include <mach/msm_iomap.h>
 #include <mach/dma.h>
 #include <mach/sirc.h>
-#include <mach/pmic.h>
 
-#include <mach/vreg.h>
 #include <mach/socinfo.h>
 #include "devices.h"
 #include "timer.h"
@@ -46,7 +43,6 @@
 #include <linux/regulator/consumer.h>
 #include <linux/regulator/machine.h>
 #include <linux/msm_adc.h>
-#include <linux/pmic8058-xoadc.h>
 #include <linux/m_adcproc.h>
 #include <linux/platform_data/qcom_crypto_device.h>
 
@@ -89,8 +85,11 @@
 #define FPGA_SDCC_STATUS        0x8E0001A8
 
 /* Macros assume PMIC GPIOs start at 0 */
-#define PM8058_GPIO_PM_TO_SYS(pm_gpio)	   (pm_gpio + NR_MSM_GPIOS)
-#define PM8058_GPIO_SYS_TO_PM(sys_gpio)    (sys_gpio - NR_MSM_GPIOS)
+#define PM8058_GPIO_PM_TO_SYS(pm_gpio)  (pm_gpio + NR_MSM_GPIOS)
+#define PM8058_GPIO_SYS_TO_PM(sys_gpio) (sys_gpio - NR_MSM_GPIOS)
+#define PM8058_MPP_BASE			(NR_MSM_GPIOS + PM8058_GPIOS)
+#define PM8058_MPP_PM_TO_SYS(pm_gpio)	(pm_gpio + PM8058_MPP_BASE)
+#define PM8058_MPP_SYS_TO_PM(sys_gpio)	(sys_gpio - PM8058_MPP_BASE)
 
 #define PMIC_GPIO_5V_PA_PWR	21	/* PMIC GPIO Number 22 */
 #define PMIC_GPIO_4_2V_PA_PWR	22	/* PMIC GPIO Number 23 */
@@ -102,19 +101,33 @@
 /*
  * PM8058
  */
+struct pm8xxx_mpp_init_info {
+	unsigned			mpp;
+	struct pm8xxx_mpp_config_data	config;
+};
+
+#define PM8XXX_MPP_INIT(_mpp, _type, _level, _control) \
+{ \
+	.mpp	= PM8058_MPP_PM_TO_SYS(_mpp), \
+	.config	= { \
+		.type		= PM8XXX_MPP_TYPE_##_type, \
+		.level		= _level, \
+		.control	= PM8XXX_MPP_##_control, \
+	} \
+}
 
 static int pm8058_gpios_init(void)
 {
 	int i;
 	int rc;
 	struct pm8058_gpio_cfg {
-		int gpio;
-		struct pm8058_gpio cfg;
+		int                gpio;
+		struct pm_gpio	   cfg;
 	};
 
 	struct pm8058_gpio_cfg gpio_cfgs[] = {
 		{				/* 5V PA Power */
-			PMIC_GPIO_5V_PA_PWR,
+			PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_5V_PA_PWR),
 			{
 				.vin_sel = 0,
 				.direction = PM_GPIO_DIR_BOTH,
@@ -127,7 +140,7 @@
 			},
 		},
 		{				/* 4.2V PA Power */
-			PMIC_GPIO_4_2V_PA_PWR,
+			PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_4_2V_PA_PWR),
 			{
 				.vin_sel = 0,
 				.direction = PM_GPIO_DIR_BOTH,
@@ -142,7 +155,7 @@
 	};
 
 	for (i = 0; i < ARRAY_SIZE(gpio_cfgs); ++i) {
-		rc = pm8058_gpio_config(gpio_cfgs[i].gpio, &gpio_cfgs[i].cfg);
+		rc = pm8xxx_gpio_config(gpio_cfgs[i].gpio, &gpio_cfgs[i].cfg);
 		if (rc < 0) {
 			pr_err("%s pmic gpio config failed\n", __func__);
 			return rc;
@@ -154,37 +167,28 @@
 
 static int pm8058_mpps_init(void)
 {
-	int rc;
+	int rc, i;
 
-	/* Set up MPP 3 and 6 as analog outputs at 1.25V */
-	rc = pm8058_mpp_config_analog_output(PMIC_MPP_3,
-			PM_MPP_AOUT_LVL_1V25_2, PM_MPP_AOUT_CTL_ENABLE);
-	if (rc) {
-		pr_err("%s: Config mpp3 on pmic 8058 failed\n", __func__);
-		return rc;
+	struct pm8xxx_mpp_init_info pm8058_mpps[] = {
+		PM8XXX_MPP_INIT(PMIC_MPP_3, A_OUTPUT,
+			PM8XXX_MPP_AOUT_LVL_1V25_2, AOUT_CTRL_ENABLE),
+		PM8XXX_MPP_INIT(PMIC_MPP_6, A_OUTPUT,
+			PM8XXX_MPP_AOUT_LVL_1V25_2, AOUT_CTRL_ENABLE),
+	};
+
+	for (i = 0; i < ARRAY_SIZE(pm8058_mpps); i++) {
+		rc = pm8xxx_mpp_config(pm8058_mpps[i].mpp,
+					&pm8058_mpps[i].config);
+		if (rc) {
+			pr_err("%s: Config %d mpp pm 8058 failed\n",
+						__func__, pm8058_mpps[i].mpp);
+			return rc;
+		}
 	}
 
-	rc = pm8058_mpp_config_analog_output(PMIC_MPP_6,
-			PM_MPP_AOUT_LVL_1V25_2, PM_MPP_AOUT_CTL_ENABLE);
-	if (rc) {
-		pr_err("%s: Config mpp5 on pmic 8058 failed\n", __func__);
-		return rc;
-	}
 	return 0;
 }
 
-static struct pm8058_gpio_platform_data pm8058_gpio_data = {
-	.gpio_base = PM8058_GPIO_PM_TO_SYS(0),
-	.irq_base = PM8058_GPIO_IRQ(PMIC8058_IRQ_BASE, 0),
-	.init = pm8058_gpios_init,
-};
-
-static struct pm8058_gpio_platform_data pm8058_mpp_data = {
-	.gpio_base = PM8058_GPIO_PM_TO_SYS(PM8058_GPIOS),
-	.irq_base = PM8058_MPP_IRQ(PMIC8058_IRQ_BASE, 0),
-	.init = pm8058_mpps_init,
-};
-
 static struct regulator_consumer_supply pm8058_vreg_supply[PM8058_VREG_MAX] = {
 	[PM8058_VREG_ID_L3] = REGULATOR_SUPPLY("8058_l3", NULL),
 	[PM8058_VREG_ID_L8] = REGULATOR_SUPPLY("8058_l8", NULL),
@@ -199,7 +203,7 @@
 
 #define PM8058_VREG_INIT(_id, _min_uV, _max_uV, _modes, _ops, _apply_uV, \
 			_always_on, _pull_down) \
-	[_id] = { \
+	{ \
 		.init_data = { \
 			.constraints = { \
 				.valid_modes_mask = _modes, \
@@ -212,6 +216,7 @@
 			.num_consumer_supplies = 1, \
 			.consumer_supplies = &pm8058_vreg_supply[_id], \
 		}, \
+		.id = _id, \
 		.pull_down_enable = _pull_down, \
 		.pin_ctrl = 0, \
 		.pin_fn = PM8058_VREG_PIN_FN_ENABLE, \
@@ -233,7 +238,7 @@
 	PM8058_VREG_INIT(_id, _min_uV, _min_uV, REGULATOR_MODE_NORMAL, \
 			REGULATOR_CHANGE_STATUS, 0, 0, 1)
 
-static struct pm8058_vreg_pdata pm8058_vreg_init[PM8058_VREG_MAX] = {
+static struct pm8058_vreg_pdata pm8058_vreg_init[] = {
 	PM8058_VREG_INIT_LDO(PM8058_VREG_ID_L3, 1800000, 1800000),
 	PM8058_VREG_INIT_LDO(PM8058_VREG_ID_L8, 2200000, 2200000),
 	PM8058_VREG_INIT_LDO(PM8058_VREG_ID_L9, 2050000, 2050000),
@@ -244,22 +249,7 @@
 	PM8058_VREG_INIT_SMPS(PM8058_VREG_ID_S4, 1300000, 1300000),
 };
 
-#define PM8058_VREG(_id) { \
-	.name = "pm8058-regulator", \
-	.id = _id, \
-	.platform_data = &pm8058_vreg_init[_id], \
-	.pdata_size    = sizeof(pm8058_vreg_init[_id]), \
-}
-
 #ifdef CONFIG_SENSORS_MSM_ADC
-static struct resource resources_adc[] = {
-	{
-		.start = PM8058_ADC_IRQ(PMIC8058_IRQ_BASE),
-		.end   = PM8058_ADC_IRQ(PMIC8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-};
-
 static struct adc_access_fn xoadc_fn = {
 	pm8058_xoadc_select_chan_and_start_conv,
 	pm8058_xoadc_read_adc_code,
@@ -298,17 +288,21 @@
 
 static void pmic8058_xoadc_mpp_config(void)
 {
-	int rc;
-
-	rc = pm8058_mpp_config_analog_input(XOADC_MPP_7,
-			PM_MPP_AIN_AMUX_CH5, PM_MPP_AOUT_CTL_DISABLE);
-	if (rc)
-		pr_err("%s: Config mpp7 on pmic 8058 failed\n", __func__);
-
-	rc = pm8058_mpp_config_analog_input(XOADC_MPP_10,
-			PM_MPP_AIN_AMUX_CH6, PM_MPP_AOUT_CTL_DISABLE);
-	if (rc)
-		pr_err("%s: Config mpp10 on pmic 8058 failed\n", __func__);
+	int rc, i;
+	struct pm8xxx_mpp_init_info xoadc_mpps[] = {
+		PM8XXX_MPP_INIT(PMIC_MPP_7, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH5,
+							AOUT_CTRL_DISABLE),
+		PM8XXX_MPP_INIT(PMIC_MPP_10, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH6,
+							AOUT_CTRL_DISABLE),
+	};
+	for (i = 0; i < ARRAY_SIZE(xoadc_mpps); i++) {
+		rc = pm8xxx_mpp_config(xoadc_mpps[i].mpp,
+					&xoadc_mpps[i].config);
+		if (rc) {
+			pr_err("%s: Config MPP %d of PM8058 failed\n",
+					__func__, xoadc_mpps[i].mpp);
+		}
+	}
 }
 
 static struct regulator *vreg_ldo18_adc;
@@ -373,7 +367,7 @@
 	.conversiontime         = 54,
 };
 
-static struct xoadc_platform_data xoadc_pdata = {
+static struct xoadc_platform_data pm8058_xoadc_pdata = {
 	.xoadc_prop = &pm8058_xoadc_data,
 	.xoadc_mpp_config = pmic8058_xoadc_mpp_config,
 	.xoadc_vreg_set = pmic8058_xoadc_vreg_config,
@@ -400,7 +394,7 @@
 };
 
 #define PM8058_XO_INIT(_id, _modes, _ops, _always_on) \
-	[PM8058_XO_ID_##_id] = { \
+	{ \
 		.init_data = { \
 			.constraints = { \
 				.valid_modes_mask = _modes, \
@@ -412,63 +406,44 @@
 				ARRAY_SIZE(xo_consumers_##_id),\
 			.consumer_supplies = xo_consumers_##_id, \
 		}, \
+		.id = PM8058_XO_ID_##_id, \
 	}
 
 #define PM8058_XO_INIT_AX(_id) \
 	PM8058_XO_INIT(_id, REGULATOR_MODE_NORMAL, REGULATOR_CHANGE_STATUS, 0)
 
-static struct pm8058_xo_pdata pm8058_xo_init_pdata[PM8058_XO_ID_MAX] = {
+static struct pm8058_xo_pdata pm8058_xo_init_pdata[] = {
 	PM8058_XO_INIT_AX(A0),
 	PM8058_XO_INIT_AX(A1),
 };
 
-#define PM8058_XO(_id) { \
-	.name = PM8058_XO_BUFFER_DEV_NAME, \
-	.id = _id, \
-	.platform_data = &pm8058_xo_init_pdata[_id], \
-	.pdata_size = sizeof(pm8058_xo_init_pdata[_id]), \
-}
+#define PM8058_GPIO_INT		47
 
-/* Put sub devices with fixed location first in sub_devices array */
-static struct mfd_cell pm8058_subdevs[] = {
-	{	.name = "pm8058-mpp",
-		.platform_data	= &pm8058_mpp_data,
-		.pdata_size	= sizeof(pm8058_mpp_data),
-	},
-	{
-		.name = "pm8058-gpio",
-		.id = -1,
-		.platform_data = &pm8058_gpio_data,
-		.pdata_size	= sizeof(pm8058_gpio_data),
-	},
-#ifdef CONFIG_SENSORS_MSM_ADC
-	{
-		.name = "pm8058-xoadc",
-		.id = -1,
-		.num_resources = ARRAY_SIZE(resources_adc),
-		.resources = resources_adc,
-		.platform_data = &xoadc_pdata,
-		.pdata_size	=sizeof(xoadc_pdata),
-	},
-#endif
-	PM8058_VREG(PM8058_VREG_ID_L3),
-	PM8058_VREG(PM8058_VREG_ID_L8),
-	PM8058_VREG(PM8058_VREG_ID_L9),
-	PM8058_VREG(PM8058_VREG_ID_L14),
-	PM8058_VREG(PM8058_VREG_ID_L15),
-	PM8058_VREG(PM8058_VREG_ID_L18),
-	PM8058_VREG(PM8058_VREG_ID_S4),
-	PM8058_VREG(PM8058_VREG_ID_LVS0),
-	PM8058_XO(PM8058_XO_ID_A0),
-	PM8058_XO(PM8058_XO_ID_A1),
+static struct pm8xxx_irq_platform_data pm8xxx_irq_pdata = {
+	.irq_base		= PMIC8058_IRQ_BASE,
+	.devirq			= MSM_GPIO_TO_INT(PM8058_GPIO_INT),
+	.irq_trigger_flag	= IRQF_TRIGGER_LOW,
+};
+
+static struct pm8xxx_gpio_platform_data pm8xxx_gpio_pdata = {
+	.gpio_base	= PM8058_GPIO_PM_TO_SYS(0),
+};
+
+static struct pm8xxx_mpp_platform_data pm8xxx_mpp_pdata = {
+	.mpp_base	= PM8058_MPP_PM_TO_SYS(0),
 };
 
 static struct pm8058_platform_data pm8058_fsm9xxx_data = {
-	.irq_base = PMIC8058_IRQ_BASE,
-	.irq = MSM_GPIO_TO_INT(47),
-
-	.num_subdevs = ARRAY_SIZE(pm8058_subdevs),
-	.sub_devices = pm8058_subdevs,
+	.irq_pdata		= &pm8xxx_irq_pdata,
+	.gpio_pdata		= &pm8xxx_gpio_pdata,
+	.mpp_pdata		= &pm8xxx_mpp_pdata,
+	.regulator_pdatas	= pm8058_vreg_init,
+	.num_regulators		= ARRAY_SIZE(pm8058_vreg_init),
+	.xo_buffer_pdata	= pm8058_xo_init_pdata,
+	.num_xo_buffers		= ARRAY_SIZE(pm8058_xo_init_pdata),
+#ifdef CONFIG_SENSORS_MSM_ADC
+	.xoadc_pdata		= &pm8058_xoadc_pdata,
+#endif
 };
 
 #ifdef CONFIG_MSM_SSBI
@@ -882,13 +857,15 @@
 	msm_device_ssbi_pmic1.dev.platform_data =
 			&fsm9xxx_ssbi_pm8058_pdata;
 #endif
+	buses_init();
 
 	platform_add_devices(devices, ARRAY_SIZE(devices));
 
 #ifdef CONFIG_MSM_SPM
 	msm_spm_init(&msm_spm_data, 1);
 #endif
-	buses_init();
+	pm8058_gpios_init();
+	pm8058_mpps_init();
 	phy_init();
 	grfc_init();
 	user_gpios_init();
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 9155e0c..eda29cd 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -23,16 +23,14 @@
 #endif
 #include <linux/msm_ssbi.h>
 #include <linux/mfd/pmic8058.h>
+#include <linux/leds.h>
 #include <linux/mfd/marimba.h>
 #include <linux/i2c.h>
 #include <linux/input.h>
 #include <linux/smsc911x.h>
 #include <linux/ofn_atlab.h>
 #include <linux/power_supply.h>
-#include <linux/input/pmic8058-keypad.h>
 #include <linux/i2c/isa1200.h>
-#include <linux/pwm.h>
-#include <linux/pmic8058-pwm.h>
 #include <linux/i2c/tsc2007.h>
 #include <linux/input/kp_flip_switch.h>
 #include <linux/leds-pmic8058.h>
@@ -123,6 +121,8 @@
 /* Macros assume PMIC GPIOs start at 0 */
 #define PM8058_GPIO_PM_TO_SYS(pm_gpio)     (pm_gpio + NR_GPIO_IRQS)
 #define PM8058_GPIO_SYS_TO_PM(sys_gpio)    (sys_gpio - NR_GPIO_IRQS)
+#define PM8058_MPP_BASE			   PM8058_GPIO_PM_TO_SYS(PM8058_GPIOS)
+#define PM8058_MPP_PM_TO_SYS(pm_gpio)	   (pm_gpio + PM8058_MPP_BASE)
 
 #define PMIC_GPIO_FLASH_BOOST_ENABLE	15	/* PMIC GPIO Number 16 */
 #define PMIC_GPIO_HAP_ENABLE   16  /* PMIC GPIO Number 17 */
@@ -136,61 +136,71 @@
 #define PMIC_GPIO_QUICKVX_CLK 37 /* PMIC GPIO 38 */
 
 #define	PM_FLIP_MPP 5 /* PMIC MPP 06 */
+
+struct pm8xxx_gpio_init_info {
+	unsigned			gpio;
+	struct pm_gpio			config;
+};
+
 static int pm8058_gpios_init(void)
 {
 	int rc;
-	int pmic_gpio_hdmi_5v_en;
 
-#ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
-	struct pm8058_gpio sdcc_det = {
-		.direction      = PM_GPIO_DIR_IN,
-		.pull           = PM_GPIO_PULL_UP_1P5,
-		.vin_sel        = 2,
-		.function       = PM_GPIO_FUNC_NORMAL,
-		.inv_int_pol    = 0,
-	};
-#endif
-	struct pm8058_gpio sdc4_en = {
-		.direction      = PM_GPIO_DIR_OUT,
-		.pull           = PM_GPIO_PULL_NO,
-		.vin_sel        = PM_GPIO_VIN_L5,
-		.function       = PM_GPIO_FUNC_NORMAL,
-		.inv_int_pol    = 0,
-		.out_strength   = PM_GPIO_STRENGTH_LOW,
-		.output_value   = 0,
+	struct pm8xxx_gpio_init_info sdc4_en = {
+		PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SDC4_EN_N),
+		{
+			.direction      = PM_GPIO_DIR_OUT,
+			.pull           = PM_GPIO_PULL_NO,
+			.vin_sel        = PM8058_GPIO_VIN_L5,
+			.function       = PM_GPIO_FUNC_NORMAL,
+			.inv_int_pol    = 0,
+			.out_strength   = PM_GPIO_STRENGTH_LOW,
+			.output_value   = 0,
+		},
 	};
 
-	struct pm8058_gpio haptics_enable = {
-		.direction      = PM_GPIO_DIR_OUT,
-		.pull           = PM_GPIO_PULL_NO,
-		.out_strength   = PM_GPIO_STRENGTH_HIGH,
-		.function       = PM_GPIO_FUNC_NORMAL,
-		.inv_int_pol    = 0,
-		.vin_sel        = 2,
-		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
-		.output_value   = 0,
+	struct pm8xxx_gpio_init_info haptics_enable = {
+		PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_HAP_ENABLE),
+		{
+			.direction      = PM_GPIO_DIR_OUT,
+			.pull           = PM_GPIO_PULL_NO,
+			.out_strength   = PM_GPIO_STRENGTH_HIGH,
+			.function       = PM_GPIO_FUNC_NORMAL,
+			.inv_int_pol    = 0,
+			.vin_sel        = 2,
+			.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
+			.output_value   = 0,
+		},
 	};
 
-	struct pm8058_gpio hdmi_5V_en = {
-		.direction      = PM_GPIO_DIR_OUT,
-		.pull           = PM_GPIO_PULL_NO,
-		.vin_sel        = PM_GPIO_VIN_VPH,
-		.function       = PM_GPIO_FUNC_NORMAL,
-		.out_strength   = PM_GPIO_STRENGTH_LOW,
-		.output_value   = 0,
+	struct pm8xxx_gpio_init_info hdmi_5V_en = {
+		PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_HDMI_5V_EN_V3),
+		{
+			.direction      = PM_GPIO_DIR_OUT,
+			.pull           = PM_GPIO_PULL_NO,
+			.vin_sel        = PM8058_GPIO_VIN_VPH,
+			.function       = PM_GPIO_FUNC_NORMAL,
+			.out_strength   = PM_GPIO_STRENGTH_LOW,
+			.output_value   = 0,
+		},
 	};
 
-	struct pm8058_gpio flash_boost_enable = {
-		.direction      = PM_GPIO_DIR_OUT,
-		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
-		.output_value   = 0,
-		.pull           = PM_GPIO_PULL_NO,
-		.vin_sel        = PM_GPIO_VIN_S3,
-		.out_strength   = PM_GPIO_STRENGTH_HIGH,
-		.function       = PM_GPIO_FUNC_2,
+	struct pm8xxx_gpio_init_info flash_boost_enable = {
+		PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_FLASH_BOOST_ENABLE),
+		{
+			.direction      = PM_GPIO_DIR_OUT,
+			.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
+			.output_value   = 0,
+			.pull           = PM_GPIO_PULL_NO,
+			.vin_sel        = PM8058_GPIO_VIN_S3,
+			.out_strength   = PM_GPIO_STRENGTH_HIGH,
+			.function        = PM_GPIO_FUNC_2,
+		},
 	};
 
-	struct pm8058_gpio gpio23 = {
+	struct pm8xxx_gpio_init_info gpio23 = {
+		PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_WLAN_EXT_POR),
+		{
 			.direction      = PM_GPIO_DIR_OUT,
 			.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
 			.output_value   = 0,
@@ -198,71 +208,83 @@
 			.vin_sel        = 2,
 			.out_strength   = PM_GPIO_STRENGTH_LOW,
 			.function       = PM_GPIO_FUNC_NORMAL,
+		}
 	};
 
-
-	if (machine_is_msm8x55_svlte_surf() || machine_is_msm8x55_svlte_ffa() ||
-						machine_is_msm7x30_fluid())
-		pmic_gpio_hdmi_5v_en = PMIC_GPIO_HDMI_5V_EN_V2 ;
-	else
-		pmic_gpio_hdmi_5v_en = PMIC_GPIO_HDMI_5V_EN_V3 ;
-
-	if (machine_is_msm7x30_fluid()) {
-		rc = pm8058_gpio_config(PMIC_GPIO_HAP_ENABLE, &haptics_enable);
-		if (rc) {
-			pr_err("%s: PMIC GPIO %d write failed\n", __func__,
-				(PMIC_GPIO_HAP_ENABLE + 1));
-			return rc;
-		}
-		rc = pm8058_gpio_config(PMIC_GPIO_FLASH_BOOST_ENABLE,
-			&flash_boost_enable);
-		if (rc) {
-			pr_err("%s: PMIC GPIO %d write failed\n", __func__,
-				(PMIC_GPIO_FLASH_BOOST_ENABLE + 1));
-			return rc;
-		}
-	}
-
 #ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
-	if (machine_is_msm7x30_fluid())
-		sdcc_det.inv_int_pol = 1;
+	struct pm8xxx_gpio_init_info sdcc_det = {
+		PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SD_DET - 1),
+		{
+			.direction      = PM_GPIO_DIR_IN,
+			.pull           = PM_GPIO_PULL_UP_1P5,
+			.vin_sel        = 2,
+			.function       = PM_GPIO_FUNC_NORMAL,
+			.inv_int_pol    = 0,
+		},
+	};
 
-	rc = pm8058_gpio_config(PMIC_GPIO_SD_DET - 1, &sdcc_det);
+	if (machine_is_msm7x30_fluid())
+		sdcc_det.config.inv_int_pol = 1;
+
+	rc = pm8xxx_gpio_config(sdcc_det.gpio, &sdcc_det.config);
 	if (rc) {
 		pr_err("%s PMIC_GPIO_SD_DET config failed\n", __func__);
 		return rc;
 	}
 #endif
 
-	rc = pm8058_gpio_config(pmic_gpio_hdmi_5v_en, &hdmi_5V_en);
+	if (machine_is_msm8x55_svlte_surf() || machine_is_msm8x55_svlte_ffa() ||
+						machine_is_msm7x30_fluid())
+		hdmi_5V_en.gpio = PMIC_GPIO_HDMI_5V_EN_V2;
+	else
+		hdmi_5V_en.gpio = PMIC_GPIO_HDMI_5V_EN_V3;
+
+	hdmi_5V_en.gpio = PM8058_GPIO_PM_TO_SYS(hdmi_5V_en.gpio);
+
+	rc = pm8xxx_gpio_config(hdmi_5V_en.gpio, &hdmi_5V_en.config);
 	if (rc) {
 		pr_err("%s PMIC_GPIO_HDMI_5V_EN config failed\n", __func__);
 		return rc;
 	}
 
 	/* Deassert GPIO#23 (source for Ext_POR on WLAN-Volans) */
-	rc = pm8058_gpio_config(PMIC_GPIO_WLAN_EXT_POR, &gpio23);
+	rc = pm8xxx_gpio_config(gpio23.gpio, &gpio23.config);
 	if (rc) {
 		pr_err("%s PMIC_GPIO_WLAN_EXT_POR config failed\n", __func__);
 		return rc;
 	}
 
 	if (machine_is_msm7x30_fluid()) {
-		rc = pm8058_gpio_config(PMIC_GPIO_SDC4_EN_N, &sdc4_en);
+		/* Haptics gpio */
+		rc = pm8xxx_gpio_config(haptics_enable.gpio,
+						&haptics_enable.config);
+		if (rc) {
+			pr_err("%s: PMIC GPIO %d write failed\n", __func__,
+							haptics_enable.gpio);
+			return rc;
+		}
+		/* Flash boost gpio */
+		rc = pm8xxx_gpio_config(flash_boost_enable.gpio,
+						&flash_boost_enable.config);
+		if (rc) {
+			pr_err("%s: PMIC GPIO %d write failed\n", __func__,
+						flash_boost_enable.gpio);
+			return rc;
+		}
+		/* SCD4 gpio */
+		rc = pm8xxx_gpio_config(sdc4_en.gpio, &sdc4_en.config);
 		if (rc) {
 			pr_err("%s PMIC_GPIO_SDC4_EN_N config failed\n",
 								 __func__);
 			return rc;
 		}
-		rc = gpio_request(PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SDC4_EN_N),
-				  "sdc4_en");
+		rc = gpio_request(sdc4_en.gpio, "sdc4_en");
 		if (rc) {
 			pr_err("%s PMIC_GPIO_SDC4_EN_N gpio_request failed\n",
 				__func__);
 			return rc;
 		}
-		gpio_set_value_cansleep(
-			PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SDC4_EN_N), 0);
+		gpio_set_value_cansleep(sdc4_en.gpio, 0);
 	}
 
 	return 0;
@@ -450,12 +472,12 @@
 
 static int pm8058_pwm_config(struct pwm_device *pwm, int ch, int on)
 {
-	struct pm8058_gpio pwm_gpio_config = {
+	struct pm_gpio pwm_gpio_config = {
 		.direction      = PM_GPIO_DIR_OUT,
 		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
 		.output_value   = 0,
 		.pull           = PM_GPIO_PULL_NO,
-		.vin_sel        = PM_GPIO_VIN_S3,
+		.vin_sel        = PM8058_GPIO_VIN_S3,
 		.out_strength   = PM_GPIO_STRENGTH_HIGH,
 		.function       = PM_GPIO_FUNC_2,
 	};
@@ -469,9 +491,10 @@
 	case 2:
 		if (on) {
 			id = 24 + ch;
-			rc = pm8058_gpio_config(id - 1, &pwm_gpio_config);
+			rc = pm8xxx_gpio_config(PM8058_GPIO_PM_TO_SYS(id - 1),
+							&pwm_gpio_config);
 			if (rc)
-				pr_err("%s: pm8058_gpio_config(%d): rc=%d\n",
+				pr_err("%s: pm8xxx_gpio_config(%d): rc=%d\n",
 				       __func__, id, rc);
 		}
 		break;
@@ -660,78 +683,47 @@
 	KEY(11, 7, KEY_RIGHTSHIFT),
 };
 
-static struct resource resources_keypad[] = {
-	{
-		.start	= PM8058_KEYPAD_IRQ(PMIC8058_IRQ_BASE),
-		.end	= PM8058_KEYPAD_IRQ(PMIC8058_IRQ_BASE),
-		.flags	= IORESOURCE_IRQ,
-	},
-	{
-		.start	= PM8058_KEYSTUCK_IRQ(PMIC8058_IRQ_BASE),
-		.end	= PM8058_KEYSTUCK_IRQ(PMIC8058_IRQ_BASE),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
 static struct matrix_keymap_data surf_keymap_data = {
-        .keymap_size    = ARRAY_SIZE(surf_keymap),
-        .keymap         = surf_keymap,
+	.keymap_size    = ARRAY_SIZE(surf_keymap),
+	.keymap		= surf_keymap,
 };
 
-
-static struct pmic8058_keypad_data surf_keypad_data = {
+static struct pm8xxx_keypad_platform_data surf_keypad_data = {
 	.input_name		= "surf_keypad",
 	.input_phys_device	= "surf_keypad/input0",
 	.num_rows		= 12,
 	.num_cols		= 8,
-	.rows_gpio_start	= 8,
-	.cols_gpio_start	= 0,
-	.debounce_ms		= {8, 10},
+	.rows_gpio_start	= PM8058_GPIO_PM_TO_SYS(8),
+	.cols_gpio_start	= PM8058_GPIO_PM_TO_SYS(0),
+	.debounce_ms		= 15,
 	.scan_delay_ms		= 32,
 	.row_hold_ns		= 91500,
 	.wakeup			= 1,
-	.keymap_data            = &surf_keymap_data,
+	.keymap_data		= &surf_keymap_data,
 };
 
 static struct matrix_keymap_data fluid_keymap_data = {
-        .keymap_size    = ARRAY_SIZE(fluid_keymap),
-        .keymap         = fluid_keymap,
+	.keymap_size	= ARRAY_SIZE(fluid_keymap),
+	.keymap		= fluid_keymap,
 };
 
-
-
-static struct pmic8058_keypad_data fluid_keypad_data = {
+static struct pm8xxx_keypad_platform_data fluid_keypad_data = {
 	.input_name		= "fluid-keypad",
 	.input_phys_device	= "fluid-keypad/input0",
 	.num_rows		= 5,
 	.num_cols		= 5,
-	.rows_gpio_start	= 8,
-	.cols_gpio_start	= 0,
-	.debounce_ms		= {8, 10},
+	.rows_gpio_start	= PM8058_GPIO_PM_TO_SYS(8),
+	.cols_gpio_start	= PM8058_GPIO_PM_TO_SYS(0),
+	.debounce_ms		= 15,
 	.scan_delay_ms		= 32,
 	.row_hold_ns		= 91500,
 	.wakeup			= 1,
-	.keymap_data            = &fluid_keymap_data,
+	.keymap_data		= &fluid_keymap_data,
 };
 
 static struct pm8058_pwm_pdata pm8058_pwm_data = {
-	.config		= pm8058_pwm_config,
-	.enable		= pm8058_pwm_enable,
-};
-
-/* Put sub devices with fixed location first in sub_devices array */
-#define	PM8058_SUBDEV_KPD	0
-#define	PM8058_SUBDEV_LED	1
-
-static struct pm8058_gpio_platform_data pm8058_gpio_data = {
-	.gpio_base	= PM8058_GPIO_PM_TO_SYS(0),
-	.irq_base	= PM8058_GPIO_IRQ(PMIC8058_IRQ_BASE, 0),
-	.init		= pm8058_gpios_init,
-};
-
-static struct pm8058_gpio_platform_data pm8058_mpp_data = {
-	.gpio_base	= PM8058_GPIO_PM_TO_SYS(PM8058_GPIOS),
-	.irq_base	= PM8058_MPP_IRQ(PMIC8058_IRQ_BASE, 0),
+	.config         = pm8058_pwm_config,
+	.enable         = pm8058_pwm_enable,
 };
 
 static struct pmic8058_led pmic8058_ffa_leds[] = {
@@ -765,38 +757,6 @@
 	},
 };
 
-static struct mfd_cell pm8058_subdevs[] = {
-	{	.name = "pm8058-keypad",
-		.id		= -1,
-		.num_resources	= ARRAY_SIZE(resources_keypad),
-		.resources	= resources_keypad,
-	},
-	{	.name = "pm8058-led",
-		.id		= -1,
-	},
-	{	.name = "pm8058-gpio",
-		.id		= -1,
-		.platform_data	= &pm8058_gpio_data,
-		.pdata_size	= sizeof(pm8058_gpio_data),
-	},
-	{	.name = "pm8058-mpp",
-		.id		= -1,
-		.platform_data	= &pm8058_mpp_data,
-		.pdata_size	= sizeof(pm8058_mpp_data),
-	},
-	{	.name = "pm8058-pwm",
-		.id		= -1,
-		.platform_data	= &pm8058_pwm_data,
-		.pdata_size	= sizeof(pm8058_pwm_data),
-	},
-	{	.name = "pm8058-nfc",
-		.id		= -1,
-	},
-	{	.name = "pm8058-upl",
-		.id		= -1,
-	},
-};
-
 static struct pmic8058_leds_platform_data pm8058_surf_leds_data = {
 	.num_leds = ARRAY_SIZE(pmic8058_surf_leds),
 	.leds	= pmic8058_surf_leds,
@@ -825,13 +785,25 @@
 	.leds	= pmic8058_fluid_leds,
 };
 
-static struct pm8058_platform_data pm8058_7x30_data = {
-	.irq_base = PMIC8058_IRQ_BASE,
-	.irq = MSM_GPIO_TO_INT(PMIC_GPIO_INT),
+static struct pm8xxx_irq_platform_data pm8xxx_irq_pdata = {
+	.irq_base		= PMIC8058_IRQ_BASE,
+	.devirq			= MSM_GPIO_TO_INT(PMIC_GPIO_INT),
+	.irq_trigger_flag       = IRQF_TRIGGER_LOW,
+};
 
-	.num_subdevs = ARRAY_SIZE(pm8058_subdevs),
-	.sub_devices = pm8058_subdevs,
-	.irq_trigger_flags = IRQF_TRIGGER_LOW,
+static struct pm8xxx_gpio_platform_data pm8xxx_gpio_pdata = {
+	.gpio_base		= PM8058_GPIO_PM_TO_SYS(0),
+};
+
+static struct pm8xxx_mpp_platform_data pm8xxx_mpp_pdata = {
+	.mpp_base	= PM8058_MPP_PM_TO_SYS(0),
+};
+
+static struct pm8058_platform_data pm8058_7x30_data = {
+	.irq_pdata		= &pm8xxx_irq_pdata,
+	.gpio_pdata		= &pm8xxx_gpio_pdata,
+	.mpp_pdata		= &pm8xxx_mpp_pdata,
+	.pwm_pdata		= &pm8058_pwm_data,
 };
 
 #ifdef CONFIG_MSM_SSBI
@@ -1611,15 +1583,10 @@
 		pr_err("%s: gpio_tlmm_config (gpio=%d) failed\n",
 		       __func__, PMIC_GPIO_INT);
 
-	if (machine_is_msm7x30_fluid()) {
-		pm8058_7x30_data.sub_devices[PM8058_SUBDEV_KPD].platform_data
-			= &fluid_keypad_data;
-	} else {
-		pm8058_7x30_data.sub_devices[PM8058_SUBDEV_KPD].platform_data
-			= &surf_keypad_data;
-		pm8058_7x30_data.sub_devices[PM8058_SUBDEV_KPD].pdata_size
-                        = sizeof(surf_keypad_data);
-	}
+	if (machine_is_msm8x60_fluid())
+		pm8058_7x30_data.keypad_pdata = &fluid_keypad_data;
+	else
+		pm8058_7x30_data.keypad_pdata = &surf_keypad_data;
 
 	return 0;
 }
@@ -3246,24 +3213,27 @@
 {
         int rc;
         static int vbus_is_on;
-        struct pm8058_gpio usb_vbus = {
-                .direction      = PM_GPIO_DIR_OUT,
-                .pull           = PM_GPIO_PULL_NO,
-                .output_buffer  = PM_GPIO_OUT_BUF_CMOS,
-                .output_value   = 1,
-                .vin_sel        = 2,
-                .out_strength   = PM_GPIO_STRENGTH_MED,
-                .function       = PM_GPIO_FUNC_NORMAL,
-                .inv_int_pol    = 0,
-        };
+	struct pm8xxx_gpio_init_info usb_vbus = {
+		PM8058_GPIO_PM_TO_SYS(36),
+		{
+			.direction      = PM_GPIO_DIR_OUT,
+			.pull           = PM_GPIO_PULL_NO,
+			.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
+			.output_value   = 1,
+			.vin_sel        = 2,
+			.out_strength   = PM_GPIO_STRENGTH_MED,
+			.function       = PM_GPIO_FUNC_NORMAL,
+			.inv_int_pol    = 0,
+		},
+	};
 
         /* If VBUS is already on (or off), do nothing. */
         if (unlikely(on == vbus_is_on))
                 return;
 
         if (on) {
-                rc = pm8058_gpio_config(36, &usb_vbus);
-                if (rc) {
+		rc = pm8xxx_gpio_config(usb_vbus.gpio, &usb_vbus.config);
+		if (rc) {
                         pr_err("%s PMIC GPIO 36 write failed\n", __func__);
                         return;
                 }
@@ -4041,14 +4011,17 @@
 static unsigned quickvx_vlp_gpio =
 	GPIO_CFG(97, 0, GPIO_CFG_OUTPUT,  GPIO_CFG_NO_PULL,	GPIO_CFG_2MA);
 
-static struct pm8058_gpio pmic_quickvx_clk_gpio = {
-	.direction      = PM_GPIO_DIR_OUT,
-	.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
-	.output_value   = 1,
-	.pull           = PM_GPIO_PULL_NO,
-	.vin_sel        = PM_GPIO_VIN_S3,
-	.out_strength   = PM_GPIO_STRENGTH_HIGH,
-	.function       = PM_GPIO_FUNC_2,
+static struct pm8xxx_gpio_init_info pmic_quickvx_clk_gpio = {
+	PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_QUICKVX_CLK),
+	{
+		.direction      = PM_GPIO_DIR_OUT,
+		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
+		.output_value   = 1,
+		.pull           = PM_GPIO_PULL_NO,
+		.vin_sel        = PM8058_GPIO_VIN_S3,
+		.out_strength   = PM_GPIO_STRENGTH_HIGH,
+		.function       = PM_GPIO_FUNC_2,
+	},
 };
 
 static int display_common_power(int on)
@@ -4088,11 +4061,11 @@
 			/* bring QuickVX VLP line low */
 			gpio_set_value(97, 0);
 
-			rc = pm8058_gpio_config(PMIC_GPIO_QUICKVX_CLK,
-				&pmic_quickvx_clk_gpio);
+			rc = pm8xxx_gpio_config(pmic_quickvx_clk_gpio.gpio,
+						&pmic_quickvx_clk_gpio.config);
 			if (rc) {
-				pr_err("%s: pm8058_gpio_config(%#x)=%d\n",
-					__func__, PMIC_GPIO_QUICKVX_CLK + 1,
+				pr_err("%s: pm8xxx_gpio_config(%#x)=%d\n",
+					__func__, pmic_quickvx_clk_gpio.gpio,
 					rc);
 				return rc;
 			}
@@ -6452,16 +6425,12 @@
 
 static void __init pmic8058_leds_init(void)
 {
-	if (machine_is_msm7x30_surf()) {
-		pm8058_7x30_data.sub_devices[PM8058_SUBDEV_LED].platform_data
-			= &pm8058_surf_leds_data;
-	} else if (!machine_is_msm7x30_fluid()) {
-		pm8058_7x30_data.sub_devices[PM8058_SUBDEV_LED].platform_data
-			= &pm8058_ffa_leds_data;
-	} else if (machine_is_msm7x30_fluid()) {
-		pm8058_7x30_data.sub_devices[PM8058_SUBDEV_LED].platform_data
-			= &pm8058_fluid_leds_data;
-	}
+	if (machine_is_msm7x30_surf())
+		pm8058_7x30_data.leds_pdata = &pm8058_surf_leds_data;
+	else if (!machine_is_msm7x30_fluid())
+		pm8058_7x30_data.leds_pdata = &pm8058_ffa_leds_data;
+	else if (machine_is_msm7x30_fluid())
+		pm8058_7x30_data.leds_pdata = &pm8058_fluid_leds_data;
 }
 
 static struct msm_spm_platform_data msm_spm_data __initdata = {
@@ -6780,8 +6749,14 @@
 
 static int kp_flip_mpp_config(void)
 {
-	return pm8058_mpp_config_digital_in(PM_FLIP_MPP,
-		PM8058_MPP_DIG_LEVEL_S3, PM_MPP_DIN_TO_INT);
+	struct pm8xxx_mpp_config_data kp_flip_mpp = {
+		.type = PM8XXX_MPP_TYPE_D_INPUT,
+		.level = PM8018_MPP_DIG_LEVEL_S3,
+		.control = PM8XXX_MPP_DIN_TO_INT,
+	};
+
+	return pm8xxx_mpp_config(PM8058_MPP_PM_TO_SYS(PM_FLIP_MPP),
+						&kp_flip_mpp);
 }
 
 static struct flip_switch_pdata flip_switch_data = {
@@ -6992,6 +6967,10 @@
 		msm_adc_pdata.num_adc = ARRAY_SIZE(msm_adc_surf_device_names);
 	}
 
+	pmic8058_leds_init();
+
+	buses_init();
+
 #ifdef CONFIG_MSM_SSBI
 	msm_device_ssbi_pmic1.dev.platform_data =
 				&msm7x30_ssbi_pm8058_pdata;
@@ -7023,7 +7002,6 @@
 	msm_device_i2c_init();
 	msm_device_i2c_2_init();
 	qup_device_i2c_init();
-	buses_init();
 	msm7x30_init_marimba();
 #ifdef CONFIG_MSM7KV2_AUDIO
 	snddev_poweramp_gpio_init();
@@ -7071,7 +7049,8 @@
 
 	if (machine_is_msm7x30_surf())
 		platform_device_register(&flip_switch_device);
-	pmic8058_leds_init();
+
+	pm8058_gpios_init();
 
 	if (machine_is_msm7x30_fluid()) {
 		/* Initialize platform data for fluid v2 hardware */
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
index ab45aca..ece65f3 100644
--- a/arch/arm/mach-msm/board-msm8960.c
+++ b/arch/arm/mach-msm/board-msm8960.c
@@ -843,7 +843,6 @@
 #endif
 #endif
 
-#define MSM_PMEM_KERNEL_EBI1_SIZE  0x110C000
 #define MSM_PMEM_ADSP_SIZE         0x3800000
 #define MSM_PMEM_AUDIO_SIZE        0x28B000
 #ifdef CONFIG_FB_MSM_HDMI_AS_PRIMARY
@@ -854,10 +853,12 @@
 
 
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
-#define MSM_ION_EBI_SIZE	MSM_PMEM_SIZE
+#define MSM_PMEM_KERNEL_EBI1_SIZE  0xB0C000
+#define MSM_ION_EBI_SIZE	(MSM_PMEM_SIZE + 0x600000)
 #define MSM_ION_ADSP_SIZE	MSM_PMEM_ADSP_SIZE
 #define MSM_ION_HEAP_NUM	4
 #else
+#define MSM_PMEM_KERNEL_EBI1_SIZE  0x110C000
 #define MSM_ION_HEAP_NUM	2
 #endif
 
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index b394710..090605f 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -19,21 +19,11 @@
 #include <linux/msm_ssbi.h>
 #include <linux/mfd/pmic8058.h>
 
-#include <linux/input/pmic8058-keypad.h>
-#include <linux/pmic8058-batt-alarm.h>
-#include <linux/pmic8058-pwrkey.h>
-#include <linux/rtc/rtc-pm8058.h>
-#include <linux/pmic8058-vibrator.h>
 #include <linux/leds.h>
 #include <linux/pmic8058-othc.h>
 #include <linux/mfd/pmic8901.h>
-#include <linux/regulator/pmic8058-regulator.h>
 #include <linux/regulator/pmic8901-regulator.h>
 #include <linux/bootmem.h>
-#include <linux/pwm.h>
-#include <linux/pmic8058-pwm.h>
-#include <linux/leds-pmic8058.h>
-#include <linux/pmic8058-xoadc.h>
 #include <linux/msm_adc.h>
 #include <linux/m_adcproc.h>
 #include <linux/mfd/marimba.h>
@@ -274,6 +264,21 @@
 	GPIO_EPM_EXPANDER_IO15,
 };
 
+struct pm8xxx_mpp_init_info {
+	unsigned			mpp;
+	struct pm8xxx_mpp_config_data	config;
+};
+
+#define PM8XXX_MPP_INIT(_mpp, _type, _level, _control) \
+{ \
+	.mpp	= PM8058_MPP_PM_TO_SYS(_mpp), \
+	.config	= { \
+		.type		= PM8XXX_MPP_TYPE_##_type, \
+		.level		= _level, \
+		.control	= PM8XXX_MPP_##_control, \
+	} \
+}
+
 /*
  * The UI_INTx_N lines are pmic gpio lines which connect i2c
  * gpio expanders to the pm8058.
@@ -1054,14 +1059,14 @@
 {
 	unsigned ret = -ENODEV;
 
-	struct pm8058_gpio pmic_id_cfg = {
+	struct pm_gpio pmic_id_cfg = {
 		.direction	= PM_GPIO_DIR_IN,
 		.pull		= PM_GPIO_PULL_UP_1P5,
 		.function	= PM_GPIO_FUNC_NORMAL,
 		.vin_sel	= 2,
 		.inv_int_pol	= 0,
 	};
-	struct pm8058_gpio pmic_id_uncfg = {
+	struct pm_gpio pmic_id_uncfg = {
 		.direction	= PM_GPIO_DIR_IN,
 		.pull		= PM_GPIO_PULL_NO,
 		.function	= PM_GPIO_FUNC_NORMAL,
@@ -1092,9 +1097,10 @@
 	if (init) {
 		notify_vbus_state_func_ptr = callback;
 		INIT_DELAYED_WORK(&pmic_id_det, pmic_id_detect);
-		ret = pm8058_gpio_config(PMIC_ID_GPIO, &pmic_id_cfg);
+		ret = pm8xxx_gpio_config(PM8058_GPIO_PM_TO_SYS(PMIC_ID_GPIO),
+							&pmic_id_cfg);
 		if (ret) {
-			pr_err("%s:return val of pm8058_gpio_config: %d\n",
+			pr_err("%s:return val of pm8xxx_gpio_config: %d\n",
 						__func__,  ret);
 			return ret;
 		}
@@ -1110,9 +1116,10 @@
 	} else {
 		usb_phy_susp_dig_vol = 750000;
 		free_irq(PMICID_INT, 0);
-		ret = pm8058_gpio_config(PMIC_ID_GPIO, &pmic_id_uncfg);
+		ret = pm8xxx_gpio_config(PM8058_GPIO_PM_TO_SYS(PMIC_ID_GPIO),
+							&pmic_id_uncfg);
 		if (ret) {
-			pr_err("%s: return val of pm8058_gpio_config: %d\n",
+			pr_err("%s: return val of pm8xxx_gpio_config: %d\n",
 						__func__,  ret);
 			return ret;
 		}
@@ -4482,13 +4489,6 @@
 #endif
 
 #ifdef CONFIG_SENSORS_MSM_ADC
-static struct resource resources_adc[] = {
-	{
-		.start = PM8058_ADC_IRQ(PM8058_IRQ_BASE),
-		.end   = PM8058_ADC_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-};
 
 static struct adc_access_fn xoadc_fn = {
 	pm8058_xoadc_select_chan_and_start_conv,
@@ -4837,37 +4837,33 @@
 
 static void pmic8058_xoadc_mpp_config(void)
 {
-	int rc;
+	int rc, i;
+	struct pm8xxx_mpp_init_info xoadc_mpps[] = {
+		PM8XXX_MPP_INIT(XOADC_MPP_3, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH5,
+							AOUT_CTRL_DISABLE),
+		PM8XXX_MPP_INIT(XOADC_MPP_5, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH9,
+							AOUT_CTRL_DISABLE),
+		PM8XXX_MPP_INIT(XOADC_MPP_7, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH6,
+							AOUT_CTRL_DISABLE),
+		PM8XXX_MPP_INIT(XOADC_MPP_8, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH8,
+							AOUT_CTRL_DISABLE),
+		PM8XXX_MPP_INIT(XOADC_MPP_10, A_INPUT, PM8XXX_MPP_AIN_AMUX_CH7,
+							AOUT_CTRL_DISABLE),
+	};
 
 	rc = pm8901_mpp_config_digital_out(XOADC_MPP_4,
 			PM8901_MPP_DIG_LEVEL_S4, PM_MPP_DOUT_CTL_LOW);
 	if (rc)
 		pr_err("%s: Config mpp4 on pmic 8901 failed\n", __func__);
 
-	rc = pm8058_mpp_config_analog_input(XOADC_MPP_3,
-			PM_MPP_AIN_AMUX_CH5, PM_MPP_AOUT_CTL_DISABLE);
-	if (rc)
-		pr_err("%s: Config mpp3 on pmic 8058 failed\n", __func__);
-
-	rc = pm8058_mpp_config_analog_input(XOADC_MPP_5,
-			PM_MPP_AIN_AMUX_CH9, PM_MPP_AOUT_CTL_DISABLE);
-	if (rc)
-		pr_err("%s: Config mpp5 on pmic 8058 failed\n", __func__);
-
-	rc = pm8058_mpp_config_analog_input(XOADC_MPP_7,
-			PM_MPP_AIN_AMUX_CH6, PM_MPP_AOUT_CTL_DISABLE);
-	if (rc)
-		pr_err("%s: Config mpp7 on pmic 8058 failed\n", __func__);
-
-	rc = pm8058_mpp_config_analog_input(XOADC_MPP_8,
-			PM_MPP_AIN_AMUX_CH8, PM_MPP_AOUT_CTL_DISABLE);
-	if (rc)
-		pr_err("%s: Config mpp8 on pmic 8058 failed\n", __func__);
-
-	rc = pm8058_mpp_config_analog_input(XOADC_MPP_10,
-			PM_MPP_AIN_AMUX_CH7, PM_MPP_AOUT_CTL_DISABLE);
-	if (rc)
-		pr_err("%s: Config mpp10 on pmic 8058 failed\n", __func__);
+	for (i = 0; i < ARRAY_SIZE(xoadc_mpps); i++) {
+		rc = pm8xxx_mpp_config(xoadc_mpps[i].mpp,
+					&xoadc_mpps[i].config);
+		if (rc) {
+			pr_err("%s: Config MPP %d of PM8058 failed\n",
+					__func__, xoadc_mpps[i].mpp);
+		}
+	}
 }
 
 static struct regulator *vreg_ldo18_adc;
@@ -4932,7 +4928,7 @@
 	.conversiontime         = 54,
 };
 
-static struct xoadc_platform_data xoadc_pdata = {
+static struct xoadc_platform_data pm8058_xoadc_pdata = {
 	.xoadc_prop = &pm8058_xoadc_data,
 	.xoadc_mpp_config = pmic8058_xoadc_mpp_config,
 	.xoadc_vreg_set = pmic8058_xoadc_vreg_config,
@@ -5314,18 +5310,28 @@
 #define EXT_CHG_VALID_MPP 10
 #define EXT_CHG_VALID_MPP_2 11
 
+static struct pm8xxx_mpp_init_info isl_mpp[] = {
+	PM8XXX_MPP_INIT(EXT_CHG_VALID_MPP, D_INPUT,
+		PM8058_MPP_DIG_LEVEL_S3, DIN_TO_INT),
+	PM8XXX_MPP_INIT(EXT_CHG_VALID_MPP_2, D_BI_DIR,
+		PM8058_MPP_DIG_LEVEL_S3, BI_PULLUP_10KOHM),
+};
+
 #ifdef CONFIG_ISL9519_CHARGER
 static int isl_detection_setup(void)
 {
-	int ret = 0;
+	int ret = 0, i;
 
-	ret = pm8058_mpp_config_digital_in(EXT_CHG_VALID_MPP,
-					   PM8058_MPP_DIG_LEVEL_S3,
-					   PM_MPP_DIN_TO_INT);
-	ret |=  pm8058_mpp_config_bi_dir(EXT_CHG_VALID_MPP_2,
-					   PM8058_MPP_DIG_LEVEL_S3,
-					   PM_MPP_BI_PULLUP_10KOHM
-					   );
+	for (i = 0; i < ARRAY_SIZE(isl_mpp); i++) {
+		ret = pm8xxx_mpp_config(isl_mpp[i].mpp,
+					&isl_mpp[i].config);
+		if (ret) {
+			pr_err("%s: Config MPP %d of PM8058 failed\n",
+						 __func__, isl_mpp[i].mpp);
+			return ret;
+		}
+	}
+
 	return ret;
 }
 
@@ -5342,7 +5348,7 @@
 static struct i2c_board_info isl_charger_i2c_info[] __initdata = {
 	{
 		I2C_BOARD_INFO("isl9519q", 0x9),
-		.irq = PM8058_CBLPWR_IRQ(PM8058_IRQ_BASE),
+		.irq = PM8058_IRQ_BASE + PM8058_CBLPWR_IRQ,
 		.platform_data = &isl_data,
 	},
 };
@@ -5351,14 +5357,18 @@
 #if defined(CONFIG_SMB137B_CHARGER) || defined(CONFIG_SMB137B_CHARGER_MODULE)
 static int smb137b_detection_setup(void)
 {
-	int ret = 0;
+	int ret = 0, i;
 
-	ret = pm8058_mpp_config_digital_in(EXT_CHG_VALID_MPP,
-					PM8058_MPP_DIG_LEVEL_S3,
-					PM_MPP_DIN_TO_INT);
-	ret |=  pm8058_mpp_config_bi_dir(EXT_CHG_VALID_MPP_2,
-					PM8058_MPP_DIG_LEVEL_S3,
-					PM_MPP_BI_PULLUP_10KOHM);
+	for (i = 0; i < ARRAY_SIZE(isl_mpp); i++) {
+		ret = pm8xxx_mpp_config(isl_mpp[i].mpp,
+					&isl_mpp[i].config);
+		if (ret) {
+			pr_err("%s: Config MPP %d of PM8058 failed\n",
+						 __func__, isl_mpp[i].mpp);
+			return ret;
+		}
+	}
+
 	return ret;
 }
 
@@ -5371,7 +5381,7 @@
 static struct i2c_board_info smb137b_charger_i2c_info[] __initdata = {
 	{
 		I2C_BOARD_INFO("smb137b", 0x08),
-		.irq = PM8058_CBLPWR_IRQ(PM8058_IRQ_BASE),
+		.irq = PM8058_IRQ_BASE + PM8058_CBLPWR_IRQ,
 		.platform_data = &smb137b_data,
 	},
 };
@@ -5387,12 +5397,12 @@
 	int rc;
 	struct pm8058_gpio_cfg {
 		int                gpio;
-		struct pm8058_gpio cfg;
+		struct pm_gpio	   cfg;
 	};
 
 	struct pm8058_gpio_cfg gpio_cfgs[] = {
 		{ /* FFA ethernet */
-			6,
+			PM8058_GPIO_PM_TO_SYS(6),
 			{
 				.direction      = PM_GPIO_DIR_IN,
 				.pull           = PM_GPIO_PULL_DN,
@@ -5403,7 +5413,7 @@
 		},
 #ifdef CONFIG_MMC_MSM_CARD_HW_DETECTION
 		{
-			PMIC_GPIO_SDC3_DET - 1,
+			PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_SDC3_DET - 1),
 			{
 				.direction      = PM_GPIO_DIR_IN,
 				.pull           = PM_GPIO_PULL_UP_30,
@@ -5414,37 +5424,37 @@
 		},
 #endif
 		{ /* core&surf gpio expander */
-			UI_INT1_N,
+			PM8058_GPIO_PM_TO_SYS(UI_INT1_N),
 			{
 				.direction      = PM_GPIO_DIR_IN,
 				.pull           = PM_GPIO_PULL_NO,
-				.vin_sel        = PM_GPIO_VIN_S3,
+				.vin_sel        = PM8058_GPIO_VIN_S3,
 				.function       = PM_GPIO_FUNC_NORMAL,
 				.inv_int_pol    = 0,
 			},
 		},
 		{ /* docking gpio expander */
-			UI_INT2_N,
+			PM8058_GPIO_PM_TO_SYS(UI_INT2_N),
 			{
 				.direction      = PM_GPIO_DIR_IN,
 				.pull           = PM_GPIO_PULL_NO,
-				.vin_sel        = PM_GPIO_VIN_S3,
+				.vin_sel        = PM8058_GPIO_VIN_S3,
 				.function       = PM_GPIO_FUNC_NORMAL,
 				.inv_int_pol    = 0,
 			},
 		},
 		{ /* FHA/keypad gpio expanders */
-			UI_INT3_N,
+			PM8058_GPIO_PM_TO_SYS(UI_INT3_N),
 			{
 				.direction      = PM_GPIO_DIR_IN,
 				.pull           = PM_GPIO_PULL_NO,
-				.vin_sel        = PM_GPIO_VIN_S3,
+				.vin_sel        = PM8058_GPIO_VIN_S3,
 				.function       = PM_GPIO_FUNC_NORMAL,
 				.inv_int_pol    = 0,
 			},
 		},
 		{ /* Timpani Reset */
-			20,
+			PM8058_GPIO_PM_TO_SYS(20),
 			{
 				.direction	= PM_GPIO_DIR_OUT,
 				.output_value	= 1,
@@ -5457,7 +5467,7 @@
 			}
 		},
 		{ /* PMIC ID interrupt */
-			36,
+			PM8058_GPIO_PM_TO_SYS(36),
 			{
 				.direction	= PM_GPIO_DIR_IN,
 				.pull		= PM_GPIO_PULL_NO,
@@ -5470,7 +5480,7 @@
 
 #if defined(CONFIG_TOUCHDISC_VTD518_SHINETSU) || \
 		defined(CONFIG_TOUCHDISC_VTD518_SHINETSU_MODULE)
-	struct pm8058_gpio touchdisc_intr_gpio_cfg = {
+	struct pm_gpio touchdisc_intr_gpio_cfg = {
 		.direction      = PM_GPIO_DIR_IN,
 		.pull           = PM_GPIO_PULL_UP_1P5,
 		.vin_sel        = 2,
@@ -5480,7 +5490,7 @@
 
 #if defined(CONFIG_HAPTIC_ISA1200) || \
 			defined(CONFIG_HAPTIC_ISA1200_MODULE)
-	struct pm8058_gpio en_hap_gpio_cfg = {
+	struct pm_gpio en_hap_gpio_cfg = {
 		.direction      = PM_GPIO_DIR_OUT,
 		.pull           = PM_GPIO_PULL_NO,
 		.out_strength   = PM_GPIO_STRENGTH_HIGH,
@@ -5494,7 +5504,7 @@
 
 #if defined(CONFIG_PMIC8058_OTHC) || defined(CONFIG_PMIC8058_OTHC_MODULE)
 	struct pm8058_gpio_cfg line_in_gpio_cfg = {
-			18,
+			PM8058_GPIO_PM_TO_SYS(18),
 			{
 				.direction	= PM_GPIO_DIR_IN,
 				.pull           = PM_GPIO_PULL_UP_1P5,
@@ -5508,7 +5518,7 @@
 #if defined(CONFIG_QS_S5K4E1)
 		{
 			struct pm8058_gpio_cfg qs_hc37_cam_pd_gpio_cfg = {
-			26,
+			PM8058_GPIO_PM_TO_SYS(26),
 			{
 				.direction		= PM_GPIO_DIR_OUT,
 				.output_value	= 0,
@@ -5523,32 +5533,33 @@
 #endif
 #ifdef CONFIG_FB_MSM_LCDC_NT35582_WVGA
 	struct pm8058_gpio_cfg pmic_lcdc_nt35582_gpio_cfg = {
-		GPIO_NT35582_BL_EN_HW_PIN - 1,
+		PM8058_GPIO_PM_TO_SYS(GPIO_NT35582_BL_EN_HW_PIN - 1),
 		{
 			.direction		= PM_GPIO_DIR_OUT,
 			.output_buffer	= PM_GPIO_OUT_BUF_CMOS,
 			.output_value	= 1,
 			.pull			= PM_GPIO_PULL_UP_30,
 			/* 2.9V  PM_GPIO_VIN_L2, which gives 2.6V */
-			.vin_sel		= PM_GPIO_VIN_L5,
+			.vin_sel		= PM8058_GPIO_VIN_L5,
 			.out_strength	= PM_GPIO_STRENGTH_HIGH,
 			.function		= PM_GPIO_FUNC_NORMAL,
 			.inv_int_pol	= 0,
 		}
 	};
 #endif
-
 #if defined(CONFIG_HAPTIC_ISA1200) || \
 			defined(CONFIG_HAPTIC_ISA1200_MODULE)
 	if (machine_is_msm8x60_fluid()) {
-		rc = pm8058_gpio_config(PMIC_GPIO_HAP_ENABLE,
-				&en_hap_gpio_cfg);
+		rc = pm8xxx_gpio_config(
+			PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_HAP_ENABLE),
+			&en_hap_gpio_cfg);
 		if (rc < 0) {
 			pr_err("%s: pmic haptics gpio config failed\n",
 							__func__);
 		}
-		rc = pm8058_gpio_config(PMIC_GPIO_HAP_LDO_ENABLE,
-				&en_hap_gpio_cfg);
+		rc = pm8xxx_gpio_config(
+			PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_HAP_LDO_ENABLE),
+			&en_hap_gpio_cfg);
 		if (rc < 0) {
 			pr_err("%s: pmic haptics ldo gpio config failed\n",
 							__func__);
@@ -5561,8 +5572,9 @@
 		defined(CONFIG_TOUCHDISC_VTD518_SHINETSU_MODULE)
 	if (machine_is_msm8x60_ffa() || machine_is_msm8x60_surf() ||
 		machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa()) {
-		rc = pm8058_gpio_config(PMIC_GPIO_TOUCH_DISC_INTR,
-				&touchdisc_intr_gpio_cfg);
+		rc = pm8xxx_gpio_config(
+			PM8058_GPIO_PM_TO_SYS(PMIC_GPIO_TOUCH_DISC_INTR),
+			&touchdisc_intr_gpio_cfg);
 		if (rc < 0) {
 			pr_err("%s: Touchdisc interrupt gpio config failed\n",
 							__func__);
@@ -5575,7 +5587,7 @@
 	if (machine_is_msm8x60_ffa() || machine_is_msm8x60_surf() ||
 		machine_is_msm8x60_fusion() || machine_is_msm8x60_dragon() ||
 		machine_is_msm8x60_fusn_ffa()) {
-		rc = pm8058_gpio_config(line_in_gpio_cfg.gpio,
+		rc = pm8xxx_gpio_config(line_in_gpio_cfg.gpio,
 				&line_in_gpio_cfg.cfg);
 		if (rc < 0) {
 			pr_err("%s pmic line_in gpio config failed\n",
@@ -5587,7 +5599,7 @@
 
 #ifdef CONFIG_FB_MSM_LCDC_NT35582_WVGA
 	if (machine_is_msm8x60_dragon()) {
-		rc = pm8058_gpio_config(pmic_lcdc_nt35582_gpio_cfg.gpio,
+		rc = pm8xxx_gpio_config(pmic_lcdc_nt35582_gpio_cfg.gpio,
 				&pmic_lcdc_nt35582_gpio_cfg.cfg);
 		if (rc < 0) {
 			pr_err("%s pmic gpio config failed\n", __func__);
@@ -5599,7 +5611,7 @@
 #if defined(CONFIG_QS_S5K4E1)
 		/* qs_cam_hc37_cam_pd only for 8660 fluid qs camera*/
 		if (machine_is_msm8x60_fluid()) {
-			rc = pm8058_gpio_config(qs_hc37_cam_pd_gpio_cfg.gpio,
+			rc = pm8xxx_gpio_config(qs_hc37_cam_pd_gpio_cfg.gpio,
 					&qs_hc37_cam_pd_gpio_cfg.cfg);
 			if (rc < 0) {
 				pr_err("%s pmic qs_hc37_cam_pd gpio config failed\n",
@@ -5611,7 +5623,7 @@
 #endif
 
 	for (i = 0; i < ARRAY_SIZE(gpio_cfgs); ++i) {
-		rc = pm8058_gpio_config(gpio_cfgs[i].gpio,
+		rc = pm8xxx_gpio_config(gpio_cfgs[i].gpio,
 				&gpio_cfgs[i].cfg);
 		if (rc < 0) {
 			pr_err("%s pmic gpio config failed\n",
@@ -5679,32 +5691,19 @@
 	KEY(4, 3, KEY_KBDILLUMTOGGLE),
 };
 
-static struct resource resources_keypad[] = {
-	{
-		.start	= PM8058_KEYPAD_IRQ(PM8058_IRQ_BASE),
-		.end	= PM8058_KEYPAD_IRQ(PM8058_IRQ_BASE),
-		.flags	= IORESOURCE_IRQ,
-	},
-	{
-		.start	= PM8058_KEYSTUCK_IRQ(PM8058_IRQ_BASE),
-		.end	= PM8058_KEYSTUCK_IRQ(PM8058_IRQ_BASE),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
 static struct matrix_keymap_data ffa_keymap_data = {
 	.keymap_size	= ARRAY_SIZE(ffa_keymap),
 	.keymap		= ffa_keymap,
 };
 
-static struct pmic8058_keypad_data ffa_keypad_data = {
+static struct pm8xxx_keypad_platform_data ffa_keypad_data = {
 	.input_name		= "ffa-keypad",
 	.input_phys_device	= "ffa-keypad/input0",
 	.num_rows		= 6,
 	.num_cols		= 5,
-	.rows_gpio_start	= 8,
-	.cols_gpio_start	= 0,
-	.debounce_ms		= {8, 10},
+	.rows_gpio_start	= PM8058_GPIO_PM_TO_SYS(8),
+	.cols_gpio_start	= PM8058_GPIO_PM_TO_SYS(0),
+	.debounce_ms		= 15,
 	.scan_delay_ms		= 32,
 	.row_hold_ns            = 91500,
 	.wakeup			= 1,
@@ -5716,19 +5715,20 @@
 	.keymap = dragon_keymap,
 };
 
-static struct pmic8058_keypad_data dragon_keypad_data = {
+static struct pm8xxx_keypad_platform_data dragon_keypad_data = {
 	.input_name = "dragon-keypad",
 	.input_phys_device = "dragon-keypad/input0",
 	.num_rows = 6,
 	.num_cols = 5,
-	.rows_gpio_start = 8,
-	.cols_gpio_start = 0,
-	.debounce_ms = {8, 10},
+	.rows_gpio_start	= PM8058_GPIO_PM_TO_SYS(8),
+	.cols_gpio_start	= PM8058_GPIO_PM_TO_SYS(0),
+	.debounce_ms		= 15,
 	.scan_delay_ms = 32,
 	.row_hold_ns = 91500,
 	.wakeup = 1,
 	.keymap_data = &dragon_keymap_data,
 };
+
 static const unsigned int fluid_keymap[] = {
 	KEY(0, 0, KEY_FN_F1),	 /* LS - PUSH1 */
 	KEY(0, 1, KEY_UP),	 /* NAV - UP */
@@ -5760,50 +5760,37 @@
 	.keymap		= fluid_keymap,
 };
 
-static struct pmic8058_keypad_data fluid_keypad_data = {
+static struct pm8xxx_keypad_platform_data fluid_keypad_data = {
 	.input_name		= "fluid-keypad",
 	.input_phys_device	= "fluid-keypad/input0",
 	.num_rows		= 6,
 	.num_cols		= 5,
-	.rows_gpio_start	= 8,
-	.cols_gpio_start	= 0,
-	.debounce_ms		= {8, 10},
+	.rows_gpio_start	= PM8058_GPIO_PM_TO_SYS(8),
+	.cols_gpio_start	= PM8058_GPIO_PM_TO_SYS(0),
+	.debounce_ms		= 15,
 	.scan_delay_ms		= 32,
 	.row_hold_ns            = 91500,
 	.wakeup			= 1,
 	.keymap_data		= &fluid_keymap_data,
 };
 
-static struct resource resources_pwrkey[] = {
-	{
-		.start	= PM8058_PWRKEY_REL_IRQ(PM8058_IRQ_BASE),
-		.end	= PM8058_PWRKEY_REL_IRQ(PM8058_IRQ_BASE),
-		.flags	= IORESOURCE_IRQ,
-	},
-	{
-		.start	= PM8058_PWRKEY_PRESS_IRQ(PM8058_IRQ_BASE),
-		.end	= PM8058_PWRKEY_PRESS_IRQ(PM8058_IRQ_BASE),
-		.flags	= IORESOURCE_IRQ,
-	},
-};
-
-static struct pmic8058_pwrkey_pdata pwrkey_pdata = {
-	.pull_up		= 1,
-	.kpd_trigger_delay_us   = 970,
-	.wakeup			= 1,
-	.pwrkey_time_ms		= 500,
-};
-
-static struct pmic8058_vibrator_pdata pmic_vib_pdata = {
+static struct pm8xxx_vibrator_platform_data pm8058_vib_pdata = {
 	.initial_vibrate_ms  = 500,
 	.level_mV = 3000,
 	.max_timeout_ms = 15000,
 };
 
-#if defined(CONFIG_PMIC8058_OTHC) || defined(CONFIG_PMIC8058_OTHC_MODULE)
-#define PM8058_OTHC_CNTR_BASE0	0xA0
-#define PM8058_OTHC_CNTR_BASE1	0x134
-#define PM8058_OTHC_CNTR_BASE2	0x137
+static struct pm8xxx_rtc_platform_data pm8058_rtc_pdata = {
+	.rtc_write_enable       = false,
+	.rtc_alarm_powerup	= false,
+};
+
+static struct pm8xxx_pwrkey_platform_data pm8058_pwrkey_pdata = {
+	.pull_up		= 1,
+	.kpd_trigger_delay_us   = 970,
+	.wakeup			= 1,
+};
+
 #define PM8058_LINE_IN_DET_GPIO	PM8058_GPIO_PM_TO_SYS(18)
 
 static struct othc_accessory_info othc_accessories[]  = {
@@ -5950,42 +5937,6 @@
 	.micbias_regulator = &othc_reg,
 };
 
-static struct resource resources_othc_0[] = {
-	{
-		.name = "othc_base",
-		.start = PM8058_OTHC_CNTR_BASE0,
-		.end   = PM8058_OTHC_CNTR_BASE0,
-		.flags = IORESOURCE_IO,
-	},
-};
-
-static struct resource resources_othc_1[] = {
-	{
-		.start = PM8058_SW_1_IRQ(PM8058_IRQ_BASE),
-		.end   = PM8058_SW_1_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.start = PM8058_IR_1_IRQ(PM8058_IRQ_BASE),
-		.end   = PM8058_IR_1_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "othc_base",
-		.start = PM8058_OTHC_CNTR_BASE1,
-		.end   = PM8058_OTHC_CNTR_BASE1,
-		.flags = IORESOURCE_IO,
-	},
-};
-
-static struct resource resources_othc_2[] = {
-	{
-		.name = "othc_base",
-		.start = PM8058_OTHC_CNTR_BASE2,
-		.end   = PM8058_OTHC_CNTR_BASE2,
-		.flags = IORESOURCE_IO,
-	},
-};
 
 static void __init msm8x60_init_pm8058_othc(void)
 {
@@ -6023,143 +5974,16 @@
 		}
 	}
 }
-#endif
 
-static struct resource resources_pm8058_charger[] = {
-	{	.name = "CHGVAL",
-		.start = PM8058_CHGVAL_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_CHGVAL_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{	.name = "CHGINVAL",
-		.start = PM8058_CHGINVAL_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_CHGINVAL_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "CHGILIM",
-		.start = PM8058_CHGILIM_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_CHGILIM_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "VCP",
-		.start = PM8058_VCP_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_VCP_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-		{
-		.name = "ATC_DONE",
-		.start = PM8058_ATC_DONE_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_ATC_DONE_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "ATCFAIL",
-		.start = PM8058_ATCFAIL_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_ATCFAIL_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "AUTO_CHGDONE",
-		 .start = PM8058_AUTO_CHGDONE_IRQ(PM8058_IRQ_BASE),
-		 .end = PM8058_AUTO_CHGDONE_IRQ(PM8058_IRQ_BASE),
-		 .flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "AUTO_CHGFAIL",
-		.start = PM8058_AUTO_CHGFAIL_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_AUTO_CHGFAIL_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "CHGSTATE",
-		.start = PM8058_CHGSTATE_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_CHGSTATE_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "FASTCHG",
-		.start = PM8058_FASTCHG_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_FASTCHG_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "CHG_END",
-		 .start = PM8058_CHG_END_IRQ(PM8058_IRQ_BASE),
-		 .end = PM8058_CHG_END_IRQ(PM8058_IRQ_BASE),
-		 .flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "BATTTEMP",
-		.start = PM8058_BATTTEMP_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_BATTTEMP_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "CHGHOT",
-		.start = PM8058_CHGHOT_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_CHGHOT_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "CHGTLIMIT",
-		.start = PM8058_CHGTLIMIT_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_CHGTLIMIT_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "CHG_GONE",
-		 .start = PM8058_CHG_GONE_IRQ(PM8058_IRQ_BASE),
-		 .end = PM8058_CHG_GONE_IRQ(PM8058_IRQ_BASE),
-		 .flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "VCPMAJOR",
-		 .start = PM8058_VCPMAJOR_IRQ(PM8058_IRQ_BASE),
-		 .end = PM8058_VCPMAJOR_IRQ(PM8058_IRQ_BASE),
-		 .flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "VBATDET",
-		 .start = PM8058_VBATDET_IRQ(PM8058_IRQ_BASE),
-		 .end = PM8058_VBATDET_IRQ(PM8058_IRQ_BASE),
-		 .flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "BATFET",
-		 .start = PM8058_BATFET_IRQ(PM8058_IRQ_BASE),
-		 .end = PM8058_BATFET_IRQ(PM8058_IRQ_BASE),
-		 .flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "BATT_REPLACE",
-		.start = PM8058_BATT_REPLACE_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_BATT_REPLACE_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "BATTCONNECT",
-		.start = PM8058_BATTCONNECT_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_BATTCONNECT_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-	{
-		.name = "VBATDET_LOW",
-		.start = PM8058_VBATDET_LOW_IRQ(PM8058_IRQ_BASE),
-		.end = PM8058_VBATDET_LOW_IRQ(PM8058_IRQ_BASE),
-		.flags = IORESOURCE_IRQ,
-	},
-};
 
 static int pm8058_pwm_config(struct pwm_device *pwm, int ch, int on)
 {
-	struct pm8058_gpio pwm_gpio_config = {
+	struct pm_gpio pwm_gpio_config = {
 		.direction      = PM_GPIO_DIR_OUT,
 		.output_buffer  = PM_GPIO_OUT_BUF_CMOS,
 		.output_value   = 0,
 		.pull           = PM_GPIO_PULL_NO,
-		.vin_sel        = PM_GPIO_VIN_VPH,
+		.vin_sel        = PM8058_GPIO_VIN_VPH,
 		.out_strength   = PM_GPIO_STRENGTH_HIGH,
 		.function       = PM_GPIO_FUNC_2,
 	};
@@ -6174,9 +5998,10 @@
 	case 2:
 		if (on) {
 			id = 24 + ch;
-			rc = pm8058_gpio_config(id - 1, &pwm_gpio_config);
+			rc = pm8xxx_gpio_config(PM8058_GPIO_PM_TO_SYS(id - 1),
+							&pwm_gpio_config);
 			if (rc)
-				pr_err("%s: pm8058_gpio_config(%d): rc=%d\n",
+				pr_err("%s: pm8xxx_gpio_config(%d): rc=%d\n",
 					__func__, id, rc);
 		}
 		break;
@@ -6217,34 +6042,6 @@
 
 #define PM8058_GPIO_INT           88
 
-static struct pm8058_gpio_platform_data pm8058_gpio_data = {
-	.gpio_base	= PM8058_GPIO_PM_TO_SYS(0),
-	.irq_base	= PM8058_GPIO_IRQ(PM8058_IRQ_BASE, 0),
-	.init		= pm8058_gpios_init,
-};
-
-static struct pm8058_gpio_platform_data pm8058_mpp_data = {
-	.gpio_base	= PM8058_GPIO_PM_TO_SYS(PM8058_GPIOS),
-	.irq_base	= PM8058_MPP_IRQ(PM8058_IRQ_BASE, 0),
-};
-
-static struct resource resources_rtc[] = {
-       {
-		.start  = PM8058_RTC_IRQ(PM8058_IRQ_BASE),
-		.end    = PM8058_RTC_IRQ(PM8058_IRQ_BASE),
-		.flags  = IORESOURCE_IRQ,
-       },
-       {
-		.start  = PM8058_RTC_ALARM_IRQ(PM8058_IRQ_BASE),
-		.end    = PM8058_RTC_ALARM_IRQ(PM8058_IRQ_BASE),
-		.flags  = IORESOURCE_IRQ,
-       },
-};
-
-static struct pm8058_rtc_platform_data pm8058_rtc_pdata = {
-	.rtc_alarm_powerup	= false,
-};
-
 static struct pmic8058_led pmic8058_flash_leds[] = {
 	[0] = {
 		.name		= "camera:flash0",
@@ -6322,156 +6119,48 @@
 	.leds	= pmic8058_fluid_flash_leds,
 };
 
-static struct resource resources_temp_alarm[] = {
-	{
-		.start  = PM8058_TEMP_ALARM_IRQ(PM8058_IRQ_BASE),
-		.end    = PM8058_TEMP_ALARM_IRQ(PM8058_IRQ_BASE),
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static struct resource resources_pm8058_misc[] = {
-	{
-		.start  = PM8058_OSCHALT_IRQ(PM8058_IRQ_BASE),
-		.end    = PM8058_OSCHALT_IRQ(PM8058_IRQ_BASE),
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-static struct resource resources_pm8058_batt_alarm[] = {
-	{
-		.start  = PM8058_BATT_ALARM_IRQ(PM8058_IRQ_BASE),
-		.end    = PM8058_BATT_ALARM_IRQ(PM8058_IRQ_BASE),
-		.flags  = IORESOURCE_IRQ,
-	},
-};
-
-#define PM8058_SUBDEV_KPD 0
-#define PM8058_SUBDEV_LED 1
-#define PM8058_SUBDEV_VIB 2
-
-static struct mfd_cell pm8058_subdevs[] = {
-	{
-		.name = "pm8058-keypad",
-		.id		= -1,
-		.num_resources	= ARRAY_SIZE(resources_keypad),
-		.resources	= resources_keypad,
-	},
-	{	.name = "pm8058-led",
-		.id		= -1,
-	},
-	{
-		.name = "pm8058-vib",
-		.id = -1,
-	},
-	{	.name = "pm8058-gpio",
-		.id		= -1,
-		.platform_data	= &pm8058_gpio_data,
-		.pdata_size = sizeof(pm8058_gpio_data),
-	},
-	{	.name = "pm8058-mpp",
-		.id		= -1,
-		.platform_data	= &pm8058_mpp_data,
-		.pdata_size = sizeof(pm8058_mpp_data),
-	},
-	{	.name = "pm8058-pwrkey",
-		.id	= -1,
-		.resources = resources_pwrkey,
-		.num_resources = ARRAY_SIZE(resources_pwrkey),
-		.platform_data = &pwrkey_pdata,
-		.pdata_size = sizeof(pwrkey_pdata),
-	},
-	{
-		.name = "pm8058-pwm",
-		.id = -1,
-		.platform_data = &pm8058_pwm_data,
-		.pdata_size = sizeof(pm8058_pwm_data),
-	},
-#ifdef CONFIG_SENSORS_MSM_ADC
-	{
-		.name = "pm8058-xoadc",
-		.id = -1,
-		.num_resources = ARRAY_SIZE(resources_adc),
-		.resources = resources_adc,
-		.platform_data = &xoadc_pdata,
-		.pdata_size = sizeof(xoadc_pdata),
-	},
-#endif
-#if defined(CONFIG_PMIC8058_OTHC) || defined(CONFIG_PMIC8058_OTHC_MODULE)
-	{
-		.name = "pm8058-othc",
-		.id = 0,
-		.platform_data = &othc_config_pdata_0,
-		.pdata_size = sizeof(othc_config_pdata_0),
-		.num_resources = ARRAY_SIZE(resources_othc_0),
-		.resources = resources_othc_0,
-	},
-	{
-		/* OTHC1 module has headset/switch dection */
-		.name = "pm8058-othc",
-		.id = 1,
-		.num_resources = ARRAY_SIZE(resources_othc_1),
-		.resources = resources_othc_1,
-		.platform_data = &othc_config_pdata_1,
-		.pdata_size = sizeof(othc_config_pdata_1),
-	},
-	{
-		.name = "pm8058-othc",
-		.id = 2,
-		.platform_data = &othc_config_pdata_2,
-		.pdata_size = sizeof(othc_config_pdata_2),
-		.num_resources = ARRAY_SIZE(resources_othc_2),
-		.resources = resources_othc_2,
-	},
-#endif
-	{
-		.name = "pm8058-rtc",
-		.id = -1,
-		.num_resources  = ARRAY_SIZE(resources_rtc),
-		.resources      = resources_rtc,
-		.platform_data = &pm8058_rtc_pdata,
-	},
-	{
-		.name = "pm8058-tm",
-		.id = -1,
-		.num_resources  = ARRAY_SIZE(resources_temp_alarm),
-		.resources      = resources_temp_alarm,
-	},
-	{	.name = "pm8058-upl",
-		.id		= -1,
-	},
-	{
-		.name = "pm8058-misc",
-		.id = -1,
-		.num_resources  = ARRAY_SIZE(resources_pm8058_misc),
-		.resources      = resources_pm8058_misc,
-	},
-	{	.name = "pm8058-batt-alarm",
-		.id		= -1,
-		.num_resources  = ARRAY_SIZE(resources_pm8058_batt_alarm),
-		.resources      = resources_pm8058_batt_alarm,
-	},
-};
-
 static struct pmic8058_charger_data pmic8058_charger_dragon = {
+		.charger_data_valid = true,
 		.max_source_current = 1800,
 		.charger_type = CHG_TYPE_AC,
 };
 
-static struct mfd_cell pm8058_charger_sub_dev = {
-		.name = "pm8058-charger",
-		.id = -1,
-		.num_resources = ARRAY_SIZE(resources_pm8058_charger),
-		.resources = resources_pm8058_charger,
+static struct pmic8058_charger_data pmic8058_charger_ffa_surf = {
+		.charger_data_valid = false,
+};
+
+static struct pm8xxx_misc_platform_data pm8058_misc_pdata = {
+	.priority		= 0,
+};
+
+static struct pm8xxx_irq_platform_data pm8058_irq_pdata = {
+	.irq_base		= PM8058_IRQ_BASE,
+	.devirq			= MSM_GPIO_TO_INT(PM8058_GPIO_INT),
+	.irq_trigger_flag	= IRQF_TRIGGER_LOW,
+};
+
+static struct pm8xxx_gpio_platform_data pm8058_gpio_pdata = {
+	.gpio_base	= PM8058_GPIO_PM_TO_SYS(0),
+};
+
+static struct pm8xxx_mpp_platform_data pm8058_mpp_pdata = {
+	.mpp_base	= PM8058_MPP_PM_TO_SYS(0),
 };
 
 static struct pm8058_platform_data pm8058_platform_data = {
-	.irq_base = PM8058_IRQ_BASE,
-	.irq = MSM_GPIO_TO_INT(PM8058_GPIO_INT),
-
-	.num_subdevs = ARRAY_SIZE(pm8058_subdevs),
-	.sub_devices = pm8058_subdevs,
-	.irq_trigger_flags = IRQF_TRIGGER_LOW,
+	.irq_pdata		= &pm8058_irq_pdata,
+	.gpio_pdata		= &pm8058_gpio_pdata,
+	.mpp_pdata		= &pm8058_mpp_pdata,
+	.rtc_pdata		= &pm8058_rtc_pdata,
+	.pwrkey_pdata		= &pm8058_pwrkey_pdata,
+	.othc0_pdata		= &othc_config_pdata_0,
+	.othc1_pdata		= &othc_config_pdata_1,
+	.othc2_pdata		= &othc_config_pdata_2,
+	.pwm_pdata		= &pm8058_pwm_data,
+	.misc_pdata		= &pm8058_misc_pdata,
+#ifdef CONFIG_SENSORS_MSM_ADC
+	.xoadc_pdata		= &pm8058_xoadc_pdata,
+#endif
 };
 
 #ifdef CONFIG_MSM_SSBI
@@ -7108,10 +6797,10 @@
 static int fm_radio_setup(struct marimba_fm_platform_data *pdata)
 {
 	int rc = 0;
-	struct pm8058_gpio cfg = {
+	struct pm_gpio cfg = {
 				.direction      = PM_GPIO_DIR_IN,
 				.pull           = PM_GPIO_PULL_NO,
-				.vin_sel        = PM_GPIO_VIN_S3,
+				.vin_sel        = PM8058_GPIO_VIN_S3,
 				.function       = PM_GPIO_FUNC_NORMAL,
 				.inv_int_pol    = 0,
 				};
@@ -7159,9 +6848,9 @@
 	}
 
 	/*GPIO 18 on PMIC is FM_IRQ*/
-	rc = pm8058_gpio_config(FM_GPIO, &cfg);
+	rc = pm8xxx_gpio_config(PM8058_GPIO_PM_TO_SYS(FM_GPIO), &cfg);
 	if (rc) {
-		printk(KERN_ERR "%s: return val of pm8058_gpio_config: %d\n",
+		printk(KERN_ERR "%s: return val of pm8xxx_gpio_config: %d\n",
 						__func__,  rc);
 		goto fm_fail_clock;
 	}
@@ -10226,7 +9915,7 @@
 {
 	uint32_t soc_platform_version;
 
-	pmic_reset_irq = PM8058_RESOUT_IRQ(PM8058_IRQ_BASE);
+	pmic_reset_irq = PM8058_IRQ_BASE + PM8058_RESOUT_IRQ;
 
 	/*
 	 * Initialize RPM first as other drivers and devices may need
@@ -10322,28 +10011,12 @@
 	msm8x60_init_pm8058_othc();
 #endif
 
-	if (machine_is_msm8x60_fluid()) {
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].
-			platform_data = &fluid_keypad_data;
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].pdata_size
-			= sizeof(fluid_keypad_data);
-	} else if (machine_is_msm8x60_dragon()) {
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].
-			platform_data = &dragon_keypad_data;
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].pdata_size
-			= sizeof(dragon_keypad_data);
-	} else {
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].
-			platform_data = &ffa_keypad_data;
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_KPD].pdata_size
-			= sizeof(ffa_keypad_data);
-
-	}
-
-	/* Disable END_CALL simulation function of powerkey on fluid */
-	if (machine_is_msm8x60_fluid()) {
-		pwrkey_pdata.pwrkey_time_ms = 0;
-	}
+	if (machine_is_msm8x60_fluid())
+		pm8058_platform_data.keypad_pdata = &fluid_keypad_data;
+	else if (machine_is_msm8x60_dragon())
+		pm8058_platform_data.keypad_pdata = &dragon_keypad_data;
+	else
+		pm8058_platform_data.keypad_pdata = &ffa_keypad_data;
 
 	/* Specify reset pin for OV9726 */
 	if (machine_is_msm8x60_dragon()) {
@@ -10351,6 +10024,31 @@
 		ov9726_sensor_8660_info.mount_angle = 270;
 	}
 
+#ifdef CONFIG_BATTERY_MSM8X60
+	if (machine_is_msm8x60_surf() || machine_is_msm8x60_ffa() ||
+		machine_is_msm8x60_fusion() || machine_is_msm8x60_dragon() ||
+		machine_is_msm8x60_fusn_ffa() || machine_is_msm8x60_fluid())
+		platform_device_register(&msm_charger_device);
+#endif
+
+	if (machine_is_msm8x60_dragon())
+		pm8058_platform_data.charger_pdata = &pmic8058_charger_dragon;
+	if (!machine_is_msm8x60_fluid())
+		pm8058_platform_data.charger_pdata = &pmic8058_charger_ffa_surf;
+
+	/* configure pmic leds */
+	if (machine_is_msm8x60_fluid())
+		pm8058_platform_data.leds_pdata = &pm8058_fluid_flash_leds_data;
+	else if (machine_is_msm8x60_dragon())
+		pm8058_platform_data.leds_pdata = &pm8058_dragon_leds_data;
+	else
+		pm8058_platform_data.leds_pdata = &pm8058_flash_leds_data;
+
+	if (machine_is_msm8x60_ffa() || machine_is_msm8x60_fusn_ffa() ||
+		machine_is_msm8x60_dragon()) {
+		pm8058_platform_data.vibrator_pdata = &pm8058_vib_pdata;
+	}
+
 	if (machine_is_msm8x60_surf() || machine_is_msm8x60_ffa() ||
 	    machine_is_msm8x60_fluid() || machine_is_msm8x60_fusion() ||
 	    machine_is_msm8x60_fusn_ffa() || machine_is_msm8x60_dragon()) {
@@ -10398,25 +10096,10 @@
 		machine_is_msm8x60_dragon())
 		msm8x60_cfg_isp1763();
 #endif
-#ifdef CONFIG_BATTERY_MSM8X60
-	if (machine_is_msm8x60_surf() || machine_is_msm8x60_ffa() ||
-		machine_is_msm8x60_fusion() || machine_is_msm8x60_dragon() ||
-		machine_is_msm8x60_fusn_ffa() || machine_is_msm8x60_fluid())
-		platform_device_register(&msm_charger_device);
-#endif
 
 	if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())
 		platform_add_devices(charm_devices, ARRAY_SIZE(charm_devices));
 
-	if (machine_is_msm8x60_dragon()) {
-		pm8058_charger_sub_dev.platform_data
-			= &pmic8058_charger_dragon;
-		pm8058_charger_sub_dev.pdata_size
-			= sizeof(pmic8058_charger_dragon);
-	}
-	if (!machine_is_msm8x60_fluid())
-		pm8058_platform_data.charger_sub_device
-			= &pm8058_charger_sub_dev;
 
 #if defined(CONFIG_SPI_QUP) || defined(CONFIG_SPI_QUP_MODULE)
 	if (machine_is_msm8x60_fluid())
@@ -10473,6 +10156,8 @@
 				msm_pm_data);
 	BUG_ON(msm_pm_boot_init(MSM_PM_BOOT_CONFIG_TZ, NULL));
 
+	pm8058_gpios_init();
+
 #ifdef CONFIG_SENSORS_MSM_ADC
 	if (machine_is_msm8x60_fluid()) {
 		msm_adc_pdata.dev_names = msm_adc_fluid_device_names;
@@ -10494,32 +10179,6 @@
 		platform_device_register(&gpio_leds);
 #endif
 
-	/* configure pmic leds */
-	if (machine_is_msm8x60_fluid()) {
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].
-			platform_data = &pm8058_fluid_flash_leds_data;
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].pdata_size
-			= sizeof(pm8058_fluid_flash_leds_data);
-	} else if (machine_is_msm8x60_dragon()) {
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].
-			platform_data = &pm8058_dragon_leds_data;
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].pdata_size
-			= sizeof(pm8058_dragon_leds_data);
-	} else {
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].
-			platform_data = &pm8058_flash_leds_data;
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_LED].pdata_size
-			= sizeof(pm8058_flash_leds_data);
-	}
-
-	if (machine_is_msm8x60_ffa() || machine_is_msm8x60_fusn_ffa() ||
-		machine_is_msm8x60_dragon()) {
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_VIB].
-					platform_data = &pmic_vib_pdata;
-		pm8058_platform_data.sub_devices[PM8058_SUBDEV_VIB].
-					pdata_size = sizeof(pmic_vib_pdata);
-	}
-
 	msm8x60_multi_sdio_init();
 
 	if (machine_is_msm8x60_fusion() || machine_is_msm8x60_fusn_ffa())
diff --git a/arch/arm/mach-msm/devices-8960.c b/arch/arm/mach-msm/devices-8960.c
index 0765251..2ea1f47 100644
--- a/arch/arm/mach-msm/devices-8960.c
+++ b/arch/arm/mach-msm/devices-8960.c
@@ -15,6 +15,7 @@
 #include <linux/list.h>
 #include <linux/platform_device.h>
 #include <linux/msm_rotator.h>
+#include <linux/ion.h>
 #include <linux/gpio.h>
 #include <asm/clkdev.h>
 #include <linux/msm_kgsl.h>
@@ -537,10 +538,11 @@
 #ifdef CONFIG_MSM_BUS_SCALING
 	.vidc_bus_client_pdata = &vidc_bus_client_data,
 #endif
-	.memtype = MEMTYPE_EBI1,
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	.memtype = ION_HEAP_EBI_ID,
 	.enable_ion = 1,
 #else
+	.memtype = MEMTYPE_EBI1,
 	.enable_ion = 0,
 #endif
 };
diff --git a/arch/arm/mach-msm/devices-msm7x30.c b/arch/arm/mach-msm/devices-msm7x30.c
index 2a39e3c..017eed9 100644
--- a/arch/arm/mach-msm/devices-msm7x30.c
+++ b/arch/arm/mach-msm/devices-msm7x30.c
@@ -548,8 +548,8 @@
 	},
 	{
 		.name	= "vbus_on",
-		.start	= PM8058_CHGVAL_IRQ(PMIC8058_IRQ_BASE),
-		.end	= PM8058_CHGVAL_IRQ(PMIC8058_IRQ_BASE),
+		.start	= PMIC8058_IRQ_BASE + PM8058_CHGVAL_IRQ,
+		.end	= PMIC8058_IRQ_BASE + PM8058_CHGVAL_IRQ,
 		.flags	= IORESOURCE_IRQ,
 	},
 };
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index 52c62fd..0ab9811 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -15,6 +15,7 @@
 #include <linux/platform_device.h>
 #include <linux/regulator/machine.h>
 #include <linux/regulator/consumer.h>
+#include <linux/ion.h>
 #include <mach/irqs.h>
 #include <mach/dma.h>
 #include <asm/mach/mmc.h>
@@ -2150,10 +2151,11 @@
 #ifdef CONFIG_MSM_BUS_SCALING
 	.vidc_bus_client_pdata = &vidc_bus_client_data,
 #endif
-	.memtype = MEMTYPE_SMI_KERNEL,
 #ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+	.memtype = ION_HEAP_SMI_ID,
 	.enable_ion = 1,
 #else
+	.memtype = MEMTYPE_SMI_KERNEL,
 	.enable_ion = 0,
 #endif
 };
diff --git a/arch/arm/mach-msm/qdsp6v2/apr.c b/arch/arm/mach-msm/qdsp6v2/apr.c
index 78f6519..13d92d1 100644
--- a/arch/arm/mach-msm/qdsp6v2/apr.c
+++ b/arch/arm/mach-msm/qdsp6v2/apr.c
@@ -266,23 +266,23 @@
 	if ((dest_id == APR_DEST_QDSP6) &&
 				(atomic_read(&dsp_state) == 0)) {
 		pr_info("%s: Wait for Lpass to bootup\n", __func__);
-		rc = wait_event_interruptible(dsp_wait,
-				(atomic_read(&dsp_state) == 1));
-		if (rc < 0) {
+		rc = wait_event_interruptible_timeout(dsp_wait,
+				(atomic_read(&dsp_state) == 1), (1 * HZ));
+		if (rc == 0) {
 			pr_err("%s: DSP is not Up\n", __func__);
 			return NULL;
 		}
-		pr_debug("%s: Lpass Up\n", __func__);
+		pr_info("%s: Lpass Up\n", __func__);
 	} else if ((dest_id == APR_DEST_MODEM) &&
 					(atomic_read(&modem_state) == 0)) {
 		pr_info("%s: Wait for modem to bootup\n", __func__);
-		rc = wait_event_interruptible(modem_wait,
-			(atomic_read(&modem_state) == 1));
-		if (rc < 0) {
+		rc = wait_event_interruptible_timeout(modem_wait,
+			(atomic_read(&modem_state) == 1), (1 * HZ));
+		if (rc == 0) {
 			pr_err("%s: Modem is not Up\n", __func__);
 			return NULL;
 		}
-		pr_debug("%s: modem Up\n", __func__);
+		pr_info("%s: modem Up\n", __func__);
 	}
 
 	if (!strcmp(svc_name, "AFE")) {
diff --git a/arch/arm/mach-msm/restart.c b/arch/arm/mach-msm/restart.c
index 00be696..28bf064 100644
--- a/arch/arm/mach-msm/restart.c
+++ b/arch/arm/mach-msm/restart.c
@@ -120,11 +120,11 @@
 #ifdef CONFIG_MSM_DLOAD_MODE
 	set_dload_mode(0);
 #endif
-	if (cpu_is_msm8x60()) {
-		pm8058_reset_pwr_off(0);
-		pm8901_reset_pwr_off(0);
-	}
 	pm8xxx_reset_pwr_off(0);
+
+	if (cpu_is_msm8x60())
+		pm8901_reset_pwr_off(0);
+
 	if (lower_pshold) {
 		__raw_writel(0, PSHOLD_CTL_SU);
 		mdelay(10000);
@@ -202,8 +202,6 @@
 
 	printk(KERN_NOTICE "Going down for restart now\n");
 
-	if (cpu_is_msm8x60())
-		pm8058_reset_pwr_off(1);
 	pm8xxx_reset_pwr_off(1);
 
 	if (cmd != NULL) {
diff --git a/drivers/gpio/pm8xxx-gpio.c b/drivers/gpio/pm8xxx-gpio.c
index 377510f..53305e3 100644
--- a/drivers/gpio/pm8xxx-gpio.c
+++ b/drivers/gpio/pm8xxx-gpio.c
@@ -432,7 +432,7 @@
 
 	return rc;
 }
-EXPORT_SYMBOL_GPL(pm8xxx_gpio_config);
+EXPORT_SYMBOL(pm8xxx_gpio_config);
 
 static struct platform_driver pm_gpio_driver = {
 	.probe		= pm_gpio_probe,
diff --git a/drivers/gpu/ion/ion.c b/drivers/gpu/ion/ion.c
index 60bc276..50420ba 100644
--- a/drivers/gpu/ion/ion.c
+++ b/drivers/gpu/ion/ion.c
@@ -618,7 +618,6 @@
 			unsigned int cmd)
 {
 	struct ion_buffer *buffer;
-	unsigned long start, end;
 	int ret = -EINVAL;
 
 	mutex_lock(&client->lock);
@@ -643,14 +642,6 @@
 		goto out;
 	}
 
-	start = (unsigned long) uaddr;
-	end = (unsigned long) uaddr + len;
-
-	if (check_vaddr_bounds(start, end)) {
-		pr_err("%s: virtual address %p is out of bounds\n",
-			__func__, uaddr);
-		goto out;
-	}
 
 	ret = buffer->heap->ops->cache_op(buffer->heap, buffer, uaddr,
 						offset, len, cmd);
@@ -1102,6 +1093,10 @@
 			return -EFAULT;
 		data.handle = ion_alloc(client, data.len, data.align,
 					     data.flags);
+
+		if (IS_ERR_OR_NULL(data.handle))
+			return PTR_ERR(data.handle);
+
 		if (copy_to_user((void __user *)arg, &data, sizeof(data)))
 			return -EFAULT;
 		break;
@@ -1174,11 +1169,21 @@
 	case ION_IOC_CLEAN_INV_CACHES:
 	{
 		struct ion_flush_data data;
+		unsigned long start, end;
 
 		if (copy_from_user(&data, (void __user *)arg,
 				sizeof(struct ion_flush_data)))
 			return -EFAULT;
 
+		start = (unsigned long) data.vaddr;
+		end = (unsigned long) data.vaddr + data.length;
+
+		if (check_vaddr_bounds(start, end)) {
+			pr_err("%s: virtual address %p is out of bounds\n",
+				__func__, data.vaddr);
+			return -EINVAL;
+		}
+
 		return ion_do_cache_op(client, data.handle, data.vaddr,
 					data.offset, data.length, cmd);
 
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/input/touchscreen/cy8c_ts.c b/drivers/input/touchscreen/cy8c_ts.c
index ac4138e..f708582 100644
--- a/drivers/input/touchscreen/cy8c_ts.c
+++ b/drivers/input/touchscreen/cy8c_ts.c
@@ -197,8 +197,7 @@
 	input_report_abs(ts->input, ABS_MT_TRACKING_ID, id);
 	input_report_abs(ts->input, ABS_MT_POSITION_X, x);
 	input_report_abs(ts->input, ABS_MT_POSITION_Y, y);
-	input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, pressure);
-	input_report_abs(ts->input, ABS_MT_WIDTH_MAJOR, ts->dd->finger_size);
+	input_report_abs(ts->input, ABS_MT_PRESSURE, pressure);
 	input_mt_sync(ts->input);
 }
 
@@ -227,8 +226,7 @@
 	}
 
 	for (i = 0; i < ts->prev_touches - touches; i++) {
-		input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR, 0);
-		input_report_abs(ts->input, ABS_MT_WIDTH_MAJOR, 0);
+		input_report_abs(ts->input, ABS_MT_PRESSURE, 0);
 		input_mt_sync(ts->input);
 	}
 
@@ -263,8 +261,7 @@
 		}
 	} else {
 		for (i = 0; i < ts->prev_touches; i++) {
-			input_report_abs(ts->input, ABS_MT_TOUCH_MAJOR,	0);
-			input_report_abs(ts->input, ABS_MT_WIDTH_MAJOR,	0);
+			input_report_abs(ts->input, ABS_MT_PRESSURE,	0);
 			input_mt_sync(ts->input);
 		}
 	}
@@ -402,10 +399,8 @@
 			ts->pdata->dis_min_x, ts->pdata->dis_max_x, 0, 0);
 	input_set_abs_params(input_device, ABS_MT_POSITION_Y,
 			ts->pdata->dis_min_y, ts->pdata->dis_max_y, 0, 0);
-	input_set_abs_params(input_device, ABS_MT_TOUCH_MAJOR,
+	input_set_abs_params(input_device, ABS_MT_PRESSURE,
 			ts->pdata->min_touch, ts->pdata->max_touch, 0, 0);
-	input_set_abs_params(input_device, ABS_MT_WIDTH_MAJOR,
-			ts->pdata->min_width, ts->pdata->max_width, 0, 0);
 	input_set_abs_params(input_device, ABS_MT_TRACKING_ID,
 			ts->pdata->min_tid, ts->pdata->max_tid, 0, 0);
 
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/media/video/msm/msm_vfe32.c b/drivers/media/video/msm/msm_vfe32.c
index e8904e2..c5cc55c 100644
--- a/drivers/media/video/msm/msm_vfe32.c
+++ b/drivers/media/video/msm/msm_vfe32.c
@@ -2092,6 +2092,9 @@
 		}
 		msm_io_memcpy(vfe32_ctrl->vfebase + vfe32_cmd[cmd->id].offset,
 			cmdp, (vfe32_cmd[cmd->id].length));
+		cmdp_local = cmdp + V32_ASF_LEN/4;
+		msm_io_memcpy(vfe32_ctrl->vfebase + V32_ASF_SPECIAL_EFX_CFG_OFF,
+			cmdp_local, V32_ASF_SPECIAL_EFX_CFG_LEN);
 		break;
 
 	case VFE_CMD_PCA_ROLL_OFF_CFG:
diff --git a/drivers/media/video/msm/msm_vfe32.h b/drivers/media/video/msm/msm_vfe32.h
index e41a544..ecb8608 100644
--- a/drivers/media/video/msm/msm_vfe32.h
+++ b/drivers/media/video/msm/msm_vfe32.h
@@ -349,6 +349,9 @@
 #define V32_MODULE_CFG_OFF 0x00000010
 #define V32_MODULE_CFG_LEN 4
 
+#define V32_ASF_SPECIAL_EFX_CFG_OFF 0x000005FC
+#define V32_ASF_SPECIAL_EFX_CFG_LEN 4
+
 #define V32_CLF_CFG_OFF 0x000006B0
 #define V32_CLF_CFG_LEN 72
 
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index a4feb838..c27fea6 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -157,6 +157,7 @@
 	tristate "PMIC8058 Power Management chip"
 	depends on MSM_SSBI
 	select MFD_CORE
+	select MFD_PM8XXX
 	select MSM_SHOW_RESUME_IRQ
 	help
 	  Say yes here for Qualcomm PM8058 chip.
diff --git a/drivers/mfd/pmic8058.c b/drivers/mfd/pmic8058.c
index 85c8a9d..77e393e 100644
--- a/drivers/mfd/pmic8058.c
+++ b/drivers/mfd/pmic8058.c
@@ -14,55 +14,32 @@
  * Qualcomm PMIC8058 driver
  *
  */
-#include <linux/interrupt.h>
-#include <linux/i2c.h>
-#include <linux/bitops.h>
+#include <linux/kernel.h>
+#include <linux/platform_device.h>
 #include <linux/slab.h>
-#include <linux/ratelimit.h>
-#include <linux/kthread.h>
+#include <linux/irq.h>
 #include <linux/msm_ssbi.h>
 #include <linux/mfd/core.h>
 #include <linux/mfd/pmic8058.h>
-#include <linux/platform_device.h>
-#include <linux/ratelimit.h>
-#include <linux/slab.h>
-#include <linux/debugfs.h>
-#include <linux/irq.h>
-#include <linux/syscore_ops.h>
-#include <linux/gpio.h>
+#include <linux/mfd/pm8xxx/core.h>
+#include <linux/msm_adc.h>
+
+#define REG_MPP_BASE			0x50
 
 /* PMIC8058 Revision */
-#define SSBI_REG_REV			0x002  /* PMIC4 revision */
+#define PM8058_REG_REV			0x002  /* PMIC4 revision */
+#define PM8058_VERSION_MASK		0xF0
+#define PM8058_REVISION_MASK		0x0F
+#define PM8058_VERSION_VALUE		0xE0
 
-/* PMIC8058 IRQ */
-#define	SSBI_REG_ADDR_IRQ_BASE		0x1BB
+/* PMIC 8058 Battery Alarm SSBI registers */
+#define REG_BATT_ALARM_THRESH		0x023
+#define REG_BATT_ALARM_CTRL1		0x024
+#define REG_BATT_ALARM_CTRL2		0x0AA
+#define REG_BATT_ALARM_PWM_CTRL		0x0A3
 
-#define	SSBI_REG_ADDR_IRQ_ROOT		(SSBI_REG_ADDR_IRQ_BASE + 0)
-#define	SSBI_REG_ADDR_IRQ_M_STATUS1	(SSBI_REG_ADDR_IRQ_BASE + 1)
-#define	SSBI_REG_ADDR_IRQ_M_STATUS2	(SSBI_REG_ADDR_IRQ_BASE + 2)
-#define	SSBI_REG_ADDR_IRQ_M_STATUS3	(SSBI_REG_ADDR_IRQ_BASE + 3)
-#define	SSBI_REG_ADDR_IRQ_M_STATUS4	(SSBI_REG_ADDR_IRQ_BASE + 4)
-#define	SSBI_REG_ADDR_IRQ_BLK_SEL	(SSBI_REG_ADDR_IRQ_BASE + 5)
-#define	SSBI_REG_ADDR_IRQ_IT_STATUS	(SSBI_REG_ADDR_IRQ_BASE + 6)
-#define	SSBI_REG_ADDR_IRQ_CONFIG	(SSBI_REG_ADDR_IRQ_BASE + 7)
-#define	SSBI_REG_ADDR_IRQ_RT_STATUS	(SSBI_REG_ADDR_IRQ_BASE + 8)
-
-#define	PM8058_IRQF_LVL_SEL		0x01	/* level select */
-#define	PM8058_IRQF_MASK_FE		0x02	/* mask falling edge */
-#define	PM8058_IRQF_MASK_RE		0x04	/* mask rising edge */
-#define	PM8058_IRQF_CLR			0x08	/* clear interrupt */
-#define	PM8058_IRQF_BITS_MASK		0x70
-#define	PM8058_IRQF_BITS_SHIFT		4
-#define	PM8058_IRQF_WRITE		0x80
-
-#define	PM8058_IRQF_MASK_ALL		(PM8058_IRQF_MASK_FE | \
-					PM8058_IRQF_MASK_RE)
-#define PM8058_IRQF_W_C_M		(PM8058_IRQF_WRITE |	\
-					PM8058_IRQF_CLR |	\
-					PM8058_IRQF_MASK_ALL)
-
-/* MISC register */
-#define	SSBI_REG_ADDR_MISC		0x1CC
+#define REG_TEMP_ALRM_CTRL		0x1B
+#define REG_TEMP_ALRM_PWM		0x9B
 
 /* PON CNTL 1 register */
 #define SSBI_REG_ADDR_PON_CNTL_1	0x01C
@@ -138,53 +115,32 @@
 /* GP_TEST1 register */
 #define SSBI_REG_ADDR_GP_TEST_1		0x07A
 
-/* IRQ */
-#define	MAX_PM_IRQ		256
-#define	MAX_PM_BLOCKS		(MAX_PM_IRQ / 8 + 1)
-#define	MAX_PM_MASTERS		(MAX_PM_BLOCKS / 8 + 1)
+#define PM8058_RTC_BASE			0x1E8
+#define PM8058_OTHC_CNTR_BASE0		0xA0
+#define PM8058_OTHC_CNTR_BASE1		0x134
+#define PM8058_OTHC_CNTR_BASE2		0x137
+
+#define SINGLE_IRQ_RESOURCE(_name, _irq) \
+{ \
+	.name	= _name, \
+	.start	= _irq, \
+	.end	= _irq, \
+	.flags	= IORESOURCE_IRQ, \
+}
 
 struct pm8058_chip {
 	struct pm8058_platform_data	pdata;
 	struct device		*dev;
+	struct pm_irq_chip	*irq_chip;
+	struct mfd_cell         *mfd_regulators, *mfd_xo_buffers;
 
-	u8	irqs_allowed[MAX_PM_BLOCKS];
-	u8	blocks_allowed[MAX_PM_MASTERS];
-	u8	masters_allowed;
-	int	pm_max_irq;
-	int	pm_max_blocks;
-	int	pm_max_masters;
-
-	u8	config[MAX_PM_IRQ];
-	u8	bus_unlock_config[MAX_PM_IRQ];
-	u8	wake_enable[MAX_PM_IRQ];
-	u16	count_wakeable;
-
-	u8	revision;
+	u8		revision;
 
 	struct mutex	pm_lock;
 };
 
-#if defined(CONFIG_DEBUG_FS)
-struct pm8058_dbg_device {
-	struct mutex		dbg_mutex;
-	struct pm8058_chip	*pm_chip;
-	struct dentry		*dent;
-	int			addr;
-};
-
-static struct pm8058_dbg_device *pmic_dbg_device;
-#endif
-
 static struct pm8058_chip *pmic_chip;
 
-/* Helper Functions */
-DEFINE_RATELIMIT_STATE(pm8058_msg_ratelimit, 60 * HZ, 10);
-
-static inline int pm8058_can_print(void)
-{
-	return __ratelimit(&pm8058_msg_ratelimit);
-}
-
 static inline int
 ssbi_read(struct device *dev, u16 addr, u8 *buf, size_t len)
 {
@@ -223,111 +179,6 @@
 	return rc;
 }
 
-/* External APIs */
-int pm8058_rev(struct pm8058_chip *chip)
-{
-	if (chip == NULL)
-		return -EINVAL;
-
-	return chip->revision;
-}
-EXPORT_SYMBOL(pm8058_rev);
-
-int pm8058_irq_get_rt_status(struct pm8058_chip *chip, int irq)
-{
-	int     rc;
-	u8      block, bits, bit;
-
-	if (chip == NULL || irq < chip->pdata.irq_base ||
-			irq >= chip->pdata.irq_base + MAX_PM_IRQ)
-		return -EINVAL;
-
-	irq -= chip->pdata.irq_base;
-
-	block = irq / 8;
-	bit = irq % 8;
-
-	mutex_lock(&chip->pm_lock);
-
-	rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, &block, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_write(): rc=%d (Select Block)\n",
-				__func__, rc);
-		goto bail_out;
-	}
-
-	rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_RT_STATUS, &bits, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_read(): rc=%d (Read RT Status)\n",
-				__func__, rc);
-		goto bail_out;
-	}
-
-	rc = (bits & (1 << bit)) ? 1 : 0;
-
-bail_out:
-	mutex_unlock(&chip->pm_lock);
-
-	return rc;
-}
-EXPORT_SYMBOL(pm8058_irq_get_rt_status);
-
-int pm8058_read(struct pm8058_chip *chip, u16 addr, u8 *values,
-		unsigned int len)
-{
-	if (chip == NULL)
-		return -EINVAL;
-
-	return ssbi_read(chip->dev, addr, values, len);
-}
-EXPORT_SYMBOL(pm8058_read);
-
-int pm8058_write(struct pm8058_chip *chip, u16 addr, u8 *values,
-		 unsigned int len)
-{
-	if (chip == NULL)
-		return -EINVAL;
-
-	return ssbi_write(chip->dev, addr, values, len);
-}
-EXPORT_SYMBOL(pm8058_write);
-
-int pm8058_misc_control(struct pm8058_chip *chip, int mask, int flag)
-{
-	int		rc;
-	u8		misc;
-
-	if (chip == NULL)
-		chip = pmic_chip;	/* for calls from non child */
-	if (chip == NULL)
-		return -ENODEV;
-
-	mutex_lock(&chip->pm_lock);
-
-	rc = ssbi_read(chip->dev, SSBI_REG_ADDR_MISC, &misc, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_read(0x%x): rc=%d\n",
-		       __func__, SSBI_REG_ADDR_MISC, rc);
-		goto get_out;
-	}
-
-	misc &= ~mask;
-	misc |= flag;
-
-	rc = ssbi_write(chip->dev, SSBI_REG_ADDR_MISC, &misc, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_write(0x%x)=0x%x: rc=%d\n",
-		       __func__, SSBI_REG_ADDR_MISC, misc, rc);
-		goto get_out;
-	}
-
-get_out:
-	mutex_unlock(&chip->pm_lock);
-
-	return rc;
-}
-EXPORT_SYMBOL(pm8058_misc_control);
-
 /**
  * pm8058_smpl_control - enables/disables SMPL detection
  * @enable: 0 = shutdown PMIC on power loss, 1 = reset PMIC on power loss
@@ -713,765 +564,694 @@
 }
 EXPORT_SYMBOL(pm8058_hard_reset_config);
 
-/* Internal functions */
-static inline int
-pm8058_config_irq(struct pm8058_chip *chip, u8 *bp, u8 *cp)
+static int pm8058_readb(const struct device *dev, u16 addr, u8 *val)
 {
-	int	rc;
+	const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+	const struct pm8058_chip *pmic = pm8058_drvdata->pm_chip_data;
 
-	rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp, 1);
-	if (rc) {
-		pr_err("%s: ssbi_write: rc=%d (Select block)\n",
-			__func__, rc);
-		goto bail_out;
-	}
-
-	rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_CONFIG, cp, 1);
-	if (rc)
-		pr_err("%s: ssbi_write: rc=%d (Configure IRQ)\n",
-			__func__, rc);
-
-bail_out:
-	return rc;
+	return msm_ssbi_read(pmic->dev->parent, addr, val, 1);
 }
 
-static void pm8058_irq_mask(struct irq_data *data)
+static int pm8058_writeb(const struct device *dev, u16 addr, u8 val)
 {
-	int	master, irq_bit;
-	struct	pm8058_chip *chip = irq_data_get_irq_chip_data(data);
-	u8	block, config;
-	unsigned int irq = data->irq;
+	const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+	const struct pm8058_chip *pmic = pm8058_drvdata->pm_chip_data;
 
-	irq -= chip->pdata.irq_base;
-	block = irq / 8;
-	master = block / 8;
-	irq_bit = irq % 8;
-
-	chip->irqs_allowed[block] &= ~(1 << irq_bit);
-	if (!chip->irqs_allowed[block]) {
-		chip->blocks_allowed[master] &= ~(1 << (block % 8));
-
-		if (!chip->blocks_allowed[master])
-			chip->masters_allowed &= ~(1 << master);
-	}
-
-	config = PM8058_IRQF_WRITE | chip->config[irq] |
-		PM8058_IRQF_MASK_FE | PM8058_IRQF_MASK_RE;
-	chip->bus_unlock_config[irq] = config;
+	return msm_ssbi_write(pmic->dev->parent, addr, &val, 1);
 }
 
-static void pm8058_irq_unmask(struct irq_data *data)
+static int pm8058_read_buf(const struct device *dev, u16 addr, u8 *buf,
+								int cnt)
 {
-	int	master, irq_bit;
-	struct	pm8058_chip *chip = irq_data_get_irq_chip_data(data);
-	u8	block, config, old_irqs_allowed, old_blocks_allowed;
-	unsigned int irq = data->irq;
+	const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+	const struct pm8058_chip *pmic = pm8058_drvdata->pm_chip_data;
 
-	irq -= chip->pdata.irq_base;
-	block = irq / 8;
-	master = block / 8;
-	irq_bit = irq % 8;
-
-	old_irqs_allowed = chip->irqs_allowed[block];
-	if (old_irqs_allowed & (1 << irq_bit)) {
-		pr_debug("%s: no need to enable an already enabled irq=%d\n",
-					__func__, irq + chip->pdata.irq_base);
-		return;
-	}
-
-	chip->irqs_allowed[block] |= 1 << irq_bit;
-	if (!old_irqs_allowed) {
-		master = block / 8;
-
-		old_blocks_allowed = chip->blocks_allowed[master];
-		chip->blocks_allowed[master] |= 1 << (block % 8);
-
-		if (!old_blocks_allowed)
-			chip->masters_allowed |= 1 << master;
-	}
-
-	config = PM8058_IRQF_WRITE | chip->config[irq];
-	chip->bus_unlock_config[irq] = config;
+	return msm_ssbi_read(pmic->dev->parent, addr, buf, cnt);
 }
 
-static void pm8058_irq_ack(struct irq_data *data)
+static int pm8058_write_buf(const struct device *dev, u16 addr, u8 *buf,
+								int cnt)
 {
-	struct	pm8058_chip *chip = irq_data_get_irq_chip_data(data);
-	u8	block, config;
-	unsigned int irq = data->irq;
+	const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+	const struct pm8058_chip *pmic = pm8058_drvdata->pm_chip_data;
 
-	irq -= chip->pdata.irq_base;
-	block = irq / 8;
-
-	config = PM8058_IRQF_WRITE | chip->config[irq] | PM8058_IRQF_CLR;
-	/* Keep the mask */
-	if (!(chip->irqs_allowed[block] & (1 << (irq % 8))))
-		config |= PM8058_IRQF_MASK_FE | PM8058_IRQF_MASK_RE;
-	chip->bus_unlock_config[irq] = config;
+	return msm_ssbi_write(pmic->dev->parent, addr, buf, cnt);
 }
 
-static int pm8058_irq_set_type(struct irq_data *data, unsigned int flow_type)
+static int pm8058_read_irq_stat(const struct device *dev, int irq)
 {
-	int	master, irq_bit;
-	struct	pm8058_chip *chip = irq_data_get_irq_chip_data(data);
-	u8	block, config;
-	unsigned int irq = data->irq;
+	const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+	const struct pm8058_chip *pmic = pm8058_drvdata->pm_chip_data;
 
-	irq -= chip->pdata.irq_base;
-	if (irq > chip->pm_max_irq) {
-		chip->pm_max_irq = irq;
-		chip->pm_max_blocks =
-			chip->pm_max_irq / 8 + 1;
-		chip->pm_max_masters =
-			chip->pm_max_blocks / 8 + 1;
-	}
-	block = irq / 8;
-	master = block / 8;
-	irq_bit = irq % 8;
-
-	chip->config[irq] = (irq_bit << PM8058_IRQF_BITS_SHIFT) |
-			PM8058_IRQF_MASK_RE | PM8058_IRQF_MASK_FE;
-	if (flow_type & (IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING)) {
-		if (flow_type & IRQF_TRIGGER_RISING)
-			chip->config[irq] &= ~PM8058_IRQF_MASK_RE;
-		if (flow_type & IRQF_TRIGGER_FALLING)
-			chip->config[irq] &= ~PM8058_IRQF_MASK_FE;
-	} else {
-		chip->config[irq] |= PM8058_IRQF_LVL_SEL;
-
-		if (flow_type & IRQF_TRIGGER_HIGH)
-			chip->config[irq] &= ~PM8058_IRQF_MASK_RE;
-		else
-			chip->config[irq] &= ~PM8058_IRQF_MASK_FE;
-	}
-
-	config = PM8058_IRQF_WRITE | chip->config[irq] | PM8058_IRQF_CLR;
-	chip->bus_unlock_config[irq] = config;
-	return 0;
-}
-
-static int pm8058_irq_set_wake(struct irq_data *data, unsigned int on)
-{
-	struct	pm8058_chip *chip = irq_data_get_irq_chip_data(data);
-	unsigned int irq = data->irq;
-
-	irq -= chip->pdata.irq_base;
-	if (on) {
-		if (!chip->wake_enable[irq]) {
-			chip->wake_enable[irq] = 1;
-			chip->count_wakeable++;
-		}
-	} else {
-		if (chip->wake_enable[irq]) {
-			chip->wake_enable[irq] = 0;
-			chip->count_wakeable--;
-		}
-	}
+	return pm8xxx_get_irq_stat(pmic->irq_chip, irq);
 
 	return 0;
 }
 
-static void pm8058_irq_bus_lock(struct irq_data *data)
+static enum pm8xxx_version pm8058_get_version(const struct device *dev)
 {
-	u8	block;
-	struct	pm8058_chip *chip = irq_data_get_irq_chip_data(data);
-	unsigned int irq = data->irq;
+	const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+	const struct pm8058_chip *pmic = pm8058_drvdata->pm_chip_data;
+	enum pm8xxx_version version = -ENODEV;
 
-	irq -= chip->pdata.irq_base;
-	block = irq / 8;
-	chip->bus_unlock_config[irq] = 0;
+	if ((pmic->revision & PM8058_VERSION_MASK) == PM8058_VERSION_VALUE)
+		version = PM8XXX_VERSION_8058;
 
-	mutex_lock(&chip->pm_lock);
+	return version;
 }
 
-static void pm8058_irq_bus_sync_unlock(struct irq_data *data)
+static int pm8058_get_revision(const struct device *dev)
 {
-	u8	block, config;
-	struct	pm8058_chip *chip = irq_data_get_irq_chip_data(data);
-	unsigned int irq = data->irq;
+	const struct pm8xxx_drvdata *pm8058_drvdata = dev_get_drvdata(dev);
+	const struct pm8058_chip *pmic = pm8058_drvdata->pm_chip_data;
 
-	irq -= chip->pdata.irq_base;
-	block = irq / 8;
-	config = chip->bus_unlock_config[irq];
-	/* dont waste cpu cycles if we dont have data to write */
-	if (config)
-		pm8058_config_irq(chip, &block, &config);
-	mutex_unlock(&chip->pm_lock);
+	return pmic->revision & PM8058_REVISION_MASK;
 }
 
-static inline int
-pm8058_read_root(struct pm8058_chip *chip, u8 *rp)
-{
-	int	rc;
-
-	rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_ROOT, rp, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_read(): rc=%d (Read Root)\n",
-			__func__, rc);
-		*rp = 0;
-	}
-
-	return rc;
-}
-
-static inline int
-pm8058_read_master(struct pm8058_chip *chip, u8 m, u8 *bp)
-{
-	int	rc;
-
-	rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_M_STATUS1 + m, bp, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_read(): rc=%d (Read Master)\n",
-			__func__, rc);
-		*bp = 0;
-	}
-
-	return rc;
-}
-
-static inline int
-pm8058_read_block(struct pm8058_chip *chip, u8 *bp, u8 *ip)
-{
-	int	rc;
-
-	rc = ssbi_write(chip->dev, SSBI_REG_ADDR_IRQ_BLK_SEL, bp, 1);
-	if (rc) {
-		pr_err("%s: FAIL ssbi_write(): rc=%d (Select Block)\n",
-		       __func__, rc);
-		*bp = 0;
-		goto bail_out;
-	}
-
-	rc = ssbi_read(chip->dev, SSBI_REG_ADDR_IRQ_IT_STATUS, ip, 1);
-	if (rc)
-		pr_err("%s: FAIL ssbi_read(): rc=%d (Read Status)\n",
-		       __func__, rc);
-
-bail_out:
-	return rc;
-}
-
-static irqreturn_t pm8058_isr_thread(int irq_requested, void *data)
-{
-	struct pm8058_chip *chip = data;
-	int	i, j, k;
-	u8	root, block, config, bits;
-	u8	blocks[MAX_PM_MASTERS];
-	int	masters = 0, irq, handled = 0, spurious = 0;
-	u16     irqs_to_handle[MAX_PM_IRQ];
-
-	mutex_lock(&chip->pm_lock);
-
-	/* Read root for masters */
-	if (pm8058_read_root(chip, &root))
-		goto bail_out;
-
-	masters = root >> 1;
-
-	if (!(masters & chip->masters_allowed) ||
-	    (masters & ~chip->masters_allowed)) {
-		spurious = 1000000;
-	}
-
-	/* Read allowed masters for blocks. */
-	for (i = 0; i < chip->pm_max_masters; i++) {
-		if (masters & (1 << i)) {
-			if (pm8058_read_master(chip, i, &blocks[i]))
-				goto bail_out;
-
-			if (!blocks[i]) {
-				if (pm8058_can_print())
-					pr_err("%s: Spurious master: %d "
-					       "(blocks=0)", __func__, i);
-				spurious += 10000;
-			}
-		} else
-			blocks[i] = 0;
-	}
-
-	/* Select block, read status and call isr */
-	for (i = 0; i < chip->pm_max_masters; i++) {
-		if (!blocks[i])
-			continue;
-
-		for (j = 0; j < 8; j++) {
-			if (!(blocks[i] & (1 << j)))
-				continue;
-
-			block = i * 8 + j;	/* block # */
-			if (pm8058_read_block(chip, &block, &bits))
-				goto bail_out;
-
-			if (!bits) {
-				if (pm8058_can_print())
-					pr_err("%s: Spurious block: "
-					       "[master, block]=[%d, %d] "
-					       "(bits=0)\n", __func__, i, j);
-				spurious += 100;
-				continue;
-			}
-
-			/* Check IRQ bits */
-			for (k = 0; k < 8; k++) {
-				if (!(bits & (1 << k)))
-					continue;
-
-				/* Check spurious interrupts */
-				if (((1 << i) & chip->masters_allowed) &&
-				    (blocks[i] & chip->blocks_allowed[i]) &&
-				    (bits & chip->irqs_allowed[block])) {
-
-					/* Found one */
-					irq = block * 8 + k;
-					irqs_to_handle[handled] = irq +
-						chip->pdata.irq_base;
-					handled++;
-				} else {
-					/* Clear and mask wrong one */
-					config = PM8058_IRQF_W_C_M |
-						(k << PM8058_IRQF_BITS_SHIFT);
-
-					pm8058_config_irq(chip,
-							  &block, &config);
-
-					if (pm8058_can_print())
-						pr_err("%s: Spurious IRQ: "
-						       "[master, block, bit]="
-						       "[%d, %d (%d), %d]\n",
-							__func__,
-						       i, j, block, k);
-					spurious++;
-				}
-			}
-		}
-
-	}
-
-bail_out:
-
-	mutex_unlock(&chip->pm_lock);
-
-	for (i = 0; i < handled; i++) {
-		int pmic_irq = irqs_to_handle[i] - chip->pdata.irq_base;
-
-		/* ack the interrupt first */
-		block  = pmic_irq / 8 ;
-		config = PM8058_IRQF_WRITE | chip->config[pmic_irq]
-				| PM8058_IRQF_CLR;
-		pm8058_config_irq(chip, &block, &config);
-
-		/* calle the action handler */
-		handle_nested_irq(irqs_to_handle[i]);
-	}
-
-	if (spurious) {
-		if (!pm8058_can_print())
-			return IRQ_HANDLED;
-
-		pr_err("%s: spurious = %d (handled = %d)\n",
-		       __func__, spurious, handled);
-		pr_err("   root = 0x%x (masters_allowed<<1 = 0x%x)\n",
-		       root, chip->masters_allowed << 1);
-		for (i = 0; i < chip->pm_max_masters; i++) {
-			if (masters & (1 << i))
-				pr_err("   blocks[%d]=0x%x, "
-				       "allowed[%d]=0x%x\n",
-				       i, blocks[i],
-				       i, chip->blocks_allowed[i]);
-		}
-	}
-
-	return IRQ_HANDLED;
-}
-
-#if defined(CONFIG_DEBUG_FS)
-
-static int check_addr(int addr, const char *func_name)
-{
-	if (addr < 0 || addr > 0x3FF) {
-		pr_err("%s: PMIC 8058 register address is invalid: %d\n",
-			func_name, addr);
-		return -EINVAL;
-	}
-	return 0;
-}
-
-static int data_set(void *data, u64 val)
-{
-	struct pm8058_dbg_device *dbgdev = data;
-	u8 reg = val;
-	int rc;
-
-	mutex_lock(&dbgdev->dbg_mutex);
-
-	rc = check_addr(dbgdev->addr, __func__);
-	if (rc)
-		goto done;
-
-	rc = pm8058_write(dbgdev->pm_chip, dbgdev->addr, &reg, 1);
-
-	if (rc)
-		pr_err("%s: FAIL pm8058_write(0x%03X)=0x%02X: rc=%d\n",
-			__func__, dbgdev->addr, reg, rc);
-done:
-	mutex_unlock(&dbgdev->dbg_mutex);
-	return rc;
-}
-
-static int data_get(void *data, u64 *val)
-{
-	struct pm8058_dbg_device *dbgdev = data;
-	int rc;
-	u8 reg;
-
-	mutex_lock(&dbgdev->dbg_mutex);
-
-	rc = check_addr(dbgdev->addr, __func__);
-	if (rc)
-		goto done;
-
-	rc = pm8058_read(dbgdev->pm_chip, dbgdev->addr, &reg, 1);
-
-	if (rc) {
-		pr_err("%s: FAIL pm8058_read(0x%03X)=0x%02X: rc=%d\n",
-			__func__, dbgdev->addr, reg, rc);
-		goto done;
-	}
-
-	*val = reg;
-done:
-	mutex_unlock(&dbgdev->dbg_mutex);
-	return rc;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(dbg_data_fops, data_get, data_set, "0x%02llX\n");
-
-static int addr_set(void *data, u64 val)
-{
-	struct pm8058_dbg_device *dbgdev = data;
-	int rc;
-
-	rc = check_addr(val, __func__);
-	if (rc)
-		return rc;
-
-	mutex_lock(&dbgdev->dbg_mutex);
-	dbgdev->addr = val;
-	mutex_unlock(&dbgdev->dbg_mutex);
-
-	return 0;
-}
-
-static int addr_get(void *data, u64 *val)
-{
-	struct pm8058_dbg_device *dbgdev = data;
-	int rc;
-
-	mutex_lock(&dbgdev->dbg_mutex);
-
-	rc = check_addr(dbgdev->addr, __func__);
-	if (rc) {
-		mutex_unlock(&dbgdev->dbg_mutex);
-		return rc;
-	}
-	*val = dbgdev->addr;
-
-	mutex_unlock(&dbgdev->dbg_mutex);
-
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(dbg_addr_fops, addr_get, addr_set, "0x%03llX\n");
-
-static int __devinit pmic8058_dbg_probe(struct pm8058_chip *chip)
-{
-	struct pm8058_dbg_device *dbgdev;
-	struct dentry *dent;
-	struct dentry *temp;
-	int rc;
-
-	if (chip == NULL) {
-		pr_err("%s: no parent data passed in.\n", __func__);
-		return -EINVAL;
-	}
-
-	dbgdev = kzalloc(sizeof *dbgdev, GFP_KERNEL);
-	if (dbgdev == NULL) {
-		pr_err("%s: kzalloc() failed.\n", __func__);
-		return -ENOMEM;
-	}
-
-	dbgdev->pm_chip = chip;
-	dbgdev->addr = -1;
-
-	dent = debugfs_create_dir("pm8058-dbg", NULL);
-	if (dent == NULL || IS_ERR(dent)) {
-		pr_err("%s: ERR debugfs_create_dir: dent=0x%X\n",
-					__func__, (unsigned)dent);
-		rc = PTR_ERR(dent);
-		goto dir_error;
-	}
-
-	temp = debugfs_create_file("addr", S_IRUSR | S_IWUSR, dent,
-					dbgdev, &dbg_addr_fops);
-	if (temp == NULL || IS_ERR(temp)) {
-		pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
-					__func__, (unsigned)temp);
-		rc = PTR_ERR(temp);
-		goto debug_error;
-	}
-
-	temp = debugfs_create_file("data", S_IRUSR | S_IWUSR, dent,
-					dbgdev, &dbg_data_fops);
-	if (temp == NULL || IS_ERR(temp)) {
-		pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
-					__func__, (unsigned)temp);
-		rc = PTR_ERR(temp);
-		goto debug_error;
-	}
-
-	mutex_init(&dbgdev->dbg_mutex);
-
-	dbgdev->dent = dent;
-
-	pmic_dbg_device = dbgdev;
-
-	return 0;
-
-debug_error:
-	debugfs_remove_recursive(dent);
-dir_error:
-	kfree(dbgdev);
-
-	return rc;
-}
-
-static int __devexit pmic8058_dbg_remove(void)
-{
-	if (pmic_dbg_device) {
-		debugfs_remove_recursive(pmic_dbg_device->dent);
-		mutex_destroy(&pmic_dbg_device->dbg_mutex);
-		kfree(pmic_dbg_device);
-	}
-	return 0;
-}
-
-#else
-
-static int __devinit pmic8058_dbg_probe(struct pm8058_chip *chip)
-{
-	return 0;
-}
-
-static int __devexit pmic8058_dbg_remove(void)
-{
-	return 0;
-}
-
-#endif
-
-static struct irq_chip pm8058_irq_chip = {
-	.name      = "pm8058",
-	.irq_ack	= pm8058_irq_ack,
-	.irq_mask	= pm8058_irq_mask,
-	.irq_unmask	= pm8058_irq_unmask,
-	.irq_set_type	= pm8058_irq_set_type,
-	.irq_set_wake	= pm8058_irq_set_wake,
-	.irq_bus_lock	= pm8058_irq_bus_lock,
-	.irq_bus_sync_unlock	= pm8058_irq_bus_sync_unlock,
+static struct pm8xxx_drvdata pm8058_drvdata = {
+	.pmic_readb		= pm8058_readb,
+	.pmic_writeb		= pm8058_writeb,
+	.pmic_read_buf		= pm8058_read_buf,
+	.pmic_write_buf		= pm8058_write_buf,
+	.pmic_read_irq_stat	= pm8058_read_irq_stat,
+	.pmic_get_version	= pm8058_get_version,
+	.pmic_get_revision	= pm8058_get_revision,
 };
 
-static int pm8058_suspend(void)
-{
-	struct	pm8058_chip *chip = pmic_chip;
-	struct irq_data *data;
-	int	i;
-
-	for (i = 0; i < MAX_PM_IRQ; i++) {
-		if (chip->config[i] && !chip->wake_enable[i]) {
-			if (!((chip->config[i] & PM8058_IRQF_MASK_ALL)
-			      == PM8058_IRQF_MASK_ALL)) {
-				data = irq_get_irq_data(i +
-						chip->pdata.irq_base);
-				pm8058_irq_bus_lock(data);
-				pm8058_irq_mask(data);
-				pm8058_irq_bus_sync_unlock(data);
-			}
-		}
-	}
-
-	if (!chip->count_wakeable)
-		disable_irq(chip->pdata.irq);
-
-	return 0;
-}
-
-extern int msm_show_resume_irq_mask;
-
-static void pm8058_show_resume_irq(void)
-{
-	u8	block, bits;
-	int i;
-	struct pm8058_chip *chip = pmic_chip;
-
-	if (!msm_show_resume_irq_mask)
-		return;
-
-	for (i = 0; i < MAX_PM_IRQ; i++) {
-		if (chip->wake_enable[i]) {
-			block = i / 8;
-			if (!pm8058_read_block(chip, &block, &bits)) {
-				if (bits & (1 << (i & 0x7)))
-					pr_warning("%s:%d triggered\n",
-					__func__, i + chip->pdata.irq_base);
-			}
-		}
-	}
-}
-
-static void pm8058_resume(void)
-{
-	struct	pm8058_chip *chip = pmic_chip;
-	struct irq_data *data;
-	int	i;
-
-	pm8058_show_resume_irq();
-
-	for (i = 0; i < MAX_PM_IRQ; i++) {
-		if (chip->config[i] && !chip->wake_enable[i]) {
-			if (!((chip->config[i] & PM8058_IRQF_MASK_ALL)
-			      == PM8058_IRQF_MASK_ALL)) {
-				data = irq_get_irq_data(i +
-						chip->pdata.irq_base);
-				pm8058_irq_bus_lock(data);
-				pm8058_irq_unmask(data);
-				pm8058_irq_bus_sync_unlock(data);
-			}
-		}
-	}
-
-	if (!chip->count_wakeable)
-		enable_irq(chip->pdata.irq);
-}
-
-static struct syscore_ops pm8058_pm = {
-	.suspend = pm8058_suspend,
-	.resume = pm8058_resume,
+static const struct resource pm8058_charger_resources[] __devinitconst = {
+	SINGLE_IRQ_RESOURCE("CHGVAL",		PM8058_CHGVAL_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGINVAL",		PM8058_CHGINVAL_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGILIM",		PM8058_CHGILIM_IRQ),
+	SINGLE_IRQ_RESOURCE("VCP",		PM8058_VCP_IRQ),
+	SINGLE_IRQ_RESOURCE("ATC_DONE",		PM8058_ATC_DONE_IRQ),
+	SINGLE_IRQ_RESOURCE("ATCFAIL",		PM8058_ATCFAIL_IRQ),
+	SINGLE_IRQ_RESOURCE("AUTO_CHGDONE",	PM8058_AUTO_CHGDONE_IRQ),
+	SINGLE_IRQ_RESOURCE("AUTO_CHGFAIL",	PM8058_AUTO_CHGFAIL_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGSTATE",		PM8058_CHGSTATE_IRQ),
+	SINGLE_IRQ_RESOURCE("FASTCHG",		PM8058_FASTCHG_IRQ),
+	SINGLE_IRQ_RESOURCE("CHG_END",		PM8058_CHG_END_IRQ),
+	SINGLE_IRQ_RESOURCE("BATTTEMP",		PM8058_BATTTEMP_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGHOT",		PM8058_CHGHOT_IRQ),
+	SINGLE_IRQ_RESOURCE("CHGTLIMIT",	PM8058_CHGTLIMIT_IRQ),
+	SINGLE_IRQ_RESOURCE("CHG_GONE",		PM8058_CHG_GONE_IRQ),
+	SINGLE_IRQ_RESOURCE("VCPMAJOR",		PM8058_VCPMAJOR_IRQ),
+	SINGLE_IRQ_RESOURCE("VBATDET",		PM8058_VBATDET_IRQ),
+	SINGLE_IRQ_RESOURCE("BATFET",		PM8058_BATFET_IRQ),
+	SINGLE_IRQ_RESOURCE("BATT_REPLACE",	PM8058_BATT_REPLACE_IRQ),
+	SINGLE_IRQ_RESOURCE("BATTCONNECT",	PM8058_BATTCONNECT_IRQ),
+	SINGLE_IRQ_RESOURCE("VBATDET_LOW",	PM8058_VBATDET_LOW_IRQ),
 };
 
+static struct mfd_cell pm8058_charger_cell __devinitdata = {
+	.name		= "pm8058-charger",
+	.id		= -1,
+	.resources	= pm8058_charger_resources,
+	.num_resources	= ARRAY_SIZE(pm8058_charger_resources),
+};
+
+static const struct resource misc_cell_resources[] __devinitconst = {
+	SINGLE_IRQ_RESOURCE("pm8xxx_osc_halt_irq", PM8058_OSCHALT_IRQ),
+};
+
+static struct mfd_cell misc_cell __devinitdata = {
+	.name		= PM8XXX_MISC_DEV_NAME,
+	.id		= -1,
+	.resources	= misc_cell_resources,
+	.num_resources	= ARRAY_SIZE(misc_cell_resources),
+};
+
+static struct mfd_cell pm8058_pwm_cell __devinitdata = {
+	.name		= "pm8058-pwm",
+	.id		= -1,
+};
+
+static struct resource xoadc_resources[] = {
+	SINGLE_IRQ_RESOURCE(NULL, PM8058_ADC_IRQ),
+};
+
+static struct mfd_cell xoadc_cell __devinitdata = {
+	.name		= "pm8058-xoadc",
+	.id		= -1,
+	.resources	= xoadc_resources,
+	.num_resources	= ARRAY_SIZE(xoadc_resources),
+};
+
+static const struct resource thermal_alarm_cell_resources[] __devinitconst = {
+	SINGLE_IRQ_RESOURCE("pm8058_tempstat_irq", PM8058_TEMPSTAT_IRQ),
+	SINGLE_IRQ_RESOURCE("pm8058_overtemp_irq", PM8058_OVERTEMP_IRQ),
+};
+
+static struct pm8xxx_tm_core_data thermal_alarm_cdata = {
+	.adc_channel			= CHANNEL_ADC_DIE_TEMP,
+	.adc_type			= PM8XXX_TM_ADC_PM8058_ADC,
+	.reg_addr_temp_alarm_ctrl	= REG_TEMP_ALRM_CTRL,
+	.reg_addr_temp_alarm_pwm	= REG_TEMP_ALRM_PWM,
+	.tm_name			= "pm8058_tz",
+	.irq_name_temp_stat		= "pm8058_tempstat_irq",
+	.irq_name_over_temp		= "pm8058_overtemp_irq",
+};
+
+static struct mfd_cell thermal_alarm_cell __devinitdata = {
+	.name		= PM8XXX_TM_DEV_NAME,
+	.id		= -1,
+	.resources	= thermal_alarm_cell_resources,
+	.num_resources	= ARRAY_SIZE(thermal_alarm_cell_resources),
+	.platform_data	= &thermal_alarm_cdata,
+	.pdata_size	= sizeof(struct pm8xxx_tm_core_data),
+};
+
+static struct mfd_cell debugfs_cell __devinitdata = {
+	.name		= "pm8xxx-debug",
+	.id		= -1,
+	.platform_data	= "pm8058-dbg",
+	.pdata_size	= sizeof("pm8058-dbg"),
+};
+
+static const struct resource othc0_cell_resources[] __devinitconst = {
+	{
+		.name	= "othc_base",
+		.start	= PM8058_OTHC_CNTR_BASE0,
+		.end	= PM8058_OTHC_CNTR_BASE0,
+		.flags	= IORESOURCE_IO,
+	},
+};
+
+static const struct resource othc1_cell_resources[] __devinitconst = {
+	SINGLE_IRQ_RESOURCE(NULL, PM8058_SW_1_IRQ),
+	SINGLE_IRQ_RESOURCE(NULL, PM8058_IR_1_IRQ),
+	{
+		.name	= "othc_base",
+		.start	= PM8058_OTHC_CNTR_BASE1,
+		.end	= PM8058_OTHC_CNTR_BASE1,
+		.flags	= IORESOURCE_IO,
+	},
+};
+
+static const struct resource othc2_cell_resources[] __devinitconst = {
+	{
+		.name	= "othc_base",
+		.start	= PM8058_OTHC_CNTR_BASE2,
+		.end	= PM8058_OTHC_CNTR_BASE2,
+		.flags	= IORESOURCE_IO,
+	},
+};
+
+static const struct resource batt_alarm_cell_resources[] __devinitconst = {
+	SINGLE_IRQ_RESOURCE("pm8058_batt_alarm_irq", PM8058_BATT_ALARM_IRQ),
+};
+
+static struct mfd_cell leds_cell __devinitdata = {
+	.name		= "pm8058-led",
+	.id		= -1,
+};
+
+static struct mfd_cell othc0_cell __devinitdata = {
+	.name		= "pm8058-othc",
+	.id		= 0,
+	.resources	= othc0_cell_resources,
+	.num_resources  = ARRAY_SIZE(othc0_cell_resources),
+};
+
+static struct mfd_cell othc1_cell __devinitdata = {
+	.name		= "pm8058-othc",
+	.id		= 1,
+	.resources	= othc1_cell_resources,
+	.num_resources  = ARRAY_SIZE(othc1_cell_resources),
+};
+
+static struct mfd_cell othc2_cell __devinitdata = {
+	.name		= "pm8058-othc",
+	.id		= 2,
+	.resources	= othc2_cell_resources,
+	.num_resources  = ARRAY_SIZE(othc2_cell_resources),
+};
+
+static struct pm8xxx_batt_alarm_core_data batt_alarm_cdata = {
+	.irq_name		= "pm8058_batt_alarm_irq",
+	.reg_addr_threshold	= REG_BATT_ALARM_THRESH,
+	.reg_addr_ctrl1		= REG_BATT_ALARM_CTRL1,
+	.reg_addr_ctrl2		= REG_BATT_ALARM_CTRL2,
+	.reg_addr_pwm_ctrl	= REG_BATT_ALARM_PWM_CTRL,
+};
+
+static struct mfd_cell batt_alarm_cell __devinitdata = {
+	.name		= PM8XXX_BATT_ALARM_DEV_NAME,
+	.id		= -1,
+	.resources	= batt_alarm_cell_resources,
+	.num_resources	= ARRAY_SIZE(batt_alarm_cell_resources),
+	.platform_data	= &batt_alarm_cdata,
+	.pdata_size	= sizeof(struct pm8xxx_batt_alarm_core_data),
+};
+
+static struct mfd_cell upl_cell __devinitdata = {
+	.name		= PM8XXX_UPL_DEV_NAME,
+	.id		= -1,
+};
+
+static struct mfd_cell nfc_cell __devinitdata = {
+	.name		= PM8XXX_NFC_DEV_NAME,
+	.id		= -1,
+};
+
+static const struct resource rtc_cell_resources[] __devinitconst = {
+	[0] = SINGLE_IRQ_RESOURCE(NULL, PM8058_RTC_ALARM_IRQ),
+	[1] = {
+		.name   = "pmic_rtc_base",
+		.start  = PM8058_RTC_BASE,
+		.end    = PM8058_RTC_BASE,
+		.flags  = IORESOURCE_IO,
+	},
+};
+
+static struct mfd_cell rtc_cell __devinitdata = {
+	.name		= PM8XXX_RTC_DEV_NAME,
+	.id		= -1,
+	.resources	= rtc_cell_resources,
+	.num_resources  = ARRAY_SIZE(rtc_cell_resources),
+};
+
+static const struct resource resources_pwrkey[] __devinitconst = {
+	SINGLE_IRQ_RESOURCE(NULL, PM8058_PWRKEY_REL_IRQ),
+	SINGLE_IRQ_RESOURCE(NULL, PM8058_PWRKEY_PRESS_IRQ),
+};
+
+static struct mfd_cell vibrator_cell __devinitdata = {
+	.name		= PM8XXX_VIBRATOR_DEV_NAME,
+	.id		= -1,
+};
+
+static struct mfd_cell pwrkey_cell __devinitdata = {
+	.name		= PM8XXX_PWRKEY_DEV_NAME,
+	.id		= -1,
+	.num_resources	= ARRAY_SIZE(resources_pwrkey),
+	.resources	= resources_pwrkey,
+};
+
+static const struct resource resources_keypad[] = {
+	SINGLE_IRQ_RESOURCE(NULL, PM8058_KEYPAD_IRQ),
+	SINGLE_IRQ_RESOURCE(NULL, PM8058_KEYSTUCK_IRQ),
+};
+
+static struct mfd_cell keypad_cell __devinitdata = {
+	.name		= PM8XXX_KEYPAD_DEV_NAME,
+	.id		= -1,
+	.num_resources  = ARRAY_SIZE(resources_keypad),
+	.resources	= resources_keypad,
+};
+
+static const struct resource mpp_cell_resources[] __devinitconst = {
+	{
+		.start	= PM8058_IRQ_BLOCK_BIT(PM8058_MPP_BLOCK_START, 0),
+		.end	= PM8058_IRQ_BLOCK_BIT(PM8058_MPP_BLOCK_START, 0)
+			  + PM8058_MPPS - 1,
+		.flags	= IORESOURCE_IRQ,
+	},
+};
+
+static struct mfd_cell mpp_cell __devinitdata = {
+	.name		= PM8XXX_MPP_DEV_NAME,
+	.id		= 0,
+	.resources	= mpp_cell_resources,
+	.num_resources	= ARRAY_SIZE(mpp_cell_resources),
+};
+
+static const struct resource gpio_cell_resources[] __devinitconst = {
+	[0] = {
+		.start = PM8058_IRQ_BLOCK_BIT(PM8058_GPIO_BLOCK_START, 0),
+		.end   = PM8058_IRQ_BLOCK_BIT(PM8058_GPIO_BLOCK_START, 0)
+			+ PM8058_GPIOS - 1,
+		.flags = IORESOURCE_IRQ,
+	},
+};
+
+static struct mfd_cell gpio_cell __devinitdata = {
+	.name		= PM8XXX_GPIO_DEV_NAME,
+	.id		= -1,
+	.resources	= gpio_cell_resources,
+	.num_resources	= ARRAY_SIZE(gpio_cell_resources),
+};
+
+static int __devinit
+pm8058_add_subdevices(const struct pm8058_platform_data *pdata,
+				struct pm8058_chip *pmic)
+{
+	int rc = 0, irq_base = 0, i;
+	struct pm_irq_chip *irq_chip;
+	static struct mfd_cell *mfd_regulators, *mfd_xo_buffers;
+
+	if (pdata->irq_pdata) {
+		pdata->irq_pdata->irq_cdata.nirqs = PM8058_NR_IRQS;
+		irq_base = pdata->irq_pdata->irq_base;
+		irq_chip = pm8xxx_irq_init(pmic->dev, pdata->irq_pdata);
+
+		if (IS_ERR(irq_chip)) {
+			pr_err("Failed to init interrupts ret=%ld\n",
+					PTR_ERR(irq_chip));
+			return PTR_ERR(irq_chip);
+		}
+		pmic->irq_chip = irq_chip;
+	}
+
+	if (pdata->gpio_pdata) {
+		pdata->gpio_pdata->gpio_cdata.ngpios = PM8058_GPIOS;
+		gpio_cell.platform_data = pdata->gpio_pdata;
+		gpio_cell.pdata_size = sizeof(struct pm8xxx_gpio_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &gpio_cell, 1,
+					NULL, irq_base);
+		if (rc) {
+			pr_err("Failed to add  gpio subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->mpp_pdata) {
+		pdata->mpp_pdata->core_data.nmpps = PM8058_MPPS;
+		pdata->mpp_pdata->core_data.base_addr = REG_MPP_BASE;
+		mpp_cell.platform_data = pdata->mpp_pdata;
+		mpp_cell.pdata_size = sizeof(struct pm8xxx_mpp_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &mpp_cell, 1, NULL,
+					irq_base);
+		if (rc) {
+			pr_err("Failed to add mpp subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->num_regulators > 0 && pdata->regulator_pdatas) {
+		mfd_regulators = kzalloc(sizeof(struct mfd_cell)
+					 * (pdata->num_regulators), GFP_KERNEL);
+		if (!mfd_regulators) {
+			pr_err("Cannot allocate %d bytes for pm8058 regulator "
+				"mfd cells\n", sizeof(struct mfd_cell)
+						* (pdata->num_regulators));
+			rc = -ENOMEM;
+			goto bail;
+		}
+		for (i = 0; i < pdata->num_regulators; i++) {
+			mfd_regulators[i].name = "pm8058-regulator";
+			mfd_regulators[i].id = pdata->regulator_pdatas[i].id;
+			mfd_regulators[i].platform_data =
+				&(pdata->regulator_pdatas[i]);
+			mfd_regulators[i].pdata_size =
+					sizeof(struct pm8058_vreg_pdata);
+		}
+		rc = mfd_add_devices(pmic->dev, 0, mfd_regulators,
+				pdata->num_regulators, NULL, irq_base);
+		if (rc) {
+			pr_err("Failed to add regulator subdevices ret=%d\n",
+				rc);
+			kfree(mfd_regulators);
+			goto bail;
+		}
+		pmic->mfd_regulators = mfd_regulators;
+	}
+
+	if (pdata->num_xo_buffers > 0 && pdata->xo_buffer_pdata) {
+		mfd_xo_buffers = kzalloc(sizeof(struct mfd_cell)
+					 * (pdata->num_xo_buffers), GFP_KERNEL);
+		if (!mfd_xo_buffers) {
+			pr_err("Cannot allocate %d bytes for pm8058 XO buffer "
+				"mfd cells\n", sizeof(struct mfd_cell)
+						* (pdata->num_xo_buffers));
+			rc = -ENOMEM;
+			goto bail;
+		}
+		for (i = 0; i < pdata->num_xo_buffers; i++) {
+			mfd_xo_buffers[i].name = PM8058_XO_BUFFER_DEV_NAME;
+			mfd_xo_buffers[i].id = pdata->xo_buffer_pdata[i].id;
+			mfd_xo_buffers[i].platform_data =
+				&(pdata->xo_buffer_pdata[i]);
+			mfd_xo_buffers[i].pdata_size =
+					sizeof(struct pm8058_xo_pdata);
+		}
+		rc = mfd_add_devices(pmic->dev, 0, mfd_xo_buffers,
+				pdata->num_xo_buffers, NULL, irq_base);
+		if (rc) {
+			pr_err("Failed to add XO buffer subdevices ret=%d\n",
+				rc);
+			kfree(mfd_xo_buffers);
+			goto bail;
+		}
+		pmic->mfd_xo_buffers = mfd_xo_buffers;
+	}
+
+	if (pdata->keypad_pdata) {
+		keypad_cell.platform_data = pdata->keypad_pdata;
+		keypad_cell.pdata_size =
+			sizeof(struct pm8xxx_keypad_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &keypad_cell, 1, NULL,
+					irq_base);
+		if (rc) {
+			pr_err("Failed to add keypad subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->rtc_pdata) {
+		rtc_cell.platform_data = pdata->rtc_pdata;
+		rtc_cell.pdata_size = sizeof(struct pm8xxx_rtc_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &rtc_cell, 1, NULL,
+						irq_base);
+		if (rc) {
+			pr_err("Failed to add rtc subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->pwrkey_pdata) {
+		pwrkey_cell.platform_data = pdata->pwrkey_pdata;
+		pwrkey_cell.pdata_size =
+			sizeof(struct pm8xxx_pwrkey_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &pwrkey_cell, 1, NULL,
+							irq_base);
+		if (rc) {
+			pr_err("Failed to add pwrkey subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->vibrator_pdata) {
+		vibrator_cell.platform_data = pdata->vibrator_pdata;
+		vibrator_cell.pdata_size =
+				sizeof(struct pm8xxx_vibrator_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &vibrator_cell, 1, NULL,
+								irq_base);
+		if (rc) {
+			pr_err("Failed to add vibrator subdevice ret=%d\n",
+									rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->leds_pdata) {
+		leds_cell.platform_data = pdata->leds_pdata;
+		leds_cell.pdata_size =
+			sizeof(struct pmic8058_leds_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &leds_cell, 1, NULL,
+								irq_base);
+		if (rc) {
+			pr_err("Failed to add leds subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->xoadc_pdata) {
+		xoadc_cell.platform_data = pdata->xoadc_pdata;
+		xoadc_cell.pdata_size =
+			sizeof(struct xoadc_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &xoadc_cell, 1, NULL,
+								irq_base);
+		if (rc) {
+			pr_err("Failed to add leds subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->othc0_pdata) {
+		othc0_cell.platform_data = pdata->othc0_pdata;
+		othc0_cell.pdata_size =
+			sizeof(struct pmic8058_othc_config_pdata);
+		rc = mfd_add_devices(pmic->dev, 0, &othc0_cell, 1, NULL, 0);
+		if (rc) {
+			pr_err("Failed to add othc0 subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->othc1_pdata) {
+		othc1_cell.platform_data = pdata->othc1_pdata;
+		othc1_cell.pdata_size =
+			sizeof(struct pmic8058_othc_config_pdata);
+		rc = mfd_add_devices(pmic->dev, 0, &othc1_cell, 1, NULL,
+								irq_base);
+		if (rc) {
+			pr_err("Failed to add othc1 subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->othc2_pdata) {
+		othc2_cell.platform_data = pdata->othc2_pdata;
+		othc2_cell.pdata_size =
+			sizeof(struct pmic8058_othc_config_pdata);
+		rc = mfd_add_devices(pmic->dev, 0, &othc2_cell, 1, NULL, 0);
+		if (rc) {
+			pr_err("Failed to add othc2 subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->pwm_pdata) {
+		pm8058_pwm_cell.platform_data = pdata->pwm_pdata;
+		pm8058_pwm_cell.pdata_size = sizeof(struct pm8058_pwm_pdata);
+		rc = mfd_add_devices(pmic->dev, 0, &pm8058_pwm_cell, 1, NULL,
+								irq_base);
+		if (rc) {
+			pr_err("Failed to add pwm subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	if (pdata->misc_pdata) {
+		misc_cell.platform_data = pdata->misc_pdata;
+		misc_cell.pdata_size = sizeof(struct pm8xxx_misc_platform_data);
+		rc = mfd_add_devices(pmic->dev, 0, &misc_cell, 1, NULL,
+				      irq_base);
+		if (rc) {
+			pr_err("Failed to add  misc subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	rc = mfd_add_devices(pmic->dev, 0, &thermal_alarm_cell, 1, NULL,
+				irq_base);
+	if (rc) {
+		pr_err("Failed to add thermal alarm subdevice ret=%d\n",
+			rc);
+		goto bail;
+	}
+
+	rc = mfd_add_devices(pmic->dev, 0, &batt_alarm_cell, 1, NULL,
+				irq_base);
+	if (rc) {
+		pr_err("Failed to add battery alarm subdevice ret=%d\n",
+			rc);
+		goto bail;
+	}
+
+	rc = mfd_add_devices(pmic->dev, 0, &upl_cell, 1, NULL, 0);
+	if (rc) {
+		pr_err("Failed to add upl subdevice ret=%d\n", rc);
+		goto bail;
+	}
+
+	rc = mfd_add_devices(pmic->dev, 0, &nfc_cell, 1, NULL, 0);
+	if (rc) {
+		pr_err("Failed to add upl subdevice ret=%d\n", rc);
+		goto bail;
+	}
+
+	if (pdata->charger_pdata) {
+		pm8058_charger_cell.platform_data = pdata->charger_pdata;
+		pm8058_charger_cell.pdata_size = sizeof(struct
+						pmic8058_charger_data);
+		rc = mfd_add_devices(pmic->dev, 0, &pm8058_charger_cell,
+						1, NULL, irq_base);
+		if (rc) {
+			pr_err("Failed to add charger subdevice ret=%d\n", rc);
+			goto bail;
+		}
+	}
+
+	rc = mfd_add_devices(pmic->dev, 0, &debugfs_cell, 1, NULL, irq_base);
+	if (rc) {
+		pr_err("Failed to add debugfs subdevice ret=%d\n", rc);
+		goto bail;
+	}
+
+	return rc;
+bail:
+	if (pmic->irq_chip) {
+		pm8xxx_irq_exit(pmic->irq_chip);
+		pmic->irq_chip = NULL;
+	}
+	return rc;
+}
+
 static int __devinit pm8058_probe(struct platform_device *pdev)
 {
-	int	i, rc;
-	struct	pm8058_platform_data *pdata = pdev->dev.platform_data;
-	struct	pm8058_chip *chip;
+	int rc;
+	struct pm8058_platform_data *pdata = pdev->dev.platform_data;
+	struct pm8058_chip *pmic;
 
-	if (pdata == NULL || !gpio_is_valid(pdata->irq)) {
+	if (pdata == NULL) {
 		pr_err("%s: No platform_data or IRQ.\n", __func__);
 		return -ENODEV;
 	}
 
-	if (pdata->num_subdevs == 0) {
-		pr_err("%s: No sub devices to support.\n", __func__);
-		return -ENODEV;
-	}
-
-	chip = kzalloc(sizeof *chip, GFP_KERNEL);
-	if (chip == NULL) {
+	pmic = kzalloc(sizeof *pmic, GFP_KERNEL);
+	if (pmic == NULL) {
 		pr_err("%s: kzalloc() failed.\n", __func__);
 		return -ENOMEM;
 	}
 
-	chip->dev = &pdev->dev;
+	pmic->dev = &pdev->dev;
+
+	pm8058_drvdata.pm_chip_data = pmic;
+	platform_set_drvdata(pdev, &pm8058_drvdata);
+
+	mutex_init(&pmic->pm_lock);
+	pmic_chip = pmic;
 
 	/* Read PMIC chip revision */
-	rc = ssbi_read(chip->dev, SSBI_REG_REV, &chip->revision, 1);
+	rc = pm8058_readb(pmic->dev, PM8058_REG_REV, &pmic->revision);
 	if (rc)
-		pr_err("%s: Failed on ssbi_read for revision: rc=%d.\n",
+		pr_err("%s: Failed on pm8058_readb for revision: rc=%d.\n",
 			__func__, rc);
-	pr_info("%s: PMIC revision: %X\n", __func__, chip->revision);
 
-	(void) memcpy((void *)&chip->pdata, (const void *)pdata,
-		      sizeof(chip->pdata));
+	pr_info("%s: PMIC revision: %X\n", __func__, pmic->revision);
 
-	mutex_init(&chip->pm_lock);
-	irq_set_handler_data(pdata->irq, (void *)chip);
-	irq_set_irq_wake(pdata->irq, 1);
+	(void) memcpy((void *)&pmic->pdata, (const void *)pdata,
+		      sizeof(pmic->pdata));
 
-	chip->pm_max_irq = 0;
-	chip->pm_max_blocks = 0;
-	chip->pm_max_masters = 0;
-
-	platform_set_drvdata(pdev, chip);
-
-	pmic_chip = chip;
-
-	/* Register for all reserved IRQs */
-	for (i = pdata->irq_base; i < (pdata->irq_base + MAX_PM_IRQ); i++) {
-		irq_set_chip(i, &pm8058_irq_chip);
-		irq_set_chip_data(i, (void *)chip);
-		irq_set_handler(i, handle_edge_irq);
-		set_irq_flags(i, IRQF_VALID);
-		irq_set_nested_thread(i, 1);
+	rc = pm8058_add_subdevices(pdata, pmic);
+	if (rc) {
+		pr_err("Cannot add subdevices rc=%d\n", rc);
+		goto err;
 	}
 
-	rc = mfd_add_devices(chip->dev, 0, pdata->sub_devices,
-			     pdata->num_subdevs, NULL, 0);
-
-	/* Add charger sub device with the chip parameter as driver data */
-	if (pdata->charger_sub_device) {
-		rc = mfd_add_devices(chip->dev, 0,
-					pdata->charger_sub_device,
-					1, NULL, 0);
-	}
-
-	if (pdata->init) {
-		rc = pdata->init(chip);
-		if (rc != 0) {
-			pr_err("%s: board init failed\n", __func__);
-			chip->dev = NULL;
-			kfree(chip);
-			return -ENODEV;
-		}
-	}
-
-	rc = request_threaded_irq(pdata->irq, NULL, pm8058_isr_thread,
-			IRQF_ONESHOT | IRQF_DISABLED | pdata->irq_trigger_flags,
-			"pm8058-irq", chip);
-	if (rc < 0)
-		pr_err("%s: could not request irq %d: %d\n", __func__,
-				pdata->irq, rc);
-
-	rc = pmic8058_dbg_probe(chip);
-	if (rc < 0)
-		pr_err("%s: could not set up debugfs: %d\n", __func__, rc);
-
 	rc = pm8058_hard_reset_config(SHUTDOWN_ON_HARD_RESET);
 	if (rc < 0)
 		pr_err("%s: failed to config shutdown on hard reset: %d\n",
 								__func__, rc);
 
-	register_syscore_ops(&pm8058_pm);
-
 	return 0;
+
+err:
+	mfd_remove_devices(pmic->dev);
+	platform_set_drvdata(pdev, NULL);
+	kfree(pmic);
+	return rc;
 }
 
 static int __devexit pm8058_remove(struct platform_device *pdev)
 {
-	struct	pm8058_chip *chip;
+	struct pm8xxx_drvdata *drvdata;
+	struct pm8058_chip *pmic = NULL;
 
-	chip = platform_get_drvdata(pdev);
-	if (chip) {
-		if (chip->pm_max_irq) {
-			irq_set_irq_wake(chip->pdata.irq, 0);
-			free_irq(chip->pdata.irq, chip);
-		}
-		mutex_destroy(&chip->pm_lock);
-		chip->dev = NULL;
-
-		kfree(chip);
+	drvdata = platform_get_drvdata(pdev);
+	if (drvdata)
+		pmic = drvdata->pm_chip_data;
+	if (pmic) {
+		if (pmic->dev)
+			mfd_remove_devices(pmic->dev);
+		if (pmic->irq_chip)
+			pm8xxx_irq_exit(pmic->irq_chip);
+		mutex_destroy(&pmic->pm_lock);
+		kfree(pmic->mfd_regulators);
+		kfree(pmic);
 	}
-
-	pmic8058_dbg_remove();
+	platform_set_drvdata(pdev, NULL);
 
 	return 0;
 }
@@ -1489,7 +1269,7 @@
 {
 	return platform_driver_register(&pm8058_driver);
 }
-arch_initcall(pm8058_init);
+postcore_initcall(pm8058_init);
 
 static void __exit pm8058_exit(void)
 {
diff --git a/drivers/misc/Kconfig b/drivers/misc/Kconfig
index dfbf345..3d7738e 100644
--- a/drivers/misc/Kconfig
+++ b/drivers/misc/Kconfig
@@ -601,21 +601,19 @@
 	  on the PM8XXX chips. The vibrator is controlled using the
 	  timed output class.
 
-config PMIC8058_NFC
-	tristate "Qualcomm PM8058 support for Near Field Communication"
-	depends on PMIC8058
-	default y
+config PMIC8XXX_NFC
+	tristate "Qualcomm PM8XXX support for Near Field Communication"
+	depends on MFD_PM8XXX
 	help
-	  Qualcomm PM8058 chip has a module to support NFC (Near Field
+	  Qualcomm PM8XXX chips have a module to support NFC (Near Field
 	  Communication). This option enables the driver to support it.
 
-config PMIC8058_UPL
-	tristate "Qualcomm PM8058 support for User Programmable Logic"
-	depends on PMIC8058
-	default n
+config PMIC8XXX_UPL
+	tristate "Qualcomm PM8XXX support for User Programmable Logic"
+	depends on MFD_PM8XXX
 	help
 	  This option enables device driver support for User Programmable Logic
-	  on Qualcomm PM8058 chip.  The UPL module provides a means to implement
+	  on Qualcomm PM8XXX chips. The UPL module provides a means to implement
 	  simple truth table based logic via a set of control registers. I/O may
 	  be routed in and out of the UPL module via GPIO or DTEST pins.
 
diff --git a/drivers/misc/Makefile b/drivers/misc/Makefile
index a38ccfd..b7f23c8 100644
--- a/drivers/misc/Makefile
+++ b/drivers/misc/Makefile
@@ -59,8 +59,8 @@
 obj-$(CONFIG_PMIC8058_PWM) += pmic8058-pwm.o
 obj-$(CONFIG_PMIC8058_VIBRATOR) += pmic8058-vibrator.o
 obj-$(CONFIG_PMIC8XXX_VIBRATOR) += pm8xxx-vibrator.o
-obj-$(CONFIG_PMIC8058_NFC) += pmic8058-nfc.o
-obj-$(CONFIG_PMIC8058_UPL) += pmic8058-upl.o
+obj-$(CONFIG_PMIC8XXX_NFC) += pm8xxx-nfc.o
+obj-$(CONFIG_PMIC8XXX_UPL) += pm8xxx-upl.o
 obj-$(CONFIG_MSM_MEMORY_LOW_POWER_MODE_SUSPEND_DEEP_POWER_DOWN) \
 	+= msm_migrate_pages.o
 obj-$(CONFIG_PMIC8058_XOADC) += pmic8058-xoadc.o
diff --git a/drivers/misc/pm8xxx-nfc.c b/drivers/misc/pm8xxx-nfc.c
new file mode 100644
index 0000000..1aaa3e3
--- /dev/null
+++ b/drivers/misc/pm8xxx-nfc.c
@@ -0,0 +1,311 @@
+/* Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+/*
+ * Qualcomm PMIC8XXX NFC driver
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <linux/mfd/pm8xxx/core.h>
+#include <linux/mfd/pm8xxx/nfc.h>
+
+/* PM8XXX NFC */
+#define SSBI_REG_NFC_CTRL	0x14D
+#define SSBI_REG_NFC_TEST	0x14E
+
+/* NFC_CTRL */
+#define PM8XXX_NFC_SUPPORT_EN		0x80
+#define PM8XXX_NFC_LDO_EN		0x40
+#define PM8XXX_NFC_EN			0x20
+#define PM8XXX_NFC_EXT_VDDLDO_EN	0x10
+#define PM8XXX_NFC_VPH_PWR_EN		0x08
+#define PM8XXX_NFC_RESERVED		0x04
+#define PM8XXX_NFC_VDDLDO_LEVEL		0x03
+
+/* NFC_TEST */
+#define PM8XXX_NFC_VDDLDO_MON_EN	0x80
+#define PM8XXX_NFC_ATEST_EN		0x40
+#define PM8XXX_NFC_DTEST1_EN		0x20
+#define PM8XXX_NFC_RESERVED2		0x18
+#define PM8XXX_NFC_VDDLDO_OK_S		0x04
+#define PM8XXX_NFC_MBG_EN_S		0x02
+#define PM8XXX_NFC_EXT_EN_S		0x01
+
+struct pm8xxx_nfc_device {
+	struct device *dev;
+	struct mutex		nfc_mutex;
+#if defined(CONFIG_DEBUG_FS)
+	struct dentry		*dent;
+#endif
+};
+static struct pm8xxx_nfc_device	*nfc_dev;
+
+/* APIs */
+/*
+ * pm8xxx_nfc_request - request a handle to access NFC device
+ */
+struct pm8xxx_nfc_device *pm8xxx_nfc_request(void)
+{
+	return nfc_dev;
+}
+EXPORT_SYMBOL(pm8xxx_nfc_request);
+
+/*
+ * pm8xxx_nfc_config - configure NFC signals
+ *
+ * @nfcdev: the NFC device
+ * @mask: signal mask to configure
+ * @flags: control flags
+ */
+int pm8xxx_nfc_config(struct pm8xxx_nfc_device *nfcdev, u32 mask, u32 flags)
+{
+	u8	nfc_ctrl, nfc_test, m, f;
+	int	rc;
+
+	if (nfcdev == NULL || IS_ERR(nfcdev) || !mask)
+		return -EINVAL;
+
+	mutex_lock(&nfcdev->nfc_mutex);
+
+	if (!(mask & PM_NFC_CTRL_REQ))
+		goto config_test;
+
+	rc = pm8xxx_readb(nfcdev->dev->parent, SSBI_REG_NFC_CTRL, &nfc_ctrl);
+	if (rc) {
+		pr_err("%s: FAIL pm8xxx_readb(): rc=%d (nfc_ctrl=0x%x)\n",
+		       __func__, rc, nfc_ctrl);
+		goto config_done;
+	}
+
+	m = mask & 0x00ff;
+	f = flags & 0x00ff;
+	nfc_ctrl &= ~m;
+	nfc_ctrl |= m & f;
+
+	rc = pm8xxx_writeb(nfcdev->dev->parent, SSBI_REG_NFC_CTRL, nfc_ctrl);
+	if (rc) {
+		pr_err("%s: FAIL pm8xxx_writeb(): rc=%d (nfc_ctrl=0x%x)\n",
+		       __func__, rc, nfc_ctrl);
+		goto config_done;
+	}
+
+config_test:
+	if (!(mask & PM_NFC_TEST_REQ))
+		goto config_done;
+
+	rc = pm8xxx_readb(nfcdev->dev->parent, SSBI_REG_NFC_TEST, &nfc_test);
+	if (rc) {
+		pr_err("%s: FAIL pm8xxx_readb(): rc=%d (nfc_test=0x%x)\n",
+		       __func__, rc, nfc_test);
+		goto config_done;
+	}
+
+	m = (mask >> 8) & 0x00ff;
+	f = (flags >> 8) & 0x00ff;
+	nfc_test &= ~m;
+	nfc_test |= m & f;
+
+	rc = pm8xxx_writeb(nfcdev->dev->parent, SSBI_REG_NFC_TEST, nfc_test);
+	if (rc) {
+		pr_err("%s: FAIL pm8xxx_writeb(): rc=%d (nfc_test=0x%x)\n",
+		       __func__, rc, nfc_test);
+		goto config_done;
+	}
+
+config_done:
+	mutex_unlock(&nfcdev->nfc_mutex);
+	return 0;
+}
+EXPORT_SYMBOL(pm8xxx_nfc_config);
+
+/*
+ * pm8xxx_nfc_get_status - get NFC status
+ *
+ * @nfcdev: the NFC device
+ * @mask: of status mask to read
+ * @status: pointer to the status variable
+ */
+int pm8xxx_nfc_get_status(struct pm8xxx_nfc_device *nfcdev,
+			  u32 mask, u32 *status)
+{
+	u8	nfc_ctrl, nfc_test;
+	u32	st;
+	int	rc;
+
+	if (nfcdev == NULL || IS_ERR(nfcdev) || status == NULL)
+		return -EINVAL;
+
+	st = 0;
+	mutex_lock(&nfcdev->nfc_mutex);
+
+	if (!(mask & PM_NFC_CTRL_REQ))
+		goto read_test;
+
+	rc = pm8xxx_readb(nfcdev->dev->parent, SSBI_REG_NFC_CTRL, &nfc_ctrl);
+	if (rc) {
+		pr_err("%s: FAIL pm8xxx_readb(): rc=%d (nfc_ctrl=0x%x)\n",
+		       __func__, rc, nfc_ctrl);
+		goto get_status_done;
+	}
+
+read_test:
+	if (!(mask & (PM_NFC_TEST_REQ | PM_NFC_TEST_STATUS)))
+		goto get_status_done;
+
+	rc = pm8xxx_readb(nfcdev->dev->parent, SSBI_REG_NFC_TEST, &nfc_test);
+	if (rc)
+		pr_err("%s: FAIL pm8xxx_readb(): rc=%d (nfc_test=0x%x)\n",
+		       __func__, rc, nfc_test);
+
+get_status_done:
+	st = nfc_ctrl;
+	st |= nfc_test << 8;
+	*status = st;
+
+	mutex_unlock(&nfcdev->nfc_mutex);
+	return 0;
+}
+EXPORT_SYMBOL(pm8xxx_nfc_get_status);
+
+/*
+ * pm8xxx_nfc_free - free the NFC device
+ */
+void pm8xxx_nfc_free(struct pm8xxx_nfc_device *nfcdev)
+{
+	/* Disable all signals */
+	pm8xxx_nfc_config(nfcdev, PM_NFC_CTRL_REQ, 0);
+}
+EXPORT_SYMBOL(pm8xxx_nfc_free);
+
+#if defined(CONFIG_DEBUG_FS)
+static int pm8xxx_nfc_debug_set(void *data, u64 val)
+{
+	struct pm8xxx_nfc_device *nfcdev;
+	u32	mask, control;
+	int	rc;
+
+	nfcdev = (struct pm8xxx_nfc_device *)data;
+	control = (u32)val & 0xffff;
+	mask = ((u32)val >> 16) & 0xffff;
+	rc = pm8xxx_nfc_config(nfcdev, mask, control);
+	if (rc)
+		pr_err("%s: ERR pm8xxx_nfc_config: rc=%d, "
+		       "[mask, control]=[0x%x, 0x%x]\n",
+		       __func__, rc, mask, control);
+
+	return 0;
+}
+
+static int pm8xxx_nfc_debug_get(void *data, u64 *val)
+{
+	struct pm8xxx_nfc_device *nfcdev;
+	u32	status;
+	int	rc;
+
+	nfcdev = (struct pm8xxx_nfc_device *)data;
+	rc = pm8xxx_nfc_get_status(nfcdev, (u32)-1, &status);
+	if (rc)
+		pr_err("%s: ERR pm8xxx_nfc_get_status: rc=%d, status=0x%x\n",
+		       __func__, rc, status);
+
+	if (val)
+		*val = (u64)status;
+	return 0;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(pm8xxx_nfc_fops, pm8xxx_nfc_debug_get,
+			pm8xxx_nfc_debug_set, "%llu\n");
+
+static int pm8xxx_nfc_debug_init(struct pm8xxx_nfc_device *nfcdev)
+{
+	struct dentry *dent;
+
+	dent = debugfs_create_file("pm8xxx-nfc", 0644, NULL,
+				   (void *)nfcdev, &pm8xxx_nfc_fops);
+
+	if (dent == NULL || IS_ERR(dent))
+		pr_err("%s: ERR debugfs_create_file: dent=0x%x\n",
+		       __func__, (unsigned)dent);
+
+	nfcdev->dent = dent;
+	return 0;
+}
+#endif
+
+static int __devinit pm8xxx_nfc_probe(struct platform_device *pdev)
+{
+	struct pm8xxx_nfc_device	*nfcdev;
+
+	nfcdev = kzalloc(sizeof *nfcdev, GFP_KERNEL);
+	if (nfcdev == NULL) {
+		pr_err("%s: kzalloc() failed.\n", __func__);
+		return -ENOMEM;
+	}
+
+	mutex_init(&nfcdev->nfc_mutex);
+
+	nfcdev->dev = &pdev->dev;
+	nfc_dev = nfcdev;
+	platform_set_drvdata(pdev, nfcdev);
+
+#if defined(CONFIG_DEBUG_FS)
+	pm8xxx_nfc_debug_init(nfc_dev);
+#endif
+
+	pr_notice("%s: OK\n", __func__);
+	return 0;
+}
+
+static int __devexit pm8xxx_nfc_remove(struct platform_device *pdev)
+{
+	struct pm8xxx_nfc_device *nfcdev = platform_get_drvdata(pdev);
+
+#if defined(CONFIG_DEBUG_FS)
+	debugfs_remove(nfcdev->dent);
+#endif
+
+	platform_set_drvdata(pdev, NULL);
+	kfree(nfcdev);
+	return 0;
+}
+
+static struct platform_driver pm8xxx_nfc_driver = {
+	.probe		= pm8xxx_nfc_probe,
+	.remove		= __devexit_p(pm8xxx_nfc_remove),
+	.driver		= {
+		.name = PM8XXX_NFC_DEV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init pm8xxx_nfc_init(void)
+{
+	return platform_driver_register(&pm8xxx_nfc_driver);
+}
+
+static void __exit pm8xxx_nfc_exit(void)
+{
+	platform_driver_unregister(&pm8xxx_nfc_driver);
+}
+
+module_init(pm8xxx_nfc_init);
+module_exit(pm8xxx_nfc_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("PM8XXX NFC driver");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("platform:" PM8XXX_NFC_DEV_NAME);
diff --git a/drivers/misc/pm8xxx-upl.c b/drivers/misc/pm8xxx-upl.c
new file mode 100644
index 0000000..d3d9746f
--- /dev/null
+++ b/drivers/misc/pm8xxx-upl.c
@@ -0,0 +1,350 @@
+/* Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+/*
+ * Qualcomm PM8XXX UPL driver
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/platform_device.h>
+#include <linux/err.h>
+#include <linux/debugfs.h>
+#include <linux/slab.h>
+#include <linux/mfd/pm8xxx/core.h>
+#include <linux/mfd/pm8xxx/upl.h>
+
+/* PMIC8XXX UPL registers */
+#define SSBI_REG_UPL_CTRL		0x17B
+#define SSBI_REG_UPL_TRUTHTABLE1	0x17C
+#define SSBI_REG_UPL_TRUTHTABLE2	0x17D
+
+struct pm8xxx_upl_device {
+	struct device		*dev;
+	struct mutex		upl_mutex;
+#if defined(CONFIG_DEBUG_FS)
+	struct dentry		*dent;
+#endif
+};
+static struct pm8xxx_upl_device *upl_dev;
+
+/* APIs */
+
+/*
+ * pm8xxx_upl_request - request a handle to access UPL device
+ */
+struct pm8xxx_upl_device *pm8xxx_upl_request(void)
+{
+	return upl_dev;
+}
+EXPORT_SYMBOL(pm8xxx_upl_request);
+
+/*
+ * pm8xxx_upl_read_truthtable - read value currently stored in UPL truth table
+ *
+ * @upldev: the UPL device
+ * @truthtable: value read from UPL truth table
+ */
+int pm8xxx_upl_read_truthtable(struct pm8xxx_upl_device *upldev,
+				u16 *truthtable)
+{
+	int rc = 0;
+	u8 table[2];
+
+	if (upldev == NULL || IS_ERR(upldev))
+		return -EINVAL;
+
+	mutex_lock(&upldev->upl_mutex);
+
+	rc = pm8xxx_readb(upldev->dev->parent, SSBI_REG_UPL_TRUTHTABLE1,
+							&(table[0]));
+	if (rc) {
+		pr_err("%s: FAIL pm8xxx_readb(0x%X)=0x%02X: rc=%d\n",
+			__func__, SSBI_REG_UPL_TRUTHTABLE1, table[0], rc);
+		goto upl_read_done;
+	}
+
+	rc = pm8xxx_readb(upldev->dev->parent, SSBI_REG_UPL_TRUTHTABLE2,
+							&(table[1]));
+	if (rc)
+		pr_err("%s: FAIL pm8xxx_readb(0x%X)=0x%02X: rc=%d\n",
+			__func__, SSBI_REG_UPL_TRUTHTABLE2, table[1], rc);
+upl_read_done:
+	mutex_unlock(&upldev->upl_mutex);
+	*truthtable = (((u16)table[1]) << 8) | table[0];
+	return rc;
+}
+EXPORT_SYMBOL(pm8xxx_upl_read_truthtable);
+
+/*
+ * pm8xxx_upl_writes_truthtable - write value into UPL truth table
+ *
+ * @upldev: the UPL device
+ * @truthtable: value written to UPL truth table
+ *
+ * Each bit in parameter "truthtable" corresponds to the UPL output for a given
+ * set of input pin values. For example, if the input pins have the following
+ * values: A=1, B=1, C=1, D=0, then the UPL would output the value of bit 14
+ * (0b1110) in parameter "truthtable".
+ */
+int pm8xxx_upl_write_truthtable(struct pm8xxx_upl_device *upldev,
+				u16 truthtable)
+{
+	int rc = 0;
+	u8 table[2];
+
+	if (upldev == NULL || IS_ERR(upldev))
+		return -EINVAL;
+
+	table[0] = truthtable & 0xFF;
+	table[1] = (truthtable >> 8) & 0xFF;
+
+	mutex_lock(&upldev->upl_mutex);
+
+	rc = pm8xxx_writeb(upldev->dev->parent, SSBI_REG_UPL_TRUTHTABLE1,
+								table[0]);
+	if (rc) {
+		pr_err("%s: FAIL pm8xxx_writeb(0x%X)=0x%04X: rc=%d\n",
+			__func__, SSBI_REG_UPL_TRUTHTABLE1, table[0], rc);
+		goto upl_write_done;
+	}
+
+	rc = pm8xxx_writeb(upldev->dev->parent, SSBI_REG_UPL_TRUTHTABLE2,
+								table[1]);
+	if (rc)
+		pr_err("%s: FAIL pm8xxx_writeb(0x%X)=0x%04X: rc=%d\n",
+			__func__, SSBI_REG_UPL_TRUTHTABLE2, table[1], rc);
+upl_write_done:
+	mutex_unlock(&upldev->upl_mutex);
+	return rc;
+}
+EXPORT_SYMBOL(pm8xxx_upl_write_truthtable);
+
+/*
+ * pm8xxx_upl_config - configure UPL I/O settings and UPL enable/disable
+ *
+ * @upldev: the UPL device
+ * @mask: setting mask to configure
+ * @flags: setting flags
+ */
+int pm8xxx_upl_config(struct pm8xxx_upl_device *upldev, u32 mask, u32 flags)
+{
+	int rc;
+	u8 upl_ctrl, m, f;
+
+	if (upldev == NULL || IS_ERR(upldev))
+		return -EINVAL;
+
+	mutex_lock(&upldev->upl_mutex);
+
+	rc = pm8xxx_readb(upldev->dev->parent, SSBI_REG_UPL_CTRL, &upl_ctrl);
+	if (rc) {
+		pr_err("%s: FAIL pm8xxx_readb(0x%X)=0x%02X: rc=%d\n",
+			__func__, SSBI_REG_UPL_CTRL, upl_ctrl, rc);
+		goto upl_config_done;
+	}
+
+	m = mask & 0x00ff;
+	f = flags & 0x00ff;
+	upl_ctrl &= ~m;
+	upl_ctrl |= m & f;
+
+	rc = pm8xxx_writeb(upldev->dev->parent, SSBI_REG_UPL_CTRL, upl_ctrl);
+	if (rc)
+		pr_err("%s: FAIL pm8xxx_writeb(0x%X)=0x%02X: rc=%d\n",
+			__func__, SSBI_REG_UPL_CTRL, upl_ctrl, rc);
+upl_config_done:
+	mutex_unlock(&upldev->upl_mutex);
+	return rc;
+}
+EXPORT_SYMBOL(pm8xxx_upl_config);
+
+#if defined(CONFIG_DEBUG_FS)
+
+static int truthtable_set(void *data, u64 val)
+{
+	int rc;
+
+	rc = pm8xxx_upl_write_truthtable(data, val);
+	if (rc)
+		pr_err("%s: pm8xxx_upl_write_truthtable: rc=%d, "
+			"truthtable=0x%llX\n", __func__, rc, val);
+	return rc;
+}
+
+static int truthtable_get(void *data, u64 *val)
+{
+	int rc;
+	u16 truthtable;
+
+	rc = pm8xxx_upl_read_truthtable(data, &truthtable);
+	if (rc)
+		pr_err("%s: pm8xxx_upl_read_truthtable: rc=%d, "
+			"truthtable=0x%X\n", __func__, rc, truthtable);
+	if (val)
+		*val = truthtable;
+
+	return rc;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(upl_truthtable_fops, truthtable_get,
+			truthtable_set, "0x%04llX\n");
+
+/* enter values as 0xMMMMFFFF where MMMM is the mask and FFFF is the flags */
+static int control_set(void *data, u64 val)
+{
+	u8 mask, flags;
+	int rc;
+
+	flags = val & 0xFFFF;
+	mask = (val >> 16) & 0xFFFF;
+
+	rc = pm8xxx_upl_config(data, mask, flags);
+	if (rc)
+		pr_err("%s: pm8xxx_upl_config: rc=%d, mask = 0x%X, "
+			"flags = 0x%X\n", __func__, rc, mask, flags);
+	return rc;
+}
+
+static int control_get(void *data, u64 *val)
+{
+	struct pm8xxx_upl_device *upldev;
+	int rc = 0;
+	u8 ctrl;
+
+	upldev = data;
+
+	mutex_lock(&upldev->upl_mutex);
+
+	rc = pm8xxx_readb(upldev->dev->parent, SSBI_REG_UPL_CTRL, &ctrl);
+	if (rc)
+		pr_err("%s: FAIL pm8xxx_readb(): rc=%d (ctrl=0x%02X)\n",
+		       __func__, rc, ctrl);
+
+	mutex_unlock(&upldev->upl_mutex);
+
+	*val = ctrl;
+
+	return rc;
+}
+
+DEFINE_SIMPLE_ATTRIBUTE(upl_control_fops, control_get,
+			control_set, "0x%02llX\n");
+
+static int pm8xxx_upl_debug_init(struct pm8xxx_upl_device *upldev)
+{
+	struct dentry *dent;
+	struct dentry *temp;
+
+	dent = debugfs_create_dir("pm8xxx-upl", NULL);
+	if (dent == NULL || IS_ERR(dent)) {
+		pr_err("%s: ERR debugfs_create_dir: dent=0x%X\n",
+					__func__, (unsigned)dent);
+		return -ENOMEM;
+	}
+
+	temp = debugfs_create_file("truthtable", S_IRUSR | S_IWUSR, dent,
+					upldev, &upl_truthtable_fops);
+	if (temp == NULL || IS_ERR(temp)) {
+		pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
+					__func__, (unsigned)dent);
+		goto debug_error;
+	}
+
+	temp = debugfs_create_file("control", S_IRUSR | S_IWUSR, dent,
+					upldev, &upl_control_fops);
+	if (temp == NULL || IS_ERR(temp)) {
+		pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
+					__func__, (unsigned)dent);
+		goto debug_error;
+	}
+
+	upldev->dent = dent;
+	return 0;
+
+debug_error:
+	debugfs_remove_recursive(dent);
+	return -ENOMEM;
+}
+
+static int __devexit pm8xxx_upl_debug_remove(struct pm8xxx_upl_device *upldev)
+{
+	debugfs_remove_recursive(upldev->dent);
+	return 0;
+}
+
+#endif /* CONFIG_DEBUG_FS */
+
+static int __devinit pm8xxx_upl_probe(struct platform_device *pdev)
+{
+	struct pm8xxx_upl_device	*upldev;
+
+	upldev = kzalloc(sizeof *upldev, GFP_KERNEL);
+	if (upldev == NULL) {
+		pr_err("%s: kzalloc() failed.\n", __func__);
+		return -ENOMEM;
+	}
+
+	mutex_init(&upldev->upl_mutex);
+
+	upl_dev = upldev;
+	upldev->dev = &pdev->dev;
+	platform_set_drvdata(pdev, upldev);
+
+#if defined(CONFIG_DEBUG_FS)
+	pm8xxx_upl_debug_init(upl_dev);
+#endif
+	pr_notice("%s: OK\n", __func__);
+	return 0;
+}
+
+static int __devexit pm8xxx_upl_remove(struct platform_device *pdev)
+{
+	struct pm8xxx_upl_device *upldev = platform_get_drvdata(pdev);
+
+#if defined(CONFIG_DEBUG_FS)
+	pm8xxx_upl_debug_remove(upldev);
+#endif
+
+	platform_set_drvdata(pdev, NULL);
+	kfree(upldev);
+	pr_notice("%s: OK\n", __func__);
+
+	return 0;
+}
+
+static struct platform_driver pm8xxx_upl_driver = {
+	.probe		= pm8xxx_upl_probe,
+	.remove		= __devexit_p(pm8xxx_upl_remove),
+	.driver		= {
+		.name = PM8XXX_UPL_DEV_NAME,
+		.owner = THIS_MODULE,
+	},
+};
+
+static int __init pm8xxx_upl_init(void)
+{
+	return platform_driver_register(&pm8xxx_upl_driver);
+}
+
+static void __exit pm8xxx_upl_exit(void)
+{
+	platform_driver_unregister(&pm8xxx_upl_driver);
+}
+
+module_init(pm8xxx_upl_init);
+module_exit(pm8xxx_upl_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_DESCRIPTION("PM8XXX UPL driver");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("platform:" PM8XXX_UPL_DEV_NAME);
diff --git a/drivers/misc/pm8xxx-vibrator.c b/drivers/misc/pm8xxx-vibrator.c
index 8aa7f72..4f22efe 100644
--- a/drivers/misc/pm8xxx-vibrator.c
+++ b/drivers/misc/pm8xxx-vibrator.c
@@ -27,6 +27,7 @@
 #define VIB_DRV_SEL_MASK	0xf8
 #define VIB_DRV_SEL_SHIFT	0x03
 #define VIB_DRV_EN_MANUAL_MASK	0xfc
+#define VIB_DRV_LOGIC_SHIFT	0x2
 
 #define VIB_MAX_LEVEL_mV	3100
 #define VIB_MIN_LEVEL_mV	1200
@@ -43,6 +44,40 @@
 	u8  reg_vib_drv;
 };
 
+static struct pm8xxx_vib *vib_dev;
+
+int pm8xxx_vibrator_config(struct pm8xxx_vib_config *vib_config)
+{
+	u8 reg = 0;
+	int rc;
+
+	if (vib_dev == NULL) {
+		pr_err("%s: vib_dev is NULL\n", __func__);
+		return -EINVAL;
+	}
+
+	if (vib_config->drive_mV) {
+		if ((vib_config->drive_mV < VIB_MIN_LEVEL_mV) ||
+			(vib_config->drive_mV > VIB_MAX_LEVEL_mV)) {
+			pr_err("Invalid vibrator drive strength\n");
+			return -EINVAL;
+		}
+	}
+
+	reg = (vib_config->drive_mV / 100) << VIB_DRV_SEL_SHIFT;
+
+	reg |= (!!vib_config->active_low) << VIB_DRV_LOGIC_SHIFT;
+
+	reg |= vib_config->enable_mode;
+
+	rc = pm8xxx_writeb(vib_dev->dev->parent, VIB_DRV, reg);
+	if (rc)
+		pr_err("%s: pm8xxx write failed: rc=%d\n", __func__, rc);
+
+	return rc;
+}
+EXPORT_SYMBOL(pm8xxx_vibrator_config);
+
 /* REVISIT: just for debugging, will be removed in final working version */
 static void __dump_vib_regs(struct pm8xxx_vib *vib, char *msg)
 {
@@ -240,6 +275,8 @@
 
 	platform_set_drvdata(pdev, vib);
 
+	vib_dev = vib;
+
 	return 0;
 
 err_read_vib:
diff --git a/drivers/misc/pmic8058-nfc.c b/drivers/misc/pmic8058-nfc.c
deleted file mode 100644
index 76a19f4..0000000
--- a/drivers/misc/pmic8058-nfc.c
+++ /dev/null
@@ -1,322 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-/*
- * Qualcomm PMIC8058 NFC driver
- *
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/mfd/pmic8058.h>
-#include <linux/pmic8058-nfc.h>
-#include <linux/debugfs.h>
-#include <linux/slab.h>
-
-/* PMIC8058 NFC */
-#define	SSBI_REG_NFC_CTRL	0x14D
-#define	SSBI_REG_NFC_TEST	0x14E
-
-/* NFC_CTRL */
-#define	PM8058_NFC_SUPPORT_EN		0x80
-#define	PM8058_NFC_LDO_EN		0x40
-#define	PM8058_NFC_EN			0x20
-#define	PM8058_NFC_EXT_VDDLDO_EN	0x10
-#define	PM8058_NFC_VPH_PWR_EN		0x08
-#define	PM8058_NFC_RESERVED		0x04
-#define	PM8058_NFC_VDDLDO_LEVEL		0x03
-
-/* NFC_TEST */
-#define	PM8058_NFC_VDDLDO_MON_EN	0x80
-#define	PM8058_NFC_ATEST_EN		0x40
-#define	PM8058_NFC_DTEST1_EN		0x20
-#define	PM8058_NFC_RESERVED2		0x18
-#define	PM8058_NFC_VDDLDO_OK_S		0x04
-#define	PM8058_NFC_MBG_EN_S		0x02
-#define	PM8058_NFC_EXT_EN_S		0x01
-
-struct pm8058_nfc_device {
-	struct mutex		nfc_mutex;
-	struct pm8058_chip	*pm_chip;
-#if defined(CONFIG_DEBUG_FS)
-	struct dentry 		*dent;
-#endif
-};
-static struct pm8058_nfc_device	*nfc_dev;
-
-/* APIs */
-/*
- * pm8058_nfc_request - request a handle to access NFC device
- */
-struct pm8058_nfc_device *pm8058_nfc_request(void)
-{
-	return nfc_dev;
-}
-EXPORT_SYMBOL(pm8058_nfc_request);
-
-/*
- * pm8058_nfc_config - configure NFC signals
- *
- * @nfcdev: the NFC device
- * @mask: signal mask to configure
- * @flags: control flags
- */
-int pm8058_nfc_config(struct pm8058_nfc_device *nfcdev, u32 mask, u32 flags)
-{
-	u8	nfc_ctrl, nfc_test, m, f;
-	int	rc;
-
-	if (nfcdev == NULL || IS_ERR(nfcdev) || !mask)
-		return -EINVAL;
-	if (nfcdev->pm_chip == NULL)
-		return -ENODEV;
-
-	mutex_lock(&nfcdev->nfc_mutex);
-
-	if (!(mask & PM_NFC_CTRL_REQ))
-		goto config_test;
-
-	rc = pm8058_read(nfcdev->pm_chip, SSBI_REG_NFC_CTRL, &nfc_ctrl, 1);
-	if (rc) {
-		pr_err("%s: FAIL pm8058_read(): rc=%d (nfc_ctrl=0x%x)\n",
-		       __func__, rc, nfc_ctrl);
-		goto config_done;
-	}
-
-	m = mask & 0x00ff;
-	f = flags & 0x00ff;
-	nfc_ctrl &= ~m;
-	nfc_ctrl |= m & f;
-
-	rc = pm8058_write(nfcdev->pm_chip, SSBI_REG_NFC_CTRL, &nfc_ctrl, 1);
-	if (rc) {
-		pr_err("%s: FAIL pm8058_write(): rc=%d (nfc_ctrl=0x%x)\n",
-		       __func__, rc, nfc_ctrl);
-		goto config_done;
-	}
-
-config_test:
-	if (!(mask & PM_NFC_TEST_REQ))
-		goto config_done;
-
-	rc = pm8058_read(nfcdev->pm_chip, SSBI_REG_NFC_TEST, &nfc_test, 1);
-	if (rc) {
-		pr_err("%s: FAIL pm8058_read(): rc=%d (nfc_test=0x%x)\n",
-		       __func__, rc, nfc_test);
-		goto config_done;
-	}
-
-	m = (mask >> 8) & 0x00ff;
-	f = (flags >> 8) & 0x00ff;
-	nfc_test &= ~m;
-	nfc_test |= m & f;
-
-	rc = pm8058_write(nfcdev->pm_chip, SSBI_REG_NFC_TEST, &nfc_test, 1);
-	if (rc) {
-		pr_err("%s: FAIL pm8058_write(): rc=%d (nfc_test=0x%x)\n",
-		       __func__, rc, nfc_test);
-		goto config_done;
-	}
-
-config_done:
-	mutex_unlock(&nfcdev->nfc_mutex);
-	return 0;
-}
-EXPORT_SYMBOL(pm8058_nfc_config);
-
-/*
- * pm8058_nfc_get_status - get NFC status
- *
- * @nfcdev: the NFC device
- * @mask: of status mask to read
- * @status: pointer to the status variable
- */
-int pm8058_nfc_get_status(struct pm8058_nfc_device *nfcdev,
-			  u32 mask, u32 *status)
-{
-	u8	nfc_ctrl, nfc_test;
-	u32	st;
-	int	rc;
-
-	if (nfcdev == NULL || IS_ERR(nfcdev) || status == NULL)
-		return -EINVAL;
-	if (nfcdev->pm_chip == NULL)
-		return -ENODEV;
-
-	st = 0;
-	mutex_lock(&nfcdev->nfc_mutex);
-
-	if (!(mask & PM_NFC_CTRL_REQ))
-		goto read_test;
-
-	rc = pm8058_read(nfcdev->pm_chip, SSBI_REG_NFC_CTRL, &nfc_ctrl, 1);
-	if (rc) {
-		pr_err("%s: FAIL pm8058_read(): rc=%d (nfc_ctrl=0x%x)\n",
-		       __func__, rc, nfc_ctrl);
-		goto get_status_done;
-	}
-
-read_test:
-	if (!(mask & (PM_NFC_TEST_REQ | PM_NFC_TEST_STATUS)))
-		goto get_status_done;
-
-	rc = pm8058_read(nfcdev->pm_chip, SSBI_REG_NFC_TEST, &nfc_test, 1);
-	if (rc)
-		pr_err("%s: FAIL pm8058_read(): rc=%d (nfc_test=0x%x)\n",
-		       __func__, rc, nfc_test);
-
-get_status_done:
-	st = nfc_ctrl;
-	st |= nfc_test << 8;
-	*status = st;
-
-	mutex_unlock(&nfcdev->nfc_mutex);
-	return 0;
-}
-EXPORT_SYMBOL(pm8058_nfc_get_status);
-
-/*
- * pm8058_nfc_free - free the NFC device
- */
-void pm8058_nfc_free(struct pm8058_nfc_device *nfcdev)
-{
-	/* Disable all signals */
-	pm8058_nfc_config(nfcdev, PM_NFC_CTRL_REQ, 0);
-}
-EXPORT_SYMBOL(pm8058_nfc_free);
-
-#if defined(CONFIG_DEBUG_FS)
-static int pm8058_nfc_debug_set(void *data, u64 val)
-{
-	struct pm8058_nfc_device *nfcdev;
-	u32	mask, control;
-	int	rc;
-
-	nfcdev = (struct pm8058_nfc_device *)data;
-	control = (u32)val & 0xffff;
-	mask = ((u32)val >> 16) & 0xffff;
-	rc = pm8058_nfc_config(nfcdev, mask, control);
-	if (rc)
-		pr_err("%s: ERR pm8058_nfc_config: rc=%d, "
-		       "[mask, control]=[0x%x, 0x%x]\n",
-		       __func__, rc, mask, control);
-
-	return 0;
-}
-
-static int pm8058_nfc_debug_get(void *data, u64 *val)
-{
-	struct pm8058_nfc_device *nfcdev;
-	u32	status;
-	int	rc;
-
-	nfcdev = (struct pm8058_nfc_device *)data;
-	rc = pm8058_nfc_get_status(nfcdev, (u32)-1, &status);
-	if (rc)
-		pr_err("%s: ERR pm8058_nfc_get_status: rc=%d, status=0x%x\n",
-		       __func__, rc, status);
-
-	if (val)
-		*val = (u64)status;
-	return 0;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(pm8058_nfc_fops, pm8058_nfc_debug_get,
-			pm8058_nfc_debug_set, "%llu\n");
-
-static int pm8058_nfc_debug_init(struct pm8058_nfc_device *nfcdev)
-{
-	struct dentry *dent;
-
-	dent = debugfs_create_file("pm8058-nfc", 0644, NULL,
-				   (void *)nfcdev, &pm8058_nfc_fops);
-
-	if (dent == NULL || IS_ERR(dent))
-		pr_err("%s: ERR debugfs_create_file: dent=0x%x\n",
-		       __func__, (unsigned)dent);
-
-	nfcdev->dent = dent;
-	return 0;
-}
-#endif
-
-static int __devinit pmic8058_nfc_probe(struct platform_device *pdev)
-{
-	struct pm8058_chip		*pm_chip;
-	struct pm8058_nfc_device	*nfcdev;
-
-	pm_chip = dev_get_drvdata(pdev->dev.parent);
-	if (pm_chip == NULL) {
-		pr_err("%s: no parent data passed in.\n", __func__);
-		return -EFAULT;
-	}
-
-	nfcdev = kzalloc(sizeof *nfcdev, GFP_KERNEL);
-	if (nfcdev == NULL) {
-		pr_err("%s: kzalloc() failed.\n", __func__);
-		return -ENOMEM;
-	}
-
-	mutex_init(&nfcdev->nfc_mutex);
-
-	nfcdev->pm_chip = pm_chip;
-	nfc_dev = nfcdev;
-	platform_set_drvdata(pdev, nfcdev);
-
-#if defined(CONFIG_DEBUG_FS)
-	pm8058_nfc_debug_init(nfc_dev);
-#endif
-
-	pr_notice("%s: OK\n", __func__);
-	return 0;
-}
-
-static int __devexit pmic8058_nfc_remove(struct platform_device *pdev)
-{
-	struct pm8058_nfc_device *nfcdev = platform_get_drvdata(pdev);
-
-#if defined(CONFIG_DEBUG_FS)
-	debugfs_remove(nfcdev->dent);
-#endif
-
-	platform_set_drvdata(pdev, nfcdev->pm_chip);
-	kfree(nfcdev);
-	return 0;
-}
-
-static struct platform_driver pmic8058_nfc_driver = {
-	.probe		= pmic8058_nfc_probe,
-	.remove		= __devexit_p(pmic8058_nfc_remove),
-	.driver		= {
-		.name = "pm8058-nfc",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init pm8058_nfc_init(void)
-{
-	return platform_driver_register(&pmic8058_nfc_driver);
-}
-
-static void __exit pm8058_nfc_exit(void)
-{
-	platform_driver_unregister(&pmic8058_nfc_driver);
-}
-
-module_init(pm8058_nfc_init);
-module_exit(pm8058_nfc_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("PMIC8058 NFC driver");
-MODULE_VERSION("1.0");
-MODULE_ALIAS("platform:pmic8058-nfc");
diff --git a/drivers/misc/pmic8058-pwm.c b/drivers/misc/pmic8058-pwm.c
index ad03b88..33407b7 100644
--- a/drivers/misc/pmic8058-pwm.c
+++ b/drivers/misc/pmic8058-pwm.c
@@ -19,11 +19,11 @@
 
 #include <linux/module.h>
 #include <linux/platform_device.h>
+#include <linux/slab.h>
 #include <linux/err.h>
 #include <linux/pwm.h>
-#include <linux/mfd/pmic8058.h>
+#include <linux/mfd/pm8xxx/core.h>
 #include <linux/pmic8058-pwm.h>
-#include <linux/slab.h>
 
 #define	PM8058_LPG_BANKS		8
 #define	PM8058_PWM_CHANNELS		PM8058_LPG_BANKS	/* MAX=8 */
@@ -179,6 +179,7 @@
 struct pm8058_pwm_chip;
 
 struct pwm_device {
+	struct device		*dev;
 	int			pwm_id;		/* = bank/channel id */
 	int			in_use;
 	const char		*label;
@@ -188,14 +189,13 @@
 	int			use_lut;	/* Use LUT to output PWM */
 	u8			pwm_ctl[PM8058_LPG_CTL_REGS];
 	int			irq;
-	struct pm8058_pwm_chip	*chip;
+	struct pm8058_pwm_chip  *chip;
 };
 
 struct pm8058_pwm_chip {
 	struct pwm_device	pwm_dev[PM8058_PWM_CHANNELS];
 	u8			bank_mask;
 	struct mutex		pwm_mutex;
-	struct pm8058_chip	*pm_chip;
 	struct pm8058_pwm_pdata	*pdata;
 };
 
@@ -244,9 +244,10 @@
 	else
 		reg = chip->bank_mask & ~(1 << pwm->pwm_id);
 
-	rc = pm8058_write(chip->pm_chip, SSBI_REG_ADDR_LPG_BANK_EN, &reg, 1);
+	rc = pm8xxx_writeb(pwm->dev->parent,
+				SSBI_REG_ADDR_LPG_BANK_EN, reg);
 	if (rc) {
-		pr_err("pm8058_write(): rc=%d (Enable LPG Bank)\n", rc);
+		pr_err("pm8xxx_write(): rc=%d (Enable LPG Bank)\n", rc);
 		goto bail_out;
 	}
 	chip->bank_mask = reg;
@@ -261,10 +262,10 @@
 	u8	reg;
 
 	reg = pwm->pwm_id;
-	rc = pm8058_write(pwm->chip->pm_chip, SSBI_REG_ADDR_LPG_BANK_SEL,
-			     &reg, 1);
+	rc = pm8xxx_writeb(pwm->dev->parent,
+			SSBI_REG_ADDR_LPG_BANK_SEL, reg);
 	if (rc)
-		pr_err("pm8058_write(): rc=%d (Select PWM Bank)\n", rc);
+		pr_err("pm8xxx_write(): rc=%d (Select PWM Bank)\n", rc);
 	return rc;
 }
 
@@ -284,10 +285,10 @@
 		reg &= ~PM8058_PWM_RAMP_GEN_START;
 	}
 
-	rc = pm8058_write(pwm->chip->pm_chip, SSBI_REG_ADDR_LPG_CTL(0),
-			  &reg, 1);
+	rc = pm8xxx_writeb(pwm->dev->parent, SSBI_REG_ADDR_LPG_CTL(0),
+									reg);
 	if (rc)
-		pr_err("pm8058_write(): rc=%d (Enable PWM Ctl 0)\n", rc);
+		pr_err("pm8xxx_write(): rc=%d (Enable PWM Ctl 0)\n", rc);
 	else
 		pwm->pwm_ctl[0] = reg;
 	return rc;
@@ -415,15 +416,13 @@
 		cfg1 = (pwm_value >> 1) & 0x80;
 		cfg1 |= start_idx + i;
 
-		rc = pm8058_write(pwm->chip->pm_chip,
-			     SSBI_REG_ADDR_LPG_LUT_CFG0,
-			     &cfg0, 1);
+		rc = pm8xxx_writeb(pwm->dev->parent,
+			     SSBI_REG_ADDR_LPG_LUT_CFG0, cfg0);
 		if (rc)
 			break;
 
-		rc = pm8058_write(pwm->chip->pm_chip,
-			     SSBI_REG_ADDR_LPG_LUT_CFG1,
-			     &cfg1, 1);
+		rc = pm8xxx_writeb(pwm->dev->parent,
+			     SSBI_REG_ADDR_LPG_LUT_CFG1, cfg1);
 		if (rc)
 			break;
 	}
@@ -539,11 +538,11 @@
 
 	/* Write in reverse way so 0 would be the last */
 	for (i = end - 1; i >= start; i--) {
-		rc = pm8058_write(pwm->chip->pm_chip,
+		rc = pm8xxx_writeb(pwm->dev->parent,
 				  SSBI_REG_ADDR_LPG_CTL(i),
-				  &pwm->pwm_ctl[i], 1);
+				  pwm->pwm_ctl[i]);
 		if (rc) {
-			pr_err("pm8058_write(): rc=%d (PWM Ctl[%d])\n", rc, i);
+			pr_err("pm8xxx_write(): rc=%d (PWM Ctl[%d])\n", rc, i);
 			return rc;
 		}
 	}
@@ -957,8 +956,8 @@
 	case PM_PWM_LED_2:
 		conf = mode & PM8058_LED_MODE_MASK;
 		conf |= (max_current / 2) << PM8058_LED_CURRENT_SHIFT;
-		rc = pm8058_write(pwm->chip->pm_chip,
-				  SSBI_REG_ADDR_LED(id), &conf, 1);
+		rc = pm8xxx_writeb(pwm->dev->parent,
+				  SSBI_REG_ADDR_LED(id), conf);
 		break;
 
 	case PM_PWM_LED_KPD:
@@ -982,8 +981,8 @@
 		}
 		conf |= (max_current / 20) << PM8058_FLASH_CURRENT_SHIFT;
 		id -= PM_PWM_LED_KPD;
-		rc = pm8058_write(pwm->chip->pm_chip,
-				  SSBI_REG_ADDR_FLASH(id), &conf, 1);
+		rc = pm8xxx_writeb(pwm->dev->parent,
+				  SSBI_REG_ADDR_FLASH(id), conf);
 		break;
 	default:
 		rc = -EINVAL;
@@ -1012,10 +1011,10 @@
 			/* Only Test 1 available */
 			reg |= (1 << PM8058_PWM_DTEST_SHIFT) &
 				PM8058_PWM_DTEST_MASK;
-		rc = pm8058_write(pwm->chip->pm_chip, SSBI_REG_ADDR_LPG_TEST,
-				  &reg, 1);
+		rc = pm8xxx_writeb(pwm->dev->parent,
+			SSBI_REG_ADDR_LPG_TEST, reg);
 		if (rc)
-			pr_err("pm8058_write(DTEST=0x%x): rc=%d\n", reg, rc);
+			pr_err("pm8xxx_write(DTEST=0x%x): rc=%d\n", reg, rc);
 
 	}
 	return rc;
@@ -1024,16 +1023,9 @@
 
 static int __devinit pmic8058_pwm_probe(struct platform_device *pdev)
 {
-	struct pm8058_chip	*pm_chip;
 	struct pm8058_pwm_chip	*chip;
 	int	i;
 
-	pm_chip = dev_get_drvdata(pdev->dev.parent);
-	if (pm_chip == NULL) {
-		pr_err("no parent data passed in.\n");
-		return -EFAULT;
-	}
-
 	chip = kzalloc(sizeof *chip, GFP_KERNEL);
 	if (chip == NULL) {
 		pr_err("kzalloc() failed.\n");
@@ -1043,12 +1035,12 @@
 	for (i = 0; i < PM8058_PWM_CHANNELS; i++) {
 		chip->pwm_dev[i].pwm_id = i;
 		chip->pwm_dev[i].chip = chip;
+		chip->pwm_dev[i].dev = &pdev->dev;
 	}
 
 	mutex_init(&chip->pwm_mutex);
 
 	chip->pdata = pdev->dev.platform_data;
-	chip->pm_chip = pm_chip;
 	pwm_chip = chip;
 	platform_set_drvdata(pdev, chip);
 
diff --git a/drivers/misc/pmic8058-upl.c b/drivers/misc/pmic8058-upl.c
deleted file mode 100644
index ae0abd8..0000000
--- a/drivers/misc/pmic8058-upl.c
+++ /dev/null
@@ -1,363 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-/*
- * Qualcomm PMIC8058 UPL driver
- *
- */
-
-#include <linux/module.h>
-#include <linux/platform_device.h>
-#include <linux/err.h>
-#include <linux/mfd/pmic8058.h>
-#include <linux/pmic8058-upl.h>
-#include <linux/debugfs.h>
-#include <linux/slab.h>
-
-/* PMIC8058 UPL registers */
-#define	SSBI_REG_UPL_CTRL		0x17B
-#define	SSBI_REG_UPL_TRUTHTABLE1	0x17C
-#define	SSBI_REG_UPL_TRUTHTABLE2	0x17D
-
-struct pm8058_upl_device {
-	struct mutex		upl_mutex;
-	struct pm8058_chip	*pm_chip;
-#if defined(CONFIG_DEBUG_FS)
-	struct dentry		*dent;
-#endif
-};
-static struct pm8058_upl_device *upl_dev;
-
-/* APIs */
-
-/*
- * pm8058_upl_request - request a handle to access UPL device
- */
-struct pm8058_upl_device *pm8058_upl_request(void)
-{
-	return upl_dev;
-}
-EXPORT_SYMBOL(pm8058_upl_request);
-
-/*
- * pm8058_upl_read_truthtable - read value currently stored in UPL truth table
- *
- * @upldev: the UPL device
- * @truthtable: value read from UPL truth table
- */
-int pm8058_upl_read_truthtable(struct pm8058_upl_device *upldev,
-				u16 *truthtable)
-{
-	int rc = 0;
-	u8 table[2];
-
-	if (upldev == NULL || IS_ERR(upldev))
-		return -EINVAL;
-	if (upldev->pm_chip == NULL)
-		return -ENODEV;
-
-	mutex_lock(&upldev->upl_mutex);
-
-	rc = pm8058_read(upldev->pm_chip, SSBI_REG_UPL_TRUTHTABLE1,
-			&(table[0]), 1);
-	if (rc) {
-		pr_err("%s: FAIL pm8058_read(0x%X)=0x%02X: rc=%d\n",
-			__func__, SSBI_REG_UPL_TRUTHTABLE1, table[0], rc);
-		goto upl_read_done;
-	}
-
-	rc = pm8058_read(upldev->pm_chip, SSBI_REG_UPL_TRUTHTABLE2,
-			&(table[1]), 1);
-	if (rc)
-		pr_err("%s: FAIL pm8058_read(0x%X)=0x%02X: rc=%d\n",
-			__func__, SSBI_REG_UPL_TRUTHTABLE2, table[1], rc);
-upl_read_done:
-	mutex_unlock(&upldev->upl_mutex);
-	*truthtable = (((u16)table[1]) << 8) | table[0];
-	return rc;
-}
-EXPORT_SYMBOL(pm8058_upl_read_truthtable);
-
-/*
- * pm8058_upl_writes_truthtable - write value into UPL truth table
- *
- * @upldev: the UPL device
- * @truthtable: value written to UPL truth table
- *
- * Each bit in parameter "truthtable" corresponds to the UPL output for a given
- * set of input pin values. For example, if the input pins have the following
- * values: A=1, B=1, C=1, D=0, then the UPL would output the value of bit 14
- * (0b1110) in parameter "truthtable".
- */
-int pm8058_upl_write_truthtable(struct pm8058_upl_device *upldev,
-				u16 truthtable)
-{
-	int rc = 0;
-	u8 table[2];
-
-	if (upldev == NULL || IS_ERR(upldev))
-		return -EINVAL;
-	if (upldev->pm_chip == NULL)
-		return -ENODEV;
-
-	table[0] = truthtable & 0xFF;
-	table[1] = (truthtable >> 8) & 0xFF;
-
-	mutex_lock(&upldev->upl_mutex);
-
-	rc = pm8058_write(upldev->pm_chip, SSBI_REG_UPL_TRUTHTABLE1,
-				&(table[0]), 1);
-	if (rc) {
-		pr_err("%s: FAIL pm8058_write(0x%X)=0x%04X: rc=%d\n",
-			__func__, SSBI_REG_UPL_TRUTHTABLE1, table[0], rc);
-		goto upl_write_done;
-	}
-
-	rc = pm8058_write(upldev->pm_chip, SSBI_REG_UPL_TRUTHTABLE2,
-				&(table[1]), 1);
-	if (rc)
-		pr_err("%s: FAIL pm8058_write(0x%X)=0x%04X: rc=%d\n",
-			__func__, SSBI_REG_UPL_TRUTHTABLE2, table[1], rc);
-upl_write_done:
-	mutex_unlock(&upldev->upl_mutex);
-	return rc;
-}
-EXPORT_SYMBOL(pm8058_upl_write_truthtable);
-
-/*
- * pm8058_upl_config - configure UPL I/O settings and UPL enable/disable
- *
- * @upldev: the UPL device
- * @mask: setting mask to configure
- * @flags: setting flags
- */
-int pm8058_upl_config(struct pm8058_upl_device *upldev, u32 mask, u32 flags)
-{
-	int rc;
-	u8 upl_ctrl, m, f;
-
-	if (upldev == NULL || IS_ERR(upldev))
-		return -EINVAL;
-	if (upldev->pm_chip == NULL)
-		return -ENODEV;
-
-	mutex_lock(&upldev->upl_mutex);
-
-	rc = pm8058_read(upldev->pm_chip, SSBI_REG_UPL_CTRL, &upl_ctrl, 1);
-	if (rc) {
-		pr_err("%s: FAIL pm8058_read(0x%X)=0x%02X: rc=%d\n",
-			__func__, SSBI_REG_UPL_CTRL, upl_ctrl, rc);
-		goto upl_config_done;
-	}
-
-	m = mask & 0x00ff;
-	f = flags & 0x00ff;
-	upl_ctrl &= ~m;
-	upl_ctrl |= m & f;
-
-	rc = pm8058_write(upldev->pm_chip, SSBI_REG_UPL_CTRL, &upl_ctrl, 1);
-	if (rc)
-		pr_err("%s: FAIL pm8058_write(0x%X)=0x%02X: rc=%d\n",
-			__func__, SSBI_REG_UPL_CTRL, upl_ctrl, rc);
-upl_config_done:
-	mutex_unlock(&upldev->upl_mutex);
-	return rc;
-}
-EXPORT_SYMBOL(pm8058_upl_config);
-
-#if defined(CONFIG_DEBUG_FS)
-
-static int truthtable_set(void *data, u64 val)
-{
-	int rc;
-
-	rc = pm8058_upl_write_truthtable(data, val);
-	if (rc)
-		pr_err("%s: pm8058_upl_write_truthtable: rc=%d, "
-			"truthtable=0x%llX\n", __func__, rc, val);
-	return rc;
-}
-
-static int truthtable_get(void *data, u64 *val)
-{
-	int rc;
-	u16 truthtable;
-
-	rc = pm8058_upl_read_truthtable(data, &truthtable);
-	if (rc)
-		pr_err("%s: pm8058_upl_read_truthtable: rc=%d, "
-			"truthtable=0x%X\n", __func__, rc, truthtable);
-	if (val)
-		*val = truthtable;
-
-	return rc;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(upl_truthtable_fops, truthtable_get,
-			truthtable_set, "0x%04llX\n");
-
-/* enter values as 0xMMMMFFFF where MMMM is the mask and FFFF is the flags */
-static int control_set(void *data, u64 val)
-{
-	u8 mask, flags;
-	int rc;
-
-	flags = val & 0xFFFF;
-	mask = (val >> 16) & 0xFFFF;
-
-	rc = pm8058_upl_config(data, mask, flags);
-	if (rc)
-		pr_err("%s: pm8058_upl_config: rc=%d, mask = 0x%X, "
-			"flags = 0x%X\n", __func__, rc, mask, flags);
-	return rc;
-}
-
-static int control_get(void *data, u64 *val)
-{
-	struct pm8058_upl_device *upldev;
-	int rc = 0;
-	u8 ctrl;
-
-	upldev = data;
-
-	mutex_lock(&upldev->upl_mutex);
-
-	rc = pm8058_read(upldev->pm_chip, SSBI_REG_UPL_CTRL, &ctrl, 1);
-	if (rc)
-		pr_err("%s: FAIL pm8058_read(): rc=%d (ctrl=0x%02X)\n",
-		       __func__, rc, ctrl);
-
-	mutex_unlock(&upldev->upl_mutex);
-
-	*val = ctrl;
-
-	return rc;
-}
-
-DEFINE_SIMPLE_ATTRIBUTE(upl_control_fops, control_get,
-			control_set, "0x%02llX\n");
-
-static int pm8058_upl_debug_init(struct pm8058_upl_device *upldev)
-{
-	struct dentry *dent;
-	struct dentry *temp;
-
-	dent = debugfs_create_dir("pm8058-upl", NULL);
-	if (dent == NULL || IS_ERR(dent)) {
-		pr_err("%s: ERR debugfs_create_dir: dent=0x%X\n",
-					__func__, (unsigned)dent);
-		return -ENOMEM;
-	}
-
-	temp = debugfs_create_file("truthtable", S_IRUSR | S_IWUSR, dent,
-					upldev, &upl_truthtable_fops);
-	if (temp == NULL || IS_ERR(temp)) {
-		pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
-					__func__, (unsigned)dent);
-		goto debug_error;
-	}
-
-	temp = debugfs_create_file("control", S_IRUSR | S_IWUSR, dent,
-					upldev, &upl_control_fops);
-	if (temp == NULL || IS_ERR(temp)) {
-		pr_err("%s: ERR debugfs_create_file: dent=0x%X\n",
-					__func__, (unsigned)dent);
-		goto debug_error;
-	}
-
-	upldev->dent = dent;
-	return 0;
-
-debug_error:
-	debugfs_remove_recursive(dent);
-	return -ENOMEM;
-}
-
-static int __devexit pm8058_upl_debug_remove(struct pm8058_upl_device *upldev)
-{
-	debugfs_remove_recursive(upldev->dent);
-	return 0;
-}
-
-#endif /* CONFIG_DEBUG_FS */
-
-static int __devinit pmic8058_upl_probe(struct platform_device *pdev)
-{
-	struct pm8058_chip		*pm_chip;
-	struct pm8058_upl_device	*upldev;
-
-	pm_chip = dev_get_drvdata(pdev->dev.parent);
-	if (pm_chip == NULL) {
-		pr_err("%s: no parent data passed in.\n", __func__);
-		return -EFAULT;
-	}
-
-	upldev = kzalloc(sizeof *upldev, GFP_KERNEL);
-	if (upldev == NULL) {
-		pr_err("%s: kzalloc() failed.\n", __func__);
-		return -ENOMEM;
-	}
-
-	mutex_init(&upldev->upl_mutex);
-
-	upldev->pm_chip = pm_chip;
-	upl_dev = upldev;
-	platform_set_drvdata(pdev, upldev);
-
-#if defined(CONFIG_DEBUG_FS)
-	pm8058_upl_debug_init(upl_dev);
-#endif
-	pr_notice("%s: OK\n", __func__);
-	return 0;
-}
-
-static int __devexit pmic8058_upl_remove(struct platform_device *pdev)
-{
-	struct pm8058_upl_device *upldev = platform_get_drvdata(pdev);
-
-#if defined(CONFIG_DEBUG_FS)
-	pm8058_upl_debug_remove(upldev);
-#endif
-
-	platform_set_drvdata(pdev, upldev->pm_chip);
-	kfree(upldev);
-	pr_notice("%s: OK\n", __func__);
-
-	return 0;
-}
-
-static struct platform_driver pmic8058_upl_driver = {
-	.probe		= pmic8058_upl_probe,
-	.remove		= __devexit_p(pmic8058_upl_remove),
-	.driver		= {
-		.name = "pm8058-upl",
-		.owner = THIS_MODULE,
-	},
-};
-
-static int __init pm8058_upl_init(void)
-{
-	return platform_driver_register(&pmic8058_upl_driver);
-}
-
-static void __exit pm8058_upl_exit(void)
-{
-	platform_driver_unregister(&pmic8058_upl_driver);
-}
-
-module_init(pm8058_upl_init);
-module_exit(pm8058_upl_exit);
-
-MODULE_LICENSE("GPL v2");
-MODULE_DESCRIPTION("PMIC8058 UPL driver");
-MODULE_VERSION("1.0");
-MODULE_ALIAS("platform:pmic8058-upl");
diff --git a/drivers/misc/pmic8058-xoadc.c b/drivers/misc/pmic8058-xoadc.c
index b63800c..14b790f 100644
--- a/drivers/misc/pmic8058-xoadc.c
+++ b/drivers/misc/pmic8058-xoadc.c
@@ -17,7 +17,7 @@
 #include <linux/platform_device.h>
 #include <linux/err.h>
 #include <linux/msm_adc.h>
-#include <linux/pmic8058-xoadc.h>
+#include <linux/mfd/pm8xxx/core.h>
 #include <linux/mfd/pmic8058.h>
 #include <linux/interrupt.h>
 #include <linux/slab.h>
@@ -54,8 +54,8 @@
 #define ADC_ARB_USRP_DATA1                      0x19C
 
 struct pmic8058_adc {
+	struct device *dev;
 	struct xoadc_platform_data *pdata;
-	struct pm8058_chip *pm_chip;
 	struct adc_properties *adc_prop;
 	struct xoadc_conv_state	conv[2];
 	int xoadc_queue_count;
@@ -144,8 +144,8 @@
 	/* Write twice to the CNTRL register for the arbiter settings
 	   to take into effect */
 	for (i = 0; i < 2; i++) {
-		rc = pm8058_write(adc_pmic->pm_chip, ADC_ARB_USRP_CNTRL,
-					&data_arb_cntrl, 1);
+		rc = pm8xxx_writeb(adc_pmic->dev->parent, ADC_ARB_USRP_CNTRL,
+							data_arb_cntrl);
 		if (rc < 0) {
 			pr_debug("%s: PM8058 write failed\n", __func__);
 			return rc;
@@ -165,8 +165,8 @@
 {
 
 	struct pmic8058_adc *adc_pmic = pmic_adc[adc_instance];
-	u8 data_arb_cntrl, data_amux_chan, data_arb_rsv, data_ana_param;
-	u8 data_dig_param, data_ana_param2;
+	u8 data_arb_cntrl = 0, data_amux_chan = 0, data_arb_rsv = 0;
+	u8 data_dig_param = 0, data_ana_param2 = 0, data_ana_param = 0;
 	int rc;
 
 	rc = pm8058_xoadc_arb_cntrl(1, adc_instance, slot->chan_path);
@@ -307,15 +307,15 @@
 		break;
 	}
 
-	rc = pm8058_write(adc_pmic->pm_chip,
-			ADC_ARB_USRP_AMUX_CNTRL, &data_amux_chan, 1);
+	rc = pm8xxx_writeb(adc_pmic->dev->parent,
+			ADC_ARB_USRP_AMUX_CNTRL, data_amux_chan);
 	if (rc < 0) {
 		pr_debug("%s: PM8058 write failed\n", __func__);
 		return rc;
 	}
 
-	rc = pm8058_write(adc_pmic->pm_chip,
-			ADC_ARB_USRP_RSV, &data_arb_rsv, 1);
+	rc = pm8xxx_writeb(adc_pmic->dev->parent,
+			ADC_ARB_USRP_RSV, data_arb_rsv);
 	if (rc < 0) {
 		pr_debug("%s: PM8058 write failed\n", __func__);
 		return rc;
@@ -341,22 +341,22 @@
 		break;
 	}
 
-	rc = pm8058_write(adc_pmic->pm_chip,
-				ADC_ARB_USRP_ANA_PARAM, &data_ana_param, 1);
+	rc = pm8xxx_writeb(adc_pmic->dev->parent,
+				ADC_ARB_USRP_ANA_PARAM, data_ana_param);
 	if (rc < 0) {
 		pr_debug("%s: PM8058 write failed\n", __func__);
 		return rc;
 	}
 
-	rc = pm8058_write(adc_pmic->pm_chip,
-				ADC_ARB_USRP_DIG_PARAM, &data_dig_param, 1);
+	rc = pm8xxx_writeb(adc_pmic->dev->parent,
+			ADC_ARB_USRP_DIG_PARAM, data_dig_param);
 	if (rc < 0) {
 		pr_debug("%s: PM8058 write failed\n", __func__);
 		return rc;
 	}
 
-	rc = pm8058_write(adc_pmic->pm_chip,
-				ADC_ARB_USRP_ANA_PARAM, &data_ana_param2, 1);
+	rc = pm8xxx_writeb(adc_pmic->dev->parent,
+			ADC_ARB_USRP_ANA_PARAM, data_ana_param2);
 	if (rc < 0) {
 		pr_debug("%s: PM8058 write failed\n", __func__);
 		return rc;
@@ -364,8 +364,8 @@
 
 	enable_irq(adc_pmic->adc_irq);
 
-	rc = pm8058_write(adc_pmic->pm_chip,
-				ADC_ARB_USRP_CNTRL, &data_arb_cntrl, 1);
+	rc = pm8xxx_writeb(adc_pmic->dev->parent,
+				ADC_ARB_USRP_CNTRL, data_arb_cntrl);
 	if (rc < 0) {
 		pr_debug("%s: PM8058 write failed\n", __func__);
 		return rc;
@@ -434,13 +434,15 @@
 	if (!xoadc_initialized)
 		return -ENODEV;
 
-	rc = pm8058_read(adc_pmic->pm_chip, ADC_ARB_USRP_DATA0, &rslt_lsb, 1);
+	rc = pm8xxx_readb(adc_pmic->dev->parent, ADC_ARB_USRP_DATA0,
+							&rslt_lsb);
 	if (rc < 0) {
 		pr_debug("%s: PM8058 read failed\n", __func__);
 		return rc;
 	}
 
-	rc = pm8058_read(adc_pmic->pm_chip, ADC_ARB_USRP_DATA1, &rslt_msb, 1);
+	rc = pm8xxx_readb(adc_pmic->dev->parent, ADC_ARB_USRP_DATA1,
+							&rslt_msb);
 	if (rc < 0) {
 		pr_debug("%s: PM8058 read failed\n", __func__);
 		return rc;
@@ -657,7 +659,7 @@
 
 	wake_lock_destroy(&adc_pmic->adc_wakelock);
 	msm_xo_put(adc_pmic->adc_voter);
-	platform_set_drvdata(pdev, adc_pmic->pm_chip);
+	platform_set_drvdata(pdev, NULL);
 	device_init_wakeup(&pdev->dev, 0);
 	kfree(adc_pmic);
 	xoadc_initialized = false;
@@ -668,16 +670,9 @@
 static int __devinit pm8058_xoadc_probe(struct platform_device *pdev)
 {
 	struct xoadc_platform_data *pdata = pdev->dev.platform_data;
-	struct pm8058_chip *pm_chip;
 	struct pmic8058_adc *adc_pmic;
 	int i, rc = 0;
 
-	pm_chip = dev_get_drvdata(pdev->dev.parent);
-	if (pm_chip == NULL) {
-		dev_err(&pdev->dev, "no parent data passed in\n");
-		return -EFAULT;
-	}
-
 	if (!pdata) {
 		dev_err(&pdev->dev, "no platform data?\n");
 		return -EINVAL;
@@ -689,7 +684,7 @@
 		return -ENOMEM;
 	}
 
-	adc_pmic->pm_chip = pm_chip;
+	adc_pmic->dev = &pdev->dev;
 	adc_pmic->adc_prop = pdata->xoadc_prop;
 	adc_pmic->xoadc_num = pdata->xoadc_num;
 	adc_pmic->xoadc_queue_count = 0;
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index cca1035..3590e6d 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -244,7 +244,7 @@
 
 config BATTERY_MSM8X60
 	tristate "MSM8X60 battery"
-	select PMIC8058_BATTALARM
+	select PMIC8XXX_BATTALARM
 	help
 	  Some MSM boards have dual charging paths to charge the battery.
 	  Say Y to enable support for the battery charging in
diff --git a/drivers/power/pmic8058-charger.c b/drivers/power/pmic8058-charger.c
index a3ce54d..70b5d59 100644
--- a/drivers/power/pmic8058-charger.c
+++ b/drivers/power/pmic8058-charger.c
@@ -15,7 +15,6 @@
 #include <linux/moduleparam.h>
 #include <linux/platform_device.h>
 #include <linux/errno.h>
-#include <linux/mfd/pmic8058.h>
 #include <linux/interrupt.h>
 #include <linux/delay.h>
 #include <linux/bitops.h>
@@ -25,8 +24,10 @@
 #include <linux/slab.h>
 #include <linux/msm_adc.h>
 #include <linux/notifier.h>
-#include <linux/pmic8058-batt-alarm.h>
+#include <linux/mfd/pm8xxx/core.h>
+#include <linux/mfd/pmic8058.h>
 #include <linux/pmic8058-charger.h>
+#include <linux/mfd/pm8xxx/batt-alarm.h>
 
 #include <mach/msm_xo.h>
 #include <mach/msm_hsusb.h>
@@ -177,7 +178,6 @@
 
 struct pm8058_charger {
 	struct pmic_charger_pdata *pdata;
-	struct pm8058_chip *pm_chip;
 	struct device *dev;
 
 	int pmic_chg_irq[PMIC_CHG_MAX_INTS];
@@ -228,7 +228,11 @@
 	if (rc)
 		goto out;
 
-	rc = pm8058_batt_alarm_threshold_set(resume_mv, 4300);
+	rc = pm8xxx_batt_alarm_threshold_set(
+			PM8XXX_BATT_ALARM_LOWER_COMPARATOR, resume_mv);
+	if (!rc)
+		rc = pm8xxx_batt_alarm_threshold_set(
+			PM8XXX_BATT_ALARM_UPPER_COMPARATOR, 4300);
 
 out:
 	mutex_unlock(&batt_alarm_lock);
@@ -255,15 +259,9 @@
 
 static int pm_chg_get_rt_status(int irq)
 {
-	int count = 3;
 	int ret;
 
-	while ((ret =
-		pm8058_irq_get_rt_status(pm8058_chg.pm_chip, irq)) == -EAGAIN
-	       && count--) {
-		dev_info(pm8058_chg.dev, "%s trycount=%d\n", __func__, count);
-		cpu_relax();
-	}
+	ret = pm8xxx_read_irq_stat(pm8058_chg.dev->parent, irq);
 	if (ret == -EAGAIN)
 		return 0;
 	else
@@ -281,53 +279,53 @@
 	u8 temp;
 	int temp2;
 
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_CNTRL = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_CNTRL_2 = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_VMAX_SEL, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_VMAX_SEL, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_VMAX_SEL = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_VBAT_DET, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_VBAT_DET, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_VBAT_DET = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_IMAX, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_IMAX, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_IMAX = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TRICKLE, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TRICKLE, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_TRICKLE = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_ITERM, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_ITERM, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_ITERM = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TTRKL_MAX, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TTRKL_MAX, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_TTRKL_MAX = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TCHG_MAX, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TCHG_MAX, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_TCHG_MAX = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEMP_THRESH, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEMP_THRESH, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_TEMP_THRESH = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEMP_REG, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEMP_REG, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_TEMP_REG = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_PULSE, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_PULSE, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_PULSE = 0x%x\n", temp);
 
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_STATUS_CLEAR_IRQ_1,
-		    &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_STATUS_CLEAR_IRQ_1,
+		    &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_1 = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_STATUS_CLEAR_IRQ_3,
-		    &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_STATUS_CLEAR_IRQ_3,
+		    &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_3 = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_STATUS_CLEAR_IRQ_10,
-		    &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_STATUS_CLEAR_IRQ_10,
+		    &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_10 = 0x%x\n",
 		temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_STATUS_CLEAR_IRQ_11,
-		    &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_STATUS_CLEAR_IRQ_11,
+		    &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_STATUS_CLEAR_IRQ_11 = 0x%x\n",
 		temp);
 
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_MASK_IRQ_1, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_MASK_IRQ_1, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_1 = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_MASK_IRQ_3, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_MASK_IRQ_3, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_3 = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_MASK_IRQ_10, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_MASK_IRQ_10, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_10 = 0x%x\n", temp);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_MASK_IRQ_11, &temp, 1);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_MASK_IRQ_11, &temp);
 	dev_dbg(pm8058_chg.dev, "PM8058_CHG_MASK_IRQ_11 = 0x%x\n", temp);
 
 	temp2 = pm_chg_get_rt_status(pm8058_chg.pmic_chg_irq[CHGVAL_IRQ]);
@@ -405,7 +403,7 @@
 	u8 temp;
 	int ret;
 
-	ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+	ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
 	if (ret)
 		return ret;
 	if (value)
@@ -413,7 +411,7 @@
 	else
 		temp &= ~BIT(CHG_USB_SUSPEND);
 
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, temp);
 }
 
 static int pm_chg_auto_disable(int value)
@@ -421,7 +419,7 @@
 	u8 temp;
 	int ret;
 
-	ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
 	if (ret)
 		return ret;
 	if (value)
@@ -429,7 +427,7 @@
 	else
 		temp &= ~BIT(CHARGE_AUTO_DIS);
 
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, temp);
 }
 
 static int pm_chg_batt_temp_disable(int value)
@@ -437,7 +435,7 @@
 	u8 temp;
 	int ret;
 
-	ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
 	if (ret)
 		return ret;
 	if (value)
@@ -445,7 +443,7 @@
 	else
 		temp &= ~BIT(CHG_BATT_TEMP_DIS);
 
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, temp);
 }
 
 static int pm_chg_vbatdet_set(int voltage)
@@ -463,7 +461,7 @@
 	temp = diff / PM8058_CHG_V_STEP_MV;
 	dev_dbg(pm8058_chg.dev, "%s voltage=%d setting %02x\n", __func__,
 		voltage, temp);
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_VBAT_DET, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_VBAT_DET, temp);
 }
 
 static int pm_chg_imaxsel_set(int chg_current)
@@ -484,7 +482,7 @@
 			__func__, chg_current);
 		temp = 31;
 	}
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_IMAX, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_IMAX, temp);
 }
 
 #define PM8058_CHG_VMAX_MIN  3300
@@ -501,7 +499,7 @@
 	temp = (voltage - PM8058_CHG_V_MIN_MV) / PM8058_CHG_V_STEP_MV;
 	dev_dbg(pm8058_chg.dev, "%s mV=%d setting %02x\n", __func__, voltage,
 		temp);
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_VMAX_SEL, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_VMAX_SEL, temp);
 }
 
 static int pm_chg_failed_clear(int value)
@@ -509,14 +507,14 @@
 	u8 temp;
 	int ret;
 
-	ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
 	if (ret)
 		return ret;
 	if (value)
 		temp |= BIT(CHG_FAILED_CLEAR);
 	else
 		temp &= ~BIT(CHG_FAILED_CLEAR);
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, temp);
 }
 
 static int pm_chg_iterm_set(int chg_current)
@@ -524,7 +522,7 @@
 	u8 temp;
 
 	temp = (chg_current / PM8058_CHG_I_TERM_STEP_MA) - 1;
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_ITERM, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_ITERM, temp);
 }
 
 static int pm_chg_tchg_set(int minutes)
@@ -532,7 +530,7 @@
 	u8 temp;
 
 	temp = (minutes >> PM8058_CHG_T_TCHG_SHIFT) - 1;
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TCHG_MAX, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TCHG_MAX, temp);
 }
 
 static int pm_chg_ttrkl_set(int minutes)
@@ -540,7 +538,8 @@
 	u8 temp;
 
 	temp = minutes - 1;
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TTRKL_MAX, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TTRKL_MAX,
+									temp);
 }
 
 static int pm_chg_enum_done_enable(int value)
@@ -548,7 +547,7 @@
 	u8 temp;
 	int ret;
 
-	ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, &temp);
 	if (ret)
 		return ret;
 	if (value)
@@ -556,7 +555,7 @@
 	else
 		temp &= ~BIT(ENUM_DONE);
 
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL_2, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL_2, temp);
 }
 
 static uint32_t get_fsm_state(void)
@@ -564,8 +563,8 @@
 	u8 temp;
 
 	temp = 0x00;
-	pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_3, &temp, 1);
-	pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEST_3, &temp, 1);
+	pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_3, temp);
+	pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEST_3, &temp);
 	return (uint32_t)temp;
 }
 
@@ -590,7 +589,7 @@
 	u8 temp;
 	int ret;
 
-	ret = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+	ret = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
 	if (ret)
 		return ret;
 	if (value)
@@ -598,7 +597,7 @@
 	else
 		temp &= ~BIT(CHG_CHARGE_DIS);
 
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, temp);
 }
 
 static void pm8058_start_system_current(struct msm_hardware_charger *hw_chg,
@@ -734,7 +733,11 @@
 	case PMIC8058_CHG_STATE_ATC:
 	case PMIC8058_CHG_STATE_FAST_CHG:
 	case PMIC8058_CHG_STATE_TRKL_CHG:
-		rc = pm8058_batt_alarm_state_set(0, 0);
+		rc = pm8xxx_batt_alarm_disable(
+				PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+		if (!rc)
+			rc = pm8xxx_batt_alarm_disable(
+				PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
 		if (rc)
 			dev_err(pm8058_chg.dev,
 				"%s: unable to set alarm state\n", __func__);
@@ -863,25 +866,25 @@
 		}
 	} else {
 		if (pm8058_chg.present) {
-			ret = pm8058_read(pm8058_chg.pm_chip,
+			ret = pm8xxx_readb(pm8058_chg.dev->parent,
 						PM8058_OVP_TEST_REG,
-						&old, 1);
+						&old);
 			temp = old | BIT(FORCE_OVP_OFF);
-			ret = pm8058_write(pm8058_chg.pm_chip,
+			ret = pm8xxx_writeb(pm8058_chg.dev->parent,
 						PM8058_OVP_TEST_REG,
-						&temp, 1);
+						temp);
 			temp = 0xFC;
-			ret = pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST,
-						&temp, 1);
+			ret = pm8xxx_writeb(pm8058_chg.dev->parent,
+					PM8058_CHG_TEST, temp);
 			/* 10 ms sleep is for the VCHG to discharge */
 			msleep(10);
 			temp = 0xF0;
-			ret = pm8058_write(pm8058_chg.pm_chip,
+			ret = pm8xxx_writeb(pm8058_chg.dev->parent,
 						PM8058_CHG_TEST,
-						&temp, 1);
-			ret = pm8058_write(pm8058_chg.pm_chip,
+						temp);
+			ret = pm8xxx_writeb(pm8058_chg.dev->parent,
 						PM8058_OVP_TEST_REG,
-						&old, 1);
+						old);
 
 			pm_chg_enum_done_enable(0);
 			pm_chg_auto_disable(1);
@@ -904,21 +907,21 @@
 
 		pm_chg_enum_done_enable(0);
 		pm_chg_auto_disable(1);
-		ret = pm8058_read(pm8058_chg.pm_chip,
-				PM8058_OVP_TEST_REG, &old, 1);
+		ret = pm8xxx_readb(pm8058_chg.dev->parent,
+				PM8058_OVP_TEST_REG, &old);
 		temp = old | BIT(FORCE_OVP_OFF);
-		ret = pm8058_write(pm8058_chg.pm_chip,
-				PM8058_OVP_TEST_REG, &temp, 1);
+		ret = pm8xxx_writeb(pm8058_chg.dev->parent,
+				PM8058_OVP_TEST_REG, temp);
 		temp = 0xFC;
-		ret = pm8058_write(pm8058_chg.pm_chip,
-				PM8058_CHG_TEST, &temp, 1);
+		ret = pm8xxx_writeb(pm8058_chg.dev->parent,
+				PM8058_CHG_TEST, temp);
 		/* 10 ms sleep is for the VCHG to discharge */
 		msleep(10);
 		temp = 0xF0;
-		ret = pm8058_write(pm8058_chg.pm_chip,
-				PM8058_CHG_TEST, &temp, 1);
-		ret = pm8058_write(pm8058_chg.pm_chip,
-				PM8058_OVP_TEST_REG, &old, 1);
+		ret = pm8xxx_writeb(pm8058_chg.dev->parent,
+				PM8058_CHG_TEST, temp);
+		ret = pm8xxx_writeb(pm8058_chg.dev->parent,
+				PM8058_OVP_TEST_REG, old);
 
 		if (!is_chg_plugged_in()) {
 			msm_charger_notify_event(&usb_hw_chg,
@@ -983,8 +986,8 @@
 	u8 temp;
 
 	temp = 0x00;
-	if (!pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_3, &temp, 1)) {
-		pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEST_3, &temp, 1);
+	if (!pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_3, temp)) {
+		pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEST_3, &temp);
 		dev_dbg(pm8058_chg.dev, "%s state=%d\n", __func__, temp);
 	}
 	return IRQ_HANDLED;
@@ -1187,7 +1190,7 @@
 			"%s:couldnt find resource AUTO_CHGDONE\n", __func__);
 		goto err_out;
 	} else {
-		ret = request_threaded_irq(res->start, NULL,
+		ret = request_irq(res->start,
 				  pm8058_chg_auto_chgdone_handler,
 				  IRQF_TRIGGER_RISING,
 				  res->name, NULL);
@@ -1208,7 +1211,7 @@
 			"%s:couldnt find resource AUTO_CHGFAIL\n", __func__);
 		goto err_out;
 	} else {
-		ret = request_threaded_irq(res->start, NULL,
+		ret = request_irq(res->start,
 				  pm8058_chg_auto_chgfail_handler,
 				  IRQF_TRIGGER_RISING, res->name, NULL);
 		if (ret < 0) {
@@ -1227,7 +1230,7 @@
 			"%s:couldnt find resource CHGSTATE\n", __func__);
 		goto err_out;
 	} else {
-		ret = request_threaded_irq(res->start, NULL,
+		ret = request_irq(res->start,
 				  pm8058_chg_chgstate_handler,
 				  IRQF_TRIGGER_RISING, res->name, NULL);
 		if (ret < 0) {
@@ -1246,7 +1249,7 @@
 			"%s:couldnt find resource FASTCHG\n", __func__);
 		goto err_out;
 	} else {
-		ret = request_threaded_irq(res->start, NULL,
+		ret = request_irq(res->start,
 				  pm8058_chg_fastchg_handler,
 				  IRQF_TRIGGER_RISING, res->name, NULL);
 		if (ret < 0) {
@@ -1265,7 +1268,7 @@
 			"%s:couldnt find resource CHG_END\n", __func__);
 		goto err_out;
 	} else {
-		ret = request_threaded_irq(res->start, NULL,
+		ret = request_irq(res->start,
 				  pm8058_chg_batttemp_handler,
 				  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 				  res->name, NULL);
@@ -1286,7 +1289,7 @@
 			"%s:couldnt find resource BATT_REPLACE\n", __func__);
 		goto err_out;
 	} else {
-		ret = request_threaded_irq(res->start, NULL,
+		ret = request_irq(res->start,
 				  pm8058_chg_batt_replace_handler,
 				  IRQF_TRIGGER_RISING, res->name, NULL);
 		if (ret < 0) {
@@ -1305,7 +1308,7 @@
 			"%s:couldnt find resource BATTCONNECT\n", __func__);
 		goto err_out;
 	} else {
-		ret = request_threaded_irq(res->start, NULL,
+		ret = request_irq(res->start,
 				  pm8058_chg_battconnect_handler,
 				  IRQF_TRIGGER_RISING | IRQF_TRIGGER_FALLING,
 				  res->name, NULL);
@@ -1351,7 +1354,7 @@
 	u8 temp;
 	int rc;
 
-	rc = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+	rc = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
 	if (rc)
 		return rc;
 
@@ -1367,7 +1370,7 @@
 	u8 temp;
 	int rc;
 
-	rc = pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+	rc = pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, &temp);
 	if (rc)
 		return rc;
 	if (on)
@@ -1375,7 +1378,7 @@
 	else
 		temp &= ~BIT(CHG_CHARGE_BAT);
 
-	return pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_CNTRL, &temp, 1);
+	return pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_CNTRL, temp);
 
 }
 EXPORT_SYMBOL(pm8058_set_charge_batt);
@@ -1496,12 +1499,12 @@
 	u8 temp;
 
 	temp = 0xA3;
-	pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_2, &temp, 1);
+	pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_2, temp);
 	temp = 0x84;
-	pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_2, &temp, 1);
+	pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_2, temp);
 	msleep(2);
 	temp = 0x80;
-	pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST_2, &temp, 1);
+	pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST_2, temp);
 	return 0;
 }
 
@@ -1511,7 +1514,7 @@
 	int ret;
 	u8 temp;
 
-	ret = pm8058_read(pm8058_chg.pm_chip, i, &temp, 1);
+	ret = pm8xxx_readb(pm8058_chg.dev->parent, i, &temp);
 	if (ret)
 		return -EAGAIN;
 	*val = temp;
@@ -1525,7 +1528,7 @@
 	u8 temp;
 
 	temp = (u8) val;
-	ret = pm8058_write(pm8058_chg.pm_chip, i, &temp, 1);
+	ret = pm8xxx_writeb(pm8058_chg.dev->parent, i, temp);
 	mb();
 	if (ret)
 		return -EAGAIN;
@@ -1821,7 +1824,11 @@
 		break;
 	/* expected case - trip of low threshold */
 	case 1:
-		rc = pm8058_batt_alarm_state_set(0, 0);
+		rc = pm8xxx_batt_alarm_disable(
+				PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+		if (!rc)
+			rc = pm8xxx_batt_alarm_disable(
+				PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
 		if (rc)
 			dev_err(pm8058_chg.dev,
 				"%s: unable to set alarm state\n", __func__);
@@ -1841,8 +1848,15 @@
 
 static int pm8058_monitor_for_recharging(void)
 {
+	int rc;
 	/* enable low comparator */
-	return pm8058_batt_alarm_state_set(1, 0);
+	rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+	if (!rc)
+		return pm8xxx_batt_alarm_enable(
+				PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
+
+	return rc;
+
 }
 
 static struct msm_battery_gauge pm8058_batt_gauge = {
@@ -1860,33 +1874,30 @@
 	int ret = 0;
 
 	temp = 0x10;
-	ret |= pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST, &temp, 1);
-	ret |= pm8058_read(pm8058_chg.pm_chip, PM8058_CHG_TEST, &old, 1);
+	ret |= pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST, temp);
+	ret |= pm8xxx_readb(pm8058_chg.dev->parent, PM8058_CHG_TEST, &old);
 	old = old & ~BIT(IGNORE_LL);
 	temp = 0x90  | (0xF & old);
-	ret |= pm8058_write(pm8058_chg.pm_chip, PM8058_CHG_TEST, &temp, 1);
+	ret |= pm8xxx_writeb(pm8058_chg.dev->parent, PM8058_CHG_TEST, temp);
 
 	return ret;
 }
 
 static int __devinit pm8058_charger_probe(struct platform_device *pdev)
 {
-	struct pm8058_chip *pm_chip;
 	struct pmic8058_charger_data *pdata;
 	int rc = 0;
 
-	pm_chip = dev_get_drvdata(pdev->dev.parent);
-	if (pm_chip == NULL) {
-		pr_err("%s:no parent data passed in.\n", __func__);
-		return -EFAULT;
-	}
-
-	pm8058_chg.pm_chip = pm_chip;
 	pm8058_chg.pdata = pdev->dev.platform_data;
 	pm8058_chg.dev = &pdev->dev;
 	pdata = (struct pmic8058_charger_data *) pm8058_chg.pdata;
 
-	if (pdata) {
+	if (pdata == NULL) {
+		pr_err("%s: pdata not present\n", __func__);
+		return -EINVAL;
+	}
+
+	if (pdata->charger_data_valid) {
 		usb_hw_chg.type = pdata->charger_type;
 		chg_data.charger_type = pdata->charger_type;
 		chg_data.max_source_current = pdata->max_source_current;
@@ -1928,7 +1939,10 @@
 	pm8058_chg_enable_irq(BATTTEMP_IRQ);
 	pm8058_chg_enable_irq(BATTCONNECT_IRQ);
 
-	rc = pm8058_batt_alarm_state_set(0, 0);
+	rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+	if (!rc)
+		rc = pm8xxx_batt_alarm_disable(
+			PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
 	if (rc) {
 		pr_err("%s: unable to set batt alarm state\n", __func__);
 		goto free_irq;
@@ -1938,26 +1952,31 @@
 	 * The batt-alarm driver requires sane values for both min / max,
 	 * regardless of whether they're both activated.
 	 */
-	rc = pm8058_batt_alarm_threshold_set(resume_mv, 4300);
+	rc = pm8xxx_batt_alarm_threshold_set(
+			PM8XXX_BATT_ALARM_LOWER_COMPARATOR, resume_mv);
+	if (!rc)
+		rc = pm8xxx_batt_alarm_threshold_set(
+			PM8XXX_BATT_ALARM_UPPER_COMPARATOR, 4300);
 	if (rc) {
 		pr_err("%s: unable to set batt alarm threshold\n", __func__);
 		goto free_irq;
 	}
 
-	rc = pm8058_batt_alarm_hold_time_set(PM8058_BATT_ALARM_HOLD_TIME_16_MS);
+	rc = pm8xxx_batt_alarm_hold_time_set(
+				PM8XXX_BATT_ALARM_HOLD_TIME_16_MS);
 	if (rc) {
 		pr_err("%s: unable to set batt alarm hold time\n", __func__);
 		goto free_irq;
 	}
 
 	/* PWM enabled at 2Hz */
-	rc = pm8058_batt_alarm_pwm_rate_set(1, 7, 4);
+	rc = pm8xxx_batt_alarm_pwm_rate_set(1, 7, 4);
 	if (rc) {
 		pr_err("%s: unable to set batt alarm pwm rate\n", __func__);
 		goto free_irq;
 	}
 
-	rc = pm8058_batt_alarm_register_notifier(&alarm_notifier);
+	rc = pm8xxx_batt_alarm_register_notifier(&alarm_notifier);
 	if (rc) {
 		pr_err("%s: unable to register alarm notifier\n", __func__);
 		goto free_irq;
@@ -1987,11 +2006,14 @@
 	remove_debugfs_entries();
 	kfree(chip);
 
-	rc = pm8058_batt_alarm_state_set(0, 0);
+	rc = pm8xxx_batt_alarm_disable(PM8XXX_BATT_ALARM_UPPER_COMPARATOR);
+	if (!rc)
+		rc = pm8xxx_batt_alarm_disable(
+			PM8XXX_BATT_ALARM_LOWER_COMPARATOR);
 	if (rc)
 		pr_err("%s: unable to set batt alarm state\n", __func__);
 
-	rc |= pm8058_batt_alarm_unregister_notifier(&alarm_notifier);
+	rc |= pm8xxx_batt_alarm_unregister_notifier(&alarm_notifier);
 	if (rc)
 		pr_err("%s: unable to register alarm notifier\n", __func__);
 	return rc;
diff --git a/drivers/regulator/pm8058-xo.c b/drivers/regulator/pm8058-xo.c
index 581e228..b778660 100644
--- a/drivers/regulator/pm8058-xo.c
+++ b/drivers/regulator/pm8058-xo.c
@@ -19,6 +19,7 @@
 #include <linux/bitops.h>
 #include <linux/mfd/pmic8058.h>
 #include <linux/regulator/driver.h>
+#include <linux/mfd/pm8xxx/core.h>
 #include <linux/regulator/pm8058-xo.h>
 
 /* XO buffer masks and values */
@@ -39,6 +40,7 @@
 #define XO_DISABLE		(XO_MODE_MANUAL | XO_BUFFER_DISABLE)
 
 struct pm8058_xo_buffer {
+	struct device			*dev;
 	struct pm8058_xo_pdata		*pdata;
 	struct regulator_dev		*rdev;
 	u16				ctrl_addr;
@@ -55,7 +57,7 @@
 	XO_BUFFER(A1, 0x186),
 };
 
-static int pm8058_xo_buffer_write(struct pm8058_chip *chip,
+static int pm8058_xo_buffer_write(struct pm8058_xo_buffer *xo,
 		u16 addr, u8 val, u8 mask, u8 *reg_save)
 {
 	u8	reg;
@@ -63,10 +65,10 @@
 
 	reg = (*reg_save & ~mask) | (val & mask);
 	if (reg != *reg_save)
-		rc = pm8058_write(chip, addr, &reg, 1);
+		rc = pm8xxx_writeb(xo->dev->parent, addr, reg);
 
 	if (rc)
-		pr_err("FAIL: pm8058_write: rc=%d\n", rc);
+		pr_err("FAIL: pm8xxx_write: rc=%d\n", rc);
 	else
 		*reg_save = reg;
 	return rc;
@@ -75,10 +77,9 @@
 static int pm8058_xo_buffer_enable(struct regulator_dev *dev)
 {
 	struct pm8058_xo_buffer *xo = rdev_get_drvdata(dev);
-	struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
 	int rc;
 
-	rc = pm8058_xo_buffer_write(chip, xo->ctrl_addr, XO_ENABLE,
+	rc = pm8058_xo_buffer_write(xo, xo->ctrl_addr, XO_ENABLE,
 				    XO_ENABLE_MASK, &xo->ctrl_reg);
 	if (rc)
 		pr_err("FAIL: pm8058_xo_buffer_write: rc=%d\n", rc);
@@ -99,10 +100,9 @@
 static int pm8058_xo_buffer_disable(struct regulator_dev *dev)
 {
 	struct pm8058_xo_buffer *xo = rdev_get_drvdata(dev);
-	struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
 	int rc;
 
-	rc = pm8058_xo_buffer_write(chip, xo->ctrl_addr, XO_DISABLE,
+	rc = pm8058_xo_buffer_write(xo, xo->ctrl_addr, XO_DISABLE,
 				    XO_ENABLE_MASK, &xo->ctrl_reg);
 	if (rc)
 		pr_err("FAIL: pm8058_xo_buffer_write: rc=%d\n", rc);
@@ -130,23 +130,21 @@
 	VREG_DESCRIP(PM8058_XO_ID_A1, "8058_xo_a1", &pm8058_xo_ops),
 };
 
-static int pm8058_init_xo_buffer(struct pm8058_chip *chip,
-				 struct pm8058_xo_buffer *xo)
+static int pm8058_init_xo_buffer(struct pm8058_xo_buffer *xo)
 {
 	int	rc;
 
 	/* Save the current control register state */
-	rc = pm8058_read(chip, xo->ctrl_addr, &xo->ctrl_reg, 1);
+	rc = pm8xxx_readb(xo->dev->parent, xo->ctrl_addr, &xo->ctrl_reg);
 
 	if (rc)
-		pr_err("FAIL: pm8058_read: rc=%d\n", rc);
+		pr_err("FAIL: pm8xxx_read: rc=%d\n", rc);
 	return rc;
 }
 
 static int __devinit pm8058_xo_buffer_probe(struct platform_device *pdev)
 {
 	struct regulator_desc *rdesc;
-	struct pm8058_chip *chip;
 	struct pm8058_xo_buffer *xo;
 	int rc = 0;
 
@@ -154,16 +152,15 @@
 		return -EINVAL;
 
 	if (pdev->id >= 0 && pdev->id < PM8058_XO_ID_MAX) {
-		chip = dev_get_drvdata(pdev->dev.parent);
 		rdesc = &pm8058_xo_buffer_desc[pdev->id];
 		xo = &pm8058_xo_buffer[pdev->id];
 		xo->pdata = pdev->dev.platform_data;
+		xo->dev  = &pdev->dev;
 
-		rc = pm8058_init_xo_buffer(chip, xo);
+		rc = pm8058_init_xo_buffer(xo);
 		if (rc)
 			goto bail;
 
-		platform_set_drvdata(pdev, chip);
 		xo->rdev = regulator_register(rdesc, &pdev->dev,
 					&xo->pdata->init_data, xo);
 		if (IS_ERR(xo->rdev)) {
diff --git a/drivers/regulator/pmic8058-regulator.c b/drivers/regulator/pmic8058-regulator.c
index c11f32b..e137b0f 100644
--- a/drivers/regulator/pmic8058-regulator.c
+++ b/drivers/regulator/pmic8058-regulator.c
@@ -18,6 +18,7 @@
 #include <linux/mfd/pmic8058.h>
 #include <linux/regulator/driver.h>
 #include <linux/regulator/machine.h>
+#include <linux/mfd/pm8xxx/core.h>
 #include <linux/regulator/pmic8058-regulator.h>
 
 /* Regulator types */
@@ -205,6 +206,7 @@
 };
 
 struct pm8058_vreg {
+	struct device			*dev;
 	struct pm8058_vreg_pdata	*pdata;
 	struct regulator_dev		*rdev;
 	struct pm8058_enable		*global_enable[GLOBAL_ENABLE_MAX];
@@ -375,11 +377,9 @@
 	NCP(NCP, 0x090, 0x0EC),
 };
 
-static int pm8058_smps_set_voltage_advanced(struct pm8058_vreg *vreg,
-					struct pm8058_chip *chip, int uV,
+static int pm8058_smps_set_voltage_advanced(struct pm8058_vreg *vreg, int uV,
 					int force_on);
-static int pm8058_smps_set_voltage_legacy(struct pm8058_vreg *vreg,
-					struct pm8058_chip *chip, int uV);
+static int pm8058_smps_set_voltage_legacy(struct pm8058_vreg *vreg, int uV);
 static int _pm8058_vreg_is_enabled(struct pm8058_vreg *vreg);
 
 static unsigned int pm8058_vreg_get_mode(struct regulator_dev *dev);
@@ -387,7 +387,7 @@
 static void print_write_error(struct pm8058_vreg *vreg, int rc,
 				const char *func);
 
-static int pm8058_vreg_write(struct pm8058_chip *chip,
+static int pm8058_vreg_write(struct pm8058_vreg *vreg,
 		u16 addr, u8 val, u8 mask, u8 *reg_save)
 {
 	int rc = 0;
@@ -395,9 +395,9 @@
 
 	reg = (*reg_save & ~mask) | (val & mask);
 	if (reg != *reg_save)
-		rc = pm8058_write(chip, addr, &reg, 1);
+		rc = pm8xxx_writeb(vreg->dev->parent, addr, reg);
 	if (rc)
-		pr_err("%s: pm8058_write failed, rc=%d\n", __func__, rc);
+		pr_err("%s: pm8xxx_write failed, rc=%d\n", __func__, rc);
 	else
 		*reg_save = reg;
 	return rc;
@@ -416,14 +416,13 @@
 }
 
 
-static int pm8058_vreg_set_global_enable(struct pm8058_vreg *vreg,
-					 struct pm8058_chip *chip, int on)
+static int pm8058_vreg_set_global_enable(struct pm8058_vreg *vreg, int on)
 {
 	int rc = 0, i;
 
 	for (i = 0;
 	     (i < GLOBAL_ENABLE_MAX) && !rc && vreg->global_enable[i]; i++)
-		rc = pm8058_vreg_write(chip, vreg->global_enable[i]->addr,
+		rc = pm8058_vreg_write(vreg, vreg->global_enable[i]->addr,
 					(on ? vreg->global_enable_mask[i] : 0),
 					vreg->global_enable_mask[i],
 					&vreg->global_enable[i]->reg);
@@ -452,8 +451,7 @@
 	return ret;
 }
 
-static int pm8058_vreg_set_pin_ctrl(struct pm8058_vreg *vreg,
-		struct pm8058_chip *chip, int on)
+static int pm8058_vreg_set_pin_ctrl(struct pm8058_vreg *vreg, int on)
 {
 	int rc = 0, bank;
 	u8 val = 0, mask;
@@ -473,7 +471,7 @@
 				val |= LDO_TEST_PIN_CTRL_EN3;
 
 			bank = (pf == PM8058_VREG_PIN_FN_ENABLE ? 5 : 6);
-			rc = pm8058_vreg_write(chip, vreg->test_addr,
+			rc = pm8058_vreg_write(vreg, vreg->test_addr,
 				val | REGULATOR_BANK_SEL(bank)
 				  | REGULATOR_BANK_WRITE,
 				LDO_TEST_PIN_CTRL_MASK | REGULATOR_BANK_MASK,
@@ -484,26 +482,25 @@
 			val = LDO_TEST_LPM_SEL_CTRL | REGULATOR_BANK_WRITE
 				| REGULATOR_BANK_SEL(0);
 			mask = LDO_TEST_LPM_MASK | REGULATOR_BANK_MASK;
-			rc = pm8058_vreg_write(chip, vreg->test_addr, val, mask,
+			rc = pm8058_vreg_write(vreg, vreg->test_addr, val, mask,
 						&vreg->test_reg[0]);
 			if (rc)
 				goto bail;
 
 			if (pf == PM8058_VREG_PIN_FN_ENABLE) {
 				/* Pin control ON/OFF */
-				rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+				rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
 					LDO_CTRL_PM_HPM,
 					LDO_ENABLE_MASK | LDO_CTRL_PM_MASK,
 					&vreg->ctrl_reg);
 				if (rc)
 					goto bail;
-				rc = pm8058_vreg_set_global_enable(vreg, chip,
-								   0);
+				rc = pm8058_vreg_set_global_enable(vreg, 0);
 				if (rc)
 					goto bail;
 			} else {
 				/* Pin control LPM/HPM */
-				rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+				rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
 					LDO_ENABLE | LDO_CTRL_PM_LPM,
 					LDO_ENABLE_MASK | LDO_CTRL_PM_MASK,
 					&vreg->ctrl_reg);
@@ -512,14 +509,14 @@
 			}
 		} else {
 			/* Pin control off */
-			rc = pm8058_vreg_write(chip, vreg->test_addr,
+			rc = pm8058_vreg_write(vreg, vreg->test_addr,
 				REGULATOR_BANK_SEL(5) | REGULATOR_BANK_WRITE,
 				LDO_TEST_PIN_CTRL_MASK | REGULATOR_BANK_MASK,
 				&vreg->test_reg[5]);
 			if (rc)
 				goto bail;
 
-			rc = pm8058_vreg_write(chip, vreg->test_addr,
+			rc = pm8058_vreg_write(vreg, vreg->test_addr,
 				REGULATOR_BANK_SEL(6) | REGULATOR_BANK_WRITE,
 				LDO_TEST_PIN_CTRL_MASK | REGULATOR_BANK_MASK,
 				&vreg->test_reg[6]);
@@ -551,29 +548,29 @@
 				if (pc & PM8058_VREG_PIN_CTRL_A1)
 					val |= SMPS_PIN_CTRL_LPM_A1;
 			}
-			rc = pm8058_vreg_set_global_enable(vreg, chip, 0);
+			rc = pm8058_vreg_set_global_enable(vreg, 0);
 			if (rc)
 				goto bail;
 
-			rc = pm8058_smps_set_voltage_legacy(vreg, chip,
+			rc = pm8058_smps_set_voltage_legacy(vreg,
 							vreg->save_uV);
 			if (rc)
 				goto bail;
 
-			rc = pm8058_vreg_write(chip, vreg->sleep_ctrl_addr, val,
+			rc = pm8058_vreg_write(vreg, vreg->sleep_ctrl_addr, val,
 				SMPS_PIN_CTRL_MASK | SMPS_PIN_CTRL_LPM_MASK,
 				&vreg->sleep_ctrl_reg);
 			if (rc)
 				goto bail;
 
-			rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+			rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
 				(pf == PM8058_VREG_PIN_FN_ENABLE
 				       ? 0 : SMPS_LEGACY_ENABLE),
 				SMPS_LEGACY_ENABLE, &vreg->ctrl_reg);
 			if (rc)
 				goto bail;
 
-			rc = pm8058_vreg_write(chip, vreg->clk_ctrl_addr,
+			rc = pm8058_vreg_write(vreg, vreg->clk_ctrl_addr,
 				(pf == PM8058_VREG_PIN_FN_ENABLE
 				       ? SMPS_CLK_CTRL_PWM : SMPS_CLK_CTRL_PFM),
 				SMPS_CLK_CTRL_MASK, &vreg->clk_ctrl_reg);
@@ -584,20 +581,20 @@
 			if (!SMPS_IN_ADVANCED_MODE(vreg)) {
 				if (_pm8058_vreg_is_enabled(vreg))
 					val = SMPS_LEGACY_ENABLE;
-				rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+				rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
 					val, SMPS_LEGACY_ENABLE,
 					&vreg->ctrl_reg);
 				if (rc)
 					goto bail;
 			}
 
-			rc = pm8058_vreg_write(chip, vreg->sleep_ctrl_addr, 0,
+			rc = pm8058_vreg_write(vreg, vreg->sleep_ctrl_addr, 0,
 				SMPS_PIN_CTRL_MASK | SMPS_PIN_CTRL_LPM_MASK,
 				&vreg->sleep_ctrl_reg);
 			if (rc)
 				goto bail;
 
-			rc = pm8058_smps_set_voltage_advanced(vreg, chip,
+			rc = pm8058_smps_set_voltage_advanced(vreg,
 							 vreg->save_uV, 0);
 			if (rc)
 				goto bail;
@@ -615,13 +612,13 @@
 			if (pc & PM8058_VREG_PIN_CTRL_A1)
 				val |= LVS_PIN_CTRL_EN3;
 
-			rc = pm8058_vreg_write(chip, vreg->ctrl_addr, val,
+			rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, val,
 					LVS_PIN_CTRL_MASK | LVS_ENABLE_MASK,
 					&vreg->ctrl_reg);
 			if (rc)
 				goto bail;
 
-			rc = pm8058_vreg_set_global_enable(vreg, chip, 0);
+			rc = pm8058_vreg_set_global_enable(vreg, 0);
 			if (rc)
 				goto bail;
 		} else {
@@ -629,7 +626,7 @@
 			if (_pm8058_vreg_is_enabled(vreg))
 				val = LVS_ENABLE;
 
-			rc = pm8058_vreg_write(chip, vreg->ctrl_addr, val,
+			rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, val,
 					LVS_ENABLE_MASK | LVS_PIN_CTRL_MASK,
 					&vreg->ctrl_reg);
 			if (rc)
@@ -649,7 +646,6 @@
 static int pm8058_vreg_enable(struct regulator_dev *dev)
 {
 	struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
 	int mode;
 	int rc = 0;
 
@@ -657,16 +653,15 @@
 
 	if (mode == REGULATOR_MODE_IDLE) {
 		/* Turn on pin control. */
-		rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 1);
+		rc = pm8058_vreg_set_pin_ctrl(vreg, 1);
 		if (rc)
 			goto bail;
 		return rc;
 	}
 	if (vreg->type == REGULATOR_TYPE_SMPS && SMPS_IN_ADVANCED_MODE(vreg))
-		rc = pm8058_smps_set_voltage_advanced(vreg, chip,
-							vreg->save_uV, 1);
+		rc = pm8058_smps_set_voltage_advanced(vreg, vreg->save_uV, 1);
 	else
-		rc = pm8058_vreg_write(chip, vreg->ctrl_addr, REGULATOR_EN_MASK,
+		rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, REGULATOR_EN_MASK,
 			REGULATOR_EN_MASK, &vreg->ctrl_reg);
 bail:
 	if (rc)
@@ -706,26 +701,25 @@
 static int pm8058_vreg_disable(struct regulator_dev *dev)
 {
 	struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
 	int rc = 0;
 
 	/* Disable in global control register. */
-	rc = pm8058_vreg_set_global_enable(vreg, chip, 0);
+	rc = pm8058_vreg_set_global_enable(vreg, 0);
 	if (rc)
 		goto bail;
 
 	/* Turn off pin control. */
-	rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+	rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
 	if (rc)
 		goto bail;
 
 	/* Disable in local control register. */
 	if (vreg->type == REGULATOR_TYPE_SMPS && SMPS_IN_ADVANCED_MODE(vreg))
-		rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+		rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
 			SMPS_ADVANCED_BAND_OFF, SMPS_ADVANCED_BAND_MASK,
 			&vreg->ctrl_reg);
 	else
-		rc = pm8058_vreg_write(chip, vreg->ctrl_addr, 0,
+		rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, 0,
 			REGULATOR_EN_MASK, &vreg->ctrl_reg);
 
 bail:
@@ -735,8 +729,7 @@
 	return rc;
 }
 
-static int pm8058_pldo_set_voltage(struct pm8058_chip *chip,
-		struct pm8058_vreg *vreg, int uV)
+static int pm8058_pldo_set_voltage(struct pm8058_vreg *vreg, int uV)
 {
 	int vmin, rc = 0;
 	unsigned vprog, fine_step;
@@ -775,7 +768,7 @@
 		|| ((range_sel ^ vreg->test_reg[2]) & LDO_TEST_RANGE_SEL_MASK)
 		|| ((fine_step_reg ^ vreg->test_reg[2])
 			& LDO_TEST_FINE_STEP_MASK))) {
-		rc = pm8058_vreg_write(chip, vreg->test_addr,
+		rc = pm8058_vreg_write(vreg, vreg->test_addr,
 			REGULATOR_BANK_SEL(2) | REGULATOR_BANK_WRITE,
 			REGULATOR_BANK_MASK | LDO_TEST_VPROG_UPDATE_MASK,
 			&vreg->test_reg[2]);
@@ -784,13 +777,13 @@
 	}
 
 	/* Write new voltage. */
-	rc = pm8058_vreg_write(chip, vreg->ctrl_addr, vprog,
+	rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, vprog,
 				LDO_CTRL_VPROG_MASK, &vreg->ctrl_reg);
 	if (rc)
 		goto bail;
 
 	/* Write range extension. */
-	rc = pm8058_vreg_write(chip, vreg->test_addr,
+	rc = pm8058_vreg_write(vreg, vreg->test_addr,
 			range_ext | REGULATOR_BANK_SEL(4)
 			 | REGULATOR_BANK_WRITE,
 			LDO_TEST_RANGE_EXT_MASK | REGULATOR_BANK_MASK,
@@ -799,7 +792,7 @@
 		goto bail;
 
 	/* Write fine step, range select and program voltage update. */
-	rc = pm8058_vreg_write(chip, vreg->test_addr,
+	rc = pm8058_vreg_write(vreg, vreg->test_addr,
 			fine_step_reg | range_sel | REGULATOR_BANK_SEL(2)
 			 | REGULATOR_BANK_WRITE | LDO_TEST_VPROG_UPDATE_MASK,
 			LDO_TEST_FINE_STEP_MASK | LDO_TEST_RANGE_SEL_MASK
@@ -812,8 +805,7 @@
 	return rc;
 }
 
-static int pm8058_nldo_set_voltage(struct pm8058_chip *chip,
-		struct pm8058_vreg *vreg, int uV)
+static int pm8058_nldo_set_voltage(struct pm8058_vreg *vreg, int uV)
 {
 	unsigned vprog, fine_step_reg;
 	int rc;
@@ -826,13 +818,13 @@
 	vprog >>= 1;
 
 	/* Write new voltage. */
-	rc = pm8058_vreg_write(chip, vreg->ctrl_addr, vprog,
+	rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, vprog,
 				LDO_CTRL_VPROG_MASK, &vreg->ctrl_reg);
 	if (rc)
 		goto bail;
 
 	/* Write fine step. */
-	rc = pm8058_vreg_write(chip, vreg->test_addr,
+	rc = pm8058_vreg_write(vreg, vreg->test_addr,
 			fine_step_reg | REGULATOR_BANK_SEL(2)
 			 | REGULATOR_BANK_WRITE | LDO_TEST_VPROG_UPDATE_MASK,
 			LDO_TEST_FINE_STEP_MASK | REGULATOR_BANK_MASK
@@ -849,12 +841,11 @@
 		int min_uV, int max_uV, unsigned *selector)
 {
 	struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
 
 	if (vreg->is_nmos)
-		return pm8058_nldo_set_voltage(chip, vreg, min_uV);
+		return pm8058_nldo_set_voltage(vreg, min_uV);
 	else
-		return pm8058_pldo_set_voltage(chip, vreg, min_uV);
+		return pm8058_pldo_set_voltage(vreg, min_uV);
 }
 
 static int pm8058_pldo_get_voltage(struct pm8058_vreg *vreg)
@@ -967,8 +958,7 @@
 }
 
 static int pm8058_smps_set_voltage_advanced(struct pm8058_vreg *vreg,
-					struct pm8058_chip *chip, int uV,
-					int force_on)
+					int uV,	int force_on)
 {
 	u8 vprog, band;
 	int rc, new_uV;
@@ -992,7 +982,7 @@
 		band = SMPS_ADVANCED_BAND_OFF;
 
 	/* Set advanced mode bit to 1. */
-	rc = pm8058_vreg_write(chip, vreg->test_addr, SMPS_ADVANCED_MODE
+	rc = pm8058_vreg_write(vreg, vreg->test_addr, SMPS_ADVANCED_MODE
 		| REGULATOR_BANK_WRITE | REGULATOR_BANK_SEL(7),
 		SMPS_ADVANCED_MODE_MASK | REGULATOR_BANK_MASK,
 		&vreg->test_reg[7]);
@@ -1000,7 +990,7 @@
 		goto bail;
 
 	/* Set voltage and voltage band. */
-	rc = pm8058_vreg_write(chip, vreg->ctrl_addr, band | vprog,
+	rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, band | vprog,
 			SMPS_ADVANCED_BAND_MASK | SMPS_ADVANCED_VPROG_MASK,
 			&vreg->ctrl_reg);
 	if (rc)
@@ -1012,8 +1002,7 @@
 	return rc;
 }
 
-static int pm8058_smps_set_voltage_legacy(struct pm8058_vreg *vreg,
-					struct pm8058_chip *chip, int uV)
+static int pm8058_smps_set_voltage_legacy(struct pm8058_vreg *vreg, int uV)
 {
 	u8 vlow, vref, vprog, pd, en;
 	int rc;
@@ -1033,7 +1022,7 @@
 	}
 
 	/* set vlow bit for ultra low voltage mode */
-	rc = pm8058_vreg_write(chip, vreg->test_addr,
+	rc = pm8058_vreg_write(vreg, vreg->test_addr,
 		vlow | REGULATOR_BANK_WRITE | REGULATOR_BANK_SEL(1),
 		REGULATOR_BANK_MASK | SMPS_LEGACY_VLOW_SEL_MASK,
 		&vreg->test_reg[1]);
@@ -1041,7 +1030,7 @@
 		goto bail;
 
 	/* Set advanced mode bit to 0. */
-	rc = pm8058_vreg_write(chip, vreg->test_addr, SMPS_LEGACY_MODE
+	rc = pm8058_vreg_write(vreg, vreg->test_addr, SMPS_LEGACY_MODE
 		| REGULATOR_BANK_WRITE | REGULATOR_BANK_SEL(7),
 		SMPS_ADVANCED_MODE_MASK | REGULATOR_BANK_MASK,
 		&vreg->test_reg[7]);
@@ -1052,7 +1041,7 @@
 	pd = (vreg->pdata->pull_down_enable ? SMPS_LEGACY_PULL_DOWN_ENABLE : 0);
 
 	/* Set voltage (and the rest of the control register). */
-	rc = pm8058_vreg_write(chip, vreg->ctrl_addr, en | pd | vref | vprog,
+	rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, en | pd | vref | vprog,
 		SMPS_LEGACY_ENABLE | SMPS_LEGACY_PULL_DOWN_ENABLE
 		| SMPS_LEGACY_VREF_SEL_MASK | SMPS_LEGACY_VPROG_MASK,
 		&vreg->ctrl_reg);
@@ -1067,16 +1056,15 @@
 		int min_uV, int max_uV, unsigned *selector)
 {
 	struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
 	int rc = 0;
 
 	if (min_uV < SMPS_UV_MIN || min_uV > SMPS_UV_MAX)
 		return -EINVAL;
 
 	if (SMPS_IN_ADVANCED_MODE(vreg))
-		rc = pm8058_smps_set_voltage_advanced(vreg, chip, min_uV, 0);
+		rc = pm8058_smps_set_voltage_advanced(vreg, min_uV, 0);
 	else
-		rc = pm8058_smps_set_voltage_legacy(vreg, chip, min_uV);
+		rc = pm8058_smps_set_voltage_legacy(vreg, min_uV);
 
 	if (rc)
 		print_write_error(vreg, rc, __func__);
@@ -1088,7 +1076,6 @@
 		int min_uV, int max_uV, unsigned *selector)
 {
 	struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
 	int rc;
 	u8 val;
 
@@ -1098,7 +1085,7 @@
 	val = (min_uV - NCP_UV_MIN) / NCP_UV_STEP;
 
 	/* voltage setting */
-	rc = pm8058_vreg_write(chip, vreg->ctrl_addr, val, NCP_VPROG_MASK,
+	rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, val, NCP_VPROG_MASK,
 			&vreg->ctrl_reg);
 	if (rc)
 		print_write_error(vreg, rc, __func__);
@@ -1113,8 +1100,7 @@
 	return NCP_UV_MIN + vprog * NCP_UV_STEP;
 }
 
-static int pm8058_ldo_set_mode(struct pm8058_vreg *vreg,
-		struct pm8058_chip *chip, unsigned int mode)
+static int pm8058_ldo_set_mode(struct pm8058_vreg *vreg, unsigned int mode)
 {
 	int rc = 0;
 	u8 mask, val;
@@ -1125,13 +1111,13 @@
 		val = (_pm8058_vreg_is_enabled(vreg) ? LDO_ENABLE : 0)
 			| LDO_CTRL_PM_HPM;
 		mask = LDO_ENABLE_MASK | LDO_CTRL_PM_MASK;
-		rc = pm8058_vreg_write(chip, vreg->ctrl_addr, val, mask,
+		rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, val, mask,
 					&vreg->ctrl_reg);
 		if (rc)
 			goto bail;
 
 		if (pm8058_vreg_using_pin_ctrl(vreg))
-			rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+			rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
 		if (rc)
 			goto bail;
 		break;
@@ -1141,7 +1127,7 @@
 		val = (_pm8058_vreg_is_enabled(vreg) ? LDO_ENABLE : 0)
 			| LDO_CTRL_PM_LPM;
 		mask = LDO_ENABLE_MASK | LDO_CTRL_PM_MASK;
-		rc = pm8058_vreg_write(chip, vreg->ctrl_addr, val, mask,
+		rc = pm8058_vreg_write(vreg, vreg->ctrl_addr, val, mask,
 					&vreg->ctrl_reg);
 		if (rc)
 			goto bail;
@@ -1149,13 +1135,13 @@
 		val = LDO_TEST_LPM_SEL_CTRL | REGULATOR_BANK_WRITE
 			| REGULATOR_BANK_SEL(0);
 		mask = LDO_TEST_LPM_MASK | REGULATOR_BANK_MASK;
-		rc = pm8058_vreg_write(chip, vreg->test_addr, val, mask,
+		rc = pm8058_vreg_write(vreg, vreg->test_addr, val, mask,
 					&vreg->test_reg[0]);
 		if (rc)
 			goto bail;
 
 		if (pm8058_vreg_using_pin_ctrl(vreg))
-			rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+			rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
 		if (rc)
 			goto bail;
 		break;
@@ -1163,7 +1149,7 @@
 	case REGULATOR_MODE_IDLE:
 		/* Pin Control */
 		if (_pm8058_vreg_is_enabled(vreg))
-			rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 1);
+			rc = pm8058_vreg_set_pin_ctrl(vreg, 1);
 		if (rc)
 			goto bail;
 		break;
@@ -1180,8 +1166,7 @@
 	return rc;
 }
 
-static int pm8058_smps_set_mode(struct pm8058_vreg *vreg,
-		struct pm8058_chip *chip, unsigned int mode)
+static int pm8058_smps_set_mode(struct pm8058_vreg *vreg, unsigned int mode)
 {
 	int rc = 0;
 	u8 mask, val;
@@ -1191,13 +1176,13 @@
 		/* HPM */
 		val = SMPS_CLK_CTRL_PWM;
 		mask = SMPS_CLK_CTRL_MASK;
-		rc = pm8058_vreg_write(chip, vreg->clk_ctrl_addr, val, mask,
+		rc = pm8058_vreg_write(vreg, vreg->clk_ctrl_addr, val, mask,
 					&vreg->clk_ctrl_reg);
 		if (rc)
 			goto bail;
 
 		if (pm8058_vreg_using_pin_ctrl(vreg))
-			rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+			rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
 		if (rc)
 			goto bail;
 		break;
@@ -1206,13 +1191,13 @@
 		/* LPM */
 		val = SMPS_CLK_CTRL_PFM;
 		mask = SMPS_CLK_CTRL_MASK;
-		rc = pm8058_vreg_write(chip, vreg->clk_ctrl_addr, val, mask,
+		rc = pm8058_vreg_write(vreg, vreg->clk_ctrl_addr, val, mask,
 					&vreg->clk_ctrl_reg);
 		if (rc)
 			goto bail;
 
 		if (pm8058_vreg_using_pin_ctrl(vreg))
-			rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+			rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
 		if (rc)
 			goto bail;
 		break;
@@ -1220,7 +1205,7 @@
 	case REGULATOR_MODE_IDLE:
 		/* Pin Control */
 		if (_pm8058_vreg_is_enabled(vreg))
-			rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 1);
+			rc = pm8058_vreg_set_pin_ctrl(vreg, 1);
 		if (rc)
 			goto bail;
 		break;
@@ -1237,18 +1222,17 @@
 	return rc;
 }
 
-static int pm8058_lvs_set_mode(struct pm8058_vreg *vreg,
-		struct pm8058_chip *chip, unsigned int mode)
+static int pm8058_lvs_set_mode(struct pm8058_vreg *vreg, unsigned int mode)
 {
 	int rc = 0;
 
 	if (mode == REGULATOR_MODE_IDLE) {
 		/* Use pin control. */
 		if (_pm8058_vreg_is_enabled(vreg))
-			rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 1);
+			rc = pm8058_vreg_set_pin_ctrl(vreg, 1);
 	} else {
 		/* Turn off pin control. */
-		rc = pm8058_vreg_set_pin_ctrl(vreg, chip, 0);
+		rc = pm8058_vreg_set_pin_ctrl(vreg, 0);
 	}
 
 	return rc;
@@ -1268,7 +1252,6 @@
 static int pm8058_vreg_set_mode(struct regulator_dev *dev, unsigned int mode)
 {
 	struct pm8058_vreg *vreg = rdev_get_drvdata(dev);
-	struct pm8058_chip *chip = dev_get_drvdata(dev->dev.parent);
 	unsigned prev_optimum = vreg->optimum;
 	unsigned prev_pc_vote = vreg->pc_vote;
 	unsigned prev_mode_initialized = vreg->mode_initialized;
@@ -1320,13 +1303,13 @@
 
 	switch (vreg->type) {
 	case REGULATOR_TYPE_LDO:
-		rc = pm8058_ldo_set_mode(vreg, chip, new_mode);
+		rc = pm8058_ldo_set_mode(vreg, new_mode);
 		break;
 	case REGULATOR_TYPE_SMPS:
-		rc = pm8058_smps_set_mode(vreg, chip, new_mode);
+		rc = pm8058_smps_set_mode(vreg, new_mode);
 		break;
 	case REGULATOR_TYPE_LVS:
-		rc = pm8058_lvs_set_mode(vreg, chip, new_mode);
+		rc = pm8058_lvs_set_mode(vreg, new_mode);
 		break;
 	}
 
@@ -1499,24 +1482,25 @@
 	VREG_DESCRIP(PM8058_VREG_ID_NCP, "8058_ncp", &pm8058_ncp_ops),
 };
 
-static int pm8058_master_enable_init(struct pm8058_chip *chip)
+static int pm8058_master_enable_init(struct pm8058_vreg *vreg)
 {
 	int rc = 0, i;
 
 	for (i = 0; i < MASTER_ENABLE_COUNT; i++) {
-		rc = pm8058_read(chip, m_en[i].addr, &(m_en[i].reg), 1);
+		rc = pm8xxx_readb(vreg->dev->parent, m_en[i].addr,
+							&(m_en[i].reg));
 		if (rc)
 			goto bail;
 	}
 
 bail:
 	if (rc)
-		pr_err("%s: pm8058_read failed, rc=%d\n", __func__, rc);
+		pr_err("%s: pm8xxx_read failed, rc=%d\n", __func__, rc);
 
 	return rc;
 }
 
-static int pm8058_init_ldo(struct pm8058_chip *chip, struct pm8058_vreg *vreg)
+static int pm8058_init_ldo(struct pm8058_vreg *vreg)
 {
 	int rc = 0, i;
 	u8 bank;
@@ -1524,11 +1508,12 @@
 	/* Save the current test register state. */
 	for (i = 0; i < LDO_TEST_BANKS; i++) {
 		bank = REGULATOR_BANK_SEL(i);
-		rc = pm8058_write(chip, vreg->test_addr, &bank, 1);
+		rc = pm8xxx_writeb(vreg->dev->parent, vreg->test_addr, bank);
 		if (rc)
 			goto bail;
 
-		rc = pm8058_read(chip, vreg->test_addr, &vreg->test_reg[i], 1);
+		rc = pm8xxx_readb(vreg->dev->parent, vreg->test_addr,
+							&vreg->test_reg[i]);
 		if (rc)
 			goto bail;
 		vreg->test_reg[i] |= REGULATOR_BANK_WRITE;
@@ -1540,14 +1525,14 @@
 		vreg->optimum = REGULATOR_MODE_FAST;
 
 	/* Set pull down enable based on platform data. */
-	rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+	rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
 		     (vreg->pdata->pull_down_enable ? LDO_PULL_DOWN_ENABLE : 0),
 		     LDO_PULL_DOWN_ENABLE_MASK, &vreg->ctrl_reg);
 bail:
 	return rc;
 }
 
-static int pm8058_init_smps(struct pm8058_chip *chip, struct pm8058_vreg *vreg)
+static int pm8058_init_smps(struct pm8058_vreg *vreg)
 {
 	int rc = 0, i;
 	u8 bank;
@@ -1555,24 +1540,26 @@
 	/* Save the current test2 register state. */
 	for (i = 0; i < SMPS_TEST_BANKS; i++) {
 		bank = REGULATOR_BANK_SEL(i);
-		rc = pm8058_write(chip, vreg->test_addr, &bank, 1);
+		rc = pm8xxx_writeb(vreg->dev->parent, vreg->test_addr, bank);
 		if (rc)
 			goto bail;
 
-		rc = pm8058_read(chip, vreg->test_addr, &vreg->test_reg[i],
-				1);
+		rc = pm8xxx_readb(vreg->dev->parent, vreg->test_addr,
+							&vreg->test_reg[i]);
 		if (rc)
 			goto bail;
 		vreg->test_reg[i] |= REGULATOR_BANK_WRITE;
 	}
 
 	/* Save the current clock control register state. */
-	rc = pm8058_read(chip, vreg->clk_ctrl_addr, &vreg->clk_ctrl_reg, 1);
+	rc = pm8xxx_readb(vreg->dev->parent, vreg->clk_ctrl_addr,
+						&vreg->clk_ctrl_reg);
 	if (rc)
 		goto bail;
 
 	/* Save the current sleep control register state. */
-	rc = pm8058_read(chip, vreg->sleep_ctrl_addr, &vreg->sleep_ctrl_reg, 1);
+	rc = pm8xxx_readb(vreg->dev->parent, vreg->sleep_ctrl_addr,
+						&vreg->sleep_ctrl_reg);
 	if (rc)
 		goto bail;
 
@@ -1585,7 +1572,7 @@
 		vreg->optimum = REGULATOR_MODE_FAST;
 
 	/* Set advanced mode pull down enable based on platform data. */
-	rc = pm8058_vreg_write(chip, vreg->test_addr,
+	rc = pm8058_vreg_write(vreg, vreg->test_addr,
 		(vreg->pdata->pull_down_enable
 			? SMPS_ADVANCED_PULL_DOWN_ENABLE : 0)
 		| REGULATOR_BANK_SEL(6) | REGULATOR_BANK_WRITE,
@@ -1596,7 +1583,7 @@
 
 	if (!SMPS_IN_ADVANCED_MODE(vreg)) {
 		/* Set legacy mode pull down enable based on platform data. */
-		rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+		rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
 			(vreg->pdata->pull_down_enable
 				? SMPS_LEGACY_PULL_DOWN_ENABLE : 0),
 			SMPS_LEGACY_PULL_DOWN_ENABLE, &vreg->ctrl_reg);
@@ -1608,26 +1595,27 @@
 	return rc;
 }
 
-static int pm8058_init_lvs(struct pm8058_chip *chip, struct pm8058_vreg *vreg)
+static int pm8058_init_lvs(struct pm8058_vreg *vreg)
 {
 	int rc = 0;
 
 	vreg->optimum = REGULATOR_MODE_FAST;
 
 	/* Set pull down enable based on platform data. */
-	rc = pm8058_vreg_write(chip, vreg->ctrl_addr,
+	rc = pm8058_vreg_write(vreg, vreg->ctrl_addr,
 		(vreg->pdata->pull_down_enable
 			? LVS_PULL_DOWN_ENABLE : LVS_PULL_DOWN_DISABLE),
 		LVS_PULL_DOWN_ENABLE_MASK, &vreg->ctrl_reg);
 	return rc;
 }
 
-static int pm8058_init_ncp(struct pm8058_chip *chip, struct pm8058_vreg *vreg)
+static int pm8058_init_ncp(struct pm8058_vreg *vreg)
 {
 	int rc = 0;
 
 	/* Save the current test1 register state. */
-	rc = pm8058_read(chip, vreg->test_addr, &vreg->test_reg[0], 1);
+	rc = pm8xxx_readb(vreg->dev->parent, vreg->test_addr,
+					&vreg->test_reg[0]);
 	if (rc)
 		goto bail;
 
@@ -1637,8 +1625,7 @@
 	return rc;
 }
 
-static int pm8058_init_regulator(struct pm8058_chip *chip,
-		struct pm8058_vreg *vreg)
+static int pm8058_init_regulator(struct pm8058_vreg *vreg)
 {
 	static int master_enable_inited;
 	int rc = 0;
@@ -1646,28 +1633,28 @@
 	vreg->mode_initialized = 0;
 
 	if (!master_enable_inited) {
-		rc = pm8058_master_enable_init(chip);
+		rc = pm8058_master_enable_init(vreg);
 		if (!rc)
 			master_enable_inited = 1;
 	}
 
 	/* save the current control register state */
-	rc = pm8058_read(chip, vreg->ctrl_addr, &vreg->ctrl_reg, 1);
+	rc = pm8xxx_readb(vreg->dev->parent, vreg->ctrl_addr, &vreg->ctrl_reg);
 	if (rc)
 		goto bail;
 
 	switch (vreg->type) {
 	case REGULATOR_TYPE_LDO:
-		rc = pm8058_init_ldo(chip, vreg);
+		rc = pm8058_init_ldo(vreg);
 		break;
 	case REGULATOR_TYPE_SMPS:
-		rc = pm8058_init_smps(chip, vreg);
+		rc = pm8058_init_smps(vreg);
 		break;
 	case REGULATOR_TYPE_LVS:
-		rc = pm8058_init_lvs(chip, vreg);
+		rc = pm8058_init_lvs(vreg);
 		break;
 	case REGULATOR_TYPE_NCP:
-		rc = pm8058_init_ncp(chip, vreg);
+		rc = pm8058_init_ncp(vreg);
 		break;
 	}
 
@@ -1681,7 +1668,6 @@
 static int __devinit pm8058_vreg_probe(struct platform_device *pdev)
 {
 	struct regulator_desc *rdesc;
-	struct pm8058_chip *chip;
 	struct pm8058_vreg *vreg;
 	const char *reg_name = NULL;
 	int rc = 0;
@@ -1690,13 +1676,13 @@
 		return -EINVAL;
 
 	if (pdev->id >= 0 && pdev->id < PM8058_VREG_MAX) {
-		chip = dev_get_drvdata(pdev->dev.parent);
 		rdesc = &pm8058_vreg_descrip[pdev->id];
 		vreg = &pm8058_vreg[pdev->id];
 		vreg->pdata = pdev->dev.platform_data;
 		reg_name = pm8058_vreg_descrip[pdev->id].name;
+		vreg->dev = &pdev->dev;
 
-		rc = pm8058_init_regulator(chip, vreg);
+		rc = pm8058_init_regulator(vreg);
 		if (rc)
 			goto bail;
 
@@ -1705,7 +1691,6 @@
 			vreg->pdata->init_data.constraints.valid_modes_mask
 			      &= ~(REGULATOR_MODE_NORMAL | REGULATOR_MODE_IDLE);
 
-		platform_set_drvdata(pdev, chip);
 		vreg->rdev = regulator_register(rdesc, &pdev->dev,
 				&vreg->pdata->init_data, vreg);
 		if (IS_ERR(vreg->rdev)) {
diff --git a/drivers/thermal/pm8xxx-tm.c b/drivers/thermal/pm8xxx-tm.c
index d9f9c9e..1d518e3 100644
--- a/drivers/thermal/pm8xxx-tm.c
+++ b/drivers/thermal/pm8xxx-tm.c
@@ -30,6 +30,7 @@
 #include <linux/mfd/pm8xxx/tm.h>
 #include <linux/completion.h>
 #include <linux/mfd/pm8xxx/pm8921-adc.h>
+#include <linux/msm_adc.h>
 
 /* Register TEMP_ALARM_CTRL bits */
 #define	TEMP_ALARM_CTRL_ST3_SD		0x80
@@ -226,6 +227,43 @@
 	return 0;
 }
 
+static int pm8xxx_tz_get_temp_pm8058_adc(struct thermal_zone_device *thermal,
+			      unsigned long *temp)
+{
+	struct pm8xxx_tm_chip *chip = thermal->devdata;
+	DECLARE_COMPLETION_ONSTACK(wait);
+	struct adc_chan_result adc_result = {
+		.physical = 0lu,
+	};
+	int rc;
+
+	if (!chip || !temp)
+		return -EINVAL;
+
+	*temp = chip->temp;
+
+	rc = adc_channel_request_conv(chip->adc_handle, &wait);
+	if (rc < 0) {
+		pr_err("%s: adc_channel_request_conv() failed, rc = %d\n",
+			__func__, rc);
+		return rc;
+	}
+
+	wait_for_completion(&wait);
+
+	rc = adc_channel_read_result(chip->adc_handle, &adc_result);
+	if (rc < 0) {
+		pr_err("%s: adc_channel_read_result() failed, rc = %d\n",
+			__func__, rc);
+		return rc;
+	}
+
+	*temp = adc_result.physical;
+	chip->temp = adc_result.physical;
+
+	return 0;
+}
+
 static int pm8xxx_tz_get_temp_pm8921_adc(struct thermal_zone_device *thermal,
 				      unsigned long *temp)
 {
@@ -372,6 +410,15 @@
 	.get_crit_temp = pm8xxx_tz_get_crit_temp,
 };
 
+static struct thermal_zone_device_ops pm8xxx_thermal_zone_ops_pm8058_adc = {
+	.get_temp = pm8xxx_tz_get_temp_pm8058_adc,
+	.get_mode = pm8xxx_tz_get_mode,
+	.set_mode = pm8xxx_tz_set_mode,
+	.get_trip_type = pm8xxx_tz_get_trip_type,
+	.get_trip_temp = pm8xxx_tz_get_trip_temp,
+	.get_crit_temp = pm8xxx_tz_get_crit_temp,
+};
+
 static void pm8xxx_tm_work(struct work_struct *work)
 {
 	struct pm8xxx_tm_chip *chip
@@ -465,6 +512,24 @@
 	return rc;
 }
 
+static int pm8xxx_init_adc(struct pm8xxx_tm_chip *chip, bool enable)
+{
+	int rc = 0;
+
+	if (chip->cdata.adc_type == PM8XXX_TM_ADC_PM8058_ADC) {
+		if (enable) {
+			rc = adc_channel_open(chip->cdata.adc_channel,
+						&(chip->adc_handle));
+			if (rc < 0)
+				pr_err("adc_channel_open() failed.\n");
+		} else {
+			adc_channel_close(chip->adc_handle);
+		}
+	}
+
+	return rc;
+}
+
 static int __devinit pm8xxx_tm_probe(struct platform_device *pdev)
 {
 	const struct pm8xxx_tm_core_data *cdata = pdev->dev.platform_data;
@@ -505,18 +570,27 @@
 		goto err_free_chip;
 	}
 
+	rc = pm8xxx_init_adc(chip, true);
+	if (rc < 0) {
+		pr_err("Unable to initialize adc\n");
+		goto err_free_chip;
+	}
+
 	/* Select proper thermal zone ops functions based on ADC type. */
 	if (chip->cdata.adc_type == PM8XXX_TM_ADC_PM8921_ADC)
 		tz_ops = &pm8xxx_thermal_zone_ops_pm8921_adc;
+	else if (chip->cdata.adc_type == PM8XXX_TM_ADC_PM8058_ADC)
+		tz_ops = &pm8xxx_thermal_zone_ops_pm8058_adc;
 	else
 		tz_ops = &pm8xxx_thermal_zone_ops_no_adc;
 
 	chip->tz_dev = thermal_zone_device_register(chip->cdata.tm_name,
 			TRIP_NUM, chip, tz_ops, 0, 0, 0, 0);
+
 	if (chip->tz_dev == NULL) {
 		pr_err("thermal_zone_device_register() failed.\n");
 		rc = -ENODEV;
-		goto err_free_chip;
+		goto err_fail_adc;
 	}
 
 	rc = pm8xxx_tm_init_reg(chip);
@@ -564,6 +638,8 @@
 	cancel_work_sync(&chip->irq_work);
 err_free_tz:
 	thermal_zone_device_unregister(chip->tz_dev);
+err_fail_adc:
+	pm8xxx_init_adc(chip, false);
 err_free_chip:
 	kfree(chip);
 	return rc;
@@ -579,6 +655,7 @@
 		free_irq(chip->overtemp_irq, chip);
 		free_irq(chip->tempstat_irq, chip);
 		pm8xxx_tm_shutdown_override(chip, SOFTWARE_OVERRIDE_DISABLED);
+		pm8xxx_init_adc(chip, false);
 		thermal_zone_device_unregister(chip->tz_dev);
 		kfree(chip);
 	}
diff --git a/drivers/usb/otg/msm_otg.c b/drivers/usb/otg/msm_otg.c
index 1eb8511..4622725 100644
--- a/drivers/usb/otg/msm_otg.c
+++ b/drivers/usb/otg/msm_otg.c
@@ -25,6 +25,8 @@
 #include <linux/debugfs.h>
 #include <linux/seq_file.h>
 #include <linux/pm_runtime.h>
+#include <linux/of.h>
+#include <linux/dma-mapping.h>
 
 #include <linux/usb.h>
 #include <linux/usb/otg.h>
@@ -2031,17 +2033,147 @@
 	debugfs_remove_recursive(msm_otg_dbg_root);
 }
 
+static u64 msm_otg_dma_mask = DMA_BIT_MASK(64);
+static struct platform_device *msm_otg_add_pdev(
+		struct platform_device *ofdev, const char *name)
+{
+	struct platform_device *pdev;
+	const struct resource *res = ofdev->resource;
+	unsigned int num = ofdev->num_resources;
+	int retval;
+
+	pdev = platform_device_alloc(name, -1);
+	if (!pdev) {
+		retval = -ENOMEM;
+		goto error;
+	}
+
+	pdev->dev.coherent_dma_mask = DMA_BIT_MASK(32);
+	pdev->dev.dma_mask = &msm_otg_dma_mask;
+
+	if (num) {
+		retval = platform_device_add_resources(pdev, res, num);
+		if (retval)
+			goto error;
+	}
+
+	retval = platform_device_add(pdev);
+	if (retval)
+		goto error;
+
+	return pdev;
+
+error:
+	platform_device_put(pdev);
+	return ERR_PTR(retval);
+}
+
+static int msm_otg_setup_devices(struct platform_device *ofdev,
+		enum usb_mode_type mode, bool init)
+{
+	const char *gadget_name = "msm_hsusb";
+	const char *host_name = "msm_hsusb_host";
+	static struct platform_device *gadget_pdev;
+	static struct platform_device *host_pdev;
+	int retval = 0;
+
+	if (!init) {
+		if (gadget_pdev)
+			platform_device_unregister(gadget_pdev);
+		if (host_pdev)
+			platform_device_unregister(host_pdev);
+		return 0;
+	}
+
+	switch (mode) {
+	case USB_OTG:
+		/* fall through */
+	case USB_PERIPHERAL:
+		gadget_pdev = msm_otg_add_pdev(ofdev, gadget_name);
+		if (IS_ERR(gadget_pdev)) {
+			retval = PTR_ERR(gadget_pdev);
+			break;
+		}
+		if (mode == USB_PERIPHERAL)
+			break;
+		/* fall through */
+	case USB_HOST:
+		host_pdev = msm_otg_add_pdev(ofdev, host_name);
+		if (IS_ERR(host_pdev)) {
+			retval = PTR_ERR(host_pdev);
+			if (mode == USB_OTG)
+				platform_device_unregister(gadget_pdev);
+		}
+		break;
+	default:
+		break;
+	}
+
+	return retval;
+}
+
+struct msm_otg_platform_data *msm_otg_dt_to_pdata(struct platform_device *pdev)
+{
+	struct device_node *node = pdev->dev.of_node;
+	struct msm_otg_platform_data *pdata;
+	int len = 0;
+
+	pdata = devm_kzalloc(&pdev->dev, sizeof(*pdata), GFP_KERNEL);
+	if (!pdata) {
+		pr_err("unable to allocate platform data\n");
+		return NULL;
+	}
+	of_get_property(node, "qcom,hsusb-otg-phy-init-seq", &len);
+	if (len) {
+		pdata->phy_init_seq = devm_kzalloc(&pdev->dev, len, GFP_KERNEL);
+		if (!pdata->phy_init_seq)
+			return NULL;
+		of_property_read_u32_array(node, "qcom,hsusb-otg-phy-init-seq",
+				pdata->phy_init_seq,
+				len/sizeof(*pdata->phy_init_seq));
+	}
+	of_property_read_u32(node, "qcom,hsusb-otg-power-budget",
+				&pdata->power_budget);
+	of_property_read_u32(node, "qcom,hsusb-otg-mode",
+				&pdata->mode);
+	of_property_read_u32(node, "qcom,hsusb-otg-otg-control",
+				&pdata->otg_control);
+	of_property_read_u32(node, "qcom,hsusb-otg-default-mode",
+				&pdata->default_mode);
+	of_property_read_u32(node, "qcom,hsusb-otg-phy-type",
+				&pdata->phy_type);
+	of_property_read_u32(node, "qcom,hsusb-otg-pmic-id-irq",
+				&pdata->pmic_id_irq);
+	of_property_read_string(node, "qcom,hsusb-otg-pclk-src-name",
+				&pdata->pclk_src_name);
+	return pdata;
+}
+
 static int __init msm_otg_probe(struct platform_device *pdev)
 {
 	int ret = 0;
 	struct resource *res;
 	struct msm_otg *motg;
 	struct otg_transceiver *otg;
+	struct msm_otg_platform_data *pdata;
 
 	dev_info(&pdev->dev, "msm_otg probe\n");
-	if (!pdev->dev.platform_data) {
+
+	if (pdev->dev.of_node) {
+		dev_dbg(&pdev->dev, "device tree enabled\n");
+		pdata = msm_otg_dt_to_pdata(pdev);
+		if (!pdata)
+			return -ENOMEM;
+		ret = msm_otg_setup_devices(pdev, pdata->mode, true);
+		if (ret) {
+			dev_err(&pdev->dev, "devices setup failed\n");
+			return ret;
+		}
+	} else if (!pdev->dev.platform_data) {
 		dev_err(&pdev->dev, "No platform data given. Bailing out\n");
 		return -ENODEV;
+	} else {
+		pdata = pdev->dev.platform_data;
 	}
 
 	motg = kzalloc(sizeof(struct msm_otg), GFP_KERNEL);
@@ -2051,7 +2183,7 @@
 	}
 
 	the_msm_otg = motg;
-	motg->pdata = pdev->dev.platform_data;
+	motg->pdata = pdata;
 	otg = &motg->otg;
 	otg->dev = &pdev->dev;
 
@@ -2289,6 +2421,8 @@
 	if (otg->host || otg->gadget)
 		return -EBUSY;
 
+	if (pdev->dev.of_node)
+		msm_otg_setup_devices(pdev, motg->pdata->mode, false);
 	if (motg->pdata->otg_control == OTG_PMIC_CONTROL)
 		pm8921_charger_unregister_vbus_sn(0);
 	msm_otg_debugfs_cleanup();
@@ -2428,6 +2562,12 @@
 };
 #endif
 
+static struct of_device_id msm_otg_dt_match[] = {
+	{	.compatible = "qcom,hsusb-otg",
+	},
+	{}
+};
+
 static struct platform_driver msm_otg_driver = {
 	.remove = __devexit_p(msm_otg_remove),
 	.driver = {
@@ -2436,6 +2576,7 @@
 #ifdef CONFIG_PM
 		.pm = &msm_otg_dev_pm_ops,
 #endif
+		.of_match_table = msm_otg_dt_match,
 	},
 };
 
diff --git a/drivers/video/msm/Makefile b/drivers/video/msm/Makefile
index f5a7c9e..dc02da4 100644
--- a/drivers/video/msm/Makefile
+++ b/drivers/video/msm/Makefile
@@ -10,6 +10,7 @@
 
 ifeq ($(CONFIG_FB_MSM_MDP40),y)
 obj-y += mdp4_util.o
+obj-y += mdp4_hsic.o
 else
 obj-y += mdp_hw_init.o
 obj-y += mdp_ppp.o
diff --git a/drivers/video/msm/mdp4.h b/drivers/video/msm/mdp4.h
index 0aeb91e..65b64f6 100644
--- a/drivers/video/msm/mdp4.h
+++ b/drivers/video/msm/mdp4.h
@@ -222,6 +222,15 @@
 
 #define MDP4_MAX_PLANE		4
 
+struct mdp4_hsic_regs {
+	int32_t params[NUM_HSIC_PARAM];
+	int32_t conv_matrix[3][3];
+	int32_t	pre_limit[6];
+	int32_t post_limit[6];
+	int32_t pre_bias[3];
+	int32_t post_bias[3];
+	int32_t dirty;
+};
 
 struct mdp4_overlay_pipe {
 	uint32 pipe_used;
@@ -298,6 +307,7 @@
 	uint32 dmap_cnt;
 	uint32 blt_end;
 	uint32 luma_align_size;
+	struct mdp4_hsic_regs hsic_regs;
 	struct completion dmas_comp;
 	struct mdp_overlay req_data;
 };
@@ -637,4 +647,6 @@
 int mdp4_writeback_init(struct fb_info *info);
 int mdp4_writeback_terminate(struct fb_info *info);
 
+void mdp4_hsic_set(struct mdp4_overlay_pipe *pipe, struct dpp_ctrl *ctrl);
+void mdp4_hsic_update(struct mdp4_overlay_pipe *pipe);
 #endif /* MDP_H */
diff --git a/drivers/video/msm/mdp4_hsic.c b/drivers/video/msm/mdp4_hsic.c
new file mode 100644
index 0000000..5735f45
--- /dev/null
+++ b/drivers/video/msm/mdp4_hsic.c
@@ -0,0 +1,534 @@
+/* Copyright (c) 2009-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.
+ *
+ */
+
+#include <linux/module.h>
+#include <linux/types.h>
+#include <linux/msm_mdp.h>
+#include "mdp.h"
+#include "mdp4.h"
+
+/* Definitions */
+#define MDP4_CSC_MV_OFF		0x4400
+#define MDP4_CSC_PRE_BV_OFF	0x4500
+#define MDP4_CSC_POST_BV_OFF	0x4580
+#define MDP4_CSC_PRE_LV_OFF	0x4600
+#define MDP4_CSC_POST_LV_OFF	0x4680
+#define MDP_VG1_BASE	(MDP_BASE + MDP4_VIDEO_BASE)
+
+#define MDP_VG1_CSC_MVn(n)	(MDP_VG1_BASE + MDP4_CSC_MV_OFF + 4 * (n))
+#define MDP_VG1_CSC_PRE_LVn(n)	(MDP_VG1_BASE + MDP4_CSC_PRE_LV_OFF + 4 * (n))
+#define MDP_VG1_CSC_POST_LVn(n)	(MDP_VG1_BASE + MDP4_CSC_POST_LV_OFF + 4 * (n))
+#define MDP_VG1_CSC_PRE_BVn(n)	(MDP_VG1_BASE + MDP4_CSC_PRE_BV_OFF + 4 * (n))
+#define MDP_VG1_CSC_POST_BVn(n)	(MDP_VG1_BASE + MDP4_CSC_POST_BV_OFF + 4 * (n))
+
+#define Q16	(16)
+#define Q16_ONE	(1 << Q16)
+
+#define Q16_VALUE(x)	((int32_t)((uint32_t)x << Q16))
+#define Q16_PERCENT_VALUE(x, n)	((int32_t)( \
+				div_s64(((int64_t)x * (int64_t)Q16_ONE), n)))
+
+#define Q16_WHOLE(x)	((int32_t)(x >> 16))
+#define Q16_FRAC(x)	((int32_t)(x & 0xFFFF))
+#define Q16_S1Q16_MUL(x, y)	(((x >> 1) * (y >> 1)) >> 14)
+
+#define Q16_MUL(x, y)	((int32_t)((((int64_t)x) * ((int64_t)y)) >> Q16))
+#define Q16_NEGATE(x)	(0 - (x))
+
+/*
+ * HSIC Control min/max values
+ *    These settings are based on the maximum/minimum allowed modifications to
+ *    HSIC controls for layer and display color.  Allowing too much variation in
+ *    the CSC block will result in color clipping resulting in unwanted color
+ *    shifts.
+ */
+#define TRIG_MAX	Q16_VALUE(128)
+#define CON_SAT_MAX	Q16_VALUE(128)
+#define INTENSITY_MAX	(Q16_VALUE(2047) >> 12)
+
+#define HUE_MAX	Q16_VALUE(100)
+#define HUE_MIN	Q16_VALUE(-100)
+#define HUE_DEF	Q16_VALUE(0)
+
+#define SAT_MAX	Q16_VALUE(100)
+#define SAT_MIN	Q16_VALUE(-100)
+#define SAT_DEF	CON_SAT_MAX
+
+#define CON_MAX	Q16_VALUE(100)
+#define CON_MIN	Q16_VALUE(-100)
+#define CON_DEF	CON_SAT_MAX
+
+#define INTEN_MAX	Q16_VALUE(100)
+#define INTEN_MIN	Q16_VALUE(-100)
+#define INTEN_DEF	Q16_VALUE(0)
+
+enum {
+	DIRTY,
+	GENERATED,
+	CLEAN
+};
+
+/* local vars*/
+static int32_t csc_matrix_tab[3][3] = {
+	{0x00012a00, 0x00000000, 0x00019880},
+	{0x00012a00, 0xffff9b80, 0xffff3000},
+	{0x00012a00, 0x00020480, 0x00000000}
+};
+
+static int32_t csc_yuv2rgb_conv_tab[3][3] = {
+	{0x00010000, 0x00000000, 0x000123cb},
+	{0x00010000, 0xffff9af9, 0xffff6b5e},
+	{0x00010000, 0x00020838, 0x00000000}
+};
+
+static int32_t csc_rgb2yuv_conv_tab[3][3] = {
+	{0x00004c8b, 0x00009645, 0x00001d2f},
+	{0xffffda56, 0xffffb60e, 0x00006f9d},
+	{0x00009d70, 0xffff7c2a, 0xffffe666}
+};
+
+static uint32_t csc_pre_bv_tab[3]  = {0xfffff800, 0xffffc000, 0xffffc000};
+static uint32_t csc_post_bv_tab[3] = {0x00000000, 0x00000000, 0x00000000};
+
+static uint32_t csc_pre_lv_tab[6] =  {0x00000000, 0x00007f80, 0x00000000,
+					0x00007f80, 0x00000000, 0x00007f80};
+static uint32_t csc_post_lv_tab[6] = {0x00000000, 0x00007f80, 0x00000000,
+					0x00007f80, 0x00000000, 0x00007f80};
+
+/* Lookup table for Sin/Cos lookup - Q16*/
+static const int32_t  trig_lut[65] = {
+	0x00000000, /* sin((2*M_PI/256) * 0x00);*/
+	0x00000648, /* sin((2*M_PI/256) * 0x01);*/
+	0x00000C90, /* sin((2*M_PI/256) * 0x02);*/
+	0x000012D5,
+	0x00001918,
+	0x00001F56,
+	0x00002590,
+	0x00002BC4,
+	0x000031F1,
+	0x00003817,
+	0x00003E34,
+	0x00004447,
+	0x00004A50,
+	0x0000504D,
+	0x0000563E,
+	0x00005C22,
+	0x000061F8,
+	0x000067BE,
+	0x00006D74,
+	0x0000731A,
+	0x000078AD,
+	0x00007E2F,
+	0x0000839C,
+	0x000088F6,
+	0x00008E3A,
+	0x00009368,
+	0x00009880,
+	0x00009D80,
+	0x0000A268,
+	0x0000A736,
+	0x0000ABEB,
+	0x0000B086,
+	0x0000B505,
+	0x0000B968,
+	0x0000BDAF,
+	0x0000C1D8,
+	0x0000C5E4,
+	0x0000C9D1,
+	0x0000CD9F,
+	0x0000D14D,
+	0x0000D4DB,
+	0x0000D848,
+	0x0000DB94,
+	0x0000DEBE,
+	0x0000E1C6,
+	0x0000E4AA,
+	0x0000E768,
+	0x0000EA0A,
+	0x0000EC83,
+	0x0000EED9,
+	0x0000F109,
+	0x0000F314,
+	0x0000F4FA,
+	0x0000F6BA,
+	0x0000F854,
+	0x0000F9C8,
+	0x0000FB15,
+	0x0000FC3B,
+	0x0000FD3B,
+	0x0000FE13,
+	0x0000FEC4,
+	0x0000FF4E,
+	0x0000FFB1,
+	0x0000FFEC,
+	0x00010000, /* sin((2*M_PI/256) * 0x40);*/
+};
+
+void trig_values_q16(int32_t deg, int32_t *cos, int32_t *sin)
+{
+	int32_t   angle;
+	int32_t   quad, anglei, anglef;
+	int32_t   v0 = 0, v1 = 0;
+	int32_t   t1, t2;
+
+	/*
+	 * Scale the angle so that 256 is one complete revolution and mask it
+	 * to this domain
+	 * NOTE: 0xB60B == 256/360
+	 */
+	angle = Q16_MUL(deg, 0xB60B) & 0x00FFFFFF;
+
+	/* Obtain a quadrant number, integer, and fractional part */
+	quad   =  angle >> 22;
+	anglei = (angle >> 16) & 0x3F;
+	anglef =  angle & 0xFFFF;
+
+	/*
+	 * Using the integer part, obtain the lookup table entry and its
+	 * complement. Using the quadrant, swap and negate these as
+	 * necessary.
+	 * (The values and all derivatives of sine and cosine functions
+	 * can be derived from these values)
+	 */
+	switch (quad) {
+	case 0x0:
+		v0 += trig_lut[anglei];
+		v1 += trig_lut[0x40-anglei];
+		break;
+
+	case 0x1:
+		v0 += trig_lut[0x40-anglei];
+		v1 -= trig_lut[anglei];
+		break;
+
+	case 0x2:
+		v0 -= trig_lut[anglei];
+		v1 -= trig_lut[0x40-anglei];
+		break;
+
+	case 0x3:
+		v0 -= trig_lut[0x40-anglei];
+		v1 += trig_lut[anglei];
+		break;
+	}
+
+	/*
+	 * Multiply the fractional part by 2*PI/256 to move it from lookup
+	 *  table units to radians, giving us the coefficient for first
+	 *  derivatives.
+	 */
+	t1 = Q16_S1Q16_MUL(anglef, 0x0648);
+
+	/*
+	 * Square this and divide by 2 to get the coefficient for second
+	 *   derivatives
+	 */
+	t2 = Q16_S1Q16_MUL(t1, t1) >> 1;
+
+	*sin = v0 + Q16_S1Q16_MUL(v1, t1) - Q16_S1Q16_MUL(v0, t2);
+
+	*cos = v1 - Q16_S1Q16_MUL(v0, t1) - Q16_S1Q16_MUL(v1, t2);
+}
+
+/* Convert input Q16 value to s4.9 */
+int16_t convert_q16_s49(int32_t q16Value)
+{	/* Top half is the whole number, Bottom half is fractional portion*/
+	int16_t whole = Q16_WHOLE(q16Value);
+	int32_t fraction  = Q16_FRAC(q16Value);
+
+	/* Clamp whole to 3 bits */
+	if (whole > 7)
+		whole = 7;
+	else if (whole < -7)
+		whole = -7;
+
+	/* Reduce fraction to 9 bits. */
+	fraction = (fraction<<9)>>Q16;
+
+	return (int16_t) ((int16_t)whole<<9) | ((int16_t)fraction);
+}
+
+/* Convert input Q16 value to uint16 */
+int16_t convert_q16_int16(int32_t val)
+{
+	int32_t rounded;
+
+	if (val >= 0) {
+		/* Add 0.5 */
+		rounded = val + (Q16_ONE>>1);
+	} else {
+		/* Subtract 0.5 */
+		rounded = val - (Q16_ONE>>1);
+	}
+
+	/* Truncate rounded value */
+	return (int16_t)(rounded>>Q16);
+}
+
+/*
+ * norm_q16
+ *              Return a Q16 value represeting a normalized value
+ *
+ * value       -100%                 0%               +100%
+ *                 |-----------------|----------------|
+ *                 ^                 ^                ^
+ *             q16MinValue     q16DefaultValue       q16MaxValue
+ *
+ */
+int32_t norm_q16(int32_t value, int32_t min, int32_t default_val, int32_t max,
+								int32_t range)
+{
+	int32_t diff, perc, mul, result;
+
+	if (0 == value) {
+		result = default_val;
+	} else if (value > 0) {
+		/* value is between 0% and +100% represent 1.0 -> QRange Max */
+		diff = range;
+		perc = Q16_PERCENT_VALUE(value, max);
+		mul = Q16_MUL(perc, diff);
+		result = default_val + mul;
+	} else {
+		/* if (value <= 0) */
+		diff = -range;
+		perc = Q16_PERCENT_VALUE(-value, -min);
+		mul = Q16_MUL(perc, diff);
+		result = default_val + mul;
+	}
+	return result;
+}
+
+void matrix_mul_3x3(int32_t dest[][3], int32_t a[][3], int32_t b[][3])
+{
+	int32_t i, j, k;
+	int32_t tmp[3][3];
+
+	for (i = 0; i < 3; i++) {
+		for (j = 0; j < 3; j++) {
+			tmp[i][j] = 0;
+			for (k = 0; k < 3; k++)
+				tmp[i][j] += Q16_MUL(a[i][k], b[k][j]);
+		}
+	}
+
+	/* in case dest = a or b*/
+	for (i = 0; i < 3; i++) {
+		for (j = 0; j < 3; j++)
+			dest[i][j] = tmp[i][j];
+	}
+}
+
+#define CONVERT(x)	(x)/*convert_q16_s49((x))*/
+void pr_params(struct mdp4_hsic_regs *regs)
+{
+	int i;
+	if (regs) {
+		for (i = 0; i < NUM_HSIC_PARAM; i++) {
+			pr_info("\t: hsic->params[%d] =	0x%08x [raw = 0x%08x]\n",
+			i, CONVERT(regs->params[i]), regs->params[i]);
+		}
+	}
+}
+
+void pr_3x3_matrix(int32_t in[][3])
+{
+	pr_info("\t[0x%08x\t0x%08x\t0x%08x]\n", CONVERT(in[0][0]),
+	CONVERT(in[0][1]), CONVERT(in[0][2]));
+	pr_info("\t[0x%08x\t0x%08x\t0x%08x]\n", CONVERT(in[1][0]),
+	CONVERT(in[1][1]), CONVERT(in[1][2]));
+	pr_info("\t[0x%08x\t0x%08x\t0x%08x]\n", CONVERT(in[2][0]),
+	CONVERT(in[2][1]), CONVERT(in[2][2]));
+}
+
+void _hsic_get(struct mdp4_hsic_regs *regs, int32_t type, int8_t *val)
+{
+	if (type < 0 || type >= NUM_HSIC_PARAM)
+		BUG_ON(-EINVAL);
+	*val = regs->params[type];
+	pr_info("%s: getting params[%d] = %d\n", __func__, type, *val);
+}
+
+void _hsic_set(struct mdp4_hsic_regs *regs, int32_t type, int8_t val)
+{
+	if (type < 0 || type >= NUM_HSIC_PARAM)
+		BUG_ON(-EINVAL);
+
+	if (regs->params[type] != Q16_VALUE(val)) {
+		regs->params[type] = Q16_VALUE(val);
+		regs->dirty = DIRTY;
+	}
+}
+
+void _hsic_generate_csc_matrix(struct mdp4_overlay_pipe *pipe)
+{
+	int i, j;
+	int32_t sin, cos;
+
+	int32_t hue_matrix[3][3];
+	int32_t con_sat_matrix[3][3];
+	struct mdp4_hsic_regs *regs = &(pipe->hsic_regs);
+
+	memset(con_sat_matrix, 0x0, sizeof(con_sat_matrix));
+	memset(hue_matrix, 0x0, sizeof(hue_matrix));
+
+	/*
+	 * HSIC control require matrix multiplication of these two tables
+	 *  [T 0 0][1 0  0]   T = Contrast       C=Cos(Hue)
+	 *  [0 S 0][0 C -N]   S = Saturation     N=Sin(Hue)
+	 *  [0 0 S][0 N  C]
+	 */
+
+	con_sat_matrix[0][0] = norm_q16(regs->params[HSIC_CON], CON_MIN,
+						CON_DEF, CON_MAX, CON_SAT_MAX);
+	con_sat_matrix[1][1] = norm_q16(regs->params[HSIC_SAT], SAT_MIN,
+						SAT_DEF, SAT_MAX, CON_SAT_MAX);
+	con_sat_matrix[2][2] = con_sat_matrix[1][1];
+
+	hue_matrix[0][0] = TRIG_MAX;
+
+	trig_values_q16(norm_q16(regs->params[HSIC_HUE], HUE_MIN, HUE_DEF,
+					 HUE_MAX, TRIG_MAX), &cos, &sin);
+
+	cos = Q16_MUL(cos, TRIG_MAX);
+	sin = Q16_MUL(sin, TRIG_MAX);
+
+	hue_matrix[1][1] = cos;
+	hue_matrix[2][2] = cos;
+	hue_matrix[2][1] = sin;
+	hue_matrix[1][2] = Q16_NEGATE(sin);
+
+	/* Generate YUV CSC matrix */
+	matrix_mul_3x3(regs->conv_matrix, con_sat_matrix, hue_matrix);
+
+	if (!(pipe->op_mode & MDP4_OP_SRC_DATA_YCBCR)) {
+		/* Convert input RGB to YUV then apply CSC matrix */
+		pr_info("Pipe %d, has RGB input\n", pipe->pipe_num);
+		matrix_mul_3x3(regs->conv_matrix, regs->conv_matrix,
+							csc_rgb2yuv_conv_tab);
+	}
+
+	/* Normalize the matrix */
+	for (i = 0; i < 3; i++) {
+		for (j = 0; j < 3; j++)
+			regs->conv_matrix[i][j] = (regs->conv_matrix[i][j]>>14);
+	}
+
+	/* Multiply above result by current csc table */
+	matrix_mul_3x3(regs->conv_matrix, regs->conv_matrix, csc_matrix_tab);
+
+	if (!(pipe->op_mode & MDP4_OP_SRC_DATA_YCBCR)) {
+		/*HACK:only "works"for src side*/
+		/* Convert back to RGB */
+		pr_info("Pipe %d, has RGB output\n", pipe->pipe_num);
+		matrix_mul_3x3(regs->conv_matrix, csc_yuv2rgb_conv_tab,
+							regs->conv_matrix);
+	}
+
+	/* Update clamps pre and post. */
+	/* TODO: different tables for different color formats? */
+	for (i = 0; i < 6; i++) {
+		regs->pre_limit[i] = csc_pre_lv_tab[i];
+		regs->post_limit[i] = csc_post_lv_tab[i];
+	}
+
+	/* update bias values, pre and post */
+	for (i = 0; i < 3; i++) {
+		regs->pre_bias[i] = csc_pre_bv_tab[i];
+		regs->post_bias[i] = csc_post_bv_tab[i] +
+				norm_q16(regs->params[HSIC_INT],
+				INTEN_MIN, INTEN_DEF, INTEN_MAX, INTENSITY_MAX);
+	}
+
+	regs->dirty = GENERATED;
+}
+
+void _hsic_update_mdp(struct mdp4_overlay_pipe *pipe)
+{
+	struct mdp4_hsic_regs *regs = &(pipe->hsic_regs);
+	int i, j, k;
+
+	uint32_t *csc_mv;
+	uint32_t *pre_lv;
+	uint32_t *post_lv;
+	uint32_t *pre_bv;
+	uint32_t *post_bv;
+
+	switch (pipe->pipe_num) {
+	case OVERLAY_PIPE_VG2:
+		csc_mv = (uint32_t *) (MDP_VG1_CSC_MVn(0) +
+					MDP4_VIDEO_OFF);
+		pre_lv = (uint32_t *) (MDP_VG1_CSC_PRE_LVn(0) +
+					MDP4_VIDEO_OFF);
+		post_lv = (uint32_t *) (MDP_VG1_CSC_POST_LVn(0) +
+					MDP4_VIDEO_OFF);
+		pre_bv = (uint32_t *) (MDP_VG1_CSC_PRE_BVn(0) +
+					MDP4_VIDEO_OFF);
+		post_bv = (uint32_t *) (MDP_VG1_CSC_POST_BVn(0) +
+					MDP4_VIDEO_OFF);
+		break;
+	case OVERLAY_PIPE_VG1:
+	default:
+			csc_mv = (uint32_t *) MDP_VG1_CSC_MVn(0);
+			pre_lv = (uint32_t *) MDP_VG1_CSC_PRE_LVn(0);
+			post_lv = (uint32_t *) MDP_VG1_CSC_POST_LVn(0);
+			pre_bv = (uint32_t *) MDP_VG1_CSC_PRE_BVn(0);
+			post_bv = (uint32_t *) MDP_VG1_CSC_POST_BVn(0);
+		break;
+	}
+
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_ON, FALSE);
+
+	for (i = 0; i < 3; i++) {
+		for (j = 0; j < 3; j++) {
+			k = (3*i) + j;
+			MDP_OUTP(csc_mv + k, convert_q16_s49(
+						regs->conv_matrix[i][j]));
+		}
+	}
+
+	for (i = 0; i < 6; i++) {
+		MDP_OUTP(pre_lv + i, convert_q16_s49(regs->pre_limit[i]));
+		MDP_OUTP(post_lv + i, convert_q16_s49(regs->post_limit[i]));
+	}
+
+	for (i = 0; i < 3; i++) {
+		MDP_OUTP(pre_bv + i, convert_q16_s49(regs->pre_bias[i]));
+		MDP_OUTP(post_bv + i, convert_q16_s49(regs->post_bias[i]));
+	}
+	mdp_pipe_ctrl(MDP_CMD_BLOCK, MDP_BLOCK_POWER_OFF, FALSE);
+
+	regs->dirty = CLEAN;
+}
+
+void mdp4_hsic_get(struct mdp4_overlay_pipe *pipe, struct dpp_ctrl *ctrl)
+{
+	int i;
+	for (i = 0; i < NUM_HSIC_PARAM; i++)
+		_hsic_get(&(pipe->hsic_regs), i, &(ctrl->hsic_params[i]));
+}
+
+void mdp4_hsic_set(struct mdp4_overlay_pipe *pipe, struct dpp_ctrl *ctrl)
+{
+	int i;
+	for (i = 0; i < NUM_HSIC_PARAM; i++)
+		_hsic_set(&(pipe->hsic_regs), i, ctrl->hsic_params[i]);
+
+	if (pipe->hsic_regs.dirty == DIRTY)
+		_hsic_generate_csc_matrix(pipe);
+}
+
+void mdp4_hsic_update(struct mdp4_overlay_pipe *pipe)
+{
+	if (pipe->hsic_regs.dirty == GENERATED)
+		_hsic_update_mdp(pipe);
+}
diff --git a/drivers/video/msm/mdp4_overlay.c b/drivers/video/msm/mdp4_overlay.c
index dbed160..90b68ca 100644
--- a/drivers/video/msm/mdp4_overlay.c
+++ b/drivers/video/msm/mdp4_overlay.c
@@ -2114,6 +2114,10 @@
 		}
 	}
 
+	/* precompute HSIC matrices */
+	if (req->flags & MDP_DPP_HSIC)
+		mdp4_hsic_set(pipe, &(req->dpp));
+
 	mdp4_stat.overlay_set[pipe->mixer_num]++;
 
 	if (ctrl->panel_mode & MDP4_PANEL_MDDI) {
@@ -2163,6 +2167,8 @@
 	struct msm_fb_data_type *mfd = (struct msm_fb_data_type *)info->par;
 	struct mdp4_overlay_pipe *pipe;
 	uint32 flags;
+	struct dpp_ctrl dpp;
+	int i;
 
 	if (mfd == NULL)
 		return -ENODEV;
@@ -2247,6 +2253,15 @@
 	}
 #endif
 
+	/* Reset any HSIC settings to default */
+	if (pipe->flags & MDP_DPP_HSIC) {
+		for (i = 0; i < NUM_HSIC_PARAM; i++)
+			dpp.hsic_params[i] = 0;
+
+		mdp4_hsic_set(pipe, &dpp);
+		mdp4_hsic_update(pipe);
+	}
+
 	mdp4_stat.overlay_unset[pipe->mixer_num]++;
 
 	mdp4_overlay_pipe_free(pipe);
@@ -2533,6 +2548,10 @@
 		}
 	}
 
+	/* write out DPP HSIC registers */
+	if (pipe->flags & MDP_DPP_HSIC)
+		mdp4_hsic_update(pipe);
+
 	mdp4_stat.overlay_play[pipe->mixer_num]++;
 	mutex_unlock(&mfd->dma->ov_mutex);
 end:
diff --git a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
index a0637aa..df65d26 100644
--- a/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
+++ b/drivers/video/msm/vidc/1080p/ddl/vcd_ddl_utils.c
@@ -64,7 +64,7 @@
 		}
 		addr->alloc_handle = ion_alloc(
 		ddl_context->video_ion_client, alloc_size, SZ_4K,
-			(1<<ION_HEAP_EBI_ID));
+			(1<<res_trk_get_mem_type()));
 		if (!addr->alloc_handle) {
 			DDL_MSG_ERROR("%s() :DDL ION alloc failed\n",
 						 __func__);
diff --git a/drivers/video/msm/vidc/common/init/vidc_init.c b/drivers/video/msm/vidc/common/init/vidc_init.c
index 8da4ba5..1217f1f 100644
--- a/drivers/video/msm/vidc/common/init/vidc_init.c
+++ b/drivers/video/msm/vidc/common/init/vidc_init.c
@@ -526,7 +526,8 @@
 		}
 		phys_addr += buffer_addr_offset;
 		(*kernel_vaddr) += buffer_addr_offset;
-		flags = MSM_SUBSYSTEM_MAP_IOVA;
+		flags = (buffer == BUFFER_TYPE_INPUT) ? MSM_SUBSYSTEM_MAP_IOVA :
+		MSM_SUBSYSTEM_MAP_IOVA|MSM_SUBSYSTEM_ALIGN_IOVA_8K;
 		mapped_buffer = msm_subsystem_map_buffer(phys_addr, length,
 		flags, vidc_mmu_subsystem,
 		sizeof(vidc_mmu_subsystem)/sizeof(unsigned int));
diff --git a/drivers/video/msm/vidc/common/vcd/vcd_sub.c b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
index 35ee946..3924088 100644
--- a/drivers/video/msm/vidc/common/vcd/vcd_sub.c
+++ b/drivers/video/msm/vidc/common/vcd/vcd_sub.c
@@ -57,8 +57,8 @@
 		pr_err("%s() map table is full", __func__);
 		goto bailout;
 	}
+	memtype = res_trk_get_mem_type();
 	if (!cctxt->vcd_enable_ion) {
-		memtype = res_trk_get_mem_type();
 		map_buffer->phy_addr = (phys_addr_t)
 		allocate_contiguous_memory_nomap(sz, memtype, SZ_4K);
 		if (!map_buffer->phy_addr) {
@@ -68,7 +68,7 @@
 	} else {
 		map_buffer->alloc_handle = ion_alloc(
 			    cctxt->vcd_ion_client, sz, SZ_4K,
-			    (1<<ION_HEAP_EBI_ID));
+			    (1<<memtype));
 		if (!map_buffer->alloc_handle) {
 			pr_err("%s() ION alloc failed", __func__);
 			goto bailout;
diff --git a/include/linux/mfd/pm8xxx/gpio.h b/include/linux/mfd/pm8xxx/gpio.h
index 0a9c95d..f2e4a21 100644
--- a/include/linux/mfd/pm8xxx/gpio.h
+++ b/include/linux/mfd/pm8xxx/gpio.h
@@ -59,6 +59,16 @@
 #define	PM_GPIO_VIN_L3			5
 #define	PM_GPIO_VIN_L17			6
 
+/* vin_sel: Voltage Input select on PM8058 */
+#define PM8058_GPIO_VIN_VPH		0
+#define PM8058_GPIO_VIN_BB		1
+#define PM8058_GPIO_VIN_S3		2
+#define PM8058_GPIO_VIN_L3		3
+#define PM8058_GPIO_VIN_L7		4
+#define PM8058_GPIO_VIN_L6		5
+#define PM8058_GPIO_VIN_L5		6
+#define PM8058_GPIO_VIN_L2		7
+
 /* out_strength */
 #define	PM_GPIO_STRENGTH_NO		0
 #define	PM_GPIO_STRENGTH_HIGH		1
diff --git a/include/linux/pmic8058-nfc.h b/include/linux/mfd/pm8xxx/nfc.h
similarity index 70%
rename from include/linux/pmic8058-nfc.h
rename to include/linux/mfd/pm8xxx/nfc.h
index 5b2d6cf..e58e0a9 100644
--- a/include/linux/pmic8058-nfc.h
+++ b/include/linux/mfd/pm8xxx/nfc.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved.
  *
  * This program is free software; you can redistribute it and/or modify
  * it under the terms of the GNU General Public License version 2 and
@@ -10,10 +10,12 @@
  * GNU General Public License for more details.
  *
  */
-#ifndef __PMIC8058_NFC_H__
-#define __PMIC8058_NFC_H__
+#ifndef __PM8XXX_NFC_H__
+#define __PM8XXX_NFC_H__
 
-struct pm8058_nfc_device;
+struct pm8xxx_nfc_device;
+
+#define PM8XXX_NFC_DEV_NAME		"pm8xxx-nfc"
 
 /* masks, flags and status */
 #define	PM_NFC_VDDLDO_MON_LEVEL		0x0003
@@ -46,32 +48,32 @@
 					PM_NFC_VDDLDO_OK_HIGH)
 
 /*
- * pm8058_nfc_request - request a handle to access NFC device
+ * pm8xxx_nfc_request - request a handle to access NFC device
  */
-struct pm8058_nfc_device *pm8058_nfc_request(void);
+struct pm8xxx_nfc_device *pm8xxx_nfc_request(void);
 
 /*
- * pm8058_nfc_config - configure NFC signals
+ * pm8xxx_nfc_config - configure NFC signals
  *
  * @nfcdev: the NFC device
  * @mask: signal mask to configure
  * @flags: control flags
  */
-int pm8058_nfc_config(struct pm8058_nfc_device *nfcdev, u32 mask, u32 flags);
+int pm8xxx_nfc_config(struct pm8xxx_nfc_device *nfcdev, u32 mask, u32 flags);
 
 /*
- * pm8058_nfc_get_status - get NFC status
+ * pm8xxx_nfc_get_status - get NFC status
  *
  * @nfcdev: the NFC device
  * @mask: of status mask to read
  * @status: pointer to the status variable
  */
-int pm8058_nfc_get_status(struct pm8058_nfc_device *nfcdev,
+int pm8xxx_nfc_get_status(struct pm8xxx_nfc_device *nfcdev,
 			  u32 mask, u32 *status);
 
 /*
- * pm8058_nfc_free - free the NFC device
+ * pm8xxx_nfc_free - free the NFC device
  */
-void pm8058_nfc_free(struct pm8058_nfc_device *nfcdev);
+void pm8xxx_nfc_free(struct pm8xxx_nfc_device *nfcdev);
 
-#endif /* __PMIC8058_NFC_H__ */
+#endif /* __PM8XXX_NFC_H__ */
diff --git a/include/linux/mfd/pm8xxx/tm.h b/include/linux/mfd/pm8xxx/tm.h
index 01edb97..5eeefd9 100644
--- a/include/linux/mfd/pm8xxx/tm.h
+++ b/include/linux/mfd/pm8xxx/tm.h
@@ -24,6 +24,7 @@
 
 enum pm8xxx_tm_adc_type {
 	PM8XXX_TM_ADC_NONE,	/* Estimates temp based on overload level. */
+	PM8XXX_TM_ADC_PM8058_ADC,
 	PM8XXX_TM_ADC_PM8921_ADC,
 };
 
diff --git a/include/linux/mfd/pm8xxx/upl.h b/include/linux/mfd/pm8xxx/upl.h
new file mode 100644
index 0000000..b0e94a9
--- /dev/null
+++ b/include/linux/mfd/pm8xxx/upl.h
@@ -0,0 +1,65 @@
+/* Copyright (c) 2010,2011 Code Aurora Forum. All rights reserved.
+ *
+ * This program is free software; you can redistribute it and/or modify
+ * it under the terms of the GNU General Public License version 2 and
+ * only version 2 as published by the Free Software Foundation.
+ *
+ * This program is distributed in the hope that it will be useful,
+ * but WITHOUT ANY WARRANTY; without even the implied warranty of
+ * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+ * GNU General Public License for more details.
+ *
+ */
+#ifndef __PM8XXX_UPL_H__
+#define __PM8XXX_UPL_H__
+
+struct pm8xxx_upl_device;
+
+#define PM8XXX_UPL_DEV_NAME		"pm8xxx-upl"
+
+/* control masks and flags */
+#define PM8XXX_UPL_MOD_ENABLE_MASK	(0x10)
+#define PM8XXX_UPL_MOD_ENABLE		(0x10)
+#define PM8XXX_UPL_MOD_DISABLE		(0x00)
+
+#define PM8XXX_UPL_OUT_DTEST_MASK	(0xE0)
+#define PM8XXX_UPL_OUT_GPIO_ONLY	(0x00)
+#define PM8XXX_UPL_OUT_DTEST_1		(0x80)
+#define PM8XXX_UPL_OUT_DTEST_2		(0xA0)
+#define PM8XXX_UPL_OUT_DTEST_3		(0xC0)
+#define PM8XXX_UPL_OUT_DTEST_4		(0xE0)
+
+#define PM8XXX_UPL_IN_A_MASK		(0x01)
+#define PM8XXX_UPL_IN_A_GPIO		(0x00)
+#define PM8XXX_UPL_IN_A_DTEST		(0x01)
+#define PM8XXX_UPL_IN_B_MASK		(0x02)
+#define PM8XXX_UPL_IN_B_GPIO		(0x00)
+#define PM8XXX_UPL_IN_B_DTEST		(0x02)
+#define PM8XXX_UPL_IN_C_MASK		(0x04)
+#define PM8XXX_UPL_IN_C_GPIO		(0x00)
+#define PM8XXX_UPL_IN_C_DTEST		(0x04)
+#define PM8XXX_UPL_IN_D_MASK		(0x08)
+#define PM8XXX_UPL_IN_D_GPIO		(0x00)
+#define PM8XXX_UPL_IN_D_DTEST		(0x08)
+
+/*
+ * pm8xxx_upl_request - request a handle to access UPL device
+ */
+struct pm8xxx_upl_device *pm8xxx_upl_request(void);
+
+int pm8xxx_upl_read_truthtable(struct pm8xxx_upl_device *upldev,
+				u16 *truthtable);
+
+int pm8xxx_upl_write_truthtable(struct pm8xxx_upl_device *upldev,
+				u16 truthtable);
+
+/*
+ * pm8xxx_upl_config - configure UPL I/O settings and UPL enable/disable
+ *
+ * @upldev: the UPL device
+ * @mask: setting mask to configure
+ * @flags: setting flags
+ */
+int pm8xxx_upl_config(struct pm8xxx_upl_device *upldev, u32 mask, u32 flags);
+
+#endif /* __PM8XXX_UPL_H__ */
diff --git a/include/linux/mfd/pm8xxx/vibrator.h b/include/linux/mfd/pm8xxx/vibrator.h
index 3a269a0..cfea1c9 100644
--- a/include/linux/mfd/pm8xxx/vibrator.h
+++ b/include/linux/mfd/pm8xxx/vibrator.h
@@ -15,10 +15,25 @@
 
 #define PM8XXX_VIBRATOR_DEV_NAME "pm8xxx-vib"
 
+enum pm8xxx_vib_en_mode {
+	PM8XXX_VIB_MANUAL,
+	PM8XXX_VIB_DTEST1,
+	PM8XXX_VIB_DTEST2,
+	PM8XXX_VIB_DTEST3
+};
+
+struct pm8xxx_vib_config {
+	u16			drive_mV;
+	u8			active_low;
+	enum pm8xxx_vib_en_mode	enable_mode;
+};
+
 struct pm8xxx_vibrator_platform_data {
 	int initial_vibrate_ms;
 	int max_timeout_ms;
 	int level_mV;
 };
 
+int pm8xxx_vibrator_config(struct pm8xxx_vib_config *vib_config);
+
 #endif /* __PMIC8XXX_VIBRATOR_H__ */
diff --git a/include/linux/mfd/pmic8058.h b/include/linux/mfd/pmic8058.h
index 4d9f257..cf753b5d 100644
--- a/include/linux/mfd/pmic8058.h
+++ b/include/linux/mfd/pmic8058.h
@@ -15,12 +15,39 @@
  *
  */
 
+#ifndef __MFD_PMIC8058_H__
+#define __MFD_PMIC8058_H__
+
 #include <linux/irq.h>
 #include <linux/mfd/core.h>
+#include <linux/mfd/pm8xxx/irq.h>
+#include <linux/mfd/pm8xxx/gpio.h>
+#include <linux/mfd/pm8xxx/mpp.h>
+#include <linux/mfd/pm8xxx/rtc.h>
+#include <linux/input/pmic8xxx-pwrkey.h>
+#include <linux/input/pmic8xxx-keypad.h>
+#include <linux/mfd/pm8xxx/vibrator.h>
+#include <linux/mfd/pm8xxx/nfc.h>
+#include <linux/mfd/pm8xxx/upl.h>
+#include <linux/mfd/pm8xxx/misc.h>
+#include <linux/mfd/pm8xxx/batt-alarm.h>
+#include <linux/leds-pmic8058.h>
+#include <linux/pmic8058-othc.h>
+#include <linux/mfd/pm8xxx/tm.h>
+#include <linux/pmic8058-xoadc.h>
+#include <linux/regulator/pmic8058-regulator.h>
+#include <linux/regulator/pm8058-xo.h>
+#include <linux/pwm.h>
+#include <linux/pmic8058-pwm.h>
 
 #define PM8058_GPIOS		40
 #define PM8058_MPPS		12
 
+#define PM8058_GPIO_BLOCK_START	24
+#define PM8058_MPP_BLOCK_START	16
+
+#define PM8058_NR_IRQS		256
+
 #define PM8058_IRQ_BLOCK_BIT(block, bit) ((block) * 8 + (bit))
 
 /* MPPs and GPIOs [0,N) */
@@ -29,146 +56,58 @@
 #define PM8058_GPIO_IRQ(base, gpio)	((base) + \
 					PM8058_IRQ_BLOCK_BIT(24, (gpio)))
 
-#define PM8058_KEYPAD_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(9, 2))
-#define PM8058_KEYSTUCK_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(9, 3))
+/* PM8058 IRQ's */
+#define PM8058_VCP_IRQ			PM8058_IRQ_BLOCK_BIT(1, 0)
+#define PM8058_CHGILIM_IRQ		PM8058_IRQ_BLOCK_BIT(1, 3)
+#define PM8058_VBATDET_LOW_IRQ		PM8058_IRQ_BLOCK_BIT(1, 4)
+#define PM8058_BATT_REPLACE_IRQ		PM8058_IRQ_BLOCK_BIT(1, 5)
+#define PM8058_CHGINVAL_IRQ		PM8058_IRQ_BLOCK_BIT(1, 6)
+#define PM8058_CHGVAL_IRQ		PM8058_IRQ_BLOCK_BIT(1, 7)
+#define PM8058_CHG_END_IRQ		PM8058_IRQ_BLOCK_BIT(2, 0)
+#define PM8058_FASTCHG_IRQ		PM8058_IRQ_BLOCK_BIT(2, 1)
+#define PM8058_CHGSTATE_IRQ		PM8058_IRQ_BLOCK_BIT(2, 3)
+#define PM8058_AUTO_CHGFAIL_IRQ		PM8058_IRQ_BLOCK_BIT(2, 4)
+#define PM8058_AUTO_CHGDONE_IRQ		PM8058_IRQ_BLOCK_BIT(2, 5)
+#define PM8058_ATCFAIL_IRQ		PM8058_IRQ_BLOCK_BIT(2, 6)
+#define PM8058_ATC_DONE_IRQ		PM8058_IRQ_BLOCK_BIT(2, 7)
+#define PM8058_OVP_OK_IRQ		PM8058_IRQ_BLOCK_BIT(3, 0)
+#define PM8058_COARSE_DET_OVP_IRQ	PM8058_IRQ_BLOCK_BIT(3, 1)
+#define PM8058_VCPMAJOR_IRQ		PM8058_IRQ_BLOCK_BIT(3, 2)
+#define PM8058_CHG_GONE_IRQ		PM8058_IRQ_BLOCK_BIT(3, 3)
+#define PM8058_CHGTLIMIT_IRQ		PM8058_IRQ_BLOCK_BIT(3, 4)
+#define PM8058_CHGHOT_IRQ		PM8058_IRQ_BLOCK_BIT(3, 5)
+#define PM8058_BATTTEMP_IRQ		PM8058_IRQ_BLOCK_BIT(3, 6)
+#define PM8058_BATTCONNECT_IRQ		PM8058_IRQ_BLOCK_BIT(3, 7)
+#define PM8058_BATFET_IRQ		PM8058_IRQ_BLOCK_BIT(5, 4)
+#define PM8058_VBATDET_IRQ		PM8058_IRQ_BLOCK_BIT(5, 5)
+#define PM8058_VBAT_IRQ			PM8058_IRQ_BLOCK_BIT(5, 6)
 
-#define PM8058_VCP_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(1, 0))
-#define PM8058_CHGILIM_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(1, 3))
-#define PM8058_VBATDET_LOW_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(1, 4))
-#define PM8058_BATT_REPLACE_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(1, 5))
-#define PM8058_CHGINVAL_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(1, 6))
-#define PM8058_CHGVAL_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(1, 7))
-#define PM8058_CHG_END_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(2, 0))
-#define PM8058_FASTCHG_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(2, 1))
-#define PM8058_CHGSTATE_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(2, 3))
-#define PM8058_AUTO_CHGFAIL_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(2, 4))
-#define PM8058_AUTO_CHGDONE_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(2, 5))
-#define PM8058_ATCFAIL_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(2, 6))
-#define PM8058_ATC_DONE_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(2, 7))
-#define PM8058_OVP_OK_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(3, 0))
-#define PM8058_COARSE_DET_OVP_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(3, 1))
-#define PM8058_VCPMAJOR_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(3, 2))
-#define PM8058_CHG_GONE_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(3, 3))
-#define PM8058_CHGTLIMIT_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(3, 4))
-#define PM8058_CHGHOT_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(3, 5))
-#define PM8058_BATTTEMP_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(3, 6))
-#define PM8058_BATTCONNECT_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(3, 7))
-#define PM8058_BATFET_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(5, 4))
-#define PM8058_VBATDET_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(5, 5))
-#define PM8058_VBAT_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(5, 6))
-
-#define PM8058_CBLPWR_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(4, 3))
-
-#define PM8058_PWRKEY_REL_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(6, 2))
-#define PM8058_PWRKEY_PRESS_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(6, 3))
-#define PM8058_SW_0_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(7, 1))
-#define PM8058_IR_0_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(7, 0))
-#define PM8058_SW_1_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(7, 3))
-#define PM8058_IR_1_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(7, 2))
-#define PM8058_SW_2_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(7, 5))
-#define PM8058_IR_2_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(7, 4))
-#define PM8058_RTC_IRQ(base) 		((base) + PM8058_IRQ_BLOCK_BIT(6, 5))
-#define PM8058_RTC_ALARM_IRQ(base) 	((base) + PM8058_IRQ_BLOCK_BIT(4, 7))
-#define PM8058_ADC_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(9, 4))
-#define PM8058_TEMP_ALARM_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(6, 7))
-#define PM8058_OSCHALT_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(4, 6))
-#define PM8058_BATT_ALARM_IRQ(base)	((base) + PM8058_IRQ_BLOCK_BIT(5, 6))
-#define PM8058_RESOUT_IRQ(base)		((base) + PM8058_IRQ_BLOCK_BIT(6, 4))
-
-struct pm8058_chip;
-
-struct pm8058_platform_data {
-	/* This table is only needed for misc interrupts. */
-	int		irq_base;
-	int		irq;
-	int 		(*init)(struct pm8058_chip *pm_chip);
-
-	int		num_subdevs;
-	struct mfd_cell *sub_devices;
-	int		irq_trigger_flags;
-	struct mfd_cell *charger_sub_device;
-};
-
-struct pm8058_gpio_platform_data {
-	int	gpio_base;
-	int	irq_base;
-	int	(*init)(void);
-};
-
-/* GPIO parameters */
-/* direction */
-#define	PM_GPIO_DIR_OUT			0x01
-#define	PM_GPIO_DIR_IN			0x02
-#define	PM_GPIO_DIR_BOTH		(PM_GPIO_DIR_OUT | PM_GPIO_DIR_IN)
-
-/* output_buffer */
-#define	PM_GPIO_OUT_BUF_OPEN_DRAIN	1
-#define	PM_GPIO_OUT_BUF_CMOS		0
-
-/* pull */
-#define	PM_GPIO_PULL_UP_30		0
-#define	PM_GPIO_PULL_UP_1P5		1
-#define	PM_GPIO_PULL_UP_31P5		2
-#define	PM_GPIO_PULL_UP_1P5_30		3
-#define	PM_GPIO_PULL_DN			4
-#define	PM_GPIO_PULL_NO			5
-
-/* vin_sel: Voltage Input Select */
-#define	PM_GPIO_VIN_VPH			0
-#define	PM_GPIO_VIN_BB			1
-#define	PM_GPIO_VIN_S3			2
-#define	PM_GPIO_VIN_L3			3
-#define	PM_GPIO_VIN_L7			4
-#define	PM_GPIO_VIN_L6			5
-#define	PM_GPIO_VIN_L5			6
-#define	PM_GPIO_VIN_L2			7
-
-/* out_strength */
-#define	PM_GPIO_STRENGTH_NO		0
-#define	PM_GPIO_STRENGTH_HIGH		1
-#define	PM_GPIO_STRENGTH_MED		2
-#define	PM_GPIO_STRENGTH_LOW		3
-
-/* function */
-#define	PM_GPIO_FUNC_NORMAL		0
-#define	PM_GPIO_FUNC_PAIRED		1
-#define	PM_GPIO_FUNC_1			2
-#define	PM_GPIO_FUNC_2			3
-#define	PM_GPIO_DTEST1			4
-#define	PM_GPIO_DTEST2			5
-#define	PM_GPIO_DTEST3			6
-#define	PM_GPIO_DTEST4			7
-
-struct pm8058_gpio {
-	int		direction;
-	int		output_buffer;
-	int		output_value;
-	int		pull;
-	int		vin_sel;	/* 0..7 */
-	int		out_strength;
-	int		function;
-	int		inv_int_pol;	/* invert interrupt polarity */
-	int		disable_pin;	/* disable pin and tri-state its pad */
-};
+#define PM8058_RTC_IRQ			PM8058_IRQ_BLOCK_BIT(6, 5)
+#define PM8058_RTC_ALARM_IRQ		PM8058_IRQ_BLOCK_BIT(4, 7)
+#define PM8058_PWRKEY_REL_IRQ		PM8058_IRQ_BLOCK_BIT(6, 2)
+#define PM8058_PWRKEY_PRESS_IRQ		PM8058_IRQ_BLOCK_BIT(6, 3)
+#define PM8058_KEYPAD_IRQ		PM8058_IRQ_BLOCK_BIT(9, 2)
+#define PM8058_KEYSTUCK_IRQ		PM8058_IRQ_BLOCK_BIT(9, 3)
+#define PM8058_BATT_ALARM_IRQ		PM8058_IRQ_BLOCK_BIT(5, 6)
+#define PM8058_SW_0_IRQ			PM8058_IRQ_BLOCK_BIT(7, 1)
+#define PM8058_IR_0_IRQ			PM8058_IRQ_BLOCK_BIT(7, 0)
+#define PM8058_SW_1_IRQ			PM8058_IRQ_BLOCK_BIT(7, 3)
+#define PM8058_IR_1_IRQ			PM8058_IRQ_BLOCK_BIT(7, 2)
+#define PM8058_SW_2_IRQ			PM8058_IRQ_BLOCK_BIT(7, 5)
+#define PM8058_IR_2_IRQ			PM8058_IRQ_BLOCK_BIT(7, 4)
+#define PM8058_TEMPSTAT_IRQ		PM8058_IRQ_BLOCK_BIT(6, 7)
+#define PM8058_OVERTEMP_IRQ		PM8058_IRQ_BLOCK_BIT(4, 2)
+#define PM8058_ADC_IRQ			PM8058_IRQ_BLOCK_BIT(9, 4)
+#define PM8058_OSCHALT_IRQ		PM8058_IRQ_BLOCK_BIT(4, 6)
+#define PM8058_CBLPWR_IRQ		PM8058_IRQ_BLOCK_BIT(4, 3)
+#define PM8058_RESOUT_IRQ		PM8058_IRQ_BLOCK_BIT(6, 4)
 
 struct pmic8058_charger_data {
 	unsigned int max_source_current;
 	int charger_type;
+	bool charger_data_valid;
 };
 
-/* chip revision */
-#define PM_8058_REV_1p0			0xE1
-#define PM_8058_REV_2p0			0xE2
-#define PM_8058_REV_2p1			0xE3
-
-/* misc: control mask and flag */
-#define	PM8058_UART_MUX_MASK		0x60
-
-#define PM8058_UART_MUX_NO		0x0
-#define PM8058_UART_MUX_1		0x20
-#define PM8058_UART_MUX_2		0x40
-#define PM8058_UART_MUX_3		0x60
-
 enum pon_config{
 	DISABLE_HARD_RESET = 0,
 	SHUTDOWN_ON_HARD_RESET,
@@ -183,19 +122,27 @@
 	PM8058_SMPL_DELAY_2p0,
 };
 
-/* Note -do not call pm8058_read and pm8058_write in an atomic context */
-int pm8058_read(struct pm8058_chip *pm_chip, u16 addr, u8 *values,
-		unsigned int len);
-int pm8058_write(struct pm8058_chip *pm_chip, u16 addr, u8 *values,
-		 unsigned int len);
-
-int pm8058_gpio_config(int gpio, struct pm8058_gpio *param);
-
-int pm8058_rev(struct pm8058_chip *pm_chip);
-
-int pm8058_irq_get_rt_status(struct pm8058_chip *pm_chip, int irq);
-
-int pm8058_misc_control(struct pm8058_chip *pm_chip, int mask, int flag);
+struct pm8058_platform_data {
+	struct pm8xxx_mpp_platform_data		*mpp_pdata;
+	struct pm8xxx_keypad_platform_data      *keypad_pdata;
+	struct pm8xxx_gpio_platform_data	*gpio_pdata;
+	struct pm8xxx_irq_platform_data		*irq_pdata;
+	struct pm8xxx_rtc_platform_data		*rtc_pdata;
+	struct pm8xxx_pwrkey_platform_data	*pwrkey_pdata;
+	struct pm8xxx_vibrator_platform_data	*vibrator_pdata;
+	struct pm8xxx_misc_platform_data	*misc_pdata;
+	struct pmic8058_leds_platform_data	*leds_pdata;
+	struct pmic8058_othc_config_pdata	*othc0_pdata;
+	struct pmic8058_othc_config_pdata	*othc1_pdata;
+	struct pmic8058_othc_config_pdata	*othc2_pdata;
+	struct xoadc_platform_data		*xoadc_pdata;
+	struct pm8058_pwm_pdata			*pwm_pdata;
+	struct pm8058_vreg_pdata		*regulator_pdatas;
+	int					num_regulators;
+	struct pm8058_xo_pdata			*xo_buffer_pdata;
+	int					num_xo_buffers;
+	struct pmic8058_charger_data		*charger_pdata;
+};
 
 #ifdef CONFIG_PMIC8058
 int pm8058_reset_pwr_off(int reset);
@@ -256,3 +203,5 @@
  * RETURNS: an appropriate -ERRNO error value on error, or zero for success.
  */
 int pm8058_stay_on(void);
+
+#endif  /* __MFD_PMIC8058_H__ */
diff --git a/include/linux/msm_adc.h b/include/linux/msm_adc.h
index 5d5fb1b..51371a6 100644
--- a/include/linux/msm_adc.h
+++ b/include/linux/msm_adc.h
@@ -344,22 +344,24 @@
 int32_t adc_channel_request_conv(void *h, struct completion *conv_complete_evt);
 int32_t adc_channel_read_result(void *h, struct adc_chan_result *chan_result);
 #else
-int32_t adc_channel_open(uint32_t channel, void **h)
+static int32_t adc_channel_open(uint32_t channel, void **h)
 {
 	pr_err("%s.not supported.\n", __func__);
 	return -ENODEV;
 }
-int32_t adc_channel_close(void *h)
+static int32_t adc_channel_close(void *h)
 {
 	pr_err("%s.not supported.\n", __func__);
 	return -ENODEV;
 }
-int32_t adc_channel_request_conv(void *h, struct completion *conv_complete_evt)
+static int32_t
+adc_channel_request_conv(void *h, struct completion *conv_complete_evt)
 {
 	pr_err("%s.not supported.\n", __func__);
 	return -ENODEV;
 }
-int32_t adc_channel_read_result(void *h, struct adc_chan_result *chan_result)
+static int32_t
+adc_channel_read_result(void *h, struct adc_chan_result *chan_result)
 {
 	pr_err("%s.not supported.\n", __func__);
 	return -ENODEV;
diff --git a/include/linux/msm_mdp.h b/include/linux/msm_mdp.h
index 5011229..5c67471 100644
--- a/include/linux/msm_mdp.h
+++ b/include/linux/msm_mdp.h
@@ -106,6 +106,14 @@
 	FB_IMG,
 };
 
+enum {
+	HSIC_HUE = 0,
+	HSIC_SAT,
+	HSIC_INT,
+	HSIC_CON,
+	NUM_HSIC_PARAM,
+};
+
 /* mdp_blit_req flag values */
 #define MDP_ROT_NOP 0
 #define MDP_FLIP_LR 0x1
@@ -132,6 +140,7 @@
 #define MDP_OV_PLAY_NOWAIT		0x00200000
 #define MDP_SOURCE_ROTATED_90		0x00100000
 #define MDP_MEMORY_ID_TYPE_FB		0x00001000
+#define MDP_DPP_HSIC			0x00080000
 
 #define MDP_TRANSP_NOP 0xffffffff
 #define MDP_ALPHA_NOP 0xff
@@ -250,6 +259,7 @@
 	 *  smoothed picture.
 	 */
 	int8_t sharp_strength;
+	int8_t hsic_params[NUM_HSIC_PARAM];
 };
 
 struct mdp_overlay {
diff --git a/include/linux/pmic8058-upl.h b/include/linux/pmic8058-upl.h
deleted file mode 100644
index a8979f4..0000000
--- a/include/linux/pmic8058-upl.h
+++ /dev/null
@@ -1,63 +0,0 @@
-/* Copyright (c) 2010, Code Aurora Forum. All rights reserved.
- *
- * This program is free software; you can redistribute it and/or modify
- * it under the terms of the GNU General Public License version 2 and
- * only version 2 as published by the Free Software Foundation.
- *
- * This program is distributed in the hope that it will be useful,
- * but WITHOUT ANY WARRANTY; without even the implied warranty of
- * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- * GNU General Public License for more details.
- *
- */
-#ifndef __PMIC8058_UPL_H__
-#define __PMIC8058_UPL_H__
-
-struct pm8058_upl_device;
-
-/* control masks and flags */
-#define PM8058_UPL_MOD_ENABLE_MASK	(0x10)
-#define PM8058_UPL_MOD_ENABLE		(0x10)
-#define PM8058_UPL_MOD_DISABLE		(0x00)
-
-#define PM8058_UPL_OUT_DTEST_MASK	(0xE0)
-#define PM8058_UPL_OUT_GPIO_ONLY	(0x00)
-#define PM8058_UPL_OUT_DTEST_1		(0x80)
-#define PM8058_UPL_OUT_DTEST_2		(0xA0)
-#define PM8058_UPL_OUT_DTEST_3		(0xC0)
-#define PM8058_UPL_OUT_DTEST_4		(0xE0)
-
-#define PM8058_UPL_IN_A_MASK		(0x01)
-#define PM8058_UPL_IN_A_GPIO		(0x00)
-#define PM8058_UPL_IN_A_DTEST		(0x01)
-#define PM8058_UPL_IN_B_MASK		(0x02)
-#define PM8058_UPL_IN_B_GPIO		(0x00)
-#define PM8058_UPL_IN_B_DTEST		(0x02)
-#define PM8058_UPL_IN_C_MASK		(0x04)
-#define PM8058_UPL_IN_C_GPIO		(0x00)
-#define PM8058_UPL_IN_C_DTEST		(0x04)
-#define PM8058_UPL_IN_D_MASK		(0x08)
-#define PM8058_UPL_IN_D_GPIO		(0x00)
-#define PM8058_UPL_IN_D_DTEST		(0x08)
-
-/*
- * pm8058_upl_request - request a handle to access UPL device
- */
-struct pm8058_upl_device *pm8058_upl_request(void);
-
-int pm8058_upl_read_truthtable(struct pm8058_upl_device *upldev,
-				u16 *truthtable);
-
-int pm8058_upl_write_truthtable(struct pm8058_upl_device *upldev,
-				u16 truthtable);
-
-/*
- * pm8058_upl_config - configure UPL I/O settings and UPL enable/disable
- *
- * @upldev: the UPL device
- * @mask: setting mask to configure
- * @flags: setting flags
- */
-int pm8058_upl_config(struct pm8058_upl_device *upldev, u32 mask, u32 flags);
-
-#endif /* __PMIC8058_UPL_H__ */
diff --git a/include/linux/regulator/pm8058-xo.h b/include/linux/regulator/pm8058-xo.h
index 9b363c4..a2b8aeb 100644
--- a/include/linux/regulator/pm8058-xo.h
+++ b/include/linux/regulator/pm8058-xo.h
@@ -25,6 +25,7 @@
 
 struct pm8058_xo_pdata {
 	struct regulator_init_data	init_data;
+	int id;
 };
 
 #endif
diff --git a/include/linux/regulator/pmic8058-regulator.h b/include/linux/regulator/pmic8058-regulator.h
index 83d4412..3eeaa61 100644
--- a/include/linux/regulator/pmic8058-regulator.h
+++ b/include/linux/regulator/pmic8058-regulator.h
@@ -80,6 +80,7 @@
 
 struct pm8058_vreg_pdata {
 	struct regulator_init_data	init_data;
+	int				id;
 	unsigned			pull_down_enable;
 	unsigned			pin_ctrl;
 	enum pm8058_vreg_pin_fn		pin_fn;
diff --git a/include/linux/usb/msm_hsusb.h b/include/linux/usb/msm_hsusb.h
index 2ee6632..4c01f5b 100644
--- a/include/linux/usb/msm_hsusb.h
+++ b/include/linux/usb/msm_hsusb.h
@@ -155,7 +155,7 @@
 	enum usb_mode_type default_mode;
 	enum msm_usb_phy_type phy_type;
 	void (*setup_gpio)(enum usb_otg_state state);
-	char *pclk_src_name;
+	const char *pclk_src_name;
 	int pmic_id_irq;
 	bool mhl_enable;
 };
diff --git a/net/bluetooth/mgmt.c b/net/bluetooth/mgmt.c
index 094bfdb..0e7ff51 100644
--- a/net/bluetooth/mgmt.c
+++ b/net/bluetooth/mgmt.c
@@ -2608,7 +2608,10 @@
 	loc_mitm = conn->auth_type & 0x01;
 	rem_mitm = conn->remote_auth & 0x01;
 
-	if (loc_cap == 0x01 && (rem_cap == 0x00 || rem_cap == 0x03))
+	if ((conn->auth_type & HCI_AT_DEDICATED_BONDING) &&
+			conn->auth_initiator && rem_cap == 0x03)
+		ev.auto_confirm = 1;
+	else if (loc_cap == 0x01 && (rem_cap == 0x00 || rem_cap == 0x03))
 		goto no_auto_confirm;