Merge "power: pm8921-charger: use trickle time for trickle charging" into msm-3.0
diff --git a/arch/arm/Kconfig b/arch/arm/Kconfig
index 4690de3..f34719f 100644
--- a/arch/arm/Kconfig
+++ b/arch/arm/Kconfig
@@ -1606,6 +1606,10 @@
 	def_bool n
 	depends on MEMORY_HOTPLUG
 
+config FIX_MOVABLE_ZONE
+	def_bool n
+	depends on MEMORY_HOTPLUG
+
 config DONT_MAP_HOLE_AFTER_MEMBANK0
 	def_bool n
 	depends on SPARSEMEM
diff --git a/arch/arm/configs/msm8660-perf_defconfig b/arch/arm/configs/msm8660-perf_defconfig
index c9082f0..d377460 100644
--- a/arch/arm/configs/msm8660-perf_defconfig
+++ b/arch/arm/configs/msm8660-perf_defconfig
@@ -315,6 +315,8 @@
 CONFIG_MT9E013=y
 CONFIG_MSM_GEMINI=y
 CONFIG_RADIO_TAVARUA=y
+CONFIG_ION=y
+CONFIG_ION_MSM=y
 CONFIG_MSM_KGSL=y
 CONFIG_KGSL_PER_PROCESS_PAGE_TABLE=y
 CONFIG_VIDEO_OUTPUT_CONTROL=y
diff --git a/arch/arm/configs/msm8960_defconfig b/arch/arm/configs/msm8960_defconfig
index 2045ff8..76ac964 100755
--- a/arch/arm/configs/msm8960_defconfig
+++ b/arch/arm/configs/msm8960_defconfig
@@ -388,11 +388,18 @@
 CONFIG_MAGIC_SYSRQ=y
 CONFIG_DEBUG_FS=y
 CONFIG_DEBUG_KERNEL=y
+CONFIG_LOCKUP_DETECTOR=y
 # CONFIG_SCHED_DEBUG is not set
 CONFIG_TIMER_STATS=y
+CONFIG_SLUB_DEBUG_ON=y
 # CONFIG_DEBUG_PREEMPT is not set
+CONFIG_DEBUG_SPINLOCK=y
+CONFIG_DEBUG_MUTEXES=y
+CONFIG_DEBUG_SPINLOCK_SLEEP=y
 CONFIG_DEBUG_INFO=y
 CONFIG_DEBUG_MEMORY_INIT=y
+CONFIG_DEBUG_LIST=y
+CONFIG_DEBUG_PAGEALLOC=y
 CONFIG_DYNAMIC_DEBUG=y
 CONFIG_DEBUG_USER=y
 CONFIG_CRYPTO_SHA256=y
diff --git a/arch/arm/configs/msm9615_defconfig b/arch/arm/configs/msm9615_defconfig
index fa6475b..714e630 100644
--- a/arch/arm/configs/msm9615_defconfig
+++ b/arch/arm/configs/msm9615_defconfig
@@ -221,7 +221,9 @@
 CONFIG_LIB80211=m
 CONFIG_NETDEVICES=y
 CONFIG_WLAN=y
-CONFIG_MSM_RMNET=y
+# CONFIG_MSM_RMNET is not set
+CONFIG_MSM_BAM_DMUX=y
+CONFIG_MSM_RMNET_BAM=y
 CONFIG_HOSTAP=m
 CONFIG_WIRELESS_EXT=y
 CONFIG_WEXT_SPY=y
diff --git a/arch/arm/mach-msm/Kconfig b/arch/arm/mach-msm/Kconfig
index 756603e..486d80e 100644
--- a/arch/arm/mach-msm/Kconfig
+++ b/arch/arm/mach-msm/Kconfig
@@ -1573,6 +1573,16 @@
 
 	  This bug is not applicable to any ScorpionMP or Scorpion Uni 65nm(SC65U) cores.
 
+config MSM_BUSPM_DEV
+	tristate "MSM Bus Performance Monitor Kernel Module"
+	depends on (ARCH_MSM8X60 || ARCH_MSM8960)
+	default m
+	help
+	  This kernel module is used to mmap() hardware registers for the
+	  performance monitors, counters, etc. The module can also be used to
+	  allocate physical memory which is used by bus performance hardware to
+	  dump performance data.
+
 config MSM_RPM_LOG
 	tristate "MSM Resource Power Manager Log Driver"
 	depends on DEBUG_FS
diff --git a/arch/arm/mach-msm/Makefile b/arch/arm/mach-msm/Makefile
index 8693875..292cee2 100644
--- a/arch/arm/mach-msm/Makefile
+++ b/arch/arm/mach-msm/Makefile
@@ -254,6 +254,7 @@
 obj-$(CONFIG_MSM_RPM_LOG) += rpm_log.o
 obj-$(CONFIG_MSM_XO) += msm_xo.o
 obj-$(CONFIG_MSM_BUS_SCALING) += msm_bus/
+obj-$(CONFIG_MSM_BUSPM_DEV) += msm-buspm-dev.o
 
 obj-$(CONFIG_MSM_IOMMU)		+= iommu.o iommu_dev.o devices-iommu.o iommu_domains.o
 
diff --git a/arch/arm/mach-msm/board-msm7x30.c b/arch/arm/mach-msm/board-msm7x30.c
index 03307f0..9fb9fb6 100644
--- a/arch/arm/mach-msm/board-msm7x30.c
+++ b/arch/arm/mach-msm/board-msm7x30.c
@@ -389,6 +389,14 @@
 	return rc;
 }
 
+/* TODO: Put the regulator to LPM / HPM in suspend/resume*/
+static int cyttsp_platform_suspend(struct i2c_client *client)
+{
+	msleep(20);
+
+	return CY_OK;
+}
+
 static int cyttsp_platform_resume(struct i2c_client *client)
 {
 	/* add any special code to strobe a wakeup pin or chip reset */
@@ -432,6 +440,7 @@
 	 */
 	.lp_intrvl = CY_LP_INTRVL_DFLT,
 	.resume = cyttsp_platform_resume,
+	.suspend = cyttsp_platform_suspend,
 	.init = cyttsp_platform_init,
 	.sleep_gpio = -1,
 	.resout_gpio = -1,
diff --git a/arch/arm/mach-msm/board-msm8960.c b/arch/arm/mach-msm/board-msm8960.c
index 1449e34..103a224 100644
--- a/arch/arm/mach-msm/board-msm8960.c
+++ b/arch/arm/mach-msm/board-msm8960.c
@@ -3341,14 +3341,16 @@
 		.name = "vdd",
 		.min_uV = CY_TMA300_VTG_MIN_UV,
 		.max_uV = CY_TMA300_VTG_MAX_UV,
-		.load_uA = CY_TMA300_CURR_24HZ_UA,
+		.hpm_load_uA = CY_TMA300_CURR_24HZ_UA,
+		.lpm_load_uA = CY_TMA300_SLEEP_CURR_UA,
 	},
 	/* TODO: Remove after runtime PM is enabled in I2C driver */
 	{
 		.name = "vcc_i2c",
 		.min_uV = CY_I2C_VTG_MIN_UV,
 		.max_uV = CY_I2C_VTG_MAX_UV,
-		.load_uA = CY_I2C_CURR_UA,
+		.hpm_load_uA = CY_I2C_CURR_UA,
+		.lpm_load_uA = CY_I2C_SLEEP_CURR_UA,
 	},
 };
 
@@ -4696,6 +4698,7 @@
 	.timer = &msm_timer,
 	.init_machine = msm8960_cdp_init,
 	.init_early = msm8960_allocate_memory_regions,
+	.init_very_early = msm8960_early_memory,
 MACHINE_END
 
 MACHINE_START(MSM8930_MTP, "QCT MSM8930 MTP")
@@ -4705,6 +4708,7 @@
 	.timer = &msm_timer,
 	.init_machine = msm8960_cdp_init,
 	.init_early = msm8960_allocate_memory_regions,
+	.init_very_early = msm8960_early_memory,
 MACHINE_END
 
 MACHINE_START(MSM8930_FLUID, "QCT MSM8930 FLUID")
@@ -4714,5 +4718,6 @@
 	.timer = &msm_timer,
 	.init_machine = msm8960_cdp_init,
 	.init_early = msm8960_allocate_memory_regions,
+	.init_very_early = msm8960_early_memory,
 MACHINE_END
 #endif
diff --git a/arch/arm/mach-msm/board-msm8x60.c b/arch/arm/mach-msm/board-msm8x60.c
index 61b70cf..d891fdf 100644
--- a/arch/arm/mach-msm/board-msm8x60.c
+++ b/arch/arm/mach-msm/board-msm8x60.c
@@ -109,6 +109,10 @@
 #include "rpm_resources.h"
 #include "acpuclock.h"
 #include "pm-boot.h"
+
+#include <linux/ion.h>
+#include <mach/ion.h>
+
 #define MSM_SHARED_RAM_PHYS 0x40000000
 
 /* Macros assume PMIC GPIOs start at 0 */
@@ -2624,6 +2628,16 @@
 #define USER_SMI_SIZE         (MSM_SMI_SIZE - KERNEL_SMI_SIZE)
 #define MSM_PMEM_SMIPOOL_SIZE USER_SMI_SIZE
 
+#define MSM_ION_EBI_SIZE        MSM_PMEM_SF_SIZE
+#define MSM_ION_ADSP_SIZE       MSM_PMEM_ADSP_SIZE
+#define MSM_ION_SMI_SIZE	MSM_USER_SMI_SIZE
+
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+#define MSM_ION_HEAP_NUM	5
+#else
+#define MSM_ION_HEAP_NUM	2
+#endif
+
 static unsigned fb_size;
 static int __init fb_size_setup(char *p)
 {
@@ -2753,6 +2767,7 @@
 };
 
 #ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 static struct android_pmem_platform_data android_pmem_pdata = {
 	.name = "pmem",
 	.allocator_type = PMEM_ALLOCATORTYPE_ALLORNOTHING,
@@ -2778,7 +2793,7 @@
 	.id = 2,
 	.dev = { .platform_data = &android_pmem_adsp_pdata },
 };
-
+#endif
 static struct android_pmem_platform_data android_pmem_audio_pdata = {
 	.name = "pmem_audio",
 	.allocator_type = PMEM_ALLOCATORTYPE_BITMAP,
@@ -2802,6 +2817,7 @@
 		}, \
 	.num_paths = 1, \
 	}
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 static struct msm_bus_paths pmem_smi_table[] = {
 	[0] = PMEM_BUS_WIDTH(0), /* Off */
 	[1] = PMEM_BUS_WIDTH(1), /* On */
@@ -2846,7 +2862,7 @@
 	.id = 7,
 	.dev = { .platform_data = &android_pmem_smipool_pdata },
 };
-
+#endif
 #endif
 
 #define GPIO_DONGLE_PWR_EN 258
@@ -3193,6 +3209,14 @@
 	return rc;
 }
 
+/* TODO: Put the regulator to LPM / HPM in suspend/resume*/
+static int cyttsp_platform_suspend(struct i2c_client *client)
+{
+	msleep(20);
+
+	return CY_OK;
+}
+
 static int cyttsp_platform_resume(struct i2c_client *client)
 {
 	/* add any special code to strobe a wakeup pin or chip reset */
@@ -3232,6 +3256,7 @@
 	.resout_gpio = -1,
 	.irq_gpio = CYTTSP_TS_GPIO_IRQ,
 	.resume = cyttsp_platform_resume,
+	.suspend = cyttsp_platform_suspend,
 	.init = cyttsp_platform_init,
 };
 
@@ -3274,6 +3299,7 @@
 	.resout_gpio = -1,
 	.irq_gpio = CYTTSP_TS_GPIO_IRQ,
 	.resume = cyttsp_platform_resume,
+	.suspend = cyttsp_platform_suspend,
 	.init = cyttsp_platform_init,
 	.disable_ghost_det = true,
 };
@@ -5001,11 +5027,13 @@
 	&msm_batt_device,
 #endif
 #ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	&android_pmem_device,
 	&android_pmem_adsp_device,
-	&android_pmem_audio_device,
 	&android_pmem_smipool_device,
 #endif
+	&android_pmem_audio_device,
+#endif
 #ifdef CONFIG_MSM_ROTATOR
 	&msm_rotator_device,
 #endif
@@ -5098,9 +5126,59 @@
 
 	&msm_tsens_device,
 	&msm_rpm_device,
-
+#ifdef CONFIG_ION_MSM
+	&ion_dev,
+#endif
 };
 
+#ifdef CONFIG_ION_MSM
+struct ion_platform_data ion_pdata = {
+	.nr = MSM_ION_HEAP_NUM,
+	.heaps = {
+		{
+			.id	= ION_HEAP_SYSTEM_ID,
+			.type	= ION_HEAP_TYPE_SYSTEM,
+			.name	= ION_VMALLOC_HEAP_NAME,
+		},
+		{
+			.id	= ION_HEAP_SYSTEM_CONTIG_ID,
+			.type	= ION_HEAP_TYPE_SYSTEM_CONTIG,
+			.name	= ION_KMALLOC_HEAP_NAME,
+		},
+#ifdef CONFIG_MSM_MULTIMEDIA_USE_ION
+		{
+			.id	= ION_HEAP_EBI_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_EBI1_HEAP_NAME,
+			.size	= MSM_ION_EBI_SIZE,
+			.memory_type = ION_EBI_TYPE,
+		},
+		{
+			.id	= ION_HEAP_ADSP_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_ADSP_HEAP_NAME,
+			.size	= MSM_ION_ADSP_SIZE,
+			.memory_type = ION_EBI_TYPE,
+		},
+		{
+			.id	= ION_HEAP_SMI_ID,
+			.type	= ION_HEAP_TYPE_CARVEOUT,
+			.name	= ION_SMI_HEAP_NAME,
+			.size	= MSM_ION_SMI_SIZE,
+			.memory_type = ION_SMI_TYPE,
+		},
+#endif
+	}
+};
+
+struct platform_device ion_dev = {
+	.name = "ion-msm",
+	.id = 1,
+	.dev = { .platform_data = &ion_pdata },
+};
+#endif
+
+
 static struct memtype_reserve msm8x60_reserve_table[] __initdata = {
 	/* Kernel SMI memory pool for video core, used for firmware */
 	/* and encoder, decoder scratch buffers */
@@ -5128,14 +5206,25 @@
 	},
 };
 
+static void reserve_ion_memory(void)
+{
+#if defined(CONFIG_ION_MSM) && defined(CONFIG_MSM_MULTIMEDIA_USE_ION)
+	msm8x60_reserve_table[MEMTYPE_EBI1].size += MSM_ION_EBI_SIZE;
+	msm8x60_reserve_table[MEMTYPE_EBI1].size += MSM_ION_ADSP_SIZE;
+	msm8x60_reserve_table[MEMTYPE_SMI].size += MSM_ION_SMI_SIZE;
+#endif
+}
+
 static void __init size_pmem_devices(void)
 {
 #ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	android_pmem_adsp_pdata.size = pmem_adsp_size;
 	android_pmem_smipool_pdata.size = MSM_PMEM_SMIPOOL_SIZE;
-	android_pmem_audio_pdata.size = MSM_PMEM_AUDIO_SIZE;
 	android_pmem_pdata.size = pmem_sf_size;
 #endif
+	android_pmem_audio_pdata.size = MSM_PMEM_AUDIO_SIZE;
+#endif
 }
 
 static void __init reserve_memory_for(struct android_pmem_platform_data *p)
@@ -5146,18 +5235,23 @@
 static void __init reserve_pmem_memory(void)
 {
 #ifdef CONFIG_ANDROID_PMEM
+#ifndef CONFIG_MSM_MULTIMEDIA_USE_ION
 	reserve_memory_for(&android_pmem_adsp_pdata);
 	reserve_memory_for(&android_pmem_smipool_pdata);
-	reserve_memory_for(&android_pmem_audio_pdata);
 	reserve_memory_for(&android_pmem_pdata);
+#endif
+	reserve_memory_for(&android_pmem_audio_pdata);
 	msm8x60_reserve_table[MEMTYPE_EBI1].size += pmem_kernel_ebi1_size;
 #endif
 }
 
+
+
 static void __init msm8x60_calculate_reserve_sizes(void)
 {
 	size_pmem_devices();
 	reserve_pmem_memory();
+	reserve_ion_memory();
 }
 
 static int msm8x60_paddr_to_memtype(unsigned int paddr)
diff --git a/arch/arm/mach-msm/clock-8960.c b/arch/arm/mach-msm/clock-8960.c
index bbe8748..a0c6878 100644
--- a/arch/arm/mach-msm/clock-8960.c
+++ b/arch/arm/mach-msm/clock-8960.c
@@ -5223,7 +5223,7 @@
 	CLK_LOOKUP("usb_hsic_p_clk",	usb_hsic_p_clk.c,	NULL),
 
 	CLK_LOOKUP("ebi1_msmbus_clk",	ebi1_msmbus_clk.c, NULL),
-	CLK_LOOKUP("ebi1_clk",		ebi1_adm_clk.c, "msm_dmov"),
+	CLK_LOOKUP("mem_clk",		ebi1_adm_clk.c, "msm_dmov"),
 
 	CLK_LOOKUP("l2_mclk",		l2_m_clk,     NULL),
 	CLK_LOOKUP("krait0_mclk",	krait0_m_clk, NULL),
diff --git a/arch/arm/mach-msm/clock-debug.c b/arch/arm/mach-msm/clock-debug.c
index 4e0d3e9..ab4d8c1 100644
--- a/arch/arm/mach-msm/clock-debug.c
+++ b/arch/arm/mach-msm/clock-debug.c
@@ -174,7 +174,7 @@
 
 	/* Find max frequency supported within voltage constraints. */
 	if (!clock->vdd_class) {
-		fmax = ULONG_MAX;
+		fmax = INT_MAX;
 	} else {
 		for (level = 0; level < ARRAY_SIZE(clock->fmax); level++)
 			if (clock->fmax[level])
@@ -213,7 +213,7 @@
 	if (!debugfs_base)
 		return -ENOMEM;
 
-	strncpy(temp, clock->dbg_name, ARRAY_SIZE(temp)-1);
+	strlcpy(temp, clock->dbg_name, ARRAY_SIZE(temp));
 	for (ptr = temp; *ptr; ptr++)
 		*ptr = tolower(*ptr);
 
diff --git a/arch/arm/mach-msm/devices-9615.c b/arch/arm/mach-msm/devices-9615.c
index 74e7871..13772ce 100644
--- a/arch/arm/mach-msm/devices-9615.c
+++ b/arch/arm/mach-msm/devices-9615.c
@@ -721,20 +721,19 @@
 };
 
 static uint8_t spm_wfi_cmd_sequence[] __initdata = {
-	0x00, 0x03, 0x0B, 0x00,
-	0x0f,
+	0x00, 0x03, 0x00, 0x0f,
 };
 
 static uint8_t spm_power_collapse_without_rpm[] __initdata = {
-	0x30, 0x20, 0x10, 0x00,
-	0x50, 0x03, 0x50, 0x00,
-	0x10, 0x20, 0x30, 0x0f,
+	0x34, 0x24, 0x14, 0x04,
+	0x54, 0x03, 0x54, 0x04,
+	0x14, 0x24, 0x3e, 0x0f,
 };
 
 static uint8_t spm_power_collapse_with_rpm[] __initdata = {
-	0x30, 0x20, 0x10, 0x00,
-	0x50, 0x07, 0x50, 0x00,
-	0x10, 0x20, 0x30, 0x0f,
+	0x34, 0x24, 0x14, 0x04,
+	0x54, 0x07, 0x54, 0x04,
+	0x14, 0x24, 0x3e, 0x0f,
 };
 
 static struct msm_spm_seq_entry msm_spm_seq_list[] __initdata = {
@@ -759,7 +758,7 @@
 	[0] = {
 		.reg_base_addr = MSM_SAW0_BASE,
 		.reg_init_values[MSM_SPM_REG_SAW2_SPM_CTL] = 0x01,
-		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1F,
+		.reg_init_values[MSM_SPM_REG_SAW2_CFG] = 0x1001,
 		.num_modes = ARRAY_SIZE(msm_spm_seq_list),
 		.modes = msm_spm_seq_list,
 	},
diff --git a/arch/arm/mach-msm/msm-buspm-dev.c b/arch/arm/mach-msm/msm-buspm-dev.c
new file mode 100644
index 0000000..296418d
--- /dev/null
+++ b/arch/arm/mach-msm/msm-buspm-dev.c
@@ -0,0 +1,256 @@
+/* Copyright (c) 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.
+ */
+
+/* #define DEBUG */
+
+#include <linux/module.h>
+#include <linux/fs.h>
+#include <linux/mm.h>
+#include <linux/err.h>
+#include <linux/slab.h>
+#include <linux/errno.h>
+#include <linux/device.h>
+#include <linux/uaccess.h>
+#include <linux/miscdevice.h>
+#include <linux/memory_alloc.h>
+#include "msm-buspm-dev.h"
+
+#define MSM_BUSPM_DRV_NAME "msm-buspm-dev"
+
+/*
+ * Allocate kernel buffer.
+ * Currently limited to one buffer per file descriptor.  If alloc() is
+ * called twice for the same descriptor, the original buffer is freed.
+ * There is also no locking protection so the same descriptor can not be shared.
+ */
+
+static inline void *msm_buspm_dev_get_vaddr(struct file *filp)
+{
+	struct msm_buspm_map_dev *dev = filp->private_data;
+
+	return (dev) ? dev->vaddr : NULL;
+}
+
+static inline unsigned long msm_buspm_dev_get_paddr(struct file *filp)
+{
+	struct msm_buspm_map_dev *dev = filp->private_data;
+
+	return (dev) ? dev->paddr : 0L;
+}
+
+static void msm_buspm_dev_free(struct file *filp)
+{
+	struct msm_buspm_map_dev *dev = filp->private_data;
+
+	if (dev) {
+		pr_debug("freeing memory at 0x%p\n", dev->vaddr);
+		free_contiguous_memory(dev->vaddr);
+		dev->paddr = 0L;
+		dev->vaddr = NULL;
+	}
+}
+
+static int msm_buspm_dev_open(struct inode *inode, struct file *filp)
+{
+	struct msm_buspm_map_dev *dev;
+
+	if (capable(CAP_SYS_ADMIN)) {
+		dev = kzalloc(sizeof(*dev), GFP_KERNEL);
+		if (dev)
+			filp->private_data = dev;
+		else
+			return -ENOMEM;
+	} else {
+		return -EPERM;
+	}
+
+	return 0;
+}
+
+static int
+msm_buspm_dev_alloc(struct file *filp, struct buspm_alloc_params data)
+{
+	unsigned long paddr;
+	void *vaddr;
+	struct msm_buspm_map_dev *dev = filp->private_data;
+
+	/* If buffer already allocated, then free it */
+	if (dev->vaddr)
+		msm_buspm_dev_free(filp);
+
+	/* Allocate uncached memory */
+	vaddr = allocate_contiguous_ebi(data.size, PAGE_SIZE, 0);
+	paddr = (vaddr) ? memory_pool_node_paddr(vaddr) : 0L;
+
+	if (vaddr == NULL) {
+		pr_err("allocation of 0x%x bytes failed", data.size);
+		return -ENOMEM;
+	}
+
+	dev->vaddr = vaddr;
+	dev->paddr = paddr;
+	dev->buflen = data.size;
+	filp->f_pos = 0;
+	pr_debug("virt addr = 0x%p\n", dev->vaddr);
+	pr_debug("phys addr = 0x%lx\n", dev->paddr);
+
+	return 0;
+}
+
+static long
+msm_buspm_dev_ioctl(struct file *filp, unsigned int cmd, unsigned long arg)
+{
+	struct buspm_xfer_req xfer;
+	struct buspm_alloc_params alloc_data;
+	unsigned long paddr;
+	int retval = 0;
+	void *buf = msm_buspm_dev_get_vaddr(filp);
+	unsigned char *dbgbuf = buf;
+
+	switch (cmd) {
+	case MSM_BUSPM_IOC_FREE:
+		pr_debug("cmd = 0x%x (FREE)\n", cmd);
+		msm_buspm_dev_free(filp);
+		break;
+
+	case MSM_BUSPM_IOC_ALLOC:
+		pr_debug("cmd = 0x%x (ALLOC)\n", cmd);
+		retval = __get_user(alloc_data.size, (size_t __user *)arg);
+
+		if (retval == 0)
+			retval = msm_buspm_dev_alloc(filp, alloc_data);
+		break;
+
+	case MSM_BUSPM_IOC_RD_PHYS_ADDR:
+		pr_debug("Read Physical Address\n");
+		paddr = msm_buspm_dev_get_paddr(filp);
+		if (paddr == 0L) {
+			retval = -EINVAL;
+		} else {
+			pr_debug("phys addr = 0x%lx\n", paddr);
+			retval = __put_user(paddr,
+				(unsigned long __user *)arg);
+		}
+		break;
+
+	case MSM_BUSPM_IOC_RDBUF:
+		pr_debug("Read Buffer: 0x%x%x%x%x\n",
+				dbgbuf[0], dbgbuf[1], dbgbuf[2], dbgbuf[3]);
+
+		if (!buf) {
+			retval = -EINVAL;
+			break;
+		}
+
+		if (copy_from_user(&xfer, (void __user *)arg, sizeof(xfer))) {
+			retval = -EFAULT;
+			break;
+		}
+
+		if ((xfer.size <= sizeof(buf)) &&
+			(copy_to_user((void __user *)xfer.data, buf,
+					xfer.size))) {
+			retval = -EFAULT;
+			break;
+		}
+		break;
+
+	case MSM_BUSPM_IOC_WRBUF:
+		pr_debug("Write Buffer\n");
+
+		if (!buf) {
+			retval = -EINVAL;
+			break;
+		}
+
+		if (copy_from_user(&xfer, (void __user *)arg, sizeof(xfer))) {
+			retval = -EFAULT;
+			break;
+		}
+
+		if ((sizeof(buf) <= xfer.size) &&
+			(copy_from_user(buf, (void __user *)xfer.data,
+			xfer.size))) {
+			retval = -EFAULT;
+			break;
+		}
+		break;
+
+	default:
+		pr_debug("Unknown command 0x%x\n", cmd);
+		retval = -EINVAL;
+		break;
+	}
+
+	return retval;
+}
+
+static int msm_buspm_dev_release(struct inode *inode, struct file *filp)
+{
+	struct msm_buspm_map_dev *dev = filp->private_data;
+
+	msm_buspm_dev_free(filp);
+	kfree(dev);
+	filp->private_data = NULL;
+
+	return 0;
+}
+
+static int msm_buspm_dev_mmap(struct file *filp, struct vm_area_struct *vma)
+{
+	pr_debug("vma = 0x%p\n", vma);
+
+	/* Mappings are uncached */
+	vma->vm_page_prot = pgprot_noncached(vma->vm_page_prot);
+	if (remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff,
+		vma->vm_end - vma->vm_start, vma->vm_page_prot))
+		return -EFAULT;
+
+	return 0;
+}
+
+static const struct file_operations msm_buspm_dev_fops = {
+	.owner		= THIS_MODULE,
+	.mmap		= msm_buspm_dev_mmap,
+	.open		= msm_buspm_dev_open,
+	.unlocked_ioctl	= msm_buspm_dev_ioctl,
+	.llseek		= noop_llseek,
+	.release	= msm_buspm_dev_release,
+};
+
+struct miscdevice msm_buspm_misc = {
+	.minor	= MISC_DYNAMIC_MINOR,
+	.name	= MSM_BUSPM_DRV_NAME,
+	.fops	= &msm_buspm_dev_fops,
+};
+
+static int __init msm_buspm_dev_init(void)
+{
+	int ret = 0;
+
+	ret = misc_register(&msm_buspm_misc);
+	if (ret < 0)
+		pr_err("%s: Cannot register misc device\n", __func__);
+
+	return ret;
+}
+
+static void __exit msm_buspm_dev_exit(void)
+{
+	misc_deregister(&msm_buspm_misc);
+}
+module_init(msm_buspm_dev_init);
+module_exit(msm_buspm_dev_exit);
+
+MODULE_LICENSE("GPL v2");
+MODULE_VERSION("1.0");
+MODULE_ALIAS("platform:"MSM_BUSPM_DRV_NAME);
diff --git a/arch/arm/mach-msm/msm-buspm-dev.h b/arch/arm/mach-msm/msm-buspm-dev.h
new file mode 100644
index 0000000..5839087
--- /dev/null
+++ b/arch/arm/mach-msm/msm-buspm-dev.h
@@ -0,0 +1,50 @@
+/* Copyright (c) 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 __MSM_BUSPM_DEV_H__
+#define __MSM_BUSPM_DEV_H__
+
+#include <linux/ioctl.h>
+
+struct msm_buspm_map_dev {
+	void            *vaddr;
+	unsigned long   paddr;
+	size_t          buflen;
+};
+
+/* Read/write data into kernel buffer */
+struct buspm_xfer_req {
+	int size;		/* Size of this request, in bytes */
+	void *data;		/* Data buffer to transfer data to/from */
+};
+
+struct buspm_alloc_params {
+	int size;
+};
+
+#define MSM_BUSPM_IOC_MAGIC	'p'
+
+#define MSM_BUSPM_IOC_FREE	\
+	_IOW(MSM_BUSPM_IOC_MAGIC, 0, void *)
+
+#define MSM_BUSPM_IOC_ALLOC	\
+	_IOW(MSM_BUSPM_IOC_MAGIC, 1, size_t)
+
+#define MSM_BUSPM_IOC_RDBUF	\
+	_IOW(MSM_BUSPM_IOC_MAGIC, 2, struct buspm_xfer_req)
+
+#define MSM_BUSPM_IOC_WRBUF	\
+	_IOW(MSM_BUSPM_IOC_MAGIC, 3, struct buspm_xfer_req)
+
+#define MSM_BUSPM_IOC_RD_PHYS_ADDR	\
+	_IOR(MSM_BUSPM_IOC_MAGIC, 4, unsigned long)
+#endif
diff --git a/arch/arm/mach-msm/timer.c b/arch/arm/mach-msm/timer.c
index b597fb1..1df3c23 100644
--- a/arch/arm/mach-msm/timer.c
+++ b/arch/arm/mach-msm/timer.c
@@ -336,6 +336,7 @@
 	struct msm_clock *clock;
 	struct msm_clock_percpu_data *clock_state, *gpt_state;
 	unsigned long irq_flags;
+	struct irq_chip *chip;
 
 	clock = clockevent_to_clock(evt);
 	clock_state = &__get_cpu_var(msm_clocks_percpu)[clock->index];
@@ -355,11 +356,9 @@
 		get_cpu_var(msm_active_clock) = clock;
 		put_cpu_var(msm_active_clock);
 		__raw_writel(TIMER_ENABLE_EN, clock->regbase + TIMER_ENABLE);
-		if (irq_get_chip(clock->irq.irq) &&
-		   irq_get_chip(clock->irq.irq)->irq_unmask) {
-			irq_get_chip(clock->irq.irq)->irq_unmask(
-				irq_get_irq_data(clock->irq.irq));
-		}
+		chip = irq_get_chip(clock->irq.irq);
+		if (chip && chip->irq_unmask)
+			chip->irq_unmask(irq_get_irq_data(clock->irq.irq));
 		if (clock != &msm_clocks[MSM_CLOCK_GPT])
 			__raw_writel(TIMER_ENABLE_EN,
 				msm_clocks[MSM_CLOCK_GPT].regbase +
@@ -375,11 +374,9 @@
 			msm_read_timer_count(clock, LOCAL_TIMER) +
 			clock_state->sleep_offset;
 		__raw_writel(0, clock->regbase + TIMER_MATCH_VAL);
-		if (irq_get_chip(clock->irq.irq) &&
-		   irq_get_chip(clock->irq.irq)->irq_mask) {
-			irq_get_chip(clock->irq.irq)->irq_mask(
-				irq_get_irq_data(clock->irq.irq));
-		}
+		chip = irq_get_chip(clock->irq.irq);
+		if (chip && chip->irq_mask)
+			chip->irq_mask(irq_get_irq_data(clock->irq.irq));
 
 		if (!is_smp() || clock != &msm_clocks[MSM_CLOCK_DGT]
 				|| smp_processor_id())
@@ -973,6 +970,7 @@
 {
 	int i;
 	int res;
+	struct irq_chip *chip;
 	struct msm_clock *dgt = &msm_clocks[MSM_CLOCK_DGT];
 	struct msm_clock *gpt = &msm_clocks[MSM_CLOCK_GPT];
 
@@ -1056,8 +1054,9 @@
 			printk(KERN_ERR "msm_timer_init: setup_irq "
 			       "failed for %s\n", cs->name);
 
-		irq_get_chip(clock->irq.irq)->irq_mask(irq_get_irq_data(
-							       clock->irq.irq));
+		chip = irq_get_chip(clock->irq.irq);
+		if (chip && chip->irq_mask)
+			chip->irq_mask(irq_get_irq_data(clock->irq.irq));
 
 		clockevents_register_device(ce);
 	}
diff --git a/arch/arm/mm/mmu.c b/arch/arm/mm/mmu.c
index 350e5a9..aeaa173 100644
--- a/arch/arm/mm/mmu.c
+++ b/arch/arm/mm/mmu.c
@@ -791,6 +791,19 @@
 {
 	int i, j, highmem = 0;
 
+#if (defined CONFIG_HIGHMEM) && (defined CONFIG_FIX_MOVABLE_ZONE)
+
+/* For now, we must ensure that a small highmem zone exists
+ * after most of it is transformed into the movable zone.
+ */
+#define MIN_HIGHMEM_SIZE (5 * SECTION_SIZE)
+	void *v_movable_start;
+
+	v_movable_start = __va(movable_reserved_start) - MIN_HIGHMEM_SIZE;
+
+	if (vmalloc_min > v_movable_start)
+		vmalloc_min = v_movable_start;
+#endif
 	for (i = 0, j = 0; i < meminfo.nr_banks; i++) {
 		struct membank *bank = &meminfo.bank[j];
 		*bank = meminfo.bank[i];
diff --git a/drivers/gpu/ion/ion_carveout_heap.c b/drivers/gpu/ion/ion_carveout_heap.c
index f6097ac..71dea89 100644
--- a/drivers/gpu/ion/ion_carveout_heap.c
+++ b/drivers/gpu/ion/ion_carveout_heap.c
@@ -101,13 +101,27 @@
 struct scatterlist *ion_carveout_heap_map_dma(struct ion_heap *heap,
 					      struct ion_buffer *buffer)
 {
-	return ERR_PTR(-EINVAL);
+	struct scatterlist *sglist;
+	struct page *page = phys_to_page(buffer->priv_phys);
+
+	if (page == NULL)
+		return NULL;
+
+	sglist = vmalloc(sizeof(struct scatterlist));
+	if (!sglist)
+		return ERR_PTR(-ENOMEM);
+
+	sg_init_table(sglist, 1);
+	sg_set_page(sglist, page, buffer->size, 0);
+
+	return sglist;
 }
 
 void ion_carveout_heap_unmap_dma(struct ion_heap *heap,
 				 struct ion_buffer *buffer)
 {
-	return;
+	if (buffer->sglist)
+		vfree(buffer->sglist);
 }
 
 void *ion_carveout_heap_map_kernel(struct ion_heap *heap,
@@ -192,6 +206,8 @@
 	.map_user = ion_carveout_heap_map_user,
 	.map_kernel = ion_carveout_heap_map_kernel,
 	.unmap_kernel = ion_carveout_heap_unmap_kernel,
+	.map_dma = ion_carveout_heap_map_dma,
+	.unmap_dma = ion_carveout_heap_unmap_dma,
 	.cache_op = ion_carveout_cache_ops,
 	.get_allocated = ion_carveout_get_allocated,
 	.get_total = ion_carveout_get_total,
diff --git a/drivers/gpu/msm/z180.c b/drivers/gpu/msm/z180.c
index 6cd57b3..9e14247 100644
--- a/drivers/gpu/msm/z180.c
+++ b/drivers/gpu/msm/z180.c
@@ -411,7 +411,7 @@
 	unsigned int sizedwords;
 
 	if (device->state & KGSL_STATE_HUNG) {
-		return -EINVAL;
+		result = -EINVAL;
 		goto error;
 	}
 	if (numibs != 1) {
diff --git a/drivers/input/touchscreen/cyttsp-i2c.c b/drivers/input/touchscreen/cyttsp-i2c.c
index a3446a3..aefce3e 100644
--- a/drivers/input/touchscreen/cyttsp-i2c.c
+++ b/drivers/input/touchscreen/cyttsp-i2c.c
@@ -2419,7 +2419,7 @@
 		}
 
 		rc = regulator_set_optimum_mode(ts->vdd[i],
-						reg_info[i].load_uA);
+						reg_info[i].hpm_load_uA);
 		if (rc < 0) {
 			pr_err("%s: regulator_set_optimum_mode failed rc=%d\n",
 								__func__, rc);
@@ -2838,6 +2838,57 @@
 }
 
 #ifdef CONFIG_PM
+static int cyttsp_regulator_lpm(struct cyttsp *ts, bool on)
+{
+	int rc = 0, i;
+	const struct cyttsp_regulator *reg_info =
+			ts->platform_data->regulator_info;
+	u8 num_reg = ts->platform_data->num_regulators;
+
+	if (on == false)
+		goto regulator_hpm;
+
+	for (i = 0; i < num_reg; i++) {
+		rc = regulator_set_optimum_mode(ts->vdd[i],
+					reg_info[i].lpm_load_uA);
+		if (rc < 0) {
+			pr_err("%s: regulator_set_optimum failed rc = %d\n",
+							__func__, rc);
+			goto fail_regulator_lpm;
+		}
+
+	}
+
+	return 0;
+
+regulator_hpm:
+	for (i = 0; i < num_reg; i++) {
+		rc = regulator_set_optimum_mode(ts->vdd[i],
+					reg_info[i].hpm_load_uA);
+		if (rc < 0) {
+			pr_err("%s: regulator_set_optimum failed"
+				"rc = %d\n", __func__, rc);
+			goto fail_regulator_hpm;
+		}
+	}
+
+	return 0;
+
+fail_regulator_lpm:
+	while (i--)
+		regulator_set_optimum_mode(ts->vdd[i],
+					reg_info[i].hpm_load_uA);
+
+	return rc;
+
+fail_regulator_hpm:
+	while (i--)
+		regulator_set_optimum_mode(ts->vdd[i],
+					reg_info[i].lpm_load_uA);
+
+	return rc;
+}
+
 /* Function to manage power-on resume */
 static int cyttsp_resume(struct device *dev)
 {
@@ -2865,6 +2916,8 @@
 		(ts->platform_data->power_state != CY_ACTIVE_STATE)) {
 		if (ts->platform_data->resume)
 			retval = ts->platform_data->resume(ts->client);
+		else
+			retval = cyttsp_regulator_lpm(ts, false);
 		/* take TTSP device out of bootloader mode;
 		 * switch back to TrueTouch operational mode */
 		if (!(retval < CY_OK)) {
@@ -2948,14 +3001,23 @@
 	if (!(retval < CY_OK)) {
 		if (ts->platform_data->use_sleep &&
 			(ts->platform_data->power_state == CY_ACTIVE_STATE)) {
+			if (ts->platform_data->suspend) {
+				retval =
+				ts->platform_data->suspend(ts->client);
+			} else {
+				retval = cyttsp_regulator_lpm(ts, true);
+			}
 			if (ts->platform_data->use_sleep & CY_USE_DEEP_SLEEP_SEL)
 				sleep_mode = CY_DEEP_SLEEP_MODE;
 			else
 				sleep_mode = CY_LOW_PWR_MODE;
 
-			retval = i2c_smbus_write_i2c_block_data(ts->client,
-				CY_REG_BASE,
-				sizeof(sleep_mode), &sleep_mode);
+			if (!(retval < CY_OK)) {
+				retval =
+				i2c_smbus_write_i2c_block_data(ts->client,
+								CY_REG_BASE,
+					sizeof(sleep_mode), &sleep_mode);
+			}
 		}
 	}
 
diff --git a/drivers/media/video/msm/msm_mctl_pp.c b/drivers/media/video/msm/msm_mctl_pp.c
index a09514b..2bf95a0 100644
--- a/drivers/media/video/msm/msm_mctl_pp.c
+++ b/drivers/media/video/msm/msm_mctl_pp.c
@@ -126,6 +126,10 @@
 
 	idx = msm_mctl_out_type_to_inst_index(
 		p_mctl->sync.pcam_sync, msg_type);
+	if (idx < 0) {
+		pr_err("%s Invalid instance. returning\n", __func__);
+		return -EINVAL;
+	}
 	pcam_inst = p_mctl->sync.pcam_sync->dev_inst[idx];
 	vb = msm_mctl_buf_find(p_mctl, pcam_inst,
 		  del_buf, msg_type, fbuf);
@@ -192,27 +196,52 @@
 }
 
 static int msm_mctl_pp_get_phy_addr(
+	struct msm_cam_v4l2_dev_inst *pcam_inst,
 	uint32_t frame_handle,
 	struct msm_pp_frame *pp_frame)
 {
 	struct msm_frame_buffer *vb = NULL;
 	struct videobuf2_contig_pmem *mem;
+	int i, buf_idx = 0;
 
 	vb = (struct msm_frame_buffer *)frame_handle;
-	mem = vb2_plane_cookie(&vb->vidbuf, 0);
+	buf_idx = vb->vidbuf.v4l2_buf.index;
 	memset(pp_frame, 0, sizeof(struct msm_pp_frame));
 	pp_frame->handle = (uint32_t)vb;
 	pp_frame->frame_id = vb->vidbuf.v4l2_buf.sequence;
-	pp_frame->image_type = (unsigned short)mem->path;
 	pp_frame->timestamp = vb->vidbuf.v4l2_buf.timestamp;
-	/* hard coded for now. Will need to expand to MP case */
-	pp_frame->num_planes = 1;
-	pp_frame->sp.addr_offset = mem->addr_offset;
-	pp_frame->sp.phy_addr = videobuf2_to_pmem_contig(&vb->vidbuf, 0);
-	pp_frame->sp.y_off = 0;
-	pp_frame->sp.cbcr_off = mem->offset.sp_off.cbcr_off;
-	pp_frame->sp.length = mem->size;
-	pp_frame->sp.fd = (int)mem->vaddr;
+	/* Get the cookie for 1st plane and store the path.
+	 * Also use this to check the number of planes in
+	 * this buffer.*/
+	mem = vb2_plane_cookie(&vb->vidbuf, 0);
+	pp_frame->image_type = (unsigned short)mem->path;
+	if (mem->buffer_type == VIDEOBUF2_SINGLE_PLANE) {
+		pp_frame->num_planes = 1;
+		pp_frame->sp.addr_offset = mem->addr_offset;
+		pp_frame->sp.phy_addr =
+			videobuf2_to_pmem_contig(&vb->vidbuf, 0);
+		pp_frame->sp.y_off = 0;
+		pp_frame->sp.cbcr_off = mem->offset.sp_off.cbcr_off;
+		pp_frame->sp.length = mem->size;
+		pp_frame->sp.fd = (int)mem->vaddr;
+	} else {
+		pp_frame->num_planes = pcam_inst->plane_info.num_planes;
+		for (i = 0; i < pp_frame->num_planes; i++) {
+			mem = vb2_plane_cookie(&vb->vidbuf, i);
+			pp_frame->mp[i].addr_offset = mem->addr_offset;
+			pp_frame->mp[i].phy_addr =
+				videobuf2_to_pmem_contig(&vb->vidbuf, i);
+			pp_frame->mp[i].data_offset =
+			pcam_inst->buf_offset[buf_idx][i].data_offset;
+			pp_frame->mp[i].fd = (int)mem->vaddr;
+			pp_frame->mp[i].length = mem->size;
+			D("%s frame id %d buffer %d plane %d phy addr 0x%x"
+				" fd %d length %d\n", __func__,
+				pp_frame->frame_id, buf_idx, i,
+				(uint32_t)pp_frame->mp[i].phy_addr,
+				pp_frame->mp[i].fd, pp_frame->mp[i].length);
+		}
+	}
 	return 0;
 }
 
@@ -235,12 +264,38 @@
 	return 0;
 }
 
+static int msm_mctl_pp_path_to_inst_index(struct msm_cam_v4l2_device *pcam,
+					int out_type)
+{
+	int image_mode;
+	switch (out_type) {
+	case OUTPUT_TYPE_P:
+		image_mode = MSM_V4L2_EXT_CAPTURE_MODE_PREVIEW;
+		break;
+	case OUTPUT_TYPE_V:
+		image_mode = MSM_V4L2_EXT_CAPTURE_MODE_VIDEO;
+		break;
+	case OUTPUT_TYPE_S:
+		image_mode = MSM_V4L2_EXT_CAPTURE_MODE_MAIN;
+		break;
+	default:
+		image_mode = -1;
+		break;
+	}
+	if ((image_mode >= 0) && pcam->dev_inst_map[image_mode])
+		return pcam->dev_inst_map[image_mode]->my_index;
+	else
+		return -EINVAL;
+}
+
 int msm_mctl_pp_proc_vpe_cmd(
 	struct msm_cam_media_controller *p_mctl,
 	struct msm_mctl_pp_cmd *pp_cmd)
 {
-	int rc = 0;
+	int rc = 0, idx;
 	void __user *argp = (void __user *)pp_cmd->value;
+	struct msm_cam_v4l2_dev_inst *pcam_inst;
+
 	switch (pp_cmd->id) {
 	case VPE_CMD_INIT:
 	case VPE_CMD_DEINIT:
@@ -422,15 +477,27 @@
 				zoom->pp_frame_cmd.cookie,
 				zoom->pp_frame_cmd.vpe_output_action,
 				zoom->pp_frame_cmd.path);
-
+		idx = msm_mctl_pp_path_to_inst_index(p_mctl->sync.pcam_sync,
+			zoom->pp_frame_cmd.path);
+		if (idx < 0) {
+			pr_err("%s Invalid path, returning\n", __func__);
+			kfree(zoom);
+			return idx;
+		}
+		pcam_inst = p_mctl->sync.pcam_sync->dev_inst[idx];
+		if (!pcam_inst) {
+			pr_err("%s Invalid instance, returning\n", __func__);
+			kfree(zoom);
+			return -EINVAL;
+		}
 		zoom->user_cmd = pp_cmd->id;
-		rc = msm_mctl_pp_get_phy_addr(
+		rc = msm_mctl_pp_get_phy_addr(pcam_inst,
 			zoom->pp_frame_cmd.src_buf_handle, &zoom->src_frame);
 		if (rc) {
 			kfree(zoom);
 			break;
 		}
-		rc = msm_mctl_pp_get_phy_addr(
+		rc = msm_mctl_pp_get_phy_addr(pcam_inst,
 			zoom->pp_frame_cmd.dest_buf_handle, &zoom->dest_frame);
 		if (rc) {
 			kfree(zoom);
diff --git a/drivers/mfd/wcd9310-core.c b/drivers/mfd/wcd9310-core.c
index aef0754..8eca7aa 100644
--- a/drivers/mfd/wcd9310-core.c
+++ b/drivers/mfd/wcd9310-core.c
@@ -573,6 +573,7 @@
 	int ret = 0;
 	int sgla_retry_cnt;
 
+	dev_info(&slim->dev, "Initialized slim device %s\n", slim->name);
 	pdata = slim->dev.platform_data;
 
 	if (!pdata) {
@@ -727,17 +728,35 @@
 	.remove = tabla_slim_remove,
 	.id_table = slimtest_id,
 };
+
+static const struct slim_device_id slimtest2x_id[] = {
+	{"tabla2x-slim", 0},
+	{}
+};
+
+static struct slim_driver tabla2x_slim_driver = {
+	.driver = {
+		.name = "tabla2x-slim",
+		.owner = THIS_MODULE,
+	},
+	.probe = tabla_slim_probe,
+	.remove = tabla_slim_remove,
+	.id_table = slimtest2x_id,
+};
+
 static int __init tabla_init(void)
 {
-	int ret;
+	int ret1, ret2;
 
-	ret = slim_driver_register(&tabla_slim_driver);
-	if (ret != 0) {
-		pr_err("Failed to register tabla SB driver: %d\n", ret);
-		goto err;
-	}
-err:
-	return ret;
+	ret1 = slim_driver_register(&tabla_slim_driver);
+	if (ret1 != 0)
+		pr_err("Failed to register tabla SB driver: %d\n", ret1);
+
+	ret2 = slim_driver_register(&tabla2x_slim_driver);
+	if (ret2 != 0)
+		pr_err("Failed to register tabla2x SB driver: %d\n", ret2);
+
+	return (ret1 && ret2) ? -1 : 0;
 }
 module_init(tabla_init);
 
diff --git a/drivers/mmc/host/msm_sdcc.c b/drivers/mmc/host/msm_sdcc.c
index c1df55e..31c4172 100644
--- a/drivers/mmc/host/msm_sdcc.c
+++ b/drivers/mmc/host/msm_sdcc.c
@@ -132,6 +132,8 @@
 static void
 msmsdcc_start_command(struct msmsdcc_host *host, struct mmc_command *cmd,
 		      u32 c);
+static inline void msmsdcc_delay(struct msmsdcc_host *host);
+
 
 #ifdef CONFIG_MMC_MSM_SPS_SUPPORT
 static int msmsdcc_sps_reset_ep(struct msmsdcc_host *host,
@@ -207,77 +209,83 @@
  * @host - Pointer to driver's host structure
  *
  */
-static void msmsdcc_soft_reset_and_restore(struct msmsdcc_host *host)
+static void msmsdcc_soft_reset(struct msmsdcc_host *host)
 {
-	if (host->is_sps_mode) {
-		/* Reset DML first */
-		msmsdcc_dml_reset(host);
-		/*
-		 * delay the SPS pipe reset in thread context as
-		 * sps_connect/sps_disconnect APIs can be called
-		 * only from non-atomic context.
-		 */
-		host->sps.pipe_reset_pending = true;
-	}
 	/*
 	 * Reset SDCC controller's DPSM (data path state machine
 	 * and CPSM (command path state machine).
 	 */
-	mb();
 	writel_relaxed(0, host->base + MMCICOMMAND);
+	msmsdcc_delay(host);
 	writel_relaxed(0, host->base + MMCIDATACTRL);
-	mb();
+	msmsdcc_delay(host);
+}
 
-	pr_debug("%s: Applied soft reset to Controller\n",
-			mmc_hostname(host->mmc));
+static void msmsdcc_hard_reset(struct msmsdcc_host *host)
+{
+	int ret;
 
-	if (host->is_sps_mode)
-		msmsdcc_dml_init(host);
+	/* Reset the controller */
+	ret = clk_reset(host->clk, CLK_RESET_ASSERT);
+	if (ret)
+		pr_err("%s: Clock assert failed at %u Hz"
+			" with err %d\n", mmc_hostname(host->mmc),
+				host->clk_rate, ret);
+
+	ret = clk_reset(host->clk, CLK_RESET_DEASSERT);
+	if (ret)
+		pr_err("%s: Clock deassert failed at %u Hz"
+			" with err %d\n", mmc_hostname(host->mmc),
+			host->clk_rate, ret);
+
+	/* Give some delay for clock reset to propogate to controller */
+	msmsdcc_delay(host);
 }
 
 static void msmsdcc_reset_and_restore(struct msmsdcc_host *host)
 {
 	if (host->plat->sdcc_v4_sup) {
-		msmsdcc_soft_reset_and_restore(host);
+		if (host->is_sps_mode) {
+			/* Reset DML first */
+			msmsdcc_dml_reset(host);
+			/*
+			 * delay the SPS pipe reset in thread context as
+			 * sps_connect/sps_disconnect APIs can be called
+			 * only from non-atomic context.
+			 */
+			host->sps.pipe_reset_pending = true;
+		}
+		mb();
+		msmsdcc_soft_reset(host);
+
+		pr_debug("%s: Applied soft reset to Controller\n",
+				mmc_hostname(host->mmc));
+
+		if (host->is_sps_mode)
+			msmsdcc_dml_init(host);
 	} else {
 		/* Give Clock reset (hard reset) to controller */
 		u32	mci_clk = 0;
 		u32	mci_mask0 = 0;
-		int ret;
 
 		/* Save the controller state */
 		mci_clk = readl_relaxed(host->base + MMCICLOCK);
 		mci_mask0 = readl_relaxed(host->base + MMCIMASK0);
-
 		mb();
-		/* Reset the controller */
-		ret = clk_reset(host->clk, CLK_RESET_ASSERT);
-		if (ret)
-			pr_err("%s: Clock assert failed at %u Hz"
-				" with err %d\n", mmc_hostname(host->mmc),
-					host->clk_rate, ret);
 
-		ret = clk_reset(host->clk, CLK_RESET_DEASSERT);
-		if (ret)
-			pr_err("%s: Clock deassert failed at %u Hz"
-				" with err %d\n", mmc_hostname(host->mmc),
-					host->clk_rate, ret);
-
+		msmsdcc_hard_reset(host);
 		pr_debug("%s: Controller has been reinitialized\n",
 				mmc_hostname(host->mmc));
 
-		mb();
 		/* Restore the contoller state */
 		writel_relaxed(host->pwr, host->base + MMCIPOWER);
+		msmsdcc_delay(host);
 		writel_relaxed(mci_clk, host->base + MMCICLOCK);
+		msmsdcc_delay(host);
 		writel_relaxed(mci_mask0, host->base + MMCIMASK0);
-		ret = clk_set_rate(host->clk, host->clk_rate);
-		if (ret)
-			pr_err("%s: Failed to set clk rate %u Hz. err %d\n",
-					mmc_hostname(host->mmc),
-					host->clk_rate, ret);
-		mb();
+		mb(); /* no delay required after writing to MASK0 register */
 	}
+
 	if (host->dummy_52_needed)
 		host->dummy_52_needed = 0;
 }
@@ -310,8 +318,6 @@
 	return retval;
 }
 
-static inline void msmsdcc_delay(struct msmsdcc_host *host);
-
 static void
 msmsdcc_stop_data(struct msmsdcc_host *host)
 {
@@ -361,8 +367,13 @@
 msmsdcc_start_command_exec(struct msmsdcc_host *host, u32 arg, u32 c)
 {
 	writel_relaxed(arg, host->base + MMCIARGUMENT);
-	msmsdcc_delay(host);
 	writel_relaxed(c, host->base + MMCICOMMAND);
+	/*
+	 * As after sending the command, we don't write any of the
+	 * controller registers and just wait for the
+	 * CMD_RESPOND_END/CMD_SENT/Command failure notication
+	 * from Controller.
+	 */
 	mb();
 }
 
@@ -374,7 +385,6 @@
 	writel_relaxed(host->cmd_timeout, host->base + MMCIDATATIMER);
 	writel_relaxed((unsigned int)host->curr.xfer_size,
 			host->base + MMCIDATALENGTH);
-	msmsdcc_delay(host);	/* Allow data parms to be applied */
 	writel_relaxed(host->cmd_datactrl, host->base + MMCIDATACTRL);
 	msmsdcc_delay(host);	/* Force delay prior to ADM or command */
 
@@ -607,6 +617,7 @@
 			host->dummy_52_sent = 1;
 			msmsdcc_start_command(host, &dummy52cmd,
 					      MCI_CPSM_PROGENA);
+			spin_unlock_irqrestore(&host->lock, flags);
 			return;
 		}
 		msmsdcc_stop_data(host);
@@ -931,7 +942,7 @@
 		}
 	}
 
-	if (host->prog_scan && (cmd->opcode == 12)) {
+	if ((cmd->flags & MMC_RSP_R1B) == MMC_RSP_R1B) {
 		*c |= MCI_CPSM_PROGENA;
 		host->prog_enable = 1;
 	}
@@ -1013,6 +1024,8 @@
 
 	if (data->flags & MMC_DATA_READ)
 		datactrl |= (MCI_DPSM_DIRECTION | MCI_RX_DATA_PEND);
+	else if (data->flags & MMC_DATA_WRITE)
+		datactrl |= MCI_DATA_PEND;
 
 	clks = (unsigned long long)data->timeout_ns * host->clk_rate;
 	do_div(clks, 1000000000UL);
@@ -1029,8 +1042,6 @@
 		host->dma.hdr.exec_func = msmsdcc_dma_exec_func;
 		host->dma.hdr.user = (void *)host;
 		host->dma.busy = 1;
-		if ((data->flags & MMC_DATA_WRITE) && !host->curr.mrq->sbc)
-			host->prog_scan = 1;
 
 		if (cmd) {
 			msmsdcc_start_command_deferred(host, cmd, &c);
@@ -1043,8 +1054,6 @@
 		msm_dmov_enqueue_cmd_ext(host->dma.channel, &host->dma.hdr);
 	} else {
 		/* SPS-BAM mode or PIO mode */
-		if ((data->flags & MMC_DATA_WRITE) && !host->curr.mrq->sbc)
-			host->prog_scan = 1;
 		writel_relaxed(timeout, base + MMCIDATATIMER);
 
 		writel_relaxed(host->curr.xfer_size, base + MMCIDATALENGTH);
@@ -1052,8 +1061,14 @@
 		writel_relaxed((readl_relaxed(host->base + MMCIMASK0) &
 				(~(MCI_IRQ_PIO))) | pio_irqmask,
 				host->base + MMCIMASK0);
-		msmsdcc_delay(host);	/* Allow parms to be applied */
 		writel_relaxed(datactrl, base + MMCIDATACTRL);
+		/*
+		 * We don't need delay after writing to DATA_CTRL register
+		 * if we are not writing to CMD register immediately after
+		 * this. As we already have delay before sending the
+		 * command, we just need mb() here.
+		 */
+		mb();
 
 		if (cmd) {
 			msmsdcc_delay(host); /* Delay between data/command */
@@ -1239,8 +1254,10 @@
 				(~(MCI_IRQ_PIO))) | MCI_RXDATAAVLBLMASK,
 				host->base + MMCIMASK0);
 		if (!host->curr.xfer_remain) {
-			/* Delay needed (same port was just written) */
-			msmsdcc_delay(host);
+			/*
+			 * back to back write to MASK0 register don't need
+			 * synchronization delay.
+			 */
 			writel_relaxed((readl_relaxed(host->base + MMCIMASK0) &
 				(~(MCI_IRQ_PIO))) | 0, host->base + MMCIMASK0);
 		}
@@ -1329,16 +1346,12 @@
 		} else { /* host->data == NULL */
 			if (!cmd->error && host->prog_enable) {
 				if (status & MCI_PROGDONE) {
-					host->prog_scan = 0;
 					host->prog_enable = 0;
-					 msmsdcc_request_end(host, cmd->mrq);
+					msmsdcc_request_end(host, cmd->mrq);
 				} else
 					host->curr.cmd = cmd;
 			} else {
-				if (host->prog_enable) {
-					host->prog_scan = 0;
-					host->prog_enable = 0;
-				}
+				host->prog_enable = 0;
 				if (host->dummy_52_needed)
 					host->dummy_52_needed = 0;
 				if (cmd->data && cmd->error)
@@ -1351,9 +1364,6 @@
 			msmsdcc_start_command(host, host->curr.mrq->cmd, 0);
 		else
 			msmsdcc_request_start(host, host->curr.mrq);
-	} else if (cmd->data) {
-		if (!(cmd->data->flags & MMC_DATA_READ))
-			msmsdcc_start_data(host, cmd->data, NULL, 0);
 	}
 }
 
@@ -1560,9 +1570,9 @@
 static void
 msmsdcc_request_start(struct msmsdcc_host *host, struct mmc_request *mrq)
 {
-	if (mrq->data && mrq->data->flags & MMC_DATA_READ) {
+	if (mrq->data) {
 		/* Queue/read data, daisy-chain command when data starts */
-		if (mrq->sbc)
+		if (mrq->sbc && (mrq->data->flags & MMC_DATA_READ))
 			msmsdcc_start_data(host, mrq->data, mrq->sbc, 0);
 		else
 			msmsdcc_start_data(host, mrq->data, mrq->cmd, 0);
@@ -1922,7 +1932,9 @@
 		if (!IS_ERR(host->pclk))
 			clk_enable(host->pclk);
 		clk_enable(host->clk);
+		msmsdcc_delay(host);
 	} else {
+		msmsdcc_delay(host);
 		clk_disable(host->clk);
 		if (!IS_ERR(host->pclk))
 			clk_disable(host->pclk);
@@ -2120,6 +2132,10 @@
 					writel_relaxed(host->mci_irqenable,
 							host->base + MMCIMASK0);
 				}
+			} else {
+				writel_relaxed(host->mci_irqenable,
+						host->base + MMCIMASK0);
+				mb();
 			}
 		}
 		spin_unlock_irqrestore(&host->lock, flags);
@@ -2222,6 +2238,7 @@
 		msmsdcc_setup_pins(host, false);
 		break;
 	case MMC_POWER_UP:
+		/* writing PWR_UP bit is redundant */
 		pwr |= MCI_PWR_UP;
 		if (host->sdcc_irq_disabled) {
 			if (host->plat->cfg_mpm_sdiowakeup)
@@ -2255,7 +2272,7 @@
 	if (host->pwr != pwr) {
 		host->pwr = pwr;
 		writel_relaxed(pwr, host->base + MMCIPOWER);
-		mb();
+		msmsdcc_delay(host);
 	}
 	if (!host->clks_on) {
 		/* force the clocks to be off */
@@ -2279,7 +2296,7 @@
 				writel_relaxed(MCI_SDIOINTMASK,
 						host->base + MMCIMASK0);
 			}
-			msmsdcc_delay(host);
+			mb();
 		}
 		msmsdcc_setup_clocks(host, false);
 		host->clks_on = 0;
@@ -2299,7 +2316,7 @@
 	else
 		clk &= ~MCI_CLK_PWRSAVE;
 	writel_relaxed(clk, host->base + MMCICLOCK);
-	mb();
+	msmsdcc_delay(host);
 
 	return 0;
 }
@@ -2446,7 +2463,7 @@
 	/* Stop SD CLK output. */
 	writel_relaxed((readl_relaxed(host->base + MMCICLOCK) |
 			MCI_CLK_PWRSAVE), host->base + MMCICLOCK);
-
+	msmsdcc_delay(host);
 	spin_unlock_irqrestore(&host->lock, flags);
 
 	/*
@@ -2460,6 +2477,7 @@
 	spin_lock_irqsave(&host->lock, flags);
 	writel_relaxed((readl_relaxed(host->base + MMCICLOCK) |
 			IO_PAD_PWR_SWITCH), host->base + MMCICLOCK);
+	msmsdcc_delay(host);
 	host->io_pad_pwr_switch = 1;
 	spin_unlock_irqrestore(&host->lock, flags);
 
@@ -2470,6 +2488,7 @@
 	/* Start SD CLK output. */
 	writel_relaxed((readl_relaxed(host->base + MMCICLOCK)
 			& ~MCI_CLK_PWRSAVE), host->base + MMCICLOCK);
+	msmsdcc_delay(host);
 	spin_unlock_irqrestore(&host->lock, flags);
 
 	/*
@@ -2683,6 +2702,7 @@
 	 */
 	writel_relaxed((readl_relaxed(host->base + MMCICLOCK)
 			& ~MCI_CLK_PWRSAVE), host->base + MMCICLOCK);
+	msmsdcc_delay(host);
 	/* first of all reset the tuning block */
 	rc = msmsdcc_init_cm_sdc4_dll(host);
 	if (rc)
@@ -2757,6 +2777,7 @@
 	/* re-enable PWESAVE */
 	writel_relaxed((readl_relaxed(host->base + MMCICLOCK) |
 			MCI_CLK_PWRSAVE), host->base + MMCICLOCK);
+	msmsdcc_delay(host);
 	host->cmd19_tuning_in_progress = 0;
 	return rc;
 }
@@ -3463,10 +3484,7 @@
 					msmsdcc_request_end(host, mrq);
 			}
 		} else {
-			if (host->prog_enable) {
-				host->prog_scan = 0;
-				host->prog_enable = 0;
-			}
+			host->prog_enable = 0;
 			msmsdcc_reset_and_restore(host);
 			msmsdcc_request_end(host, mrq);
 		}
@@ -3678,6 +3696,8 @@
 		      msmsdcc_get_min_sup_clk_rate(host)));
 
 	host->clks_on = 1;
+	/* Apply Hard reset to SDCC to put it in power on default state */
+	msmsdcc_hard_reset(host);
 
 	ret = msmsdcc_vreg_init(host, true);
 	if (ret) {
@@ -3709,6 +3729,7 @@
 	mmc->caps |= plat->mmc_bus_width;
 
 	mmc->caps |= MMC_CAP_MMC_HIGHSPEED | MMC_CAP_SD_HIGHSPEED;
+	mmc->caps |= MMC_CAP_WAIT_WHILE_BUSY;
 
 	/*
 	 * If we send the CMD23 before multi block write/read command
@@ -3749,8 +3770,6 @@
 	writel_relaxed(0, host->base + MMCIMASK0);
 	writel_relaxed(MCI_CLEAR_STATIC_MASK, host->base + MMCICLEAR);
 
-	/* Delay needed (MMCIMASK0 was just written above) */
-	msmsdcc_delay(host);
 	writel_relaxed(MCI_IRQENABLE, host->base + MMCIMASK0);
 	mb();
 	host->mci_irqenable = MCI_IRQENABLE;
@@ -4143,12 +4162,14 @@
 		 * part of LPM), then clocks should be turned on before
 		 * calling mmc_suspend_host() because mmc_suspend_host might
 		 * send some commands to the card. The clocks will be turned
-		 * off again after mmc_suspend_host. Thus for SD/MMC/SDIO
+		 * off again after mmc_suspend_host. Thus for SDIO
 		 * cards, clocks will be turned on before mmc_suspend_host
 		 * and turned off after mmc_suspend_host.
 		 */
-		mmc->ios.clock = host->clk_rate;
-		mmc->ops->set_ios(host->mmc, &host->mmc->ios);
+		if (mmc->card && mmc_card_sdio(mmc->card)) {
+			mmc->ios.clock = host->clk_rate;
+			mmc->ops->set_ios(host->mmc, &host->mmc->ios);
+		}
 
 		/*
 		 * MMC core thinks that host is disabled by now since
@@ -4217,26 +4238,26 @@
 				enable_irq(host->core_irqres->start);
 				host->sdcc_irq_disabled = 0;
 			}
-		}
-		mmc->ios.clock = host->clk_rate;
-		mmc->ops->set_ios(host->mmc, &host->mmc->ios);
+			mmc->ios.clock = host->clk_rate;
+			mmc->ops->set_ios(host->mmc, &host->mmc->ios);
 
-		spin_lock_irqsave(&host->lock, flags);
-		writel_relaxed(host->mci_irqenable, host->base + MMCIMASK0);
-		mb();
+			spin_lock_irqsave(&host->lock, flags);
+			writel_relaxed(host->mci_irqenable,
+					host->base + MMCIMASK0);
+			mb();
 
-		if (mmc->card && (mmc->card->type == MMC_TYPE_SDIO) &&
-				(mmc->pm_flags & MMC_PM_WAKE_SDIO_IRQ) &&
-				!host->sdio_irq_disabled) {
+			if ((mmc->pm_flags & MMC_PM_WAKE_SDIO_IRQ) &&
+					!host->sdio_irq_disabled) {
 				if (host->plat->sdiowakeup_irq) {
 					disable_irq_nosync(
 						host->plat->sdiowakeup_irq);
 					msmsdcc_disable_irq_wake(host);
 					host->sdio_irq_disabled = 1;
 				}
-		}
+			}
 
-		spin_unlock_irqrestore(&host->lock, flags);
+			spin_unlock_irqrestore(&host->lock, flags);
+		}
 
 		mmc_resume_host(mmc);
 
diff --git a/drivers/mmc/host/msm_sdcc.h b/drivers/mmc/host/msm_sdcc.h
index 31ece6e..590c293 100644
--- a/drivers/mmc/host/msm_sdcc.h
+++ b/drivers/mmc/host/msm_sdcc.h
@@ -77,6 +77,7 @@
 #define MCI_DPSM_DIRECTION	(1 << 1)
 #define MCI_DPSM_MODE		(1 << 2)
 #define MCI_DPSM_DMAENABLE	(1 << 3)
+#define MCI_DATA_PEND		(1 << 17)
 #define MCI_AUTO_PROG_DONE	(1 << 19)
 #define MCI_RX_DATA_PEND	(1 << 20)
 
@@ -208,7 +209,7 @@
 
 #define NR_SG		32
 
-#define MSM_MMC_IDLE_TIMEOUT	10000 /* msecs */
+#define MSM_MMC_IDLE_TIMEOUT	5000 /* msecs */
 
 /*
  * Set the request timeout to 10secs to allow
@@ -332,7 +333,6 @@
 
 	struct tasklet_struct 	dma_tlet;
 
-	unsigned int prog_scan;
 	unsigned int prog_enable;
 
 	/* Command parameters */
diff --git a/drivers/power/Kconfig b/drivers/power/Kconfig
index 179a4ac..cca1035 100644
--- a/drivers/power/Kconfig
+++ b/drivers/power/Kconfig
@@ -261,7 +261,8 @@
 
 config ISL9519_CHARGER
 	tristate "isl9519 charger"
-	depends on BATTERY_MSM8X60
+	depends on (BATTERY_MSM8X60 || PM8921_CHARGER)
+	depends on I2C
 	default n
 	help
 	  The isl9519q charger chip from intersil is connected to an external
diff --git a/drivers/power/isl9519q.c b/drivers/power/isl9519q.c
index a45d286..733de45 100644
--- a/drivers/power/isl9519q.c
+++ b/drivers/power/isl9519q.c
@@ -20,9 +20,11 @@
 #include <linux/workqueue.h>
 #include <linux/interrupt.h>
 #include <linux/msm-charger.h>
+#include <linux/mfd/pm8xxx/pm8921-charger.h>
 #include <linux/slab.h>
 #include <linux/i2c/isl9519.h>
 #include <linux/msm_adc.h>
+#include <linux/spinlock.h>
 
 #define CHG_CURRENT_REG		0x14
 #define MAX_SYS_VOLTAGE_REG	0x15
@@ -34,7 +36,7 @@
 
 #define TRCKL_CHG_STATUS_BIT	0x80
 
-#define ISL9519_CHG_PERIOD	((HZ) * 150)
+#define ISL9519_CHG_PERIOD_SEC	150
 
 struct isl9519q_struct {
 	struct i2c_client		*client;
@@ -52,6 +54,10 @@
 	struct msm_hardware_charger	adapter_hw_chg;
 	int				suspended;
 	int				charge_at_resume;
+	struct ext_chg_pm8921		ext_chg;
+	spinlock_t			lock;
+	bool				notify_by_pmic;
+	bool				trickle;
 };
 
 static int isl9519q_read_reg(struct i2c_client *client, int reg,
@@ -70,6 +76,8 @@
 	} else
 		*val = ret;
 
+	pr_debug("%s.reg=0x%x.val=0x%x.\n", __func__, reg, *val);
+
 	return 0;
 }
 
@@ -79,6 +87,8 @@
 	int ret;
 	struct isl9519q_struct *isl_chg;
 
+	pr_debug("%s.reg=0x%x.val=0x%x.\n", __func__, reg, val);
+
 	isl_chg = i2c_get_clientdata(client);
 	ret = i2c_smbus_write_word_data(isl_chg->client, reg, val);
 
@@ -91,6 +101,14 @@
 	return 0;
 }
 
+/**
+ * Read charge-current via ADC.
+ *
+ * The ISL CCMON (charge-current-monitor) pin is connected to
+ * the PMIC MPP#X pin.
+ * This not required when notify_by_pmic is used where the PMIC
+ * uses BMS to notify the ISL on charging-done / charge-resume.
+ */
 static int isl_read_adc(int channel, int *mv_reading)
 {
 	int ret;
@@ -136,98 +154,129 @@
 out:
 	*mv_reading = 0;
 	pr_debug("%s: done with error for %d\n", __func__, channel);
-	return -EINVAL;
 
+	return -EINVAL;
 }
 
-static void isl9519q_charge(struct work_struct *isl9519_work)
+static bool is_trickle_charging(struct isl9519q_struct *isl_chg)
 {
-	u16 temp;
+	u16 ctrl = 0;
 	int ret;
+
+	ret = isl9519q_read_reg(isl_chg->client, CONTROL_REG, &ctrl);
+
+	if (!ret) {
+		pr_debug("%s.control_reg=0x%x.\n", __func__, ctrl);
+	} else {
+		dev_err(&isl_chg->client->dev,
+			"%s couldnt read cntrl reg\n", __func__);
+	}
+
+	if (ctrl & TRCKL_CHG_STATUS_BIT)
+		return true;
+
+	return false;
+}
+
+static void isl_adapter_check_ichg(struct isl9519q_struct *isl_chg)
+{
+	int ichg; /* isl charger current */
+	int mv_reading = 0;
+
+	ichg = isl_read_adc(CHANNEL_ADC_BATT_AMON, &mv_reading);
+
+	dev_dbg(&isl_chg->client->dev, "%s mv_reading=%d\n",
+		__func__, mv_reading);
+	dev_dbg(&isl_chg->client->dev, "%s isl_charger_current=%d\n",
+		__func__, ichg);
+
+	if (ichg >= 0 && ichg <= isl_chg->term_current)
+		msm_charger_notify_event(&isl_chg->adapter_hw_chg,
+					 CHG_DONE_EVENT);
+
+	isl_chg->trickle = is_trickle_charging(isl_chg);
+	if (isl_chg->trickle)
+		msm_charger_notify_event(&isl_chg->adapter_hw_chg,
+					 CHG_BATT_BEGIN_FAST_CHARGING);
+}
+
+/**
+ * isl9519q_worker
+ *
+ * Periodic task required to kick the ISL HW watchdog to keep
+ * charging.
+ *
+ * @isl9519_work: work context.
+ */
+static void isl9519q_worker(struct work_struct *isl9519_work)
+{
 	struct isl9519q_struct *isl_chg;
-	int isl_charger_current;
-	int mv_reading;
 
 	isl_chg = container_of(isl9519_work, struct isl9519q_struct,
 			charge_work.work);
 
 	dev_dbg(&isl_chg->client->dev, "%s\n", __func__);
 
-	if (isl_chg->charging) {
-		isl_charger_current = isl_read_adc(CHANNEL_ADC_BATT_AMON,
-								&mv_reading);
-		dev_dbg(&isl_chg->client->dev, "%s mv_reading=%d\n",
-				__func__, mv_reading);
-		dev_dbg(&isl_chg->client->dev, "%s isl_charger_current=%d\n",
-				__func__, isl_charger_current);
-		if (isl_charger_current >= 0
-			&& isl_charger_current <= isl_chg->term_current) {
-			msm_charger_notify_event(
-					&isl_chg->adapter_hw_chg,
-					CHG_DONE_EVENT);
-		}
-		isl9519q_write_reg(isl_chg->client, CHG_CURRENT_REG,
-				isl_chg->chgcurrent);
-		ret = isl9519q_read_reg(isl_chg->client, CONTROL_REG, &temp);
-		if (!ret) {
-			if (!(temp & TRCKL_CHG_STATUS_BIT))
-				msm_charger_notify_event(
-						&isl_chg->adapter_hw_chg,
-						CHG_BATT_BEGIN_FAST_CHARGING);
-		} else {
-			dev_err(&isl_chg->client->dev,
-				"%s couldnt read cntrl reg\n", __func__);
-		}
-		schedule_delayed_work(&isl_chg->charge_work,
-						ISL9519_CHG_PERIOD);
+	if (!isl_chg->charging) {
+		pr_info("%s.stop charging.\n", __func__);
+		isl9519q_write_reg(isl_chg->client, CHG_CURRENT_REG, 0);
+		return; /* Stop periodic worker */
 	}
+
+	/* Kick the dog by writting to CHG_CURRENT_REG */
+	isl9519q_write_reg(isl_chg->client, CHG_CURRENT_REG,
+			   isl_chg->chgcurrent);
+
+	if (isl_chg->notify_by_pmic)
+		isl_chg->trickle = is_trickle_charging(isl_chg);
+	else
+		isl_adapter_check_ichg(isl_chg);
+
+	schedule_delayed_work(&isl_chg->charge_work,
+			      (ISL9519_CHG_PERIOD_SEC * HZ));
 }
 
-static int isl9519q_start_charging(struct msm_hardware_charger *hw_chg,
-		int chg_voltage, int chg_current)
+static int isl9519q_start_charging(struct isl9519q_struct *isl_chg,
+				   int chg_voltage, int chg_current)
 {
-	struct isl9519q_struct *isl_chg;
 	int ret = 0;
 
-	isl_chg = container_of(hw_chg, struct isl9519q_struct, adapter_hw_chg);
-	if (isl_chg->charging)
-		/* we are already charging */
+	pr_info("%s.\n", __func__);
+
+	if (isl_chg->charging) {
+		pr_warn("%s.already charging.\n", __func__);
 		return 0;
+	}
 
 	if (isl_chg->suspended) {
+		pr_warn("%s.suspended - can't start charging.\n", __func__);
 		isl_chg->charge_at_resume = 1;
 		return 0;
 	}
 
-	dev_dbg(&isl_chg->client->dev, "%s\n", __func__);
+	dev_dbg(&isl_chg->client->dev,
+		"%s starting timed work.period=%d seconds.\n",
+		__func__, (int) ISL9519_CHG_PERIOD_SEC);
 
-	ret = isl9519q_write_reg(isl_chg->client, CHG_CURRENT_REG,
-						isl_chg->chgcurrent);
-	if (ret) {
-		dev_err(&isl_chg->client->dev,
-			"%s coulnt write to current_reg\n", __func__);
-		goto out;
-	}
+	/*
+	 * The ISL will start charging from the worker context.
+	 * This API might be called from interrupt context.
+	 */
+	schedule_delayed_work(&isl_chg->charge_work, 1);
 
-	dev_dbg(&isl_chg->client->dev, "%s starting timed work\n",
-							__func__);
-	schedule_delayed_work(&isl_chg->charge_work,
-						ISL9519_CHG_PERIOD);
 	isl_chg->charging = true;
 
-out:
 	return ret;
 }
 
-static int isl9519q_stop_charging(struct msm_hardware_charger *hw_chg)
+static int isl9519q_stop_charging(struct isl9519q_struct *isl_chg)
 {
-	struct isl9519q_struct *isl_chg;
-	int ret = 0;
+	pr_info("%s.\n", __func__);
 
-	isl_chg = container_of(hw_chg, struct isl9519q_struct, adapter_hw_chg);
-	if (!(isl_chg->charging))
-		/* we arent charging */
+	if (!(isl_chg->charging)) {
+		pr_warn("%s.already not charging.\n", __func__);
 		return 0;
+	}
 
 	if (isl_chg->suspended) {
 		isl_chg->charge_at_resume = 0;
@@ -236,17 +285,71 @@
 
 	dev_dbg(&isl_chg->client->dev, "%s\n", __func__);
 
-	ret = isl9519q_write_reg(isl_chg->client, CHG_CURRENT_REG, 0);
-	if (ret) {
-		dev_err(&isl_chg->client->dev,
-			"%s coulnt write to current_reg\n", __func__);
-		goto out;
-	}
-
 	isl_chg->charging = false;
-	cancel_delayed_work(&isl_chg->charge_work);
-out:
-	return ret;
+	isl_chg->trickle = false;
+	/*
+	 * The ISL will stop charging from the worker context.
+	 * This API might be called from interrupt context.
+	 */
+	schedule_delayed_work(&isl_chg->charge_work, 1);
+
+	return 0;
+}
+
+static int isl_ext_start_charging(void *ctx)
+{
+	int rc;
+	struct isl9519q_struct *isl_chg = ctx;
+	unsigned long flags;
+
+	spin_lock_irqsave(&isl_chg->lock, flags);
+	rc = isl9519q_start_charging(isl_chg, 0, isl_chg->chgcurrent);
+	spin_unlock_irqrestore(&isl_chg->lock, flags);
+
+	return rc;
+}
+
+static int isl_ext_stop_charging(void *ctx)
+{
+	int rc;
+	struct isl9519q_struct *isl_chg = ctx;
+	unsigned long flags;
+
+	spin_lock_irqsave(&isl_chg->lock, flags);
+	rc = isl9519q_stop_charging(isl_chg);
+	spin_unlock_irqrestore(&isl_chg->lock, flags);
+
+	return rc;
+}
+
+static bool isl_ext_is_trickle(void *ctx)
+{
+	struct isl9519q_struct *isl_chg = ctx;
+
+	return isl_chg->trickle;
+}
+
+static int isl_adapter_start_charging(struct msm_hardware_charger *hw_chg,
+				      int chg_voltage, int chg_current)
+{
+	int rc;
+	struct isl9519q_struct *isl_chg;
+
+	isl_chg = container_of(hw_chg, struct isl9519q_struct, adapter_hw_chg);
+	rc = isl9519q_start_charging(isl_chg, chg_voltage, chg_current);
+
+	return rc;
+}
+
+static int isl_adapter_stop_charging(struct msm_hardware_charger *hw_chg)
+{
+	int rc;
+	struct isl9519q_struct *isl_chg;
+
+	isl_chg = container_of(hw_chg, struct isl9519q_struct, adapter_hw_chg);
+	rc = isl9519q_stop_charging(isl_chg);
+
+	return rc;
 }
 
 static int isl9519q_charging_switched(struct msm_hardware_charger *hw_chg)
@@ -296,6 +399,93 @@
 #define DEFAULT_MAX_VOLTAGE_REG_VALUE	0x1070
 #define DEFAULT_MIN_VOLTAGE_REG_VALUE	0x0D00
 
+static int __devinit isl9519q_init_adapter(struct isl9519q_struct *isl_chg)
+{
+	int ret;
+	struct isl_platform_data *pdata = isl_chg->client->dev.platform_data;
+	struct i2c_client *client = isl_chg->client;
+
+	isl_chg->adapter_hw_chg.type = CHG_TYPE_AC;
+	isl_chg->adapter_hw_chg.rating = 2;
+	isl_chg->adapter_hw_chg.name = "isl-adapter";
+	isl_chg->adapter_hw_chg.start_charging = isl_adapter_start_charging;
+	isl_chg->adapter_hw_chg.stop_charging = isl_adapter_stop_charging;
+	isl_chg->adapter_hw_chg.charging_switched = isl9519q_charging_switched;
+
+	ret = gpio_request(pdata->valid_n_gpio, "isl_charger_valid");
+	if (ret) {
+		dev_err(&client->dev, "%s gpio_request failed "
+				      "for %d ret=%d\n",
+			__func__, pdata->valid_n_gpio, ret);
+		goto out;
+	}
+
+	ret = msm_charger_register(&isl_chg->adapter_hw_chg);
+	if (ret) {
+		dev_err(&client->dev,
+			"%s msm_charger_register failed for ret =%d\n",
+			__func__, ret);
+		goto free_gpio;
+	}
+
+	ret = request_threaded_irq(client->irq, NULL,
+				   isl_valid_handler,
+				   IRQF_TRIGGER_FALLING |
+				   IRQF_TRIGGER_RISING,
+				   "isl_charger_valid", client);
+	if (ret) {
+		dev_err(&client->dev,
+			"%s request_threaded_irq failed "
+			"for %d ret =%d\n",
+			__func__, client->irq, ret);
+		goto unregister;
+	}
+	irq_set_irq_wake(client->irq, 1);
+
+	ret = gpio_get_value_cansleep(isl_chg->valid_n_gpio);
+	if (ret < 0) {
+		dev_err(&client->dev,
+			"%s gpio_get_value failed for %d ret=%d\n",
+			__func__, pdata->valid_n_gpio, ret);
+		/* assume absent */
+		ret = 1;
+	}
+	if (!ret) {
+		msm_charger_notify_event(&isl_chg->adapter_hw_chg,
+				CHG_INSERTED_EVENT);
+		isl_chg->present = 1;
+	}
+
+	return 0;
+
+unregister:
+	msm_charger_unregister(&isl_chg->adapter_hw_chg);
+free_gpio:
+	gpio_free(pdata->valid_n_gpio);
+out:
+	return ret;
+
+}
+
+static int __devinit isl9519q_init_ext_chg(struct isl9519q_struct *isl_chg)
+{
+	int ret;
+
+	isl_chg->ext_chg.name = "isl9519q";
+	isl_chg->ext_chg.ctx = isl_chg;
+	isl_chg->ext_chg.start_charging = isl_ext_start_charging;
+	isl_chg->ext_chg.stop_charging = isl_ext_stop_charging;
+	isl_chg->ext_chg.is_trickle = isl_ext_is_trickle;
+	ret = register_external_dc_charger(&isl_chg->ext_chg);
+	if (ret) {
+		pr_err("%s.failed to register external dc charger.ret=%d.\n",
+		       __func__, ret);
+		return ret;
+	}
+
+	return 0;
+}
+
 static int __devinit isl9519q_probe(struct i2c_client *client,
 				    const struct i2c_device_id *id)
 {
@@ -306,6 +496,8 @@
 	ret = 0;
 	pdata = client->dev.platform_data;
 
+	pr_info("%s.\n", __func__);
+
 	if (pdata == NULL) {
 		dev_err(&client->dev, "%s no platform data\n", __func__);
 		ret = -EINVAL;
@@ -324,7 +516,9 @@
 		goto out;
 	}
 
-	INIT_DELAYED_WORK(&isl_chg->charge_work, isl9519q_charge);
+	spin_lock_init(&isl_chg->lock);
+
+	INIT_DELAYED_WORK(&isl_chg->charge_work, isl9519q_worker);
 	isl_chg->client = client;
 	isl_chg->chgcurrent = pdata->chgcurrent;
 	isl_chg->term_current = pdata->term_current;
@@ -337,12 +531,14 @@
 	isl_chg->chgcurrent &= ~0x7F;
 	isl_chg->input_current &= ~0x7F;
 
-	isl_chg->adapter_hw_chg.type = CHG_TYPE_AC;
-	isl_chg->adapter_hw_chg.rating = 2;
-	isl_chg->adapter_hw_chg.name = "isl-adapter";
-	isl_chg->adapter_hw_chg.start_charging = isl9519q_start_charging;
-	isl_chg->adapter_hw_chg.stop_charging = isl9519q_stop_charging;
-	isl_chg->adapter_hw_chg.charging_switched = isl9519q_charging_switched;
+	/**
+	 * ISL is Notified by PMIC to start/stop charging, rather than
+	 * handling interrupt from ISL for End-Of-Chargring, and
+	 * monitoring the charge-current periodically. The valid_n_gpio
+	 * is also not used, dc-present is detected by PMIC.
+	 */
+	isl_chg->notify_by_pmic = (client->irq == 0);
+	i2c_set_clientdata(client, isl_chg);
 
 	if (pdata->chg_detection_config) {
 		ret = pdata->chg_detection_config();
@@ -353,35 +549,6 @@
 		}
 	}
 
-	ret = gpio_request(pdata->valid_n_gpio, "isl_charger_valid");
-	if (ret) {
-		dev_err(&client->dev, "%s gpio_request failed for %d ret=%d\n",
-			__func__, pdata->valid_n_gpio, ret);
-		goto free_isl_chg;
-	}
-
-	i2c_set_clientdata(client, isl_chg);
-
-	ret = msm_charger_register(&isl_chg->adapter_hw_chg);
-	if (ret) {
-		dev_err(&client->dev,
-			"%s msm_charger_register failed for ret =%d\n",
-			__func__, ret);
-		goto free_gpio;
-	}
-
-	ret = request_threaded_irq(client->irq, NULL,
-				   isl_valid_handler,
-				   IRQF_TRIGGER_FALLING | IRQF_TRIGGER_RISING,
-				   "isl_charger_valid", client);
-	if (ret) {
-		dev_err(&client->dev,
-			"%s request_threaded_irq failed for %d ret =%d\n",
-			__func__, client->irq, ret);
-		goto unregister;
-	}
-	irq_set_irq_wake(client->irq, 1);
-
 	isl_chg->max_system_voltage &= MAX_VOLTAGE_REG_MASK;
 	isl_chg->min_system_voltage &= MIN_VOLTAGE_REG_MASK;
 	if (isl_chg->max_system_voltage == 0)
@@ -391,57 +558,34 @@
 
 	ret = isl9519q_write_reg(isl_chg->client, MAX_SYS_VOLTAGE_REG,
 			isl_chg->max_system_voltage);
-	if (ret) {
-		dev_err(&client->dev,
-			"%s couldnt write to MAX_SYS_VOLTAGE_REG ret=%d\n",
-			__func__, ret);
-		goto free_irq;
-	}
+	if (ret)
+		goto free_isl_chg;
 
 	ret = isl9519q_write_reg(isl_chg->client, MIN_SYS_VOLTAGE_REG,
 			isl_chg->min_system_voltage);
-	if (ret) {
-		dev_err(&client->dev,
-			"%s couldnt write to MIN_SYS_VOLTAGE_REG ret=%d\n",
-			__func__, ret);
-		goto free_irq;
-	}
+	if (ret)
+		goto free_isl_chg;
 
 	if (isl_chg->input_current) {
 		ret = isl9519q_write_reg(isl_chg->client,
 				INPUT_CURRENT_REG,
 				isl_chg->input_current);
-		if (ret) {
-			dev_err(&client->dev,
-				"%s couldnt write INPUT_CURRENT_REG ret=%d\n",
-				__func__, ret);
-			goto free_irq;
-		}
+		if (ret)
+			goto free_isl_chg;
 	}
 
-	ret = gpio_get_value_cansleep(isl_chg->valid_n_gpio);
-	if (ret < 0) {
-		dev_err(&client->dev,
-			"%s gpio_get_value failed for %d ret=%d\n", __func__,
-			pdata->valid_n_gpio, ret);
-		/* assume absent */
-		ret = 1;
-	}
-	if (!ret) {
-		msm_charger_notify_event(&isl_chg->adapter_hw_chg,
-				CHG_INSERTED_EVENT);
-		isl_chg->present = 1;
-	}
+	if (isl_chg->notify_by_pmic)
+		ret = isl9519q_init_ext_chg(isl_chg);
+	else
+		ret = isl9519q_init_adapter(isl_chg);
 
-	pr_debug("%s OK chg_present=%d\n", __func__, isl_chg->present);
+	if (ret)
+		goto free_isl_chg;
+
+	pr_info("%s OK.\n", __func__);
+
 	return 0;
 
-free_irq:
-	free_irq(client->irq, NULL);
-unregister:
-	msm_charger_unregister(&isl_chg->adapter_hw_chg);
-free_gpio:
-	gpio_free(pdata->valid_n_gpio);
 free_isl_chg:
 	kfree(isl_chg);
 out:
@@ -493,7 +637,7 @@
 	isl_chg->suspended  = 0;
 	if (isl_chg->charge_at_resume) {
 		isl_chg->charge_at_resume = 0;
-		isl9519q_start_charging(&isl_chg->adapter_hw_chg, 0, 0);
+		isl9519q_start_charging(isl_chg, 0, 0);
 	}
 	return 0;
 }
@@ -519,10 +663,12 @@
 
 static int __init isl9519q_init(void)
 {
+	pr_info("%s. isl9519q SW rev 1.01\n", __func__);
+
 	return i2c_add_driver(&isl9519q_driver);
 }
 
-module_init(isl9519q_init);
+late_initcall_sync(isl9519q_init);
 
 static void __exit isl9519q_exit(void)
 {
diff --git a/drivers/slimbus/slim-msm-ctrl.c b/drivers/slimbus/slim-msm-ctrl.c
index 4a2ad3f..1e4302b 100644
--- a/drivers/slimbus/slim-msm-ctrl.c
+++ b/drivers/slimbus/slim-msm-ctrl.c
@@ -21,7 +21,6 @@
 #include <linux/delay.h>
 #include <linux/kthread.h>
 #include <linux/clk.h>
-#include <linux/pm_runtime.h>
 #include <mach/sps.h>
 
 /* Per spec.max 40 bytes per received message */
@@ -45,7 +44,6 @@
 #define MSM_SLIM_PERF_SUMM_THRESHOLD	0x8000
 #define MSM_SLIM_NCHANS			32
 #define MSM_SLIM_NPORTS			24
-#define MSM_SLIM_AUTOSUSPEND		MSEC_PER_SEC
 
 /*
  * Need enough descriptors to receive present messages from slaves
@@ -82,7 +80,6 @@
 #define QC_DEVID_SAT1	0x3
 #define QC_DEVID_SAT2	0x4
 #define QC_DEVID_PGD	0x5
-#define QC_MSM_DEVS	5
 
 /* Component registers */
 enum comp_reg {
@@ -187,12 +184,6 @@
 	REF_CLK_GEAR	= 15,
 };
 
-enum msm_ctrl_state {
-	MSM_CTRL_AWAKE,
-	MSM_CTRL_SLEEPING,
-	MSM_CTRL_ASLEEP,
-};
-
 struct msm_slim_sps_bam {
 	u32			hdl;
 	void __iomem		*base;
@@ -235,12 +226,10 @@
 	struct mutex		tx_lock;
 	u8			pgdla;
 	bool			use_rx_msgqs;
+	int			suspended;
 	int			pipe_b;
 	struct completion	reconf;
 	bool			reconf_busy;
-	bool			chan_active;
-	enum msm_ctrl_state	state;
-	int			numdevs;
 };
 
 struct msm_slim_sat {
@@ -461,11 +450,6 @@
 		 * before exiting ISR
 		 */
 		mb();
-		if (dev->ctrl.sched.usedslots == 0 &&
-			dev->state != MSM_CTRL_SLEEPING) {
-			dev->chan_active = false;
-			pm_runtime_put(dev->dev);
-		}
 		complete(&dev->reconf);
 	}
 	pstat = readl_relaxed(dev->base + PGD_PORT_INT_ST_EEn + (16 * dev->ee));
@@ -665,37 +649,17 @@
 	u8 *puc;
 	int timeout;
 	u8 la = txn->la;
-	/*
-	 * Voting for runtime PM: Slimbus has 2 possible use cases:
-	 * 1. messaging
-	 * 2. Data channels
-	 * Messaging case goes through messaging slots and data channels
-	 * use their own slots
-	 * This "get" votes for messaging bandwidth
-	 */
-	if (txn->mc < SLIM_MSG_MC_BEGIN_RECONFIGURATION ||
-		txn->mc > SLIM_MSG_MC_RECONFIGURE_NOW ||
-		dev->state != MSM_CTRL_SLEEPING)
-		pm_runtime_get_sync(dev->dev);
 	mutex_lock(&dev->tx_lock);
-	if (dev->state == MSM_CTRL_ASLEEP) {
-		dev_err(dev->dev, "runtime or system PM suspended state");
-		mutex_unlock(&dev->tx_lock);
-		pm_runtime_put(dev->dev);
-		return -EBUSY;
-	}
 	if (txn->mt == SLIM_MSG_MT_CORE &&
-		txn->mc == SLIM_MSG_MC_BEGIN_RECONFIGURATION) {
-		if (dev->reconf_busy) {
+		txn->mc == SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
+		dev->reconf_busy) {
 			wait_for_completion(&dev->reconf);
 			dev->reconf_busy = false;
-		}
-		/* This "get" votes for data channels */
-		if (dev->ctrl.sched.usedslots != 0 &&
-			!dev->chan_active) {
-			dev->chan_active = true;
-			pm_runtime_get(dev->dev);
-		}
+	}
+	if (dev->suspended) {
+		dev_err(dev->dev, "No transaction in suspended state");
+		mutex_unlock(&dev->tx_lock);
+		return -EBUSY;
 	}
 	txn->rl--;
 	pbuf = msm_get_msg_buf(ctrl, txn->rl);
@@ -704,10 +668,6 @@
 
 	if (txn->dt == SLIM_MSG_DEST_ENUMADDR) {
 		mutex_unlock(&dev->tx_lock);
-		if (txn->mc < SLIM_MSG_MC_BEGIN_RECONFIGURATION ||
-			txn->mc > SLIM_MSG_MC_RECONFIGURE_NOW ||
-			dev->state != MSM_CTRL_SLEEPING)
-			pm_runtime_put(dev->dev);
 		return -EPROTONOSUPPORT;
 	}
 	if (txn->mt == SLIM_MSG_MT_CORE && txn->la == 0xFF &&
@@ -755,15 +715,11 @@
 			 */
 			dev->pipes[*puc].connected = false;
 			mutex_unlock(&dev->tx_lock);
-			if (dev->state != MSM_CTRL_SLEEPING)
-				pm_runtime_put(dev->dev);
 			return 0;
 		}
 		if (dev->err) {
 			dev_err(dev->dev, "pipe-port connect err:%d", dev->err);
 			mutex_unlock(&dev->tx_lock);
-			if (dev->state != MSM_CTRL_SLEEPING)
-				pm_runtime_put(dev->dev);
 			return dev->err;
 		}
 		*(puc) = *(puc) + dev->pipe_b;
@@ -774,37 +730,10 @@
 	dev->wr_comp = &done;
 	msm_send_msg_buf(ctrl, pbuf, txn->rl);
 	timeout = wait_for_completion_timeout(&done, HZ);
-
-	if (dev->state == MSM_CTRL_SLEEPING &&
-			txn->mc == SLIM_MSG_MC_RECONFIGURE_NOW &&
-			txn->mt == SLIM_MSG_MT_CORE && timeout) {
-		timeout = wait_for_completion_timeout(&dev->reconf, HZ);
-		dev->reconf_busy = false;
-		if (timeout) {
-			clk_disable(dev->rclk);
-			disable_irq(dev->irq);
-			dev->state = MSM_CTRL_ASLEEP;
-		}
-	}
-	if (!timeout && dev->state == MSM_CTRL_SLEEPING &&
-			txn->mc >= SLIM_MSG_MC_BEGIN_RECONFIGURATION &&
-			txn->mc <= SLIM_MSG_MC_RECONFIGURE_NOW &&
-			txn->mt == SLIM_MSG_MT_CORE) {
-		dev->reconf_busy = false;
-		dev->state = MSM_CTRL_AWAKE;
-		dev_err(dev->dev, "clock pause failed");
-		mutex_unlock(&dev->tx_lock);
-		return -ETIMEDOUT;
-	}
-
-	mutex_unlock(&dev->tx_lock);
-	if (!txn->rbuf && dev->state == MSM_CTRL_AWAKE)
-		pm_runtime_put(dev->dev);
-
 	if (!timeout)
 		dev_err(dev->dev, "TX timed out:MC:0x%x,mt:0x%x", txn->mc,
 					txn->mt);
-
+	mutex_unlock(&dev->tx_lock);
 	return timeout ? dev->err : -ETIMEDOUT;
 }
 
@@ -834,7 +763,6 @@
 static int msm_clk_pause_wakeup(struct slim_controller *ctrl)
 {
 	struct msm_slim_ctrl *dev = slim_get_ctrldata(ctrl);
-	enable_irq(dev->irq);
 	clk_enable(dev->rclk);
 	writel_relaxed(1, dev->base + FRM_WAKEUP);
 	/* Make sure framer wakeup write goes through before exiting function */
@@ -849,7 +777,6 @@
 	 * we get the message
 	 */
 	usleep_range(5000, 5000);
-	dev->state = MSM_CTRL_AWAKE;
 	return 0;
 }
 
@@ -994,9 +921,6 @@
 				e_addr[1] == QC_DEVID_PGD &&
 				e_addr[2] != QC_CHIPID_SL)
 				dev->pgdla = laddr;
-			dev->numdevs++;
-			if (!ret && dev->numdevs == QC_MSM_DEVS)
-				pm_runtime_enable(dev->dev);
 
 		} else if (mc == SLIM_MSG_MC_REPLY_INFORMATION ||
 				mc == SLIM_MSG_MC_REPLY_VALUE) {
@@ -1004,7 +928,6 @@
 			dev_dbg(dev->dev, "tid:%d, len:%d\n", tid, len - 4);
 			slim_msg_response(&dev->ctrl, &buf[4], tid,
 						len - 4);
-			pm_runtime_put(dev->dev);
 		} else if (mc == SLIM_MSG_MC_REPORT_INFORMATION) {
 			u8 l_addr = buf[2];
 			u16 ele = (u16)buf[4] << 4;
@@ -1057,19 +980,11 @@
 			for (i = 0; i < 6; i++)
 				e_addr[i] = buf[7-i];
 
-			pm_runtime_get_sync(dev->dev);
 			slim_assign_laddr(&dev->ctrl, e_addr, 6, &laddr);
 			sat->satcl.laddr = laddr;
-		} else if (mt != SLIM_MSG_MT_CORE &&
-				mc != SLIM_MSG_MC_REPORT_PRESENT)
-			pm_runtime_get_sync(dev->dev);
+		}
 		switch (mc) {
 		case SLIM_MSG_MC_REPORT_PRESENT:
-			/* Remove runtime_pm vote once satellite acks */
-			if (mt != SLIM_MSG_MT_CORE) {
-				pm_runtime_put(dev->dev);
-				continue;
-			}
 			/* send a Manager capability msg */
 			if (sat->sent_capability)
 				continue;
@@ -1170,11 +1085,8 @@
 		default:
 			break;
 		}
-		if (!gen_ack) {
-			if (mc != SLIM_MSG_MC_REPORT_PRESENT)
-				pm_runtime_put(dev->dev);
+		if (!gen_ack)
 			continue;
-		}
 		wbuf[0] = tid;
 		if (!ret)
 			wbuf[1] = MSM_SAT_SUCCSS;
@@ -1187,7 +1099,6 @@
 		txn.wbuf = wbuf;
 		txn.mt = SLIM_MSG_MT_SRC_REFERRED_USER;
 		msm_xfer_msg(&dev->ctrl, &txn);
-		pm_runtime_put(dev->dev);
 	}
 }
 
@@ -1791,9 +1702,6 @@
 	 * function
 	 */
 	mb();
-	pm_runtime_use_autosuspend(&pdev->dev);
-	pm_runtime_set_autosuspend_delay(&pdev->dev, MSM_SLIM_AUTOSUSPEND);
-	pm_runtime_set_active(&pdev->dev);
 	dev_dbg(dev->dev, "MSM SB controller is up!\n");
 	return 0;
 
@@ -1827,13 +1735,12 @@
 	struct resource *slew_mem = dev->slew_mem;
 	struct msm_slim_sat *sat = dev->satd;
 	slim_remove_device(&sat->satcl);
-	pm_runtime_disable(&pdev->dev);
-	pm_runtime_set_suspended(&pdev->dev);
 	kfree(sat->satch);
 	destroy_workqueue(sat->wq);
 	kfree(sat);
 	free_irq(dev->irq, dev);
 	slim_del_controller(&dev->ctrl);
+	clk_disable(dev->rclk);
 	clk_put(dev->rclk);
 	msm_slim_sps_exit(dev);
 	kthread_stop(dev->rx_msgq_thread);
@@ -1853,78 +1760,79 @@
 	return 0;
 }
 
-#ifdef CONFIG_PM_RUNTIME
-static int msm_slim_runtime_idle(struct device *device)
+#ifdef CONFIG_PM
+static int msm_slim_suspend(struct device *device)
 {
 	struct platform_device *pdev = to_platform_device(device);
 	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
-	dev_dbg(device, "pm_runtime: idle...\n");
-	pm_runtime_mark_last_busy(dev->dev);
-	pm_request_autosuspend(device);
-	return -EAGAIN;
-}
-#endif
-
-/*
- * If PM_RUNTIME is not defined, these 2 functions become helper
- * functions to be called from system suspend/resume. So they are not
- * inside ifdef CONFIG_PM_RUNTIME
- */
-static int msm_slim_runtime_suspend(struct device *device)
-{
-	struct platform_device *pdev = to_platform_device(device);
-	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
-	dev_dbg(device, "pm_runtime: suspending...\n");
-	dev->state = MSM_CTRL_SLEEPING;
-	return slim_ctrl_clk_pause(&dev->ctrl, false, SLIM_CLK_UNSPECIFIED);
-}
-
-static int msm_slim_runtime_resume(struct device *device)
-{
-	struct platform_device *pdev = to_platform_device(device);
-	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
-	dev_dbg(device, "pm_runtime: resuming...\n");
+	int ret = slim_ctrl_clk_pause(&dev->ctrl, false, SLIM_CLK_UNSPECIFIED);
+	/* Make sure clock pause goes through */
 	mutex_lock(&dev->tx_lock);
-	if (dev->state == MSM_CTRL_ASLEEP) {
-		mutex_unlock(&dev->tx_lock);
-		return slim_ctrl_clk_pause(&dev->ctrl, true, 0);
+	if (!ret && dev->reconf_busy) {
+		wait_for_completion(&dev->reconf);
+		dev->reconf_busy = false;
 	}
 	mutex_unlock(&dev->tx_lock);
-	return 0;
-}
-
-#ifdef CONFIG_PM_SLEEP
-static int msm_slim_suspend(struct device *dev)
-{
-	int ret = 0;
-	if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
-		dev_dbg(dev, "system suspend");
-		ret = msm_slim_runtime_suspend(dev);
-	}
-	if (ret == -EBUSY) {
+	if (!ret) {
+		clk_disable(dev->rclk);
+		disable_irq(dev->irq);
+		dev->suspended = 1;
+	} else if (ret == -EBUSY) {
 		/*
-		* If the clock pause failed due to active channels, there is
-		* a possibility that some audio stream is active during suspend
-		* We dont want to return suspend failure in that case so that
-		* display and relevant components can still go to suspend.
-		* If there is some other error, then it should be passed-on
-		* to system level suspend
-		*/
+		 * If the clock pause failed due to active channels, there is
+		 * a possibility that some audio stream is active during suspend
+		 * We dont want to return suspend failure in that case so that
+		 * display and relevant components can still go to suspend.
+		 * If there is some other error, then it should be passed-on
+		 * to system level suspend
+		 */
 		ret = 0;
 	}
 	return ret;
 }
 
-static int msm_slim_resume(struct device *dev)
+static int msm_slim_resume(struct device *device)
 {
-	/* If runtime_pm is enabled, this resume shouldn't do anything */
-	if (!pm_runtime_enabled(dev) || !pm_runtime_suspended(dev)) {
-		dev_dbg(dev, "system resume");
-		return msm_slim_runtime_resume(dev);
+	struct platform_device *pdev = to_platform_device(device);
+	struct msm_slim_ctrl *dev = platform_get_drvdata(pdev);
+	mutex_lock(&dev->tx_lock);
+	if (dev->suspended) {
+		dev->suspended = 0;
+		mutex_unlock(&dev->tx_lock);
+		enable_irq(dev->irq);
+		return slim_ctrl_clk_pause(&dev->ctrl, true, 0);
 	}
+	mutex_unlock(&dev->tx_lock);
 	return 0;
 }
-#endif /* CONFIG_PM_SLEEP */
+#else
+#define msm_slim_suspend NULL
+#define msm_slim_resume NULL
+#endif /* CONFIG_PM */
+
+#ifdef CONFIG_PM_RUNTIME
+static int msm_slim_runtime_idle(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: idle...\n");
+	return 0;
+}
+
+static int msm_slim_runtime_suspend(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: suspending...\n");
+	return 0;
+}
+
+static int msm_slim_runtime_resume(struct device *dev)
+{
+	dev_dbg(dev, "pm_runtime: resuming...\n");
+	return 0;
+}
+#else
+#define msm_slim_runtime_idle NULL
+#define msm_slim_runtime_suspend NULL
+#define msm_slim_runtime_resume NULL
+#endif
 
 static const struct dev_pm_ops msm_slim_dev_pm_ops = {
 	SET_SYSTEM_SLEEP_PM_OPS(
diff --git a/drivers/slimbus/slimbus.c b/drivers/slimbus/slimbus.c
index bb30570..3b79129 100644
--- a/drivers/slimbus/slimbus.c
+++ b/drivers/slimbus/slimbus.c
@@ -892,6 +892,10 @@
 	cur = slim_slicecodefromsize(sl);
 	ec = ((sl | (1 << 3)) | ((msg->start_offset & 0xFFF) << 4));
 
+	ret = slim_ctrl_clk_pause(ctrl, true, 0);
+	if (ret)
+		return ret;
+
 	if (wbuf)
 		mlen += len;
 	if (rbuf) {
@@ -1123,6 +1127,10 @@
 	u8 chan = (u8)(chanh & 0xFF);
 	struct slim_ich *slc = &ctrl->chans[chan];
 
+	ret = slim_ctrl_clk_pause(ctrl, true, 0);
+	if (ret)
+		return ret;
+
 	mutex_lock(&ctrl->m_ctrl);
 	/* Make sure the channel is not already pending reconf. or active */
 	if (slc->state >= SLIM_CH_PENDING_ACTIVE) {
@@ -1185,8 +1193,11 @@
 int slim_disconnect_ports(struct slim_device *sb, u32 *ph, int nph)
 {
 	struct slim_controller *ctrl = sb->ctrl;
-	int i;
+	int i, ret;
 
+	ret = slim_ctrl_clk_pause(ctrl, true, 0);
+	if (ret)
+		return ret;
 	mutex_lock(&ctrl->m_ctrl);
 
 	for (i = 0; i < nph; i++)
@@ -2378,6 +2389,10 @@
 	u32 segdist;
 	struct slim_pending_ch *pch;
 
+	ret = slim_ctrl_clk_pause(ctrl, true, 0);
+	if (ret)
+		return ret;
+
 	mutex_lock(&ctrl->sched.m_reconf);
 	mutex_lock(&ctrl->m_ctrl);
 	ctrl->sched.pending_msgsl += sb->pending_msgsl - sb->cur_msgsl;
diff --git a/drivers/tty/serial/msm_serial_hs.c b/drivers/tty/serial/msm_serial_hs.c
index 06d614b..bc1a25b 100644
--- a/drivers/tty/serial/msm_serial_hs.c
+++ b/drivers/tty/serial/msm_serial_hs.c
@@ -262,7 +262,10 @@
 		gsbi_resource = platform_get_resource_byname(pdev,
 							     IORESOURCE_MEM,
 							     "gsbi_resource");
-		size = gsbi_resource->end - gsbi_resource->start + 1;
+		if (unlikely(!gsbi_resource))
+			return;
+
+		size = resource_size(gsbi_resource);
 		release_mem_region(gsbi_resource->start, size);
 		iounmap(msm_uport->mapped_gsbi);
 		msm_uport->mapped_gsbi = NULL;
@@ -280,7 +283,7 @@
 						     IORESOURCE_MEM,
 						     "gsbi_resource");
 	if (gsbi_resource) {
-		size = gsbi_resource->end - gsbi_resource->start + 1;
+		size = resource_size(gsbi_resource);
 		if (unlikely(!request_mem_region(gsbi_resource->start, size,
 						 "msm_serial_hs")))
 			return -EBUSY;
diff --git a/drivers/tty/serial/msm_serial_hs_lite.c b/drivers/tty/serial/msm_serial_hs_lite.c
index ad085f9..a7b53e4 100644
--- a/drivers/tty/serial/msm_serial_hs_lite.c
+++ b/drivers/tty/serial/msm_serial_hs_lite.c
@@ -799,7 +799,6 @@
 	struct msm_hsl_port *msm_hsl_port = UART_TO_MSM(port);
 	struct platform_device *pdev = to_platform_device(port->dev);
 	struct resource *uart_resource;
-	struct resource *gsbi_resource;
 	resource_size_t size;
 
 	uart_resource = platform_get_resource_byname(pdev, IORESOURCE_MEM,
@@ -815,11 +814,6 @@
 	if (msm_serial_hsl_has_gsbi(port)) {
 		iowrite32(GSBI_PROTOCOL_IDLE, msm_hsl_port->mapped_gsbi +
 			  GSBI_CONTROL_ADDR);
-		gsbi_resource = platform_get_resource_byname(pdev,
-							     IORESOURCE_MEM,
-							     "gsbi_resource");
-
-		size = gsbi_resource->end - gsbi_resource->start + 1;
 		iounmap(msm_hsl_port->mapped_gsbi);
 		msm_hsl_port->mapped_gsbi = NULL;
 	}
diff --git a/drivers/usb/gadget/f_rmnet_sdio.c b/drivers/usb/gadget/f_rmnet_sdio.c
index b15c221..f63d939 100644
--- a/drivers/usb/gadget/f_rmnet_sdio.c
+++ b/drivers/usb/gadget/f_rmnet_sdio.c
@@ -1358,17 +1358,20 @@
 	struct rmnet_sdio_dev *dev = container_of(f, struct rmnet_sdio_dev,
 								function);
 
+	cancel_delayed_work_sync(&dev->sdio_open_work);
 	destroy_workqueue(dev->wq);
 
-	rmnet_sdio_free_buf(dev);
 	dev->epout = dev->epin = dev->epnotify = NULL; /* release endpoints */
 
-	msm_sdio_dmux_close(rmnet_sdio_data_ch);
-	sdio_cmux_close(rmnet_sdio_ctl_ch);
+	if (test_bit(RMNET_SDIO_CH_OPEN, &dev->data_ch_status)) {
+		msm_sdio_dmux_close(rmnet_sdio_data_ch);
+		clear_bit(RMNET_SDIO_CH_OPEN, &dev->data_ch_status);
+	}
 
-
-	clear_bit(RMNET_SDIO_CH_OPEN, &dev->data_ch_status);
-	clear_bit(RMNET_SDIO_CH_OPEN, &dev->ctrl_ch_status);
+	if (test_bit(RMNET_SDIO_CH_OPEN, &dev->ctrl_ch_status)) {
+		sdio_cmux_close(rmnet_sdio_ctl_ch);
+		clear_bit(RMNET_SDIO_CH_OPEN, &dev->ctrl_ch_status);
+	}
 
 	debugfs_remove_recursive(dev->dent);
 
@@ -1454,7 +1457,7 @@
 
 static void rmnet_sdio_debugfs_init(struct rmnet_sdio_dev *dev)
 {
-	dev->dent = debugfs_create_dir("usb_rmnet", 0);
+	dev->dent = debugfs_create_dir("usb_rmnet_sdio", 0);
 	if (IS_ERR(dev->dent))
 		return;
 
diff --git a/drivers/usb/gadget/f_rmnet_smd.c b/drivers/usb/gadget/f_rmnet_smd.c
index b8dd3a5..08f461f 100644
--- a/drivers/usb/gadget/f_rmnet_smd.c
+++ b/drivers/usb/gadget/f_rmnet_smd.c
@@ -1218,7 +1218,7 @@
 static void rmnet_smd_debugfs_init(struct rmnet_smd_dev *dev)
 {
 
-	dent_smd = debugfs_create_dir("usb_rmnet", 0);
+	dent_smd = debugfs_create_dir("usb_rmnet_smd", 0);
 	if (IS_ERR(dent_smd))
 		return;
 
diff --git a/drivers/video/msm/mdp4_overlay_dsi_video.c b/drivers/video/msm/mdp4_overlay_dsi_video.c
index 93933f3..5cf79c1 100644
--- a/drivers/video/msm/mdp4_overlay_dsi_video.c
+++ b/drivers/video/msm/mdp4_overlay_dsi_video.c
@@ -555,6 +555,10 @@
 void mdp4_overlay0_done_dsi_video(struct mdp_dma_data *dma)
 {
 	spin_lock(&mdp_spin_lock);
+	if (dsi_pipe->blt_addr == 0) {
+		spin_unlock(&mdp_spin_lock);
+		return;
+	}
 	dma->busy = FALSE;
 	mdp4_dsi_video_blt_dmap_update(dsi_pipe);
 	dsi_pipe->dmap_cnt++;
diff --git a/drivers/video/msm/mdp4_overlay_lcdc.c b/drivers/video/msm/mdp4_overlay_lcdc.c
index e840230..0eda69a 100644
--- a/drivers/video/msm/mdp4_overlay_lcdc.c
+++ b/drivers/video/msm/mdp4_overlay_lcdc.c
@@ -451,6 +451,10 @@
 void mdp4_overlay0_done_lcdc(struct mdp_dma_data *dma)
 {
 	spin_lock(&mdp_spin_lock);
+	if (lcdc_pipe->blt_addr == 0) {
+		spin_unlock(&mdp_spin_lock);
+		return;
+	}
 	dma->busy = FALSE;
 	mdp4_lcdc_blt_dmap_update(lcdc_pipe);
 	lcdc_pipe->dmap_cnt++;
diff --git a/drivers/video/msm/mdp4_util.c b/drivers/video/msm/mdp4_util.c
index 99607e7..3d78a13 100644
--- a/drivers/video/msm/mdp4_util.c
+++ b/drivers/video/msm/mdp4_util.c
@@ -419,6 +419,55 @@
 		spin_unlock(&mdp_spin_lock);
 	}
 #endif
+
+#ifdef CONFIG_FB_MSM_OVERLAY
+	if (isr & INTR_OVERLAY0_DONE) {
+		mdp4_stat.intr_overlay0++;
+		dma = &dma2_data;
+		if (panel & (MDP4_PANEL_LCDC | MDP4_PANEL_DSI_VIDEO)) {
+			/* disable LCDC interrupt */
+			spin_lock(&mdp_spin_lock);
+			mdp_intr_mask &= ~INTR_OVERLAY0_DONE;
+			outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+			dma->waiting = FALSE;
+			spin_unlock(&mdp_spin_lock);
+			if (panel & MDP4_PANEL_LCDC)
+				mdp4_overlay0_done_lcdc(dma);
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+			else if (panel & MDP4_PANEL_DSI_VIDEO)
+				mdp4_overlay0_done_dsi_video(dma);
+#endif
+		} else {        /* MDDI, DSI_CMD  */
+#ifdef CONFIG_FB_MSM_MIPI_DSI
+			if (panel & MDP4_PANEL_DSI_CMD)
+				mdp4_overlay0_done_dsi_cmd(dma);
+#else
+			if (panel & MDP4_PANEL_MDDI)
+				mdp4_overlay0_done_mddi(dma);
+#endif
+		}
+		mdp_hw_cursor_done();
+	}
+	if (isr & INTR_OVERLAY1_DONE) {
+		mdp4_stat.intr_overlay1++;
+		/* disable DTV interrupt */
+		dma = &dma_e_data;
+		spin_lock(&mdp_spin_lock);
+		mdp_intr_mask &= ~INTR_OVERLAY1_DONE;
+		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
+		dma->waiting = FALSE;
+		spin_unlock(&mdp_spin_lock);
+#if defined(CONFIG_FB_MSM_DTV)
+		if (panel & MDP4_PANEL_DTV)
+			mdp4_overlay1_done_dtv();
+#endif
+#if defined(CONFIG_FB_MSM_TVOUT)
+		if (panel & MDP4_PANEL_ATV)
+			mdp4_overlay1_done_atv();
+#endif
+	}
+#endif	/* OVERLAY */
+
 	if (isr & INTR_DMA_P_DONE) {
 		mdp4_stat.intr_dma_p++;
 		dma = &dma2_data;
@@ -488,53 +537,6 @@
 		}
 		spin_unlock(&mdp_spin_lock);
 	}
-#ifdef CONFIG_FB_MSM_OVERLAY
-	if (isr & INTR_OVERLAY0_DONE) {
-		mdp4_stat.intr_overlay0++;
-		dma = &dma2_data;
-		if (panel & (MDP4_PANEL_LCDC | MDP4_PANEL_DSI_VIDEO)) {
-			/* disable LCDC interrupt */
-			spin_lock(&mdp_spin_lock);
-			mdp_intr_mask &= ~INTR_OVERLAY0_DONE;
-			outp32(MDP_INTR_ENABLE, mdp_intr_mask);
-			dma->waiting = FALSE;
-			spin_unlock(&mdp_spin_lock);
-			if (panel & MDP4_PANEL_LCDC)
-				mdp4_overlay0_done_lcdc(dma);
-#ifdef CONFIG_FB_MSM_MIPI_DSI
-			else if (panel & MDP4_PANEL_DSI_VIDEO)
-				mdp4_overlay0_done_dsi_video(dma);
-#endif
-		} else {        /* MDDI, DSI_CMD  */
-#ifdef CONFIG_FB_MSM_MIPI_DSI
-			if (panel & MDP4_PANEL_DSI_CMD)
-				mdp4_overlay0_done_dsi_cmd(dma);
-#else
-			if (panel & MDP4_PANEL_MDDI)
-				mdp4_overlay0_done_mddi(dma);
-#endif
-		}
-		mdp_hw_cursor_done();
-	}
-	if (isr & INTR_OVERLAY1_DONE) {
-		mdp4_stat.intr_overlay1++;
-		/* disable DTV interrupt */
-		dma = &dma_e_data;
-		spin_lock(&mdp_spin_lock);
-		mdp_intr_mask &= ~INTR_OVERLAY1_DONE;
-		outp32(MDP_INTR_ENABLE, mdp_intr_mask);
-		dma->waiting = FALSE;
-		spin_unlock(&mdp_spin_lock);
-#if defined(CONFIG_FB_MSM_DTV)
-		if (panel & MDP4_PANEL_DTV)
-			mdp4_overlay1_done_dtv();
-#endif
-#if defined(CONFIG_FB_MSM_TVOUT)
-		if (panel & MDP4_PANEL_ATV)
-			mdp4_overlay1_done_atv();
-#endif
-	}
-#endif	/* OVERLAY */
 	if (isr & INTR_DMA_P_HISTOGRAM) {
 		isr = inpdw(MDP_DMA_P_HIST_INTR_STATUS);
 		mask = inpdw(MDP_DMA_P_HIST_INTR_ENABLE);
diff --git a/drivers/video/msm/mipi_chimei_wxga_pt.c b/drivers/video/msm/mipi_chimei_wxga_pt.c
index fe7035a..4729d83 100644
--- a/drivers/video/msm/mipi_chimei_wxga_pt.c
+++ b/drivers/video/msm/mipi_chimei_wxga_pt.c
@@ -168,7 +168,12 @@
 	pinfo->mipi.stream = false; /* dma_p */
 	pinfo->mipi.mdp_trigger = DSI_CMD_TRIGGER_NONE;
 	pinfo->mipi.dma_trigger = DSI_CMD_TRIGGER_SW;
-	pinfo->mipi.fixed_packet_size = 4;
+	/*
+	 * toshiba d2l chip does not need max_pkt_szie dcs cmd
+	 * client reply len is directly configure through
+	 * RDPKTLN register (0x0404)
+	 */
+	pinfo->mipi.no_max_pkt_size = 1;
 	pinfo->mipi.force_clk_lane_hs = 1;
 
 	ret = mipi_tc358764_dsi2lvds_register(pinfo, MIPI_DSI_PRIM,
diff --git a/drivers/video/msm/mipi_dsi_host.c b/drivers/video/msm/mipi_dsi_host.c
index 600aac5..8d07e56 100644
--- a/drivers/video/msm/mipi_dsi_host.c
+++ b/drivers/video/msm/mipi_dsi_host.c
@@ -1159,20 +1159,22 @@
 			struct dsi_buf *tp, struct dsi_buf *rp,
 			struct dsi_cmd_desc *cmds, int rlen)
 {
-	int i , cnt, len, diff, pkt_size;
+	int cnt, len, diff, pkt_size;
 	unsigned long flag;
 	char cmd;
 
+	if (mfd->panel_info.mipi.no_max_pkt_size) {
+		/* Only support rlen = 4*n */
+		rlen += 3;
+		rlen &= 0x03;
+	}
+
 	len = rlen;
 	diff = 0;
 
 	if (len <= 2)
 		cnt = 4;	/* short read */
-	else if (mfd->panel_info.mipi.fixed_packet_size) {
-		len = mfd->panel_info.mipi.fixed_packet_size;
-		pkt_size = len; /* Avoid command to the device */
-		cnt = (len + 6 + 3) & ~0x03; /* Add padding for align */
-	} else {
+	else {
 		if (len > MIPI_DSI_LEN)
 			len = MIPI_DSI_LEN;	/* 8 bytes at most */
 
@@ -1203,7 +1205,7 @@
 	dsi_mdp_busy = TRUE;
 	spin_unlock_irqrestore(&dsi_mdp_lock, flag);
 
-	if (!mfd->panel_info.mipi.fixed_packet_size) {
+	if (!mfd->panel_info.mipi.no_max_pkt_size) {
 		/* packet size need to be set at every read */
 		pkt_size = len;
 		max_pktsize[0] = pkt_size;
@@ -1223,10 +1225,15 @@
 	 * at RDBK_DATA register already
 	 */
 	mipi_dsi_buf_init(rp);
-	mipi_dsi_cmd_dma_rx(rp, cnt);
+	if (mfd->panel_info.mipi.no_max_pkt_size) {
+		/*
+		 * expect rlen = n * 4
+		 * short alignement for start addr
+		 */
+		rp->data += 2;
+	}
 
-	for (i = 0; i < cnt ; i++)
-		pr_debug("%s.rp->data[%d]=0x%x.\n", __func__, i, rp->data[i]);
+	mipi_dsi_cmd_dma_rx(rp, cnt);
 
 	spin_lock_irqsave(&dsi_mdp_lock, flag);
 	dsi_mdp_busy = FALSE;
@@ -1234,12 +1241,16 @@
 	complete(&dsi_mdp_comp);
 	spin_unlock_irqrestore(&dsi_mdp_lock, flag);
 
-	/* Remove leading padding zeros if exist */
-	for (i = 0; i < cnt ; i++)
-		if (rp->data[0] == 0)
-			rp->data++;
-		else
-			break;
+	if (mfd->panel_info.mipi.no_max_pkt_size) {
+		/*
+		 * remove extra 2 bytes from previous
+		 * rx transaction at shift register
+		 * which was inserted during copy
+		 * shift registers to rx buffer
+		 * rx payload start from long alignment addr
+		 */
+		rp->data += 2;
+	}
 
 	cmd = rp->data[0];
 	switch (cmd) {
diff --git a/drivers/video/msm/msm_fb_panel.h b/drivers/video/msm/msm_fb_panel.h
index 4c415b6..16979b1 100644
--- a/drivers/video/msm/msm_fb_panel.h
+++ b/drivers/video/msm/msm_fb_panel.h
@@ -122,7 +122,7 @@
 	char dma_trigger;
 	uint32 dsi_pclk_rate;
 	/* The packet-size should not bet changed */
-	char fixed_packet_size;
+	char no_max_pkt_size;
 	/* Clock required during LP commands */
 	char force_clk_lane_hs;
 	/* Pad width */
diff --git a/include/linux/cyttsp.h b/include/linux/cyttsp.h
index 8d69031..0e5cac7 100644
--- a/include/linux/cyttsp.h
+++ b/include/linux/cyttsp.h
@@ -87,9 +87,11 @@
 #define CY_TMA300_VTG_MAX_UV		5500000
 #define CY_TMA300_VTG_MIN_UV		1710000
 #define CY_TMA300_CURR_24HZ_UA		17500
+#define CY_TMA300_SLEEP_CURR_UA		10
 #define CY_I2C_VTG_MAX_UV		1800000
 #define CY_I2C_VTG_MIN_UV		1800000
 #define CY_I2C_CURR_UA			9630
+#define CY_I2C_SLEEP_CURR_UA		10
 
 
 /* define for inclusion of TTSP App Update Load File
@@ -445,9 +447,10 @@
 
 struct cyttsp_regulator {
 	const char *name;
-	u32	min_uV;
 	u32	max_uV;
-	u32	load_uA;
+	u32	min_uV;
+	u32	hpm_load_uA;
+	u32	lpm_load_uA;
 };
 
 struct cyttsp_platform_data {
@@ -484,6 +487,7 @@
 #ifdef CY_USE_I2C_DRIVER
 	s32 (*init)(struct i2c_client *client);
 	s32 (*resume)(struct i2c_client *client);
+	s32 (*suspend)(struct i2c_client *client);
 #endif
 #ifdef CY_USE_SPI_DRIVER
 	s32 (*init)(struct spi_device *spi);
diff --git a/include/linux/ion.h b/include/linux/ion.h
index 9f220f8..4b7b8b7d1 100644
--- a/include/linux/ion.h
+++ b/include/linux/ion.h
@@ -65,6 +65,7 @@
 #define ION_VMALLOC_HEAP_NAME	"vmalloc"
 #define ION_EBI1_HEAP_NAME	"EBI1"
 #define ION_ADSP_HEAP_NAME	"adsp"
+#define ION_SMI_HEAP_NAME	"smi"
 
 #define CACHED          1
 #define UNCACHED        0
diff --git a/mm/page_alloc.c b/mm/page_alloc.c
index fef8dc3..18f239c 100644
--- a/mm/page_alloc.c
+++ b/mm/page_alloc.c
@@ -4652,6 +4652,9 @@
 	unsigned long totalpages = early_calculate_totalpages();
 	int usable_nodes = nodes_weight(node_states[N_HIGH_MEMORY]);
 
+#ifdef CONFIG_FIX_MOVABLE_ZONE
+	required_movablecore = movable_reserved_size >> PAGE_SHIFT;
+#endif
 	/*
 	 * If movablecore was specified, calculate what size of
 	 * kernelcore that corresponds so that memory usable for
diff --git a/mm/slub.c b/mm/slub.c
index 35f351f..adf609e 100644
--- a/mm/slub.c
+++ b/mm/slub.c
@@ -557,10 +557,10 @@
 		memset(p + s->objsize, val, s->inuse - s->objsize);
 }
 
-static u8 *check_bytes(u8 *start, unsigned int value, unsigned int bytes)
+static u8 *check_bytes8(u8 *start, u8 value, unsigned int bytes)
 {
 	while (bytes) {
-		if (*start != (u8)value)
+		if (*start != value)
 			return start;
 		start++;
 		bytes--;
@@ -568,6 +568,38 @@
 	return NULL;
 }
 
+static u8 *check_bytes(u8 *start, u8 value, unsigned int bytes)
+{
+	u64 value64;
+	unsigned int words, prefix;
+
+	if (bytes <= 16)
+		return check_bytes8(start, value, bytes);
+
+	value64 = value | value << 8 | value << 16 | value << 24;
+	value64 = (value64 & 0xffffffff) | value64 << 32;
+	prefix = 8 - ((unsigned long)start) % 8;
+
+	if (prefix) {
+		u8 *r = check_bytes8(start, value, prefix);
+		if (r)
+			return r;
+		start += prefix;
+		bytes -= prefix;
+	}
+
+	words = bytes / 8;
+
+	while (words) {
+		if (*(u64 *)start != value64)
+			return check_bytes8(start, value, 8);
+		start += 8;
+		words--;
+	}
+
+	return check_bytes8(start, value, bytes % 8);
+}
+
 static void restore_bytes(struct kmem_cache *s, char *message, u8 data,
 						void *from, void *to)
 {
diff --git a/sound/soc/codecs/wcd9310.c b/sound/soc/codecs/wcd9310.c
index 620822c..2adf035 100644
--- a/sound/soc/codecs/wcd9310.c
+++ b/sound/soc/codecs/wcd9310.c
@@ -2919,6 +2919,8 @@
 
 static const struct tabla_reg_mask_val tabla_codec_reg_init_val[] = {
 
+	{TABLA_A_QFUSE_CTL, 0xFF, 0x03},
+
 	/* Initialize gain registers to use register gain */
 	{TABLA_A_RX_HPH_L_GAIN, 0x10, 0x10},
 	{TABLA_A_RX_HPH_R_GAIN, 0x10, 0x10},