Merge "input: atmel_maxtouch: Report BTN_TOUCH event" 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/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/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/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;