Merge "drivers: base: Add generic cross-process locking API" into msm-3.0
diff --git a/arch/arm/configs/msm-copper_defconfig b/arch/arm/configs/msm-copper_defconfig
index 6c50ae9..a4964be 100644
--- a/arch/arm/configs/msm-copper_defconfig
+++ b/arch/arm/configs/msm-copper_defconfig
@@ -98,6 +98,14 @@
 CONFIG_USB_GADGET=y
 CONFIG_USB_GADGET_CI13XXX_MSM=y
 CONFIG_USB_G_ANDROID=y
+CONFIG_MMC=y
+CONFIG_MMC_PERF_PROFILING=y
+CONFIG_MMC_UNSAFE_RESUME=y
+CONFIG_MMC_PARANOID_SD_INIT=y
+CONFIG_MMC_BLOCK_MINORS=32
+# CONFIG_MMC_BLOCK_BOUNCE is not set
+CONFIG_MMC_TEST=m
+CONFIG_MMC_MSM=y
 CONFIG_NEW_LEDS=y
 CONFIG_LEDS_CLASS=y
 # CONFIG_LEDS_MSM_PMIC is not set
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index d84f64a..5e0cd9f 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -304,6 +304,7 @@
 CONFIG_THERMAL_TSENS=y
 CONFIG_THERMAL_PM8XXX=y
 CONFIG_PMIC8058=y
+CONFIG_PMIC8901=y
 CONFIG_MARIMBA_CORE=y
 CONFIG_TIMPANI_CODEC=y
 # CONFIG_MFD_PM8XXX_PWM is not set
diff --git a/arch/arm/configs/msm8660_defconfig b/arch/arm/configs/msm8660_defconfig
index 8f049a5..c4941db 100644
--- a/arch/arm/configs/msm8660_defconfig
+++ b/arch/arm/configs/msm8660_defconfig
@@ -295,6 +295,7 @@
 CONFIG_THERMAL_TSENS=y
 CONFIG_THERMAL_PM8XXX=y
 CONFIG_PMIC8058=y
+CONFIG_PMIC8901=y
 CONFIG_MARIMBA_CORE=y
 CONFIG_TIMPANI_CODEC=y
 # CONFIG_MFD_PM8XXX_PWM is not set
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index 83efc02..d63a018 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -26,7 +26,6 @@
 CONFIG_EMBEDDED=y
 # CONFIG_PERF_EVENTS is not set
 CONFIG_PROFILING=y
-CONFIG_OPROFILE=m
 CONFIG_MODULES=y
 CONFIG_MODULE_UNLOAD=y
 CONFIG_MODULE_FORCE_UNLOAD=y
@@ -41,6 +40,7 @@
 CONFIG_MSM_SMD=y
 CONFIG_MSM_SMD_PKG4=y
 CONFIG_MSM_BAM_DMUX=y
+# CONFIG_MSM_RESET_MODEM is not set
 CONFIG_MSM_IPC_ROUTER=y
 CONFIG_MSM_IPC_ROUTER_SMD_XPRT=y
 CONFIG_MSM_SUBSYSTEM_RESTART=y
@@ -101,7 +101,6 @@
 # CONFIG_INPUT_MOUSE is not set
 CONFIG_INPUT_MISC=y
 CONFIG_INPUT_UINPUT=y
-CONFIG_INPUT_GPIO=m
 CONFIG_INPUT_PMIC8XXX_PWRKEY=y
 CONFIG_SERIO_LIBPS2=y
 CONFIG_SERIAL_MSM=y
@@ -193,6 +192,7 @@
 CONFIG_CRYPTO_DES=y
 CONFIG_CRYPTO_TWOFISH=y
 CONFIG_CRYPTO_DEFLATE=y
+# CONFIG_CRYPTO_ANSI_CPRNG is not set
 CONFIG_CRYPTO_DEV_QCRYPTO=m
 CONFIG_CRYPTO_DEV_QCE=m
 CONFIG_CRYPTO_DEV_QCEDEV=m
diff --git a/arch/arm/mach-msm/acpuclock-9615.c b/arch/arm/mach-msm/acpuclock-9615.c
index e6206dd..1f112f6 100644
--- a/arch/arm/mach-msm/acpuclock-9615.c
+++ b/arch/arm/mach-msm/acpuclock-9615.c
@@ -56,7 +56,6 @@
 };
 
 static struct src_clock clocks[NUM_SRC] = {
-	[SRC_CXO].name  = "cxo",
 	[SRC_PLL0].name = "pll0",
 	[SRC_PLL8].name = "pll8",
 	[SRC_PLL9].name = "pll9",
@@ -320,7 +319,7 @@
 
 	for (i = 0; i < NUM_SRC; i++) {
 		if (clocks[i].name) {
-			clocks[i].clk = clk_get_sys(NULL, clocks[i].name);
+			clocks[i].clk = clk_get_sys("acpu", clocks[i].name);
 			BUG_ON(IS_ERR(clocks[i].clk));
 		}
 	}
diff --git a/arch/arm/mach-msm/bam_dmux.c b/arch/arm/mach-msm/bam_dmux.c
index 80f5803..5e2d311 100644
--- a/arch/arm/mach-msm/bam_dmux.c
+++ b/arch/arm/mach-msm/bam_dmux.c
@@ -1268,6 +1268,9 @@
 		return -ENOMEM;
 	}
 
+	if (smsm_get_state(SMSM_MODEM_STATE) & SMSM_A2_POWER_CONTROL)
+		bam_dmux_smsm_cb(NULL, 0, smsm_get_state(SMSM_MODEM_STATE));
+
 	return 0;
 }
 
diff --git a/arch/arm/mach-msm/board-msm7627-regulator.c b/arch/arm/mach-msm/board-msm7627-regulator.c
index 2ecda72c..0b3baff 100644
--- a/arch/arm/mach-msm/board-msm7627-regulator.c
+++ b/arch/arm/mach-msm/board-msm7627-regulator.c
@@ -210,7 +210,7 @@
 	PCOM_VREG_LDO(ldo13, 15, NULL,  2850000,  2850000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo14, 24, NULL,  2700000,  2700000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo15, 23, NULL,  2600000,  2600000, 0, -1, 0, 0, 0, 0),
-	PCOM_VREG_LDO(ldo16, 22, NULL,  3000000,  3000000, 0, -1, 0, 0, 0, 0),
+	PCOM_VREG_LDO(ldo16, 22, NULL,  2850000,  3000000, 0, -1, 0, 0, 0, 0),
 	PCOM_VREG_LDO(ldo17,  6, NULL,  1300000,  1300000, 0, -1, 0, 0, 0, 0),
 
 };
diff --git a/arch/arm/mach-msm/board-msm7x27.c b/arch/arm/mach-msm/board-msm7x27.c
index 3114e42..15705ec 100644
--- a/arch/arm/mach-msm/board-msm7x27.c
+++ b/arch/arm/mach-msm/board-msm7x27.c
@@ -160,10 +160,33 @@
 #endif
 
 #ifdef CONFIG_USB_MSM_OTG_72K
-struct vreg *vreg_3p3;
 static int msm_hsusb_ldo_init(int init)
 {
+	static struct regulator *reg_hsusb;
+	int rc;
 	if (init) {
+		reg_hsusb = regulator_get(NULL, "usb");
+		if (IS_ERR(reg_hsusb)) {
+			rc = PTR_ERR(reg_hsusb);
+			pr_err("%s: could not get regulator: %d\n",
+					__func__, rc);
+			goto out;
+		}
+
+		rc = regulator_set_voltage(reg_hsusb, 3300000, 3300000);
+		if (rc < 0) {
+			pr_err("%s: could not set voltage: %d\n",
+					 __func__, rc);
+			goto usb_reg_fail;
+		}
+
+		rc = regulator_enable(reg_hsusb);
+		if (rc < 0) {
+			pr_err("%s: could not enable regulator: %d\n",
+					__func__, rc);
+			goto usb_reg_fail;
+		}
+
 		/*
 		 * PHY 3.3V analog domain(VDDA33) is powered up by
 		 * an always enabled power supply (LP5900TL-3.3).
@@ -172,15 +195,22 @@
 		 * current. Hence USB VREG is explicitly turned
 		 * off here.
 		 */
-		vreg_3p3 = vreg_get(NULL, "usb");
-		if (IS_ERR(vreg_3p3))
-			return PTR_ERR(vreg_3p3);
-		vreg_enable(vreg_3p3);
-		vreg_disable(vreg_3p3);
-		vreg_put(vreg_3p3);
+
+		rc = regulator_disable(reg_hsusb);
+		if (rc < 0) {
+			pr_err("%s: could not disable regulator: %d\n",
+					__func__, rc);
+			goto usb_reg_fail;
+		}
+
+		regulator_put(reg_hsusb);
 	}
 
 	return 0;
+usb_reg_fail:
+	regulator_put(reg_hsusb);
+out:
+	return rc;
 }
 
 static int msm_hsusb_pmic_notif_init(void (*callback)(int online), int init)
@@ -548,38 +578,56 @@
 
 static int msm_fb_lcdc_power_save(int on)
 {
-	struct vreg *vreg[ARRAY_SIZE(msm_fb_lcdc_vreg)];
 	int i, rc = 0;
+	static struct regulator *vreg[ARRAY_SIZE(msm_fb_lcdc_vreg)];
+
+	if (on) {
+		for (i = 0; i < ARRAY_SIZE(msm_fb_lcdc_vreg); i++) {
+			vreg[i] = regulator_get(NULL, msm_fb_lcdc_vreg[i]);
+			if (IS_ERR(vreg[i])) {
+				rc = PTR_ERR(vreg[i]);
+				pr_err("%s: could get not regulator: %d\n",
+						__func__, rc);
+				goto reg_get_fail;
+			}
+
+			rc = regulator_set_voltage(vreg[i], 2850000, 3000000);
+			if (rc < 0) {
+				pr_err("%s: could not set voltage: %d\n",
+						__func__, rc);
+				goto reg_get_fail;
+			}
+		}
+	}
 
 	for (i = 0; i < ARRAY_SIZE(msm_fb_lcdc_vreg); i++) {
 		if (on) {
-			vreg[i] = vreg_get(0, msm_fb_lcdc_vreg[i]);
-			rc = vreg_enable(vreg[i]);
+			rc = regulator_enable(vreg[i]);
 			if (rc) {
-				printk(KERN_ERR "vreg_enable: %s vreg"
-						"operation failed \n",
-						msm_fb_lcdc_vreg[i]);
-				goto bail;
+				pr_err("%s: could not enable regulator %s:"
+					"%d\n", __func__,
+						msm_fb_lcdc_vreg[i], rc);
+				goto vreg_lcdc_fail;
 			}
 		} else {
-			int tmp;
-			vreg[i] = vreg_get(0, msm_fb_lcdc_vreg[i]);
-			tmp = vreg_disable(vreg[i]);
-			if (tmp) {
-				printk(KERN_ERR "vreg_disable: %s vreg "
-						"operation failed \n",
-						msm_fb_lcdc_vreg[i]);
-				if (!rc)
-					rc = tmp;
+			rc = regulator_disable(vreg[i]);
+			if (rc) {
+				pr_err("%s: could not disable regulator %s:"
+					"%d\n", __func__,
+					 msm_fb_lcdc_vreg[i], rc);
+
+				regulator_put(vreg[i]);
+				goto vreg_lcdc_fail;
+
 			}
-			tmp = gpio_tlmm_config(GPIO_CFG(GPIO_OUT_88, 0,
+
+			regulator_put(vreg[i]);
+			rc = gpio_tlmm_config(GPIO_CFG(GPIO_OUT_88, 0,
 						GPIO_CFG_OUTPUT, GPIO_CFG_NO_PULL,
 						GPIO_CFG_2MA), GPIO_CFG_ENABLE);
-			if (tmp) {
+			if (rc)
 				printk(KERN_ERR "gpio_tlmm_config failed\n");
-				if (!rc)
-					rc = tmp;
-			}
+
 			gpio_set_value(88, 0);
 			mdelay(15);
 			gpio_set_value(88, 1);
@@ -589,14 +637,23 @@
 
 	return rc;
 
-bail:
+reg_get_fail:
+	for (; i > 0; i--)
+		regulator_put(vreg[i - 1]);
+	return rc;
+
+vreg_lcdc_fail:
 	if (on) {
 		for (; i > 0; i--)
-			vreg_disable(vreg[i - 1]);
+			regulator_disable(vreg[i - 1]);
+	} else {
+		for (; i > 0; i--)
+			regulator_enable(vreg[i - 1]);
 	}
 
 	return rc;
 }
+
 static struct lcdc_platform_data lcdc_pdata = {
 	.lcdc_gpio_config = msm_fb_lcdc_config,
 	.lcdc_power_save   = msm_fb_lcdc_power_save,
@@ -695,20 +752,13 @@
 
 static int bluetooth_power(int on)
 {
-	struct vreg *vreg_bt;
 	int pin, rc;
+	static struct regulator *vreg_bt;
 
 	printk(KERN_DEBUG "%s\n", __func__);
 
 	/* do not have vreg bt defined, gp6 is the same */
 	/* vreg_get parameter 1 (struct device *) is ignored */
-	vreg_bt = vreg_get(NULL, "gp6");
-
-	if (IS_ERR(vreg_bt)) {
-		printk(KERN_ERR "%s: vreg get failed (%ld)\n",
-		       __func__, PTR_ERR(vreg_bt));
-		return PTR_ERR(vreg_bt);
-	}
 
 	if (on) {
 		for (pin = 0; pin < ARRAY_SIZE(bt_config_power_on); pin++) {
@@ -721,27 +771,35 @@
 				return -EIO;
 			}
 		}
+		vreg_bt = regulator_get(NULL, "gp6");
+
+		if (IS_ERR(vreg_bt)) {
+			rc = PTR_ERR(vreg_bt);
+			pr_err("%s: could get not regulator: %d\n",
+					__func__, rc);
+			goto out;
+		}
 
 		/* units of mV, steps of 50 mV */
-		rc = vreg_set_level(vreg_bt, 2600);
-		if (rc) {
-			printk(KERN_ERR "%s: vreg set level failed (%d)\n",
-			       __func__, rc);
-			return -EIO;
+		rc = regulator_set_voltage(vreg_bt, 2600000, 2600000);
+		if (rc < 0) {
+			pr_err("%s: could not set voltage: %d\n", __func__, rc);
+			goto bt_vreg_fail;
 		}
-		rc = vreg_enable(vreg_bt);
-		if (rc) {
-			printk(KERN_ERR "%s: vreg enable failed (%d)\n",
-			       __func__, rc);
-			return -EIO;
+		rc = regulator_enable(vreg_bt);
+		if (rc < 0) {
+			pr_err("%s: could not enable regulator: %d\n",
+					 __func__, rc);
+			goto bt_vreg_fail;
 		}
 	} else {
-		rc = vreg_disable(vreg_bt);
-		if (rc) {
-			printk(KERN_ERR "%s: vreg disable failed (%d)\n",
-			       __func__, rc);
-			return -EIO;
+		rc = regulator_disable(vreg_bt);
+		if (rc < 0) {
+			pr_err("%s: could not disable regulator: %d\n",
+					 __func__, rc);
+			goto bt_vreg_fail;
 		}
+		regulator_put(vreg_bt);
 		for (pin = 0; pin < ARRAY_SIZE(bt_config_power_off); pin++) {
 			rc = gpio_tlmm_config(bt_config_power_off[pin],
 					      GPIO_CFG_ENABLE);
@@ -754,6 +812,11 @@
 		}
 	}
 	return 0;
+
+bt_vreg_fail:
+	regulator_put(vreg_bt);
+out:
+	return rc;
 }
 
 static void __init bt_power_init(void)
@@ -884,68 +947,93 @@
 	}
 }
 
-static struct vreg *vreg_gp2;
-static struct vreg *vreg_gp3;
-
 static void msm_camera_vreg_config(int vreg_en)
 {
 	int rc;
+	static struct regulator *vreg_gp2;
+	static struct regulator *vreg_gp3;
 
-	if (vreg_gp2 == NULL) {
-		vreg_gp2 = vreg_get(NULL, "gp2");
+	if (vreg_gp2 == NULL && vreg_gp3 == NULL) {
+		vreg_gp2 = regulator_get(NULL, "gp2");
 		if (IS_ERR(vreg_gp2)) {
-			printk(KERN_ERR "%s: vreg_get(%s) failed (%ld)\n",
-				__func__, "gp2", PTR_ERR(vreg_gp2));
+			rc = PTR_ERR(vreg_gp2);
+			pr_err("%s: could not get regulator: %d\n",
+					__func__, rc);
 			return;
 		}
 
-		rc = vreg_set_level(vreg_gp2, 1800);
-		if (rc) {
-			printk(KERN_ERR "%s: GP2 set_level failed (%d)\n",
-				__func__, rc);
+		rc = regulator_set_voltage(vreg_gp2, 1800000, 1800000);
+		if (rc < 0) {
+			pr_err("%s: could not set voltage: %d\n",
+					__func__, rc);
+			goto cam_vreg_fail;
 		}
+
+		vreg_gp3 = regulator_get(NULL, "gp3");
+		if (IS_ERR(vreg_gp3)) {
+			rc = PTR_ERR(vreg_gp3);
+			pr_err("%s: could not get regulator: %d\n",
+					__func__, rc);
+			goto cam_vreg_fail;
+		}
+
+		rc = regulator_set_voltage(vreg_gp3, 2850000, 2850000);
+		if (rc < 0) {
+			pr_err("%s: could not set voltage: %d\n", __func__, rc);
+			goto cam_vreg2_fail;
+		}
+
+		return;
+
 	}
 
-	if (vreg_gp3 == NULL) {
-		vreg_gp3 = vreg_get(NULL, "gp3");
-		if (IS_ERR(vreg_gp3)) {
-			printk(KERN_ERR "%s: vreg_get(%s) failed (%ld)\n",
-				__func__, "gp3", PTR_ERR(vreg_gp3));
-			return;
-		}
-
-		rc = vreg_set_level(vreg_gp3, 2850);
-		if (rc) {
-			printk(KERN_ERR "%s: GP3 set level failed (%d)\n",
-				__func__, rc);
-		}
+	if (vreg_gp2 == NULL || vreg_gp3 == NULL) {
+		pr_err("Camera Regulators are not initialized\n");
+		return;
 	}
 
 	if (vreg_en) {
-		rc = vreg_enable(vreg_gp2);
+		rc = regulator_enable(vreg_gp2);
 		if (rc) {
-			printk(KERN_ERR "%s: GP2 enable failed (%d)\n",
-				 __func__, rc);
+			pr_err("%s: could not enable regulator: %d\n",
+					__func__, rc);
+			goto cam_vreg2_fail;
 		}
 
-		rc = vreg_enable(vreg_gp3);
+		rc = regulator_enable(vreg_gp3);
 		if (rc) {
-			printk(KERN_ERR "%s: GP3 enable failed (%d)\n",
-				__func__, rc);
+			pr_err("%s: could not enable regulator: %d\n",
+					__func__, rc);
+			goto vreg_gp3_fail;
 		}
 	} else {
-		rc = vreg_disable(vreg_gp2);
+		rc = regulator_disable(vreg_gp2);
 		if (rc) {
-			printk(KERN_ERR "%s: GP2 disable failed (%d)\n",
-				 __func__, rc);
+			pr_err("%s: could not disable regulator: %d\n",
+					__func__, rc);
+			return;
 		}
 
-		rc = vreg_disable(vreg_gp3);
+		rc = regulator_disable(vreg_gp3);
 		if (rc) {
-			printk(KERN_ERR "%s: GP3 disable failed (%d)\n",
-				__func__, rc);
+			pr_err("%s: could not disable regulator: %d\n",
+					__func__, rc);
+			goto cam_vreg2_fail;
 		}
 	}
+
+	return;
+
+vreg_gp3_fail:
+	if (vreg_en)
+		regulator_disable(vreg_gp2);
+
+cam_vreg2_fail:
+	regulator_put(vreg_gp3);
+cam_vreg_fail:
+	regulator_put(vreg_gp2);
+	vreg_gp3 = NULL;
+	vreg_gp2 = NULL;
 }
 
 static int config_camera_on_gpios(void)
@@ -1262,7 +1350,7 @@
 	|| defined(CONFIG_MMC_MSM_SDC4_SUPPORT))
 
 static unsigned long vreg_sts, gpio_sts;
-static struct vreg *vreg_mmc;
+static struct regulator *vreg_mmc;
 static unsigned mpp_mmc = 2;
 
 struct sdcc_gpio {
@@ -1385,10 +1473,11 @@
 				     MPP_CFG(MPP_DLOGIC_LVL_MSMP,
 				     MPP_DLOGIC_OUT_CTRL_LOW));
 			} else
-				rc = vreg_disable(vreg_mmc);
-			if (rc)
-				printk(KERN_ERR "%s: return val: %d \n",
+				rc = regulator_disable(vreg_mmc);
+			if (rc) {
+				pr_err("%s: return val: %d\n",
 					__func__, rc);
+			}
 		}
 		return 0;
 	}
@@ -1399,13 +1488,14 @@
 			     MPP_CFG(MPP_DLOGIC_LVL_MSMP,
 			     MPP_DLOGIC_OUT_CTRL_HIGH));
 		} else {
-			rc = vreg_set_level(vreg_mmc, 2850);
+			rc = regulator_set_voltage(vreg_mmc, 2850000, 2850000);
 			if (!rc)
-				rc = vreg_enable(vreg_mmc);
+				rc = regulator_enable(vreg_mmc);
 		}
-		if (rc)
-			printk(KERN_ERR "%s: return val: %d \n",
+		if (rc) {
+			pr_err("%s: return val: %d\n",
 					__func__, rc);
+		}
 	}
 	set_bit(pdev->id, &vreg_sts);
 	return 0;
@@ -1465,11 +1555,10 @@
 static void __init msm7x2x_init_mmc(void)
 {
 	if (!machine_is_msm7x25_ffa() && !machine_is_msm7x27_ffa()) {
-		vreg_mmc = vreg_get(NULL, "mmc");
+		vreg_mmc = regulator_get(NULL, "mmc");
 		if (IS_ERR(vreg_mmc)) {
-			printk(KERN_ERR "%s: vreg get failed (%ld)\n",
-			       __func__, PTR_ERR(vreg_mmc));
-			return;
+			pr_err("%s: could not get regulator: %ld\n",
+					__func__, PTR_ERR(vreg_mmc));
 		}
 	}
 
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 090605f..8f733a9 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -2525,11 +2525,6 @@
 #endif
 
 #ifdef CONFIG_I2C_SSBI
-/* PMIC SSBI */
-static struct msm_i2c_ssbi_platform_data msm_ssbi2_pdata = {
-	.controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
-};
-
 /* CODEC/TSSC SSBI */
 static struct msm_i2c_ssbi_platform_data msm_ssbi3_pdata = {
 	.controller_type = MSM_SBI_CTRL_SSBI,
@@ -4193,7 +4188,6 @@
 	&msm_gsbi12_qup_i2c_device,
 #endif
 #ifdef CONFIG_I2C_SSBI
-	&msm_device_ssbi2,
 	&msm_device_ssbi3,
 #endif
 #ifdef CONFIG_ANDROID_PMEM
@@ -5030,9 +5024,9 @@
 #endif
 #ifdef CONFIG_MSM_SSBI
 	&msm_device_ssbi_pmic1,
+	&msm_device_ssbi_pmic2,
 #endif
 #ifdef CONFIG_I2C_SSBI
-	&msm_device_ssbi2,
 	&msm_device_ssbi3,
 #endif
 #if defined(CONFIG_USB_PEHCI_HCD) || defined(CONFIG_USB_PEHCI_HCD_MODULE)
@@ -6621,19 +6615,19 @@
 
 static struct pm8901_platform_data pm8901_platform_data = {
 	.irq_base = PM8901_IRQ_BASE,
+	.irq = MSM_GPIO_TO_INT(PM8901_GPIO_INT),
 	.num_subdevs = ARRAY_SIZE(pm8901_subdevs),
 	.sub_devices = pm8901_subdevs,
 	.irq_trigger_flags = IRQF_TRIGGER_LOW,
 };
 
-static struct i2c_board_info pm8901_boardinfo[] __initdata = {
-	{
-		I2C_BOARD_INFO("pm8901-core", 0x55),
-		.irq = MSM_GPIO_TO_INT(PM8901_GPIO_INT),
+static struct msm_ssbi_platform_data msm8x60_ssbi_pm8901_pdata __devinitdata = {
+	.controller_type = MSM_SBI_CTRL_PMIC_ARBITER,
+	.slave	= {
+		.name = "pm8901-core",
 		.platform_data = &pm8901_platform_data,
 	},
 };
-
 #endif /* CONFIG_PMIC8901 */
 
 #if defined(CONFIG_MARIMBA_CORE) && (defined(CONFIG_GPIO_SX150X) \
@@ -6946,14 +6940,6 @@
 };
 
 static struct i2c_registry msm8x60_i2c_devices[] __initdata = {
-#ifdef CONFIG_PMIC8901
-	{
-		I2C_SURF | I2C_FFA | I2C_FLUID | I2C_DRAGON,
-		MSM_SSBI2_I2C_BUS_ID,
-		pm8901_boardinfo,
-		ARRAY_SIZE(pm8901_boardinfo),
-	},
-#endif
 #if defined(CONFIG_GPIO_SX150X) || defined(CONFIG_GPIO_SX150X_MODULE)
 	{
 		I2C_SURF | I2C_FFA | I2C_DRAGON,
@@ -7216,13 +7202,14 @@
 	msm_gsbi1_qup_spi_device.dev.platform_data = &msm_gsbi1_qup_spi_pdata;
 #endif
 #ifdef CONFIG_I2C_SSBI
-	msm_device_ssbi2.dev.platform_data = &msm_ssbi2_pdata;
 	msm_device_ssbi3.dev.platform_data = &msm_ssbi3_pdata;
 #endif
 
 #ifdef CONFIG_MSM_SSBI
 	msm_device_ssbi_pmic1.dev.platform_data =
 				&msm8x60_ssbi_pm8058_pdata;
+	msm_device_ssbi_pmic2.dev.platform_data =
+				&msm8x60_ssbi_pm8901_pdata;
 #endif
 
 	if (machine_is_msm8x60_fluid()) {
diff --git a/arch/arm/mach-msm/clock-9615.c b/arch/arm/mach-msm/clock-9615.c
index 7e163df..5974300 100644
--- a/arch/arm/mach-msm/clock-9615.c
+++ b/arch/arm/mach-msm/clock-9615.c
@@ -249,19 +249,83 @@
 	},
 };
 
+static DEFINE_SPINLOCK(soft_vote_lock);
+
+static int pll_acpu_vote_clk_enable(struct clk *clk)
+{
+	int ret = 0;
+	unsigned long flags;
+	struct pll_vote_clk *pll = to_pll_vote_clk(clk);
+
+	spin_lock_irqsave(&soft_vote_lock, flags);
+
+	if (!*pll->soft_vote)
+		ret = pll_vote_clk_enable(clk);
+	if (ret == 0)
+		*pll->soft_vote |= (pll->soft_vote_mask);
+
+	spin_unlock_irqrestore(&soft_vote_lock, flags);
+	return ret;
+}
+
+static void pll_acpu_vote_clk_disable(struct clk *clk)
+{
+	unsigned long flags;
+	struct pll_vote_clk *pll = to_pll_vote_clk(clk);
+
+	spin_lock_irqsave(&soft_vote_lock, flags);
+
+	*pll->soft_vote &= ~(pll->soft_vote_mask);
+	if (!*pll->soft_vote)
+		pll_vote_clk_disable(clk);
+
+	spin_unlock_irqrestore(&soft_vote_lock, flags);
+}
+
+static struct clk_ops clk_ops_pll_acpu_vote = {
+	.enable = pll_acpu_vote_clk_enable,
+	.disable = pll_acpu_vote_clk_disable,
+	.auto_off = pll_acpu_vote_clk_disable,
+	.is_enabled = pll_vote_clk_is_enabled,
+	.get_rate = pll_vote_clk_get_rate,
+	.get_parent = pll_vote_clk_get_parent,
+	.is_local = local_clk_is_local,
+};
+
+#define PLL_SOFT_VOTE_PRIMARY	BIT(0)
+#define PLL_SOFT_VOTE_ACPU	BIT(1)
+
+static unsigned int soft_vote_pll0;
+
 static struct pll_vote_clk pll0_clk = {
 	.rate = 276000000,
 	.en_reg = BB_PLL_ENA_SC0_REG,
 	.en_mask = BIT(0),
 	.status_reg = BB_PLL0_STATUS_REG,
 	.parent = &cxo_clk.c,
+	.soft_vote = &soft_vote_pll0,
+	.soft_vote_mask = PLL_SOFT_VOTE_PRIMARY,
 	.c = {
 		.dbg_name = "pll0_clk",
-		.ops = &clk_ops_pll_vote,
+		.ops = &clk_ops_pll_acpu_vote,
 		CLK_INIT(pll0_clk.c),
 	},
 };
 
+static struct pll_vote_clk pll0_acpu_clk = {
+	.rate = 276000000,
+	.en_reg = BB_PLL_ENA_SC0_REG,
+	.en_mask = BIT(0),
+	.status_reg = BB_PLL0_STATUS_REG,
+	.soft_vote = &soft_vote_pll0,
+	.soft_vote_mask = PLL_SOFT_VOTE_ACPU,
+	.c = {
+		.dbg_name = "pll0_acpu_clk",
+		.ops = &clk_ops_pll_acpu_vote,
+		CLK_INIT(pll0_acpu_clk.c),
+	},
+};
+
 static struct pll_vote_clk pll4_clk = {
 	.rate = 393216000,
 	.en_reg = BB_PLL_ENA_SC0_REG,
@@ -275,32 +339,68 @@
 	},
 };
 
+static unsigned int soft_vote_pll8;
+
 static struct pll_vote_clk pll8_clk = {
 	.rate = 384000000,
 	.en_reg = BB_PLL_ENA_SC0_REG,
 	.en_mask = BIT(8),
 	.status_reg = BB_PLL8_STATUS_REG,
 	.parent = &cxo_clk.c,
+	.soft_vote = &soft_vote_pll8,
+	.soft_vote_mask = PLL_SOFT_VOTE_PRIMARY,
 	.c = {
 		.dbg_name = "pll8_clk",
-		.ops = &clk_ops_pll_vote,
+		.ops = &clk_ops_pll_acpu_vote,
 		CLK_INIT(pll8_clk.c),
 	},
 };
 
+static struct pll_vote_clk pll8_acpu_clk = {
+	.rate = 384000000,
+	.en_reg = BB_PLL_ENA_SC0_REG,
+	.en_mask = BIT(8),
+	.status_reg = BB_PLL8_STATUS_REG,
+	.soft_vote = &soft_vote_pll8,
+	.soft_vote_mask = PLL_SOFT_VOTE_ACPU,
+	.c = {
+		.dbg_name = "pll8_acpu_clk",
+		.ops = &clk_ops_pll_acpu_vote,
+		CLK_INIT(pll8_acpu_clk.c),
+	},
+};
+
+static unsigned int soft_vote_pll9;
+
 static struct pll_vote_clk pll9_clk = {
 	.rate = 440000000,
 	.en_reg = BB_PLL_ENA_SC0_REG,
 	.en_mask = BIT(9),
 	.status_reg = SC_PLL0_STATUS_REG,
 	.parent = &cxo_clk.c,
+	.soft_vote = &soft_vote_pll9,
+	.soft_vote_mask = PLL_SOFT_VOTE_PRIMARY,
 	.c = {
 		.dbg_name = "pll9_clk",
-		.ops = &clk_ops_pll_vote,
+		.ops = &clk_ops_pll_acpu_vote,
 		CLK_INIT(pll9_clk.c),
 	},
 };
 
+static struct pll_vote_clk pll9_acpu_clk = {
+	.rate = 440000000,
+	.en_reg = BB_PLL_ENA_SC0_REG,
+	.en_mask = BIT(9),
+	.soft_vote = &soft_vote_pll9,
+	.soft_vote_mask = PLL_SOFT_VOTE_ACPU,
+	.status_reg = SC_PLL0_STATUS_REG,
+	.c = {
+		.dbg_name = "pll9_acpu_clk",
+		.ops = &clk_ops_pll_acpu_vote,
+		CLK_INIT(pll9_acpu_clk.c),
+	},
+};
+
 static struct pll_vote_clk pll14_clk = {
 	.rate = 480000000,
 	.en_reg = BB_PLL_ENA_SC0_REG,
@@ -1557,6 +1657,11 @@
 	CLK_LOOKUP("pll8",	pll8_clk.c,	NULL),
 	CLK_LOOKUP("pll9",	pll9_clk.c,	NULL),
 	CLK_LOOKUP("pll14",	pll14_clk.c,	NULL),
+
+	CLK_LOOKUP("pll0", pll0_acpu_clk.c, "acpu"),
+	CLK_LOOKUP("pll8", pll8_acpu_clk.c, "acpu"),
+	CLK_LOOKUP("pll9", pll9_acpu_clk.c, "acpu"),
+
 	CLK_LOOKUP("measure",	measure_clk.c,	"debug"),
 
 	CLK_LOOKUP("cfpb_clk",		cfpb_clk.c,	NULL),
diff --git a/arch/arm/mach-msm/clock-local.c b/arch/arm/mach-msm/clock-local.c
index c1cfb55..2391f84 100644
--- a/arch/arm/mach-msm/clock-local.c
+++ b/arch/arm/mach-msm/clock-local.c
@@ -641,7 +641,7 @@
 	return 1;
 }
 
-static int pll_vote_clk_enable(struct clk *clk)
+int pll_vote_clk_enable(struct clk *clk)
 {
 	u32 ena;
 	unsigned long flags;
@@ -660,7 +660,7 @@
 	return 0;
 }
 
-static void pll_vote_clk_disable(struct clk *clk)
+void pll_vote_clk_disable(struct clk *clk)
 {
 	u32 ena;
 	unsigned long flags;
@@ -673,19 +673,19 @@
 	spin_unlock_irqrestore(&local_clock_reg_lock, flags);
 }
 
-static unsigned long pll_vote_clk_get_rate(struct clk *clk)
+unsigned long pll_vote_clk_get_rate(struct clk *clk)
 {
 	struct pll_vote_clk *pll = to_pll_vote_clk(clk);
 	return pll->rate;
 }
 
-static struct clk *pll_vote_clk_get_parent(struct clk *clk)
+struct clk *pll_vote_clk_get_parent(struct clk *clk)
 {
 	struct pll_vote_clk *pll = to_pll_vote_clk(clk);
 	return pll->parent;
 }
 
-static int pll_vote_clk_is_enabled(struct clk *clk)
+int pll_vote_clk_is_enabled(struct clk *clk)
 {
 	struct pll_vote_clk *pll = to_pll_vote_clk(clk);
 	return !!(readl_relaxed(pll->status_reg) & BIT(16));
diff --git a/arch/arm/mach-msm/clock-local.h b/arch/arm/mach-msm/clock-local.h
index 16a9955..2107567 100644
--- a/arch/arm/mach-msm/clock-local.h
+++ b/arch/arm/mach-msm/clock-local.h
@@ -177,6 +177,8 @@
 /**
  * struct pll_vote_clk - phase locked loop (HW voteable)
  * @rate: output rate
+ * @soft_vote: soft voting variable for multiple PLL software instances
+ * @soft_vote_mask: soft voting mask for multiple PLL software instances
  * @en_reg: enable register
  * @en_mask: ORed with @en_reg to enable the clock
  * @status_reg: status register
@@ -186,6 +188,8 @@
 struct pll_vote_clk {
 	unsigned long rate;
 
+	u32 *soft_vote;
+	const u32 soft_vote_mask;
 	void __iomem *const en_reg;
 	const u32 en_mask;
 
@@ -288,6 +292,15 @@
 bool local_clk_is_local(struct clk *clk);
 
 /*
+ * PLL vote clock APIs
+ */
+int pll_vote_clk_enable(struct clk *clk);
+void pll_vote_clk_disable(struct clk *clk);
+unsigned long pll_vote_clk_get_rate(struct clk *clk);
+struct clk *pll_vote_clk_get_parent(struct clk *clk);
+int pll_vote_clk_is_enabled(struct clk *clk);
+
+/*
  * Generic set-rate implementations
  */
 void set_rate_mnd(struct rcg_clk *clk, struct clk_freq_tbl *nf);
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index 47e33d0..88fd169 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -668,53 +668,47 @@
 };
 
 static uint16_t msm_mpm_irqs_m2a[MSM_MPM_NR_MPM_IRQS] = {
-	[1] = MSM_GPIO_TO_INT(46),
-	[2] = MSM_GPIO_TO_INT(150),
-	[4] = MSM_GPIO_TO_INT(103),
-	[5] = MSM_GPIO_TO_INT(104),
-	[6] = MSM_GPIO_TO_INT(105),
-	[7] = MSM_GPIO_TO_INT(106),
-	[8] = MSM_GPIO_TO_INT(107),
-	[9] = MSM_GPIO_TO_INT(7),
-	[10] = MSM_GPIO_TO_INT(11),
-	[11] = MSM_GPIO_TO_INT(15),
-	[12] = MSM_GPIO_TO_INT(19),
-	[13] = MSM_GPIO_TO_INT(23),
-	[14] = MSM_GPIO_TO_INT(27),
-	[15] = MSM_GPIO_TO_INT(31),
-	[16] = MSM_GPIO_TO_INT(35),
-	[19] = MSM_GPIO_TO_INT(90),
-	[20] = MSM_GPIO_TO_INT(92),
-	[23] = MSM_GPIO_TO_INT(85),
-	[24] = MSM_GPIO_TO_INT(83),
+	[4] = MSM_GPIO_TO_INT(30),
+	[5] = MSM_GPIO_TO_INT(59),
+	[6] = MSM_GPIO_TO_INT(81),
+	[7] = MSM_GPIO_TO_INT(87),
+	[8] = MSM_GPIO_TO_INT(86),
+	[9] = MSM_GPIO_TO_INT(2),
+	[10] = MSM_GPIO_TO_INT(6),
+	[11] = MSM_GPIO_TO_INT(10),
+	[12] = MSM_GPIO_TO_INT(14),
+	[13] = MSM_GPIO_TO_INT(18),
+	[14] = MSM_GPIO_TO_INT(7),
+	[15] = MSM_GPIO_TO_INT(11),
+	[16] = MSM_GPIO_TO_INT(15),
+	[19] = MSM_GPIO_TO_INT(26),
+	[20] = MSM_GPIO_TO_INT(28),
+	[23] = MSM_GPIO_TO_INT(19),
+	[24] = MSM_GPIO_TO_INT(23),
 	[25] = USB1_HS_IRQ,
-	/*[27] = HDMI_IRQ,*/
-	[29] = MSM_GPIO_TO_INT(10),
-	[30] = MSM_GPIO_TO_INT(102),
-	[31] = MSM_GPIO_TO_INT(81),
-	[32] = MSM_GPIO_TO_INT(78),
-	[33] = MSM_GPIO_TO_INT(94),
-	[34] = MSM_GPIO_TO_INT(72),
-	[35] = MSM_GPIO_TO_INT(39),
-	[36] = MSM_GPIO_TO_INT(43),
-	[37] = MSM_GPIO_TO_INT(61),
-	[38] = MSM_GPIO_TO_INT(50),
-	[39] = MSM_GPIO_TO_INT(42),
-	[41] = MSM_GPIO_TO_INT(62),
-	[42] = MSM_GPIO_TO_INT(76),
-	[43] = MSM_GPIO_TO_INT(75),
-	[44] = MSM_GPIO_TO_INT(70),
-	[45] = MSM_GPIO_TO_INT(69),
-	[46] = MSM_GPIO_TO_INT(67),
-	[47] = MSM_GPIO_TO_INT(65),
-	[48] = MSM_GPIO_TO_INT(58),
-	[49] = MSM_GPIO_TO_INT(54),
-	[50] = MSM_GPIO_TO_INT(52),
-	[51] = MSM_GPIO_TO_INT(49),
-	[52] = MSM_GPIO_TO_INT(40),
-	[53] = MSM_GPIO_TO_INT(37),
-	[54] = MSM_GPIO_TO_INT(24),
-	[55] = MSM_GPIO_TO_INT(14),
+	[26] = MSM_GPIO_TO_INT(3),
+	[27] = MSM_GPIO_TO_INT(68),
+	[29] = MSM_GPIO_TO_INT(78),
+	[31] = MSM_GPIO_TO_INT(0),
+	[32] = MSM_GPIO_TO_INT(4),
+	[33] = MSM_GPIO_TO_INT(22),
+	[34] = MSM_GPIO_TO_INT(17),
+	[37] = MSM_GPIO_TO_INT(20),
+	[39] = MSM_GPIO_TO_INT(84),
+	[42] = MSM_GPIO_TO_INT(24),
+	[43] = MSM_GPIO_TO_INT(79),
+	[44] = MSM_GPIO_TO_INT(80),
+	[45] = MSM_GPIO_TO_INT(82),
+	[46] = MSM_GPIO_TO_INT(85),
+	[47] = MSM_GPIO_TO_INT(45),
+	[48] = MSM_GPIO_TO_INT(50),
+	[49] = MSM_GPIO_TO_INT(51),
+	[50] = MSM_GPIO_TO_INT(69),
+	[51] = MSM_GPIO_TO_INT(77),
+	[52] = MSM_GPIO_TO_INT(1),
+	[53] = MSM_GPIO_TO_INT(5),
+	[54] = MSM_GPIO_TO_INT(40),
+	[55] = MSM_GPIO_TO_INT(27),
 };
 
 static uint16_t msm_mpm_bypassed_apps_irqs[] = {
diff --git a/arch/arm/mach-msm/devices-msm8x60.c b/arch/arm/mach-msm/devices-msm8x60.c
index 0ab9811..43c13bc 100644
--- a/arch/arm/mach-msm/devices-msm8x60.c
+++ b/arch/arm/mach-msm/devices-msm8x60.c
@@ -900,27 +900,25 @@
 	.resource       = resources_ssbi_pmic1_resource,
 	.num_resources  = ARRAY_SIZE(resources_ssbi_pmic1_resource),
 };
-#endif
 
-#ifdef CONFIG_I2C_SSBI
-/* 8901 PMIC SSBI on /dev/i2c-7 */
 #define MSM_SSBI2_PMIC2B_PHYS	0x00C00000
-static struct resource msm_ssbi2_resources[] = {
+static struct resource resources_ssbi_pmic2_resource[] = {
 	{
-		.name   = "ssbi_base",
 		.start	= MSM_SSBI2_PMIC2B_PHYS,
 		.end	= MSM_SSBI2_PMIC2B_PHYS + SZ_4K - 1,
 		.flags	= IORESOURCE_MEM,
 	},
 };
 
-struct platform_device msm_device_ssbi2 = {
-	.name		= "i2c_ssbi",
-	.id		= MSM_SSBI2_I2C_BUS_ID,
-	.num_resources	= ARRAY_SIZE(msm_ssbi2_resources),
-	.resource	= msm_ssbi2_resources,
+struct platform_device msm_device_ssbi_pmic2 = {
+	.name		= "msm_ssbi",
+	.id		= 1,
+	.resource	= resources_ssbi_pmic2_resource,
+	.num_resources	= ARRAY_SIZE(resources_ssbi_pmic2_resource),
 };
+#endif
 
+#ifdef CONFIG_I2C_SSBI
 /* CODEC SSBI on /dev/i2c-8 */
 #define MSM_SSBI3_PHYS  0x18700000
 static struct resource msm_ssbi3_resources[] = {
diff --git a/arch/arm/mach-msm/devices.h b/arch/arm/mach-msm/devices.h
index 48686f0..a95d0b6 100644
--- a/arch/arm/mach-msm/devices.h
+++ b/arch/arm/mach-msm/devices.h
@@ -138,6 +138,7 @@
 extern struct platform_device msm_device_tsif[2];
 
 extern struct platform_device msm_device_ssbi_pmic1;
+extern struct platform_device msm_device_ssbi_pmic2;
 extern struct platform_device msm_device_ssbi1;
 extern struct platform_device msm_device_ssbi2;
 extern struct platform_device msm_device_ssbi3;
diff --git a/arch/arm/mach-msm/include/mach/msm_bus_board.h b/arch/arm/mach-msm/include/mach/msm_bus_board.h
index b0d69c7..ddbf959 100644
--- a/arch/arm/mach-msm/include/mach/msm_bus_board.h
+++ b/arch/arm/mach-msm/include/mach/msm_bus_board.h
@@ -92,6 +92,7 @@
 
 #define NODE_ID(id) ((id) & (FABRIC_ID_KEY - 1))
 #define IS_SLAVE(id) ((NODE_ID(id)) >= SLAVE_ID_KEY ? 1 : 0)
+#define CHECK_ID(iid, id) (((iid & id) != id) ? -ENXIO : iid)
 
 /*
  * The following macros are used to format the data for port halt
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
index 7b9a16e..8175738 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_arb.c
@@ -144,6 +144,11 @@
 	/* Are we there yet? */
 	if (src == dest) {
 		info = fabdev->algo->find_node(fabdev, src);
+		if (ZERO_OR_NULL_PTR(info)) {
+			MSM_BUS_ERR("Node %d not found\n", dest);
+			return -ENXIO;
+		}
+
 		for (i = 0; i <= info->num_pnodes; i++) {
 			if (info->pnode[i].next == -2) {
 				MSM_BUS_DBG("src = dst  Reusing pnode for"
@@ -161,7 +166,7 @@
 		next_pnode_id = CREATE_PNODE_ID(src, (info->num_pnodes + 1));
 		pnode_num = add_path_node(info, next_pnode_id);
 		if (pnode_num < 0) {
-			MSM_BUS_DBG("error adding path node\n");
+			MSM_BUS_ERR("Error adding path node\n");
 			return -ENXIO;
 		}
 		MSM_BUS_DBG("returning: %d, %d\n", GET_NODE(next_pnode_id),
@@ -173,6 +178,11 @@
 		 * from the radix tree
 		 */
 		info = fabdev->algo->find_node(fabdev, dest);
+		if (ZERO_OR_NULL_PTR(info)) {
+			MSM_BUS_ERR("Node %d not found\n", dest);
+			return -ENXIO;
+		}
+
 		ret_pnode = getpath(info->node_info->priv_id, dest);
 		next_pnode_id = ret_pnode;
 	} else {
@@ -190,7 +200,7 @@
 					dest);
 				pnode_num = add_path_node(info, ret_pnode);
 				if (pnode_num < 0) {
-					MSM_BUS_DBG("Error adding path node\n");
+					MSM_BUS_ERR("Error adding path node\n");
 					return -ENXIO;
 				}
 				next_pnode_id = CREATE_PNODE_ID(
@@ -213,24 +223,20 @@
 					info = fabnodeinfo->info;
 					ret_pnode = getpath(info->
 						node_info->priv_id, dest);
-					if (ret_pnode >= 0) {
-						pnode_num = add_path_node(info,
-							ret_pnode);
-						if (pnode_num < 0) {
-							MSM_BUS_ERR("Malloc"
-							"failure in adding"
-							"path node\n");
-							return -ENXIO;
-						}
-						next_pnode_id = CREATE_PNODE_ID(
-						info->node_info->priv_id,
-						pnode_num);
-						break;
+					pnode_num = add_path_node(info,
+						ret_pnode);
+					if (pnode_num < 0) {
+						MSM_BUS_ERR("Malloc failure in"
+						" adding path node\n");
+						return -ENXIO;
 					}
+					next_pnode_id = CREATE_PNODE_ID(
+					info->node_info->priv_id, pnode_num);
+					break;
 				}
 			}
 			if (next_pnode_id < 0)
-				return -EPERM;
+				return -ENXIO;
 		}
 	}
 
@@ -242,8 +248,9 @@
 	info = fabdev->algo->find_node(fabdev, src);
 	if (!info) {
 		MSM_BUS_ERR("Node info not found.\n");
-		return -EPERM;
+		return -ENXIO;
 	}
+
 	pnode_num = add_path_node(info, next_pnode_id);
 	MSM_BUS_DBG(" Last: %d[%d] = (%d, %d)\n",
 		src, info->num_pnodes, GET_NODE(next_pnode_id),
@@ -466,12 +473,24 @@
 		}
 
 		src = msm_bus_board_get_iid(pdata->usecase->vectors[i].src);
+		if (src == -ENXIO) {
+			MSM_BUS_ERR("Master %d not supported. Client cannot be"
+				" registered\n",
+				pdata->usecase->vectors[i].src);
+			goto err;
+		}
 		dest = msm_bus_board_get_iid(pdata->usecase->vectors[i].dst);
+		if (dest == -ENXIO) {
+			MSM_BUS_ERR("Slave %d not supported. Client cannot be"
+				" registered\n",
+				pdata->usecase->vectors[i].dst);
+			goto err;
+		}
 		srcfab = msm_bus_get_fabric_device(GET_FABID(src));
 		srcfab->visited = true;
 		pnode[i] = getpath(src, dest);
 		bus_for_each_dev(&msm_bus_type, NULL, NULL, clearvisitedflag);
-		if (pnode[i] < 0) {
+		if (pnode[i] == -ENXIO) {
 			MSM_BUS_ERR("Cannot register client now! Try again!\n");
 			goto err;
 		}
@@ -532,6 +551,20 @@
 	for (i = 0; i < pdata->usecase->num_paths; i++) {
 		src = msm_bus_board_get_iid(client->pdata->usecase[index].
 			vectors[i].src);
+		if (src == -ENXIO) {
+			MSM_BUS_ERR("Master %d not supported. Request cannot"
+				" be updated\n", client->pdata->usecase->
+				vectors[i].src);
+			goto err;
+		}
+
+		if (msm_bus_board_get_iid(client->pdata->usecase[index].
+			vectors[i].dst) == -ENXIO) {
+			MSM_BUS_ERR("Slave %d not supported. Request cannot"
+				" be updated\n", client->pdata->usecase->
+				vectors[i].dst);
+		}
+
 		pnode = client->src_pnode[i];
 		req_clk = client->pdata->usecase[index].vectors[i].ib;
 		req_bw = client->pdata->usecase[index].vectors[i].ab;
@@ -584,6 +617,7 @@
 		MSM_BUS_ERR("Cannot find node info!\n");
 		return -ENXIO;
 	}
+
 	MSM_BUS_DBG("Starting the loop--remove\n");
 	do {
 		struct msm_bus_inode_info *hop;
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
index d284b70..fc91291 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8660.c
@@ -826,8 +826,14 @@
 
 static int msm_bus_board_8660_get_iid(int id)
 {
-	return ((id < SLAVE_ID_KEY) ? master_iids[id] : slave_iids[id -
-		SLAVE_ID_KEY]);
+	if ((id < SLAVE_ID_KEY && id >= NMASTERS) ||
+		id >= (SLAVE_ID_KEY + NSLAVES)) {
+		MSM_BUS_ERR("Cannot get iid. Invalid id %d passed\n", id);
+		return -EINVAL;
+	}
+
+	return CHECK_ID(((id < SLAVE_ID_KEY) ? master_iids[id] :
+		slave_iids[id - SLAVE_ID_KEY]), id);
 }
 
 static struct msm_bus_board_algorithm msm_bus_board_algo = {
diff --git a/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c b/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
index 1dda082..97a3145 100644
--- a/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
+++ b/arch/arm/mach-msm/msm_bus/msm_bus_board_8960.c
@@ -859,8 +859,8 @@
 		return -EINVAL;
 	}
 
-	return ((id < SLAVE_ID_KEY) ? master_iids[id] : slave_iids[id -
-		SLAVE_ID_KEY]);
+	return CHECK_ID(((id < SLAVE_ID_KEY) ? master_iids[id] :
+		slave_iids[id - SLAVE_ID_KEY]), id);
 }
 
 static struct msm_bus_board_algorithm msm_bus_board_algo = {
diff --git a/drivers/input/touchscreen/atmel_maxtouch.c b/drivers/input/touchscreen/atmel_maxtouch.c
index d2bd4df..35507e1 100644
--- a/drivers/input/touchscreen/atmel_maxtouch.c
+++ b/drivers/input/touchscreen/atmel_maxtouch.c
@@ -939,6 +939,7 @@
 				input_mt_sync(mxt->input);
 			}
 		}
+		input_report_key(mxt->input, BTN_TOUCH, !!active_touches);
 		if (active_touches == 0)
 			input_mt_sync(mxt->input);
 		input_sync(mxt->input);
diff --git a/drivers/mfd/Kconfig b/drivers/mfd/Kconfig
index c27fea6..b1d808b 100644
--- a/drivers/mfd/Kconfig
+++ b/drivers/mfd/Kconfig
@@ -164,9 +164,9 @@
 
 config PMIC8901
 	tristate "PMIC8901 Power Management chip"
-	depends on I2C_SSBI && ARCH_MSM8X60
-	default y if I2C_SSBI && ARCH_MSM8X60
+	depends on MSM_SSBI
 	select MFD_CORE
+	select MFD_PM8XXX
 	help
 	  Say yes here for Qualcomm PM8901 chip.
 
diff --git a/drivers/mfd/pmic8901.c b/drivers/mfd/pmic8901.c
index 390de33..07bba8b 100644
--- a/drivers/mfd/pmic8901.c
+++ b/drivers/mfd/pmic8901.c
@@ -11,10 +11,11 @@
  */
 
 #include <linux/interrupt.h>
-#include <linux/i2c.h>
 #include <linux/slab.h>
 #include <linux/ratelimit.h>
+#include <linux/gpio.h>
 #include <linux/mfd/core.h>
+#include <linux/msm_ssbi.h>
 #include <linux/mfd/pmic8901.h>
 #include <linux/platform_device.h>
 #include <linux/debugfs.h>
@@ -66,8 +67,7 @@
 
 struct pm8901_chip {
 	struct pm8901_platform_data	pdata;
-
-	struct i2c_client		*dev;
+	struct device			*dev;
 
 	u8	irqs_allowed[MAX_PM_BLOCKS];
 	u8	blocks_allowed[MAX_PM_MASTERS];
@@ -107,33 +107,15 @@
 }
 
 static inline int
-ssbi_write(struct i2c_client *client, u16 addr, const u8 *buf, size_t len)
+ssbi_read(struct device *dev, u16 addr, u8 *buf, size_t len)
 {
-	int	rc;
-	struct	i2c_msg msg = {
-		.addr           = addr,
-		.flags          = 0x0,
-		.buf            = (u8 *)buf,
-		.len            = len,
-	};
-
-	rc = i2c_transfer(client->adapter, &msg, 1);
-	return (rc == 1) ? 0 : rc;
+	return msm_ssbi_read(dev->parent, addr, buf, len);
 }
 
 static inline int
-ssbi_read(struct i2c_client *client, u16 addr, u8 *buf, size_t len)
+ssbi_write(struct device *dev, u16 addr, u8 *buf, size_t len)
 {
-	int	rc;
-	struct	i2c_msg msg = {
-		.addr           = addr,
-		.flags          = I2C_M_RD,
-		.buf            = buf,
-		.len            = len,
-	};
-
-	rc = i2c_transfer(client->adapter, &msg, 1);
-	return (rc == 1) ? 0 : rc;
+	return msm_ssbi_write(dev->parent, addr, buf, len);
 }
 
 /* External APIs */
@@ -770,30 +752,24 @@
 	.irq_set_wake  = pm8901_irq_set_wake,
 };
 
-static int pm8901_probe(struct i2c_client *client,
-			const struct i2c_device_id *id)
+static int pm8901_probe(struct platform_device *pdev)
 {
-	int	i, rc;
-	struct	pm8901_platform_data *pdata = client->dev.platform_data;
-	struct	pm8901_chip *chip;
+	int i, rc;
+	struct pm8901_platform_data *pdata = pdev->dev.platform_data;
+	struct pm8901_chip *chip;
 
-	if (pdata == NULL || !client->irq) {
+	if (pdata == NULL || pdata->irq <= 0) {
 		pr_err("%s: No platform_data or IRQ.\n", __func__);
 		return -ENODEV;
 	}
 
-	if (i2c_check_functionality(client->adapter, I2C_FUNC_I2C) == 0) {
-		pr_err("%s: i2c_check_functionality failed.\n", __func__);
-		return -ENODEV;
-	}
-
 	chip = kzalloc(sizeof *chip, GFP_KERNEL);
 	if (chip == NULL) {
 		pr_err("%s: kzalloc() failed.\n", __func__);
 		return -ENOMEM;
 	}
 
-	chip->dev = client;
+	chip->dev = &pdev->dev;
 
 	/* Read PMIC chip revision */
 	rc = ssbi_read(chip->dev, SSBI_REG_REV, &chip->revision, 1);
@@ -805,14 +781,14 @@
 	(void) memcpy((void *)&chip->pdata, (const void *)pdata,
 		      sizeof(chip->pdata));
 
-	irq_set_handler_data(chip->dev->irq, (void *)chip);
-	irq_set_irq_wake(chip->dev->irq, 1);
+	irq_set_handler_data(pdata->irq, (void *)chip);
+	irq_set_irq_wake(pdata->irq, 1);
 
 	chip->pm_max_irq = 0;
 	chip->pm_max_blocks = 0;
 	chip->pm_max_masters = 0;
 
-	i2c_set_clientdata(client, chip);
+	platform_set_drvdata(pdev, chip);
 
 	pmic_chip = chip;
 	spin_lock_init(&chip->pm_lock);
@@ -825,19 +801,19 @@
 		irq_set_handler_data(i, (void *)chip);
 	}
 
-	rc = mfd_add_devices(&chip->dev->dev, 0, pdata->sub_devices,
+	rc = mfd_add_devices(chip->dev, 0, pdata->sub_devices,
 			     pdata->num_subdevs, NULL, 0);
 	if (rc) {
 		pr_err("%s: could not add devices %d\n", __func__, rc);
 		return rc;
 	}
 
-	rc = request_threaded_irq(chip->dev->irq, NULL, pm8901_isr_thread,
+	rc = request_threaded_irq(pdata->irq, NULL, pm8901_isr_thread,
 			IRQF_ONESHOT | IRQF_DISABLED | pdata->irq_trigger_flags,
 			"pm8901-irq", chip);
 	if (rc)
 		pr_err("%s: could not request irq %d: %d\n", __func__,
-				chip->dev->irq, rc);
+				pdata->irq, rc);
 
 	rc = pmic8901_dbg_probe(chip);
 	if (rc < 0)
@@ -846,18 +822,18 @@
 	return rc;
 }
 
-static int __devexit pm8901_remove(struct i2c_client *client)
+static int __devexit pm8901_remove(struct platform_device *pdev)
 {
 	struct	pm8901_chip *chip;
 
-	chip = i2c_get_clientdata(client);
+	chip = platform_get_drvdata(pdev);
 	if (chip) {
 		if (chip->pm_max_irq) {
-			irq_set_irq_wake(chip->dev->irq, 0);
-			free_irq(chip->dev->irq, chip);
+			irq_set_irq_wake(chip->pdata.irq, 0);
+			free_irq(chip->pdata.irq, chip);
 		}
 
-		mfd_remove_devices(&chip->dev->dev);
+		mfd_remove_devices(chip->dev);
 
 		chip->dev = NULL;
 
@@ -870,13 +846,13 @@
 }
 
 #ifdef CONFIG_PM
-static int pm8901_suspend(struct i2c_client *client, pm_message_t mesg)
+static int pm8901_suspend(struct platform_device *pdev, pm_message_t mesg)
 {
 	struct	pm8901_chip *chip;
 	int	i;
 	unsigned long	irqsave;
 
-	chip = i2c_get_clientdata(client);
+	chip = platform_get_drvdata(pdev);
 
 	for (i = 0; i < MAX_PM_IRQ; i++) {
 		spin_lock_irqsave(&chip->pm_lock, irqsave);
@@ -890,18 +866,18 @@
 	}
 
 	if (!chip->count_wakeable)
-		disable_irq(chip->dev->irq);
+		disable_irq(chip->pdata.irq);
 
 	return 0;
 }
 
-static int pm8901_resume(struct i2c_client *client)
+static int pm8901_resume(struct platform_device *pdev)
 {
 	struct	pm8901_chip *chip;
 	int	i;
 	unsigned long	irqsave;
 
-	chip = i2c_get_clientdata(client);
+	chip = platform_get_drvdata(pdev);
 
 	for (i = 0; i < MAX_PM_IRQ; i++) {
 		spin_lock_irqsave(&chip->pm_lock, irqsave);
@@ -915,7 +891,7 @@
 	}
 
 	if (!chip->count_wakeable)
-		enable_irq(chip->dev->irq);
+		enable_irq(chip->pdata.irq);
 
 	return 0;
 }
@@ -924,35 +900,27 @@
 #define	pm8901_resume		NULL
 #endif
 
-static const struct i2c_device_id pm8901_ids[] = {
-	{ "pm8901-core", 0 },
-	{ },
-};
-MODULE_DEVICE_TABLE(i2c, pm8901_ids);
-
-static struct i2c_driver pm8901_driver = {
-	.driver.name	= "pm8901-core",
-	.id_table	= pm8901_ids,
+static struct platform_driver pm8901_driver = {
 	.probe		= pm8901_probe,
 	.remove		= __devexit_p(pm8901_remove),
+	.driver		= {
+		.name	= "pm8901-core",
+		.owner	= THIS_MODULE,
+	},
 	.suspend	= pm8901_suspend,
 	.resume		= pm8901_resume,
 };
 
 static int __init pm8901_init(void)
 {
-	int rc = i2c_add_driver(&pm8901_driver);
-	pr_notice("%s: i2c_add_driver: rc = %d\n", __func__, rc);
-
-	return rc;
+	return  platform_driver_register(&pm8901_driver);
 }
+arch_initcall(pm8901_init);
 
 static void __exit pm8901_exit(void)
 {
-	i2c_del_driver(&pm8901_driver);
+	platform_driver_unregister(&pm8901_driver);
 }
-
-arch_initcall(pm8901_init);
 module_exit(pm8901_exit);
 
 MODULE_LICENSE("GPL v2");
diff --git a/drivers/video/msm/hdmi_msm.c b/drivers/video/msm/hdmi_msm.c
index 4ef0da6..3467e0d 100644
--- a/drivers/video/msm/hdmi_msm.c
+++ b/drivers/video/msm/hdmi_msm.c
@@ -3384,35 +3384,35 @@
 }
 
 
-static uint8 hdmi_msm_avi_iframe_lut[][15] = {
-/*	480p60	480i60	576p50	576i50	720p60	720p50	1080p60	1080i60	1080p50
-	1080i50	1080p24	1080p30	1080p25	640x480p        480p60_16_9*/
-	{0x10,	0x10,	0x10,	0x10,	0x10,	0x10,	0x10,	0x10,	0x10,
-	 0x10,	0x10,	0x10,	0x10,	0x10, 0x10}, /*00*/
-	{0x18,	0x18,	0x28,	0x28,	0x28,	0x28,	0x28,	0x28,	0x28,
-	 0x28,	0x28,	0x28,	0x28,	0x18, 0x28}, /*01*/
-	{0x04,	0x04,	0x04,	0x04,	0x04,	0x04,	0x04,	0x04,	0x04,
-	 0x04,	0x04,	0x04,	0x04,	0x88, 0x04}, /*02*/
-	{0x02,	0x06,	0x11,	0x15,	0x04,	0x13,	0x10,	0x05,	0x1F,
-	 0x14,	0x20,	0x22,	0x21,	0x01, 0x03}, /*03*/
-	{0x00,	0x01,	0x00,	0x01,	0x00,	0x00,	0x00,	0x00,	0x00,
-	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00}, /*04*/
-	{0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
-	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00}, /*05*/
-	{0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
-	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00}, /*06*/
-	{0xE1,	0xE1,	0x41,	0x41,	0xD1,	0xd1,	0x39,	0x39,	0x39,
-	 0x39,	0x39,	0x39,	0x39,	0xe1, 0xE1}, /*07*/
-	{0x01,	0x01,	0x02,	0x02,	0x02,	0x02,	0x04,	0x04,	0x04,
-	 0x04,	0x04,	0x04,	0x04,	0x01, 0x01}, /*08*/
-	{0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
-	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00}, /*09*/
-	{0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,	0x00,
-	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00}, /*10*/
-	{0xD1,	0xD1,	0xD1,	0xD1,	0x01,	0x01,	0x81,	0x81,	0x81,
-	 0x81,	0x81,	0x81,	0x81,	0x81, 0xD1}, /*11*/
-	{0x02,	0x02,	0x02,	0x02,	0x05,	0x05,	0x07,	0x07,	0x07,
-	 0x07,	0x07,	0x07,	0x07,	0x02, 0x02} /*12*/
+static uint8 hdmi_msm_avi_iframe_lut[][16] = {
+/*	480p60	480i60	576p50	576i50	720p60	 720p50	1080p60	1080i60	1080p50
+	1080i50	1080p24	1080p30	1080p25	640x480p 480p60_16_9 576p50_4_3 */
+	{0x10,	0x10,	0x10,	0x10,	0x10,	 0x10,	0x10,	0x10,	0x10,
+	 0x10,	0x10,	0x10,	0x10,	0x10, 0x10, 0x10}, /*00*/
+	{0x18,	0x18,	0x28,	0x28,	0x28,	 0x28,	0x28,	0x28,	0x28,
+	 0x28,	0x28,	0x28,	0x28,	0x18, 0x28, 0x18}, /*01*/
+	{0x04,	0x04,	0x04,	0x04,	0x04,	 0x04,	0x04,	0x04,	0x04,
+	 0x04,	0x04,	0x04,	0x04,	0x88, 0x04, 0x04}, /*02*/
+	{0x02,	0x06,	0x11,	0x15,	0x04,	 0x13,	0x10,	0x05,	0x1F,
+	 0x14,	0x20,	0x22,	0x21,	0x01, 0x03, 0x11}, /*03*/
+	{0x00,	0x01,	0x00,	0x01,	0x00,	 0x00,	0x00,	0x00,	0x00,
+	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00}, /*04*/
+	{0x00,	0x00,	0x00,	0x00,	0x00,	 0x00,	0x00,	0x00,	0x00,
+	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00}, /*05*/
+	{0x00,	0x00,	0x00,	0x00,	0x00,	 0x00,	0x00,	0x00,	0x00,
+	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00}, /*06*/
+	{0xE1,	0xE1,	0x41,	0x41,	0xD1,	 0xd1,	0x39,	0x39,	0x39,
+	 0x39,	0x39,	0x39,	0x39,	0xe1, 0xE1, 0x41}, /*07*/
+	{0x01,	0x01,	0x02,	0x02,	0x02,	 0x02,	0x04,	0x04,	0x04,
+	 0x04,	0x04,	0x04,	0x04,	0x01, 0x01, 0x02}, /*08*/
+	{0x00,	0x00,	0x00,	0x00,	0x00,	 0x00,	0x00,	0x00,	0x00,
+	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00}, /*09*/
+	{0x00,	0x00,	0x00,	0x00,	0x00,	 0x00,	0x00,	0x00,	0x00,
+	 0x00,	0x00,	0x00,	0x00,	0x00, 0x00, 0x00}, /*10*/
+	{0xD1,	0xD1,	0xD1,	0xD1,	0x01,	 0x01,	0x81,	0x81,	0x81,
+	 0x81,	0x81,	0x81,	0x81,	0x81, 0xD1, 0xD1}, /*11*/
+	{0x02,	0x02,	0x02,	0x02,	0x05,	 0x05,	0x07,	0x07,	0x07,
+	 0x07,	0x07,	0x07,	0x07,	0x02, 0x02, 0x02}  /*12*/
 };
 
 static void hdmi_msm_avi_info_frame(void)
@@ -3471,6 +3471,9 @@
 	case HDMI_VFRMT_720x480p60_16_9:
 		mode = 14;
 		break;
+	case HDMI_VFRMT_720x576p50_4_3:
+		mode = 15;
+		break;
 	default:
 		DEV_INFO("%s: mode %d not supported\n", __func__,
 			external_common_state->video_resolution);
diff --git a/include/linux/mfd/pmic8901.h b/include/linux/mfd/pmic8901.h
index 8b628c5..5d23edc 100644
--- a/include/linux/mfd/pmic8901.h
+++ b/include/linux/mfd/pmic8901.h
@@ -38,6 +38,7 @@
 struct pm8901_platform_data {
 	/* This table is only needed for misc interrupts. */
 	int		irq_base;
+	int		irq;
 
 	int		num_subdevs;
 	struct mfd_cell *sub_devices;
diff --git a/net/bluetooth/rfcomm/core.c b/net/bluetooth/rfcomm/core.c
index 16bb5ea..c4b9950 100644
--- a/net/bluetooth/rfcomm/core.c
+++ b/net/bluetooth/rfcomm/core.c
@@ -1203,6 +1203,7 @@
 			if (list_empty(&s->dlcs)) {
 				s->state = BT_DISCONN;
 				rfcomm_send_disc(s, 0);
+				rfcomm_session_clear_timer(s);
 			}
 
 			break;