Merge "msm7627a: Update the MSM-ID of 8125 1GHZ part"
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index f6d6e50..006acbf 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -98,6 +98,7 @@
 static const char *baseband_svlte2a = " androidboot.baseband=svlte2a";
 static const char *baseband_mdm     = " androidboot.baseband=mdm";
 static const char *baseband_sglte   = " androidboot.baseband=sglte";
+static const char *baseband_dsda   = " androidboot.baseband=dsda";
 
 /* Assuming unauthorized kernel image by default */
 static int auth_kernel_img = 0;
@@ -194,6 +195,10 @@
 		case BASEBAND_SGLTE:
 			cmdline_len += strlen(baseband_sglte);
 			break;
+
+		case BASEBAND_DSDA:
+			cmdline_len += strlen(baseband_dsda);
+			break;
 	}
 
 	if (cmdline_len > 0) {
@@ -272,6 +277,12 @@
 				if (have_cmdline) --dst;
 				while ((*dst++ = *src++));
 				break;
+
+			case BASEBAND_DSDA:
+				src = baseband_dsda;
+				if (have_cmdline) --dst;
+				while ((*dst++ = *src++));
+				break;
 		}
 	}
 	return cmdline_final;
@@ -366,14 +377,23 @@
 	ptr = atag_end(ptr);
 }
 
+typedef void entry_func_ptr(unsigned, unsigned, unsigned*);
 void boot_linux(void *kernel, unsigned *tags,
 		const char *cmdline, unsigned machtype,
 		void *ramdisk, unsigned ramdisk_size)
 {
+#if DEVICE_TREE
 	int ret = 0;
-	void (*entry)(unsigned, unsigned, unsigned*) = kernel;
+#endif
+
+	void (*entry)(unsigned, unsigned, unsigned*) = (entry_func_ptr*)(PA((addr_t)kernel));
+	uint32_t tags_phys = PA((addr_t)tags);
+
+	ramdisk = PA(ramdisk);
 
 #if DEVICE_TREE
+	dprintf(INFO, "Updating device tree: start\n");
+
 	/* Update the Device Tree */
 	ret = update_device_tree((void *)tags, cmdline, ramdisk, ramdisk_size);
 	if(ret)
@@ -381,13 +401,15 @@
 		dprintf(CRITICAL, "ERROR: Updating Device Tree Failed \n");
 		ASSERT(0);
 	}
+
+	dprintf(INFO, "Updating device tree: done\n");
 #else
 	/* Generating the Atags */
 	generate_atags(tags, cmdline, ramdisk, ramdisk_size);
 #endif
 
 	dprintf(INFO, "booting linux @ %p, ramdisk @ %p (%d)\n",
-		kernel, ramdisk, ramdisk_size);
+		entry, ramdisk, ramdisk_size);
 
 	enter_critical_section();
 
@@ -399,7 +421,8 @@
 #if ARM_WITH_MMU
 	arch_disable_mmu();
 #endif
-	entry(0, machtype, tags);
+
+	entry(0, machtype, (unsigned*)tags_phys);
 }
 
 unsigned page_size = 0;
@@ -408,7 +431,9 @@
 #define ROUND_TO_PAGE(x,y) (((x) + (y)) & (~(y)))
 
 static unsigned char buf[4096]; //Equal to max-supported pagesize
+#if DEVICE_TREE
 static unsigned char dt_buf[4096];
+#endif
 
 int boot_linux_from_mmc(void)
 {
@@ -416,7 +441,6 @@
 	struct boot_img_hdr *uhdr;
 	unsigned offset = 0;
 	unsigned long long ptn = 0;
-	unsigned n = 0;
 	const char *cmdline;
 	int index = INVALID_PTN;
 
@@ -425,7 +449,6 @@
 	unsigned ramdisk_actual;
 	unsigned imagesize_actual;
 	unsigned second_actual = 0;
-	unsigned dt_actual = 0;
 
 #if DEVICE_TREE
 	struct dt_table *table;
@@ -471,6 +494,11 @@
 		page_mask = page_size - 1;
 	}
 
+	/* Get virtual addresses since the hdr saves physical addresses. */
+	hdr->kernel_addr = VA((addr_t)(hdr->kernel_addr));
+	hdr->ramdisk_addr = VA((addr_t)(hdr->ramdisk_addr));
+	hdr->tags_addr = VA((addr_t)(hdr->tags_addr));
+
 	/* Authenticate Kernel */
 	if(target_use_signed_kernel() && (!device.is_unlocked) && (!device.is_tampered))
 	{
@@ -484,6 +512,8 @@
 		/* Assuming device rooted at this time */
 		device.is_tampered = 1;
 
+		dprintf(INFO, "Loading boot image (%d): start\n", imagesize_actual);
+
 		/* Read image without signature */
 		if (mmc_read(ptn + offset, (void *)image_addr, imagesize_actual))
 		{
@@ -491,6 +521,8 @@
 				return -1;
 		}
 
+		dprintf(INFO, "Loading boot image (%d): done\n", imagesize_actual);
+
 		offset = imagesize_actual;
 		/* Read signature */
 		if(mmc_read(ptn + offset, (void *)(image_addr + offset), page_size))
@@ -499,11 +531,15 @@
 		}
 		else
 		{
+			dprintf(INFO, "Authenticating boot image (%d): start\n", imagesize_actual);
+
 			auth_kernel_img = image_verify((unsigned char *)image_addr,
 					(unsigned char *)(image_addr + imagesize_actual),
 					imagesize_actual,
 					CRYPTO_AUTH_ALG_SHA256);
 
+			dprintf(INFO, "Authenticating boot image (%d): done\n", imagesize_actual);
+
 			if(auth_kernel_img)
 			{
 				/* Authorized kernel */
@@ -555,28 +591,39 @@
 	}
 	else
 	{
-		offset += page_size;
+		kernel_actual  = ROUND_TO_PAGE(hdr->kernel_size,  page_mask);
+		ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
+		second_actual  = ROUND_TO_PAGE(hdr->second_size,  page_mask);
 
-		n = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
-		if (mmc_read(ptn + offset, (void *)hdr->kernel_addr, n)) {
+		dprintf(INFO, "Loading boot image (%d): start\n",
+				kernel_actual + ramdisk_actual);
+
+		offset = page_size;
+
+		/* Load kernel */
+		if (mmc_read(ptn + offset, (void *)hdr->kernel_addr, kernel_actual)) {
 			dprintf(CRITICAL, "ERROR: Cannot read kernel image\n");
 					return -1;
 		}
-		offset += n;
+		offset += kernel_actual;
 
-		n = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
-		if(n != 0)
+		/* Load ramdisk */
+		if(ramdisk_actual != 0)
 		{
-			if (mmc_read(ptn + offset, (void *)hdr->ramdisk_addr, n)) {
+			if (mmc_read(ptn + offset, (void *)hdr->ramdisk_addr, ramdisk_actual)) {
 				dprintf(CRITICAL, "ERROR: Cannot read ramdisk image\n");
 				return -1;
 			}
 		}
-		offset += n;
+		offset += ramdisk_actual;
+
+		dprintf(INFO, "Loading boot image (%d): done\n",
+				kernel_actual + ramdisk_actual);
 
 		if(hdr->second_size != 0) {
-			n = ROUND_TO_PAGE(hdr->second_size, page_mask);
-			offset += n;
+			offset += second_actual;
+			/* Second image loading not implemented. */
+			ASSERT(0);
 		}
 
 		#if DEVICE_TREE
@@ -615,10 +662,6 @@
 	}
 
 unified_boot:
-	dprintf(INFO, "\nkernel  @ %x (%d bytes)\n", hdr->kernel_addr,
-		hdr->kernel_size);
-	dprintf(INFO, "ramdisk @ %x (%d bytes)\n", hdr->ramdisk_addr,
-		hdr->ramdisk_size);
 
 	if(hdr->cmdline[0]) {
 		cmdline = (char*) hdr->cmdline;
@@ -627,7 +670,6 @@
 	}
 	dprintf(INFO, "cmdline = '%s'\n", cmdline);
 
-	dprintf(INFO, "\nBooting Linux\n");
 	boot_linux((void *)hdr->kernel_addr, (unsigned *) hdr->tags_addr,
 		   (const char *)cmdline, board_machtype(),
 		   (void *)hdr->ramdisk_addr, hdr->ramdisk_size);
@@ -638,7 +680,6 @@
 int boot_linux_from_flash(void)
 {
 	struct boot_img_hdr *hdr = (void*) buf;
-	unsigned n;
 	struct ptentry *ptn;
 	struct ptable *ptable;
 	unsigned offset = 0;
@@ -648,6 +689,7 @@
 	unsigned kernel_actual;
 	unsigned ramdisk_actual;
 	unsigned imagesize_actual;
+	unsigned second_actual;
 
 #if DEVICE_TREE
 	struct dt_table *table;
@@ -703,6 +745,11 @@
 		return -1;
 	}
 
+	/* Get virtual addresses since the hdr saves physical addresses. */
+	hdr->kernel_addr = VA(hdr->kernel_addr);
+	hdr->ramdisk_addr = VA(hdr->ramdisk_addr);
+	hdr->tags_addr = VA(hdr->tags_addr);
+
 	/* Authenticate Kernel */
 	if(target_use_signed_kernel() && (!device.is_unlocked) && (!device.is_tampered))
 	{
@@ -716,6 +763,8 @@
 		/* Assuming device rooted at this time */
 		device.is_tampered = 1;
 
+		dprintf(INFO, "Loading boot image (%d): start\n", imagesize_actual);
+
 		/* Read image without signature */
 		if (flash_read(ptn, offset, (void *)image_addr, imagesize_actual))
 		{
@@ -723,6 +772,8 @@
 				return -1;
 		}
 
+		dprintf(INFO, "Loading boot image (%d): done\n", imagesize_actual);
+
 		offset = imagesize_actual;
 		/* Read signature */
 		if (flash_read(ptn, offset, (void *)(image_addr + offset), page_size))
@@ -731,6 +782,7 @@
 		}
 		else
 		{
+			dprintf(INFO, "Authenticating boot image (%d): start\n", imagesize_actual);
 
 			/* Verify signature */
 			auth_kernel_img = image_verify((unsigned char *)image_addr,
@@ -738,6 +790,8 @@
 						imagesize_actual,
 						CRYPTO_AUTH_ALG_SHA256);
 
+			dprintf(INFO, "Authenticating boot image (%d): done\n", imagesize_actual);
+
 			if(auth_kernel_img)
 			{
 				/* Authorized kernel */
@@ -762,23 +816,32 @@
 	{
 		offset = page_size;
 
-		n = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
-		if (flash_read(ptn, offset, (void *)hdr->kernel_addr, n)) {
+		kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
+		ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
+		second_actual = ROUND_TO_PAGE(hdr->second_size, page_mask);
+
+		dprintf(INFO, "Loading boot image (%d): start\n",
+				kernel_actual + ramdisk_actual);
+
+		if (flash_read(ptn, offset, (void *)hdr->kernel_addr, kernel_actual)) {
 			dprintf(CRITICAL, "ERROR: Cannot read kernel image\n");
 			return -1;
 		}
-		offset += n;
+		offset += kernel_actual;
 
-		n = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
-		if (flash_read(ptn, offset, (void *)hdr->ramdisk_addr, n)) {
+		if (flash_read(ptn, offset, (void *)hdr->ramdisk_addr, ramdisk_actual)) {
 			dprintf(CRITICAL, "ERROR: Cannot read ramdisk image\n");
 			return -1;
 		}
-		offset += n;
+		offset += ramdisk_actual;
+
+		dprintf(INFO, "Loading boot image (%d): done\n",
+				kernel_actual + ramdisk_actual);
 
 		if(hdr->second_size != 0) {
-			n = ROUND_TO_PAGE(hdr->second_size, page_mask);
-			offset += n;
+			offset += second_actual;
+			/* Second image loading not implemented. */
+			ASSERT(0);
 		}
 
 #if DEVICE_TREE
@@ -818,10 +881,6 @@
 
 	}
 continue_boot:
-	dprintf(INFO, "\nkernel  @ %x (%d bytes)\n", hdr->kernel_addr,
-		hdr->kernel_size);
-	dprintf(INFO, "ramdisk @ %x (%d bytes)\n", hdr->ramdisk_addr,
-		hdr->ramdisk_size);
 
 	if(hdr->cmdline[0]) {
 		cmdline = (char*) hdr->cmdline;
@@ -832,7 +891,6 @@
 
 	/* TODO: create/pass atags to kernel */
 
-	dprintf(INFO, "\nBooting Linux\n");
 	boot_linux((void *)hdr->kernel_addr, (void *)hdr->tags_addr,
 		   (const char *)cmdline, board_machtype(),
 		   (void *)hdr->ramdisk_addr, hdr->ramdisk_size);
@@ -1048,7 +1106,9 @@
 		}
 
 		/* Read device device tree in the "tags_add */
-		memmove((void*) hdr->tags_addr, boot_image_start + dt_image_offset +  dt_entry_ptr->offset, dt_entry_ptr->size);
+		memmove((void*) hdr->tags_addr,
+				boot_image_start + dt_image_offset +  dt_entry_ptr->offset,
+				dt_entry_ptr->size);
 	}
 
 	/* Everything looks fine. Return success. */
@@ -1060,7 +1120,7 @@
 {
 	unsigned kernel_actual;
 	unsigned ramdisk_actual;
-	static struct boot_img_hdr hdr;
+	struct boot_img_hdr *hdr;
 	char *ptr = ((char*) data);
 
 	if (sz < sizeof(hdr)) {
@@ -1068,18 +1128,23 @@
 		return;
 	}
 
-	memcpy(&hdr, data, sizeof(hdr));
+	hdr = (struct boot_img_hdr *)data;
 
 	/* ensure commandline is terminated */
-	hdr.cmdline[BOOT_ARGS_SIZE-1] = 0;
+	hdr->cmdline[BOOT_ARGS_SIZE-1] = 0;
 
-	if(target_is_emmc_boot() && hdr.page_size) {
-		page_size = hdr.page_size;
+	if(target_is_emmc_boot() && hdr->page_size) {
+		page_size = hdr->page_size;
 		page_mask = page_size - 1;
 	}
 
-	kernel_actual = ROUND_TO_PAGE(hdr.kernel_size, page_mask);
-	ramdisk_actual = ROUND_TO_PAGE(hdr.ramdisk_size, page_mask);
+	kernel_actual = ROUND_TO_PAGE(hdr->kernel_size, page_mask);
+	ramdisk_actual = ROUND_TO_PAGE(hdr->ramdisk_size, page_mask);
+
+	/* Get virtual addresses since the hdr saves physical addresses. */
+	hdr->kernel_addr = VA(hdr->kernel_addr);
+	hdr->ramdisk_addr = VA(hdr->ramdisk_addr);
+	hdr->tags_addr = VA(hdr->tags_addr);
 
 	/* sz should have atleast raw boot image */
 	if (page_size + kernel_actual + ramdisk_actual > sz) {
@@ -1099,12 +1164,12 @@
 	fastboot_okay("");
 	udc_stop();
 
-	memmove((void*) hdr.ramdisk_addr, ptr + page_size + kernel_actual, hdr.ramdisk_size);
-	memmove((void*) hdr.kernel_addr, ptr + page_size, hdr.kernel_size);
+	memmove((void*) hdr->ramdisk_addr, ptr + page_size + kernel_actual, hdr->ramdisk_size);
+	memmove((void*) hdr->kernel_addr, ptr + page_size, hdr->kernel_size);
 
-	boot_linux((void*) hdr.kernel_addr, (void*) hdr.tags_addr,
-		   (const char*) hdr.cmdline, board_machtype(),
-		   (void*) hdr.ramdisk_addr, hdr.ramdisk_size);
+	boot_linux((void*) hdr->kernel_addr, (void*) hdr->tags_addr,
+		   (const char*) hdr->cmdline, board_machtype(),
+		   (void*) hdr->ramdisk_addr, hdr->ramdisk_size);
 }
 
 void cmd_erase(const char *arg, void *data, unsigned sz)
diff --git a/app/aboot/fastboot.c b/app/aboot/fastboot.c
index 2b699b3..ee11a13 100644
--- a/app/aboot/fastboot.c
+++ b/app/aboot/fastboot.c
@@ -29,6 +29,7 @@
 #include <debug.h>
 #include <string.h>
 #include <stdlib.h>
+#include <platform.h>
 #include <kernel/thread.h>
 #include <kernel/event.h>
 #include <dev/udc.h>
@@ -147,7 +148,7 @@
 
 	while (len > 0) {
 		xfer = (len > MAX_USBFS_BULK_SIZE) ? MAX_USBFS_BULK_SIZE : len;
-		req->buf = buf;
+		req->buf = PA((addr_t)buf);
 		req->length = xfer;
 		req->complete = req_complete;
 		r = udc_request_queue(out, req);
@@ -184,7 +185,7 @@
 	if (fastboot_state == STATE_ERROR)
 		goto oops;
 
-	req->buf = buf;
+	req->buf = PA((addr_t)buf);
 	req->length = len;
 	req->complete = req_complete;
 	r = udc_request_queue(in, req);
diff --git a/dev/pmic/pm8921/include/dev/pm8921.h b/dev/pmic/pm8921/include/dev/pm8921.h
index 715e474..7200eb0 100644
--- a/dev/pmic/pm8921/include/dev/pm8921.h
+++ b/dev/pmic/pm8921/include/dev/pm8921.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -10,7 +10,7 @@
  *       copyright notice, this list of conditions and the following
  *       disclaimer in the documentation and/or other materials provided
  *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *     * Neither the name of Linux Foundation, Inc. nor the names of its
  *       contributors may be used to endorse or promote products derived
  *       from this software without specific prior written permission.
  *
@@ -61,6 +61,25 @@
 	mpp_end = mpp_12,
 };
 
+typedef enum {
+	BAT_VOL_2_8 = 0,
+	BAT_VOL_2_9,
+	BAT_VOL_3_0,
+	BAT_VOL_3_1,
+	BAT_VOL_3_2,
+	BAT_VOL_3_3,
+	BAT_VOL_3_4,
+	BAT_VOL_3_5,
+	BAT_VOL_3_6,
+	BAT_VOL_3_7,
+	BAT_VOL_3_8,
+	BAT_VOL_3_9,
+	BAT_VOL_4_0,
+	BAT_VOL_4_1,
+	BAT_VOL_4_2,
+	BAT_VOL_4_3,
+} bat_vol_t;
+
 #define PM_GPIO_DIR_OUT         0x01
 #define PM_GPIO_DIR_IN          0x02
 #define PM_GPIO_DIR_BOTH        (PM_GPIO_DIR_OUT | PM_GPIO_DIR_IN)
@@ -139,6 +158,13 @@
 	int disable_pin;
 };
 
+struct pm89xx_vreg {
+	const char *name;
+	uint8_t type;
+	uint16_t test_reg;
+	uint16_t ctrl_reg;
+};
+
 void pm8921_init(pm8921_dev_t *);
 int  pm8921_gpio_config(int gpio, struct pm8921_gpio *param);
 void pm8921_boot_done(void);
@@ -156,4 +182,8 @@
 int pm8921_low_voltage_switch_enable(uint8_t lvs_id);
 int pm8921_mpp_set_digital_output(uint8_t mpp_id);
 int pm8921_rtc_alarm_disable(void);
+int pm89xx_bat_alarm_set(bat_vol_t, bat_vol_t);
+int pm89xx_bat_alarm_status(uint8_t *, uint8_t *);
+int pm89xx_vbus_status(void);
+int pm89xx_ldo_set_voltage(const char * , uint32_t);
 #endif
diff --git a/dev/pmic/pm8921/pm8921.c b/dev/pmic/pm8921/pm8921.c
index 1acc021..231b8b6 100644
--- a/dev/pmic/pm8921/pm8921.c
+++ b/dev/pmic/pm8921/pm8921.c
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -10,7 +10,7 @@
  *       copyright notice, this list of conditions and the following
  *       disclaimer in the documentation and/or other materials provided
  *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *     * Neither the name of  Linux Foundation, Inc. nor the names of its
  *       contributors may be used to endorse or promote products derived
  *       from this software without specific prior written permission.
  *
@@ -27,9 +27,11 @@
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 #include <assert.h>
+#include <string.h>
 #include <sys/types.h>
 #include <err.h>
 #include <dev/pm8921.h>
+#include <platform/timer.h>
 #include "pm8921_hw.h"
 
 static pm8921_dev_t *dev;
@@ -539,3 +541,191 @@
 
 	return rc;
 }
+
+/*
+ * Set battery alarm with low & high threshold values
+ */
+int pm89xx_bat_alarm_set(bat_vol_t up_thresh_vol, bat_vol_t low_thresh_vol)
+{
+	int rc;
+	uint8_t reg = 0;
+
+	if ((up_thresh_vol > BAT_VOL_4_3) || (low_thresh_vol > BAT_VOL_4_3)) {
+		dprintf(CRITICAL, "Input voltage not in permissible range\n");
+		return 1;
+	}
+
+	/*
+	 * Write upper & lower threshold values
+	 */
+	reg = (up_thresh_vol << PM89XX_BAT_UP_THRESH_VOL) | low_thresh_vol;
+
+	rc = dev->write(&reg, 1, PM89XX_BAT_ALRM_THRESH);
+	if (rc) {
+		dprintf(CRITICAL, "Failed to set BAT_THRESH reg = %d\n", rc);
+		return rc;
+	}
+
+	/* Read Alarm control to use the existing hysteresis values */
+	rc = dev->read(&reg, 1, PM89XX_BAT_ALRM_CTRL);
+	if (rc) {
+		dprintf(CRITICAL, "Failed to read BAT_ALARM reg = %d\n", rc);
+		return rc;
+	}
+
+	/* Enable battery alarm */
+	reg |= PM89XX_BAT_ALRM_ENABLE;
+	rc = dev->write(&reg, 1, PM89XX_BAT_ALRM_CTRL);
+	if (rc) {
+		dprintf(CRITICAL, "Failed to enable BAT_ALARM reg = %d\n", rc);
+		return rc;
+	}
+
+	/* Wait for the comparator o/p to settle */
+	mdelay(10);
+
+	return rc;
+}
+
+/*
+ * API to return status of battery
+ * if the vbatt is below upper threshold return 0
+ * if the vbatt is below lower threshold return 1
+ */
+int pm89xx_bat_alarm_status(uint8_t *high_status, uint8_t *low_status)
+{
+	int rc = 0;
+	uint8_t reg = 0;
+
+	/* Read the battery status */
+	rc = dev->read(&reg, 1, PM89XX_BAT_ALRM_CTRL);
+	if (rc) {
+		dprintf(CRITICAL, "Failed to read BAT_ALARM reg = %d\n", rc);
+		return rc;
+	}
+
+	/* Return the status if battery alarm is enabled */
+	if (reg & PM89XX_BAT_ALRM_ENABLE) {
+		*high_status = (reg & PM89XX_BAT_UPR_STATUS);
+		*low_status = (reg & PM89XX_BAT_LWR_STATUS);
+	} else {
+		dprintf(CRITICAL, "Battery alarm is not enabled\n");
+		return 1;
+	}
+
+	return rc;
+}
+
+/*
+ * Return 1 if VBUS is connected, 0 otherwise
+ */
+int pm89xx_vbus_status(void)
+{
+	int rc;
+	uint8_t reg = 0;
+
+	rc = dev->read(&reg, 1, PM89XX_USB_OVP_CTRL);
+	if (rc) {
+		dprintf(CRITICAL, "Failed to read USB OVP CTRL = %d\n", rc);
+		return rc;
+	}
+
+	reg &= PM89XX_VBUS_INPUT_STATUS;
+
+	return reg;
+}
+
+static struct pm89xx_vreg *ldo_get(const char *ldo_name)
+{
+	uint8_t i;
+	struct pm89xx_vreg *ldo = NULL;
+
+	for (i = 0; i < ARRAY_SIZE(ldo_data); i++) {
+		ldo = &ldo_data[i];
+		if (!strncmp(ldo->name, ldo_name, strlen(ldo_name)))
+			break;
+	}
+
+	return ldo;
+}
+
+/*
+ * API takes LDO name & voltage as input
+ * Input voltage is taken in mVs
+ * PLDO voltage ranging from 1500mV to 3000mV
+ * NLDO voltage ranging from 750mV to 1525mV
+ */
+int pm89xx_ldo_set_voltage(const char *ldo_name, uint32_t voltage)
+{
+	uint8_t mult;
+	uint8_t val = 0;
+	int32_t ret = 0;
+	struct pm89xx_vreg *ldo;
+
+	/* Find the LDO info from table */
+	ldo = ldo_get(ldo_name);
+
+	if (!ldo) {
+		dprintf(CRITICAL, "Requested LDO is not supported : \
+				%s\n", ldo_name);
+		return -1;
+	}
+
+	/* Find the voltage multiplying factor */
+	if (ldo->type == PLDO_TYPE) {
+		if (voltage < PLDO_MV_VMIN)
+			voltage = PLDO_MV_VMIN;
+		else if (voltage > PLDO_MV_VMAX)
+			voltage = PLDO_MV_VMAX;
+		mult = (voltage - PLDO_MV_VMIN) / PLDO_MV_VSTEP;
+	} else {
+		if (voltage < NLDO_MV_VMIN)
+			voltage = NLDO_MV_VMIN;
+		else if (voltage > NLDO_MV_VMAX)
+			voltage = NLDO_MV_VMAX;
+		mult = (voltage - NLDO_MV_VMIN) / NLDO_MV_VSTEP;
+	}
+
+	/* Program the TEST reg */
+	if (ldo->type == PLDO_TYPE) {
+		/* Bank 2, only for p ldo, use 1.25V reference */
+		val = 0x0;
+		val |= (1 << PM8921_LDO_TEST_REG_RW);
+		val |= (2 << PM8921_LDO_TEST_REG_BANK_SEL);
+		ret = dev->write(&val, 1, ldo->test_reg);
+		if (ret) {
+			dprintf(CRITICAL, "Failed to write to PM8921 LDO Test \
+					Reg ret=%d.\n", ret);
+			return -1;
+		}
+
+		/*
+		 * Bank 4, only for p ldo, disable output range ext,
+		 * normal capacitance
+		 */
+		val = 0x0;
+		val |= (1 << PM8921_LDO_TEST_REG_RW);
+		val |= (4 << PM8921_LDO_TEST_REG_BANK_SEL);
+		ret = dev->write(&val, 1, ldo->test_reg);
+		if (ret) {
+			dprintf(CRITICAL, "Failed to write to PM8921 LDO Test \
+					Reg ret=%d.\n", ret);
+			return -1;
+		}
+	}
+
+	/* Program the CTRL reg */
+	val = 0x0;
+	val |= (1 << PM8921_LDO_CTRL_REG_ENABLE);
+	val |= (1 << PM8921_LDO_CTRL_REG_PULL_DOWN);
+	val |= (0 << PM8921_LDO_CTRL_REG_POWER_MODE);
+	val |= (mult << PM8921_LDO_CTRL_REG_VOLTAGE);
+	ret = dev->write(&val, 1, ldo->ctrl_reg);
+	if (ret) {
+		dprintf(CRITICAL, "Failed to write to PM8921 LDO Ctrl Reg \
+				ret=%d.\n", ret);
+		return -1;
+	}
+
+	return 0;
+}
diff --git a/dev/pmic/pm8921/pm8921_hw.h b/dev/pmic/pm8921/pm8921_hw.h
index bf43543..e75026e 100644
--- a/dev/pmic/pm8921/pm8921_hw.h
+++ b/dev/pmic/pm8921/pm8921_hw.h
@@ -1,5 +1,5 @@
 /*
- * Copyright (c) 2011-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2011-2012, Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -10,7 +10,7 @@
  *       copyright notice, this list of conditions and the following
  *       disclaimer in the documentation and/or other materials provided
  *       with the distribution.
- *     * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *     * Neither the name of Linux Foundation, Inc. nor the names of its
  *       contributors may be used to endorse or promote products derived
  *       from this software without specific prior written permission.
  *
@@ -26,6 +26,7 @@
  * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
  * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
+#include <bits.h>
 
 #define PBL_ACCESS_2                          0x005
 #define PBL_ACCESS_2_ENUM_TIMER_STOP          (1 << 1)
@@ -129,3 +130,44 @@
 #define PM8921_MPP_CTRL_DIGITAL_OUTPUT        (1 << 5)
 #define PM8921_MPP_CTRL_VIO_1                 (1 << 2)
 #define PM8921_MPP_CTRL_OUTPUT_HIGH           (1 << 0)
+
+#define PM89XX_BAT_UP_THRESH_VOL              4
+#define PM89XX_BAT_ALRM_THRESH                0x23
+#define PM89XX_BAT_ALRM_CTRL                  0x24
+#define PM89XX_USB_OVP_CTRL                   0x21C
+
+#define PM89XX_BAT_ALRM_ENABLE                BIT(7)
+#define PM89XX_BAT_UPR_STATUS                 BIT(1)
+#define PM89XX_BAT_LWR_STATUS                 BIT(0)
+
+#define PM89XX_VBUS_INPUT_STATUS              BIT(0)
+
+/* voltages are specified in mV */
+#define PLDO_MV_VMIN                          1500
+#define PLDO_MV_VMAX                          3000
+#define PLDO_MV_VSTEP                         50
+
+#define NLDO_MV_VMIN                          750
+#define NLDO_MV_VMAX                          1525
+#define NLDO_MV_VSTEP                         25
+
+#define PLDO_TYPE                             0
+#define NLDO_TYPE                             1
+
+#define LDO(_name, _type, _test_reg, _ctrl_reg) \
+{\
+	.name = _name,\
+	.type = _type,\
+	.test_reg = _test_reg,\
+	.ctrl_reg = _ctrl_reg, \
+}
+
+struct pm89xx_vreg ldo_data[] = {
+	LDO("LDO30", PLDO_TYPE, 0x0A3, 0x0A4),
+	LDO("LDO31", PLDO_TYPE, 0x0A5, 0x0A6),
+	LDO("LDO32", PLDO_TYPE, 0x0A7, 0x0A8),
+	LDO("LDO33", PLDO_TYPE, 0x0C6, 0x0C7),
+	LDO("LDO34", PLDO_TYPE, 0x0D2, 0x0D3),
+	LDO("LDO35", PLDO_TYPE, 0x0D4, 0x0D5),
+	LDO("LDO36", PLDO_TYPE, 0x0A9, 0x0AA),
+};
diff --git a/dev/pmic/pm8x41/include/pm8x41.h b/dev/pmic/pm8x41/include/pm8x41.h
index 3816325..94436b1 100644
--- a/dev/pmic/pm8x41/include/pm8x41.h
+++ b/dev/pmic/pm8x41/include/pm8x41.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -9,7 +9,7 @@
  *     copyright notice, this list of conditions and the following
  *     disclaimer in the documentation and/or other materials provided
  *     with the distribution.
- *   * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *   * Neither the name of The Linux Foundation, Inc. nor the names of its
  *     contributors may be used to endorse or promote products derived
  *     from this software without specific prior written permission.
  *
@@ -29,6 +29,8 @@
 #ifndef _PM8x41_H_
 #define _PM8x41_H_
 
+#include <sys/types.h>
+
 #define PM_GPIO_DIR_OUT         0x01
 #define PM_GPIO_DIR_IN          0x00
 #define PM_GPIO_DIR_BOTH        0x02
@@ -60,5 +62,15 @@
 void pm8x41_set_boot_done();
 int pm8x41_vol_down_key_status();
 void pm8x41_reset_configure(uint8_t);
+int pm8x41_ldo_set_voltage(const char *, uint32_t);
+int pm8x41_ldo_control(const char *, uint8_t);
 
+struct pm8x41_ldo {
+	const char *name;
+	uint8_t type;
+	uint32_t base;
+	uint32_t range_reg;
+	uint32_t step_reg;
+	uint32_t enable_reg;
+};
 #endif
diff --git a/dev/pmic/pm8x41/include/pm8x41_hw.h b/dev/pmic/pm8x41/include/pm8x41_hw.h
index 4886a8e..01fd07f 100644
--- a/dev/pmic/pm8x41/include/pm8x41_hw.h
+++ b/dev/pmic/pm8x41/include/pm8x41_hw.h
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -9,7 +9,7 @@
  *     copyright notice, this list of conditions and the following
  *     disclaimer in the documentation and/or other materials provided
  *     with the distribution.
- *   * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *   * Neither the name of The Linux Foundation, Inc. nor the names of its
  *     contributors may be used to endorse or promote products derived
  *     from this software without specific prior written permission.
  *
@@ -29,7 +29,6 @@
 #ifndef _PM8x41_HW_H_
 #define _PM8x41_HW_H_
 
-
 /* SMBB Registers */
 #define SMBB_MISC_BOOT_DONE                   0x1642
 
@@ -76,4 +75,44 @@
 #define S2_RESET_TYPE_WARM                    0x1
 #define PON_RESIN_N_RESET_S2_TIMER_MAX_VALUE  0x7
 
+/* LDO voltage ranges */
+#define NLDO_UV_MIN                           375000
+#define NLDO_UV_MAX                           1537500
+#define NLDO_UV_STEP                          12500
+#define NLDO_UV_VMIN_LOW                      750000
+
+#define PLDO_UV_VMIN_LOW                      750000
+#define PLDO_UV_VMIN_MID                      1500000
+#define PLDO_UV_VMIN_HIGH                     1750000
+
+#define PLDO_UV_MIN                           1537500
+#define PDLO_UV_MID                           3075000
+#define PLDO_UV_MAX                           4900000
+#define PLDO_UV_STEP_LOW                      12500
+#define PLDO_UV_STEP_MID                      25000
+#define PLDO_UV_STEP_HIGH                     50000
+
+#define LDO_RANGE_SEL_BIT                     0
+#define LDO_VSET_SEL_BIT                      0
+#define LDO_VREG_ENABLE_BIT                   7
+#define LDO_NORMAL_PWR_BIT                    7
+
+#define LDO_RANGE_CTRL                        0x40
+#define LDO_STEP_CTRL                         0x41
+#define LDO_POWER_MODE                        0x45
+#define LDO_EN_CTL_REG                        0x46
+
+#define PLDO_TYPE                             0
+#define NLDO_TYPE                             1
+
+#define LDO(_name, _type, _base, _range, _step, _enable) \
+{ \
+	.name = _name, \
+	.type = _type, \
+	.base = _base, \
+	.range_reg = _range, \
+	.step_reg = _step, \
+	.enable_reg = _enable, \
+}
+
 #endif
diff --git a/dev/pmic/pm8x41/pm8x41.c b/dev/pmic/pm8x41/pm8x41.c
index f6804ec..31b13cb 100644
--- a/dev/pmic/pm8x41/pm8x41.c
+++ b/dev/pmic/pm8x41/pm8x41.c
@@ -1,4 +1,4 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
 
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
@@ -9,7 +9,7 @@
  *     copyright notice, this list of conditions and the following
  *     disclaimer in the documentation and/or other materials provided
  *     with the distribution.
- *   * Neither the name of Code Aurora Forum, Inc. nor the names of its
+ *   * Neither the name of The Linux Foundation, Inc. nor the names of its
  *     contributors may be used to endorse or promote products derived
  *     from this software without specific prior written permission.
  *
@@ -30,6 +30,7 @@
 #include <debug.h>
 #include <reg.h>
 #include <spmi.h>
+#include <string.h>
 #include <pm8x41_hw.h>
 #include <pm8x41.h>
 #include <platform/timer.h>
@@ -42,6 +43,11 @@
 #define PERIPH_ID(_addr)    (((_addr) & 0xFF00) >> 8)
 #define SLAVE_ID(_addr)     ((_addr) >> 16)
 
+struct pm8x41_ldo ldo_data[] = {
+	LDO("LDO2",  NLDO_TYPE, 0x14100, LDO_RANGE_CTRL, LDO_STEP_CTRL, LDO_EN_CTL_REG),
+	LDO("LDO12", PLDO_TYPE, 0x14B00, LDO_RANGE_CTRL, LDO_STEP_CTRL, LDO_EN_CTL_REG),
+	LDO("LDO22", PLDO_TYPE, 0x15500, LDO_RANGE_CTRL, LDO_STEP_CTRL, LDO_EN_CTL_REG),
+};
 
 /* Local functions */
 static uint8_t pm8x41_reg_read(uint32_t addr)
@@ -219,3 +225,103 @@
 	val |= BIT(S2_RESET_EN_BIT);
 	REG_WRITE(PON_PS_HOLD_RESET_CTL, val);
 }
+
+static struct pm8x41_ldo *ldo_get(const char *ldo_name)
+{
+	uint8_t i;
+	struct pm8x41_ldo *ldo = NULL;
+
+	for (i = 0; i < ARRAY_SIZE(ldo_data); i++) {
+		ldo = &ldo_data[i];
+		if (!strncmp(ldo->name, ldo_name, strlen(ldo_name)))
+			break;
+	}
+	return ldo;
+}
+
+/*
+ * LDO set voltage, takes ldo name & voltage in UV as input
+ */
+int pm8x41_ldo_set_voltage(const char *name, uint32_t voltage)
+{
+	uint32_t range = 0;
+	uint32_t step = 0;
+	uint32_t mult = 0;
+	uint32_t val = 0;
+	uint32_t vmin = 0;
+	struct pm8x41_ldo *ldo;
+
+	ldo = ldo_get(name);
+	if (!ldo) {
+		dprintf(CRITICAL, "LDO requsted is not supported: %s\n", name);
+		return 1;
+	}
+
+	/* Program Normal power mode */
+	val = 0x0;
+	val = (1 << LDO_NORMAL_PWR_BIT);
+	REG_WRITE((ldo->base + LDO_POWER_MODE), val);
+
+	/*
+	 * Select range, step & vmin based on input voltage & type of LDO
+	 * LDO can operate in low, mid, high power mode
+	 */
+	if (ldo->type == PLDO_TYPE) {
+		if (voltage < PLDO_UV_MIN) {
+			range = 2;
+			step = PLDO_UV_STEP_LOW;
+			vmin = PLDO_UV_VMIN_LOW;
+		} else if (voltage < PDLO_UV_MID) {
+			range = 3;
+			step = PLDO_UV_STEP_MID;
+			vmin = PLDO_UV_VMIN_MID;
+		} else {
+			range = 4;
+			step = PLDO_UV_STEP_HIGH;
+			vmin = PLDO_UV_VMIN_HIGH;
+		}
+	} else {
+		range = 2;
+		step = NLDO_UV_STEP;
+		vmin = NLDO_UV_VMIN_LOW;
+	}
+
+	mult = (voltage - vmin) / step;
+
+	/* Set Range in voltage ctrl register */
+	val = 0x0;
+	val = range << LDO_RANGE_SEL_BIT;
+	REG_WRITE((ldo->base + ldo->range_reg), val);
+
+	/* Set multiplier in voltage ctrl register */
+	val = 0x0;
+	val = mult << LDO_VSET_SEL_BIT;
+	REG_WRITE((ldo->base + ldo->step_reg), val);
+
+	return 0;
+}
+
+/*
+ * Enable or Disable LDO
+ */
+int pm8x41_ldo_control(const char *name, uint8_t enable)
+{
+	uint32_t val = 0;
+	struct pm8x41_ldo *ldo;
+
+	ldo = ldo_get(name);
+	if (!ldo) {
+		dprintf(CRITICAL, "Requested LDO is not supported : %s\n", name);
+		return 1;
+	}
+
+	/* Enable LDO */
+	if (enable)
+		val = (1 << LDO_VREG_ENABLE_BIT);
+	else
+		val = (0 << LDO_VREG_ENABLE_BIT);
+
+	REG_WRITE((ldo->base + ldo->enable_reg), val);
+
+	return 0;
+}
diff --git a/include/platform.h b/include/platform.h
old mode 100755
new mode 100644
diff --git a/platform/copper/acpuclock.c b/platform/copper/acpuclock.c
index 8a9f96d..28cd204 100644
--- a/platform/copper/acpuclock.c
+++ b/platform/copper/acpuclock.c
@@ -1,35 +1,36 @@
-/*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *   * Neither the name of Code Aurora nor
- *     the names of its contributors may be used to endorse or promote
- *     products derived from this software without specific prior written
- *     permission.
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <err.h>
 #include <assert.h>
 #include <debug.h>
 #include <reg.h>
+#include <platform/timer.h>
 #include <platform/iomap.h>
 #include <mmc.h>
 #include <clock.h>
@@ -73,12 +74,12 @@
 	mdelay(20);
 
 	/* Take usb block out of reset */
-	writel(0, USB_HS_BCR); 
+	writel(0, USB_HS_BCR);
 
 	mdelay(20);
 
 	ret = clk_enable(iclk);
-	
+
 	if(ret)
     {
         dprintf(CRITICAL, "failed to set usb_iface_clk after async ret = %d\n", ret);
@@ -168,3 +169,123 @@
 		ASSERT(0);
 	}
 }
+
+/* Function to asynchronously reset CE.
+ * Function assumes that all the CE clocks are off.
+ */
+static void ce_async_reset(uint8_t instance)
+{
+	if (instance == 1)
+	{
+		/* TODO: Add support for instance 1. */
+		dprintf(CRITICAL, "CE instance not supported instance = %d", instance);
+		ASSERT(0);
+	}
+	else if (instance == 2)
+	{
+		/* Start the block reset for CE */
+		writel(1, GCC_CE2_BCR);
+
+		udelay(2);
+
+		/* Take CE block out of reset */
+		writel(0, GCC_CE2_BCR);
+
+		udelay(2);
+	}
+	else
+	{
+		dprintf(CRITICAL, "CE instance not supported instance = %d", instance);
+		ASSERT(0);
+	}
+}
+
+static void clock_ce_enable(uint8_t instance)
+{
+	int ret;
+	char clk_name[64];
+
+	snprintf(clk_name, 64, "ce%u_src_clk", instance);
+	ret = clk_get_set_enable(clk_name, 100000000, 1);
+	if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce_src_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	snprintf(clk_name, 64, "ce%u_core_clk", instance);
+    ret = clk_get_set_enable(clk_name, 0, 1);
+    if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce_core_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	snprintf(clk_name, 64, "ce%u_ahb_clk", instance);
+    ret = clk_get_set_enable(clk_name, 0, 1);
+    if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce_ahb_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	snprintf(clk_name, 64, "ce%u_axi_clk", instance);
+    ret = clk_get_set_enable(clk_name, 0, 1);
+    if(ret)
+	{
+		dprintf(CRITICAL, "failed to set ce_axi_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	/* Wait for 48 * #pipes cycles.
+	 * This is necessary as immediately after an access control reset (boot up)
+	 * or a debug re-enable, the Crypto core sequentially clears its internal
+	 * pipe key storage memory. If pipe key initialization writes are attempted
+	 * during this time, they may be overwritten by the internal clearing logic.
+	 */
+	udelay(1);
+}
+
+static void clock_ce_disable(uint8_t instance)
+{
+	struct clk *ahb_clk;
+	struct clk *cclk;
+	struct clk *axi_clk;
+	struct clk *src_clk;
+	char clk_name[64];
+
+	snprintf(clk_name, 64, "ce%u_src_clk", instance);
+	src_clk = clk_get(clk_name);
+
+	snprintf(clk_name, 64, "ce%u_ahb_clk", instance);
+	ahb_clk = clk_get(clk_name);
+
+	snprintf(clk_name, 64, "ce%u_axi_clk", instance);
+	axi_clk = clk_get(clk_name);
+
+	snprintf(clk_name, 64, "ce%u_core_clk", instance);
+	cclk    = clk_get(clk_name);
+
+	clk_disable(ahb_clk);
+	clk_disable(axi_clk);
+	clk_disable(cclk);
+	clk_disable(src_clk);
+
+	/* Some delay for the clocks to stabalize. */
+	udelay(1);
+}
+
+void clock_config_ce(uint8_t instance)
+{
+	/* Need to enable the clock before disabling since the clk_disable()
+	 * has a check to default to nop when the clk_enable() is not called
+	 * on that particular clock.
+	 */
+	clock_ce_enable(instance);
+
+	clock_ce_disable(instance);
+
+	ce_async_reset(instance);
+
+	clock_ce_enable(instance);
+}
diff --git a/platform/copper/copper-clock.c b/platform/copper/copper-clock.c
index ed7ace2..4b73703 100644
--- a/platform/copper/copper-clock.c
+++ b/platform/copper/copper-clock.c
@@ -1,29 +1,29 @@
-/*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *   * Neither the name of Code Aurora nor
- *     the names of its contributors may be used to endorse or promote
- *     products derived from this software without specific prior written
- *     permission.
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <assert.h>
@@ -212,7 +212,7 @@
 
 static struct vote_clk gcc_blsp1_ahb_clk = {
 	.cbcr_reg     = (uint32_t *) BLSP1_AHB_CBCR,
-	.vote_reg     = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.vote_reg     = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
 	.en_mask      = BIT(17),
 
 	.c = {
@@ -265,6 +265,58 @@
 	},
 };
 
+/* CE Clocks */
+static struct clk_freq_tbl ftbl_gcc_ce2_clk[] = {
+	F( 50000000,  gpll0,  12,   0,   0),
+	F(100000000,  gpll0,   6,   0,   0),
+	F_END
+};
+
+static struct rcg_clk ce2_clk_src = {
+	.cmd_reg      = (uint32_t *) GCC_CE2_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) GCC_CE2_CFG_RCGR,
+	.set_rate     = clock_lib2_rcg_set_rate_hid,
+	.freq_tbl     = ftbl_gcc_ce2_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "ce2_clk_src",
+		.ops      = &clk_ops_rcg,
+	},
+};
+
+static struct vote_clk gcc_ce2_clk = {
+	.cbcr_reg = (uint32_t *) GCC_CE2_CBCR,
+	.vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(2),
+
+	.c = {
+		.dbg_name = "gcc_ce2_clk",
+		.ops = &clk_ops_vote,
+	},
+};
+
+static struct vote_clk gcc_ce2_ahb_clk = {
+	.cbcr_reg = (uint32_t *) GCC_CE2_AHB_CBCR,
+	.vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(0),
+
+	.c = {
+		.dbg_name = "gcc_ce2_ahb_clk",
+		.ops = &clk_ops_vote,
+	},
+};
+
+static struct vote_clk gcc_ce2_axi_clk = {
+	.cbcr_reg = (uint32_t *) GCC_CE2_AXI_CBCR,
+	.vote_reg = (uint32_t *) APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(1),
+
+	.c = {
+		.dbg_name = "gcc_ce2_axi_clk",
+		.ops = &clk_ops_vote,
+	},
+};
 
 /* Clock lookup table */
 static struct clk_lookup msm_clocks_8974[] =
@@ -277,6 +329,11 @@
 
 	CLK_LOOKUP("usb_iface_clk",  gcc_usb_hs_ahb_clk.c),
 	CLK_LOOKUP("usb_core_clk",   gcc_usb_hs_system_clk.c),
+
+	CLK_LOOKUP("ce2_ahb_clk",  gcc_ce2_ahb_clk.c),
+	CLK_LOOKUP("ce2_axi_clk",  gcc_ce2_axi_clk.c),
+	CLK_LOOKUP("ce2_core_clk", gcc_ce2_clk.c),
+	CLK_LOOKUP("ce2_src_clk",  ce2_clk_src.c),
 };
 
 
diff --git a/platform/copper/include/platform/clock.h b/platform/copper/include/platform/clock.h
index 7d59b0c..e2d8ac9 100644
--- a/platform/copper/include/platform/clock.h
+++ b/platform/copper/include/platform/clock.h
@@ -1,29 +1,29 @@
-/*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above copyright
- *     notice, this list of conditions and the following disclaimer in the
- *     documentation and/or other materials provided with the distribution.
- *   * Neither the name of Code Aurora nor
- *     the names of its contributors may be used to endorse or promote
- *     products derived from this software without specific prior written
- *     permission.
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
- * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
- * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
- * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
- * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
- * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
- * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
- * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
- * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
- * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef __COPPER_CLOCK_H
@@ -40,5 +40,6 @@
 void clock_config_mmc(uint32_t interface, uint32_t freq);
 void clock_config_uart_dm(uint8_t id);
 void hsusb_clock_init(void);
+void clock_config_ce(uint8_t instance);
 
 #endif
diff --git a/platform/copper/include/platform/iomap.h b/platform/copper/include/platform/iomap.h
index c26f1b5..a9bf3e7 100644
--- a/platform/copper/include/platform/iomap.h
+++ b/platform/copper/include/platform/iomap.h
@@ -1,17 +1,17 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
-
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *   * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
@@ -76,6 +76,9 @@
 #define MSM_USB_BASE                (PERIPH_SS_BASE + 0x00255000)
 
 #define CLK_CTL_BASE                0xFC400000
+
+#define GCC_WDOG_DEBUG              (CLK_CTL_BASE +  0x00001780)
+
 #define USB_HS_BCR                  (CLK_CTL_BASE + 0x480)
 #define USB_BOOT_CLOCK_CTL          (CLK_CTL_BASE + 0x1A00)
 
@@ -90,6 +93,14 @@
 #define MPM2_MPM_CTRL_BASE          0xFC4A1000
 #define MPM2_MPM_PS_HOLD            0xFC4AB000
 
+/* CE 2 */
+#define  GCC_CE2_BCR                (CLK_CTL_BASE + 0x1080)
+#define  GCC_CE2_CMD_RCGR           (CLK_CTL_BASE + 0x1090)
+#define  GCC_CE2_CFG_RCGR           (CLK_CTL_BASE + 0x1094)
+#define  GCC_CE2_CBCR               (CLK_CTL_BASE + 0x1084)
+#define  GCC_CE2_AXI_CBCR           (CLK_CTL_BASE + 0x1088)
+#define  GCC_CE2_AHB_CBCR           (CLK_CTL_BASE + 0x108C)
+
 /* GPLL */
 #define GPLL0_STATUS                (CLK_CTL_BASE + 0x001C)
 #define APCS_GPLL_ENA_VOTE          (CLK_CTL_BASE + 0x1480)
diff --git a/platform/mdm9x25/acpuclock.c b/platform/mdm9x25/acpuclock.c
index ecf3dfd..a602988 100644
--- a/platform/mdm9x25/acpuclock.c
+++ b/platform/mdm9x25/acpuclock.c
@@ -116,3 +116,26 @@
 		ASSERT(0);
 	}
 }
+
+void clock_config_uart_dm(uint8_t id)
+{
+	int ret;
+	char clk_name[64];
+
+    ret = clk_get_set_enable("uart_iface_clk", 0, 1);
+    if (ret)
+	{
+		dprintf(CRITICAL, "failed to set uart_iface_clk ret = %d\n", ret);
+		ASSERT(0);
+	}
+
+	snprintf(clk_name, 64, "uart%u_core_clk", id);
+
+    ret = clk_get_set_enable(clk_name, 7372800, 1);
+	if (ret)
+	{
+		dprintf(CRITICAL, "failed to set uart%u_core_clk ret = %d\n", id, ret);
+		ASSERT(0);
+	}
+}
+
diff --git a/platform/mdm9x25/gpio.c b/platform/mdm9x25/gpio.c
index 057219e..ed53414 100644
--- a/platform/mdm9x25/gpio.c
+++ b/platform/mdm9x25/gpio.c
@@ -1,32 +1,33 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/*
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above
- *    copyright notice, this list of conditions and the following
- *    disclaimer in the documentation and/or other materials provided
- *    with the distribution.
- *  * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
+ * modification, are permitted provided that the following conditions are met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Linux Foundation nor
+ *     the names of its contributors may be used to endorse or promote
+ *     products derived from this software without specific prior written
+ *     permission.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <reg.h>
+#include <debug.h>
 #include <platform/iomap.h>
 #include <platform/gpio.h>
 
@@ -60,3 +61,21 @@
 {
 	return readl(GPIO_IN_OUT_ADDR(gpio));
 }
+
+void gpio_config_uart_dm(uint8_t id)
+{
+	if (id == 3)
+	{
+		/* configure rx gpio. */
+		gpio_tlmm_config(9, 1, GPIO_INPUT, GPIO_NO_PULL, GPIO_8MA, GPIO_DISABLE);
+
+		/* configure tx gpio. */
+		gpio_tlmm_config(8, 1, GPIO_OUTPUT, GPIO_NO_PULL, GPIO_8MA, GPIO_DISABLE);
+	}
+	else
+	{
+		dprintf(CRITICAL, "GPIO config for UART id = %d not supported.\n", id);
+		ASSERT(0);
+	}
+}
+
diff --git a/platform/mdm9x25/include/platform/clock.h b/platform/mdm9x25/include/platform/clock.h
index 016d646..267ec84 100644
--- a/platform/mdm9x25/include/platform/clock.h
+++ b/platform/mdm9x25/include/platform/clock.h
@@ -29,7 +29,10 @@
 #ifndef __PLATFORM_MDM9625_CLOCK_H
 #define __PLATFORM_MDM9625_CLOCK_H
 
+#define UART_DM_CLK_RX_TX_BIT_RATE 0xCC
+
 void hsusb_clock_init(void);
 void qpic_nand_clock_init(void);
+void clock_config_uart_dm(uint8_t id);
 
 #endif
diff --git a/platform/mdm9x25/include/platform/gpio.h b/platform/mdm9x25/include/platform/gpio.h
index 98c8050..e866efb 100644
--- a/platform/mdm9x25/include/platform/gpio.h
+++ b/platform/mdm9x25/include/platform/gpio.h
@@ -1,29 +1,29 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/*
+ * Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above
- *    copyright notice, this list of conditions and the following
- *    disclaimer in the documentation and/or other materials provided
- *    with the distribution.
- *  * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *    contributors may be used to endorse or promote products derived
- *    from this software without specific prior written permission.
+ * modification, are permitted provided that the following conditions are met:
+ *   * Redistributions of source code must retain the above copyright
+ *     notice, this list of conditions and the following disclaimer.
+ *   * Redistributions in binary form must reproduce the above copyright
+ *     notice, this list of conditions and the following disclaimer in the
+ *     documentation and/or other materials provided with the distribution.
+ *   * Neither the name of Linux Foundation nor
+ *     the names of its contributors may be used to endorse or promote
+ *     products derived from this software without specific prior written
+ *     permission.
  *
- * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
- * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
- * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
- * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
- * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
- * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
- * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
- * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
- * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
- * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
- * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
+ * AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
+ * IMPLIED WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+ * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR
+ * CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL,
+ * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
+ * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS;
+ * OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR
+ * OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF
+ * ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #ifndef __PLATFORM_MDM9625_GPIO_H
@@ -61,5 +61,6 @@
 					  uint32_t enable);
 uint32_t gpio_get_state(uint32_t gpio);
 void gpio_set(uint32_t gpio, uint32_t dir);
+void gpio_config_uart_dm(uint8_t id);
 
 #endif
diff --git a/platform/mdm9x25/include/platform/iomap.h b/platform/mdm9x25/include/platform/iomap.h
index d227057..350cae3 100644
--- a/platform/mdm9x25/include/platform/iomap.h
+++ b/platform/mdm9x25/include/platform/iomap.h
@@ -29,11 +29,14 @@
 #ifndef _PLATFORM_MDM9625_IOMAP_H_
 #define _PLATFORM_MDM9625_IOMAP_H_
 
-/*SDRAM start address */
-#define SDRAM_START_ADDR          0x0
+#define MSM_IOMAP_BASE            0xF9000000
+#define MSM_IOMAP_END             0xFEFFFFFF
 
 #define MSM_SHARED_BASE           0x00000000
 
+/*SDRAM start address */
+#define SDRAM_START_ADDR          0x00000000
+
 #define MSM_SHARED_IMEM_BASE      0xFC42B000
 #define RESTART_REASON_ADDR       (MSM_SHARED_IMEM_BASE + 0x65C)
 
@@ -65,6 +68,9 @@
 /* USB */
 #define MSM_USB_BASE              (PERIPH_SS_BASE + 0x00255000)
 
+/* UART */
+#define MSM_UART2_BASE             0xF991F000
+
 /* NAND */
 #define MSM_NAND_BASE              0xF9AF0000
 /* NAND BAM */
@@ -77,6 +83,9 @@
 #define APCS_GPLL_ENA_VOTE                   (CLK_CTL_BASE + 0x1480)
 
 /* UART */
+
+#define BLSP1_AHB_CBCR                       (CLK_CTL_BASE + 0x5C4)
+
 #define BLSP1_UART1_APPS_CBCR                (CLK_CTL_BASE + 0x684)
 #define BLSP1_UART1_APPS_CMD_RCGR            (CLK_CTL_BASE + 0x68C)
 #define BLSP1_UART1_APPS_CFG_RCGR            (CLK_CTL_BASE + 0x690)
@@ -91,6 +100,15 @@
 #define BLSP1_UART3_APPS_N                   (CLK_CTL_BASE + 0x798)
 #define BLSP1_UART3_APPS_D                   (CLK_CTL_BASE + 0x79C)
 
+#define BLSP1_UART2_APPS_CBCR                (CLK_CTL_BASE + 0x704)
+#define BLSP1_UART2_APPS_CMD_RCGR            (CLK_CTL_BASE + 0x70C)
+#define BLSP1_UART2_APPS_CFG_RCGR            (CLK_CTL_BASE + 0x710)
+#define BLSP1_UART2_APPS_M                   (CLK_CTL_BASE + 0x714)
+#define BLSP1_UART2_APPS_N                   (CLK_CTL_BASE + 0x718)
+#define BLSP1_UART2_APPS_D                   (CLK_CTL_BASE + 0x71C)
+
+#define APCS_CLOCK_BRANCH_ENA_VOTE           (CLK_CTL_BASE + 0x1484)
+
 /* USB */
 #define USB_HS_BCR                           (CLK_CTL_BASE + 0x480)
 #define USB_HS_SYSTEM_CBCR                   (CLK_CTL_BASE + 0x484)
diff --git a/platform/mdm9x25/mdm9x25-clock.c b/platform/mdm9x25/mdm9x25-clock.c
index 2f25376..d5f4ab3 100644
--- a/platform/mdm9x25/mdm9x25-clock.c
+++ b/platform/mdm9x25/mdm9x25-clock.c
@@ -77,6 +77,11 @@
 	.is_enabled = pll_vote_clk_is_enabled,
 };
 
+static struct clk_ops clk_ops_vote =
+{
+	.enable     = clock_lib2_vote_clk_enable,
+	.disable    = clock_lib2_vote_clk_disable,
+};
 
 /* Clock Sources */
 static struct fixed_clk cxo_clk_src =
@@ -104,6 +109,18 @@
 };
 
 /* UART Clocks */
+
+static struct vote_clk gcc_blsp1_ahb_clk = {
+	.cbcr_reg = BLSP1_AHB_CBCR,
+	.vote_reg = APCS_CLOCK_BRANCH_ENA_VOTE,
+	.en_mask = BIT(17),
+
+	.c = {
+		.dbg_name = "gcc_blsp1_ahb_clk",
+		.ops = &clk_ops_vote,
+	},
+};
+
 static struct clk_freq_tbl ftbl_gcc_blsp1_2_uart1_6_apps_clk[] =
 {
 	F( 3686400,  gpll0,    1,  96,  15625),
@@ -141,6 +158,24 @@
 	},
 };
 
+static struct rcg_clk blsp1_uart2_apps_clk_src =
+{
+	.cmd_reg      = (uint32_t *) BLSP1_UART2_APPS_CMD_RCGR,
+	.cfg_reg      = (uint32_t *) BLSP1_UART2_APPS_CFG_RCGR,
+	.m_reg        = (uint32_t *) BLSP1_UART2_APPS_M,
+	.n_reg        = (uint32_t *) BLSP1_UART2_APPS_N,
+	.d_reg        = (uint32_t *) BLSP1_UART2_APPS_D,
+
+	.set_rate     = clock_lib2_rcg_set_rate_mnd,
+	.freq_tbl     = ftbl_gcc_blsp1_2_uart1_6_apps_clk,
+	.current_freq = &rcg_dummy_freq,
+
+	.c = {
+		.dbg_name = "blsp1_uart2_apps_clk",
+		.ops      = &clk_ops_rcg_mnd,
+	},
+};
+
 static struct rcg_clk blsp1_uart3_apps_clk_src =
 {
 	.cmd_reg      = (uint32_t *) BLSP1_UART3_APPS_CMD_RCGR,
@@ -170,6 +205,17 @@
 	},
 };
 
+static struct branch_clk gcc_blsp1_uart2_apps_clk =
+{
+	.cbcr_reg     = (uint32_t *) BLSP1_UART2_APPS_CBCR,
+	.parent       = &blsp1_uart2_apps_clk_src.c,
+
+	.c = {
+		.dbg_name = "gcc_blsp1_uart2_apps_clk",
+		.ops      = &clk_ops_branch,
+	},
+};
+
 static struct branch_clk gcc_blsp1_uart3_apps_clk =
 {
 	.cbcr_reg     = (uint32_t *) BLSP1_UART3_APPS_CBCR,
@@ -272,7 +318,9 @@
 /* Clock lookup table */
 static struct clk_lookup mdm_9625_clocks[] =
 {
+	CLK_LOOKUP("uart_iface_clk", gcc_blsp1_ahb_clk.c),
 	CLK_LOOKUP("uart1_core_clk", gcc_blsp1_uart1_apps_clk.c),
+	CLK_LOOKUP("uart2_core_clk", gcc_blsp1_uart2_apps_clk.c),
 	CLK_LOOKUP("uart3_core_clk", gcc_blsp1_uart3_apps_clk.c),
 
 	CLK_LOOKUP("usb_iface_clk",  gcc_usb_hs_ahb_clk.c),
diff --git a/platform/mdm9x25/platform.c b/platform/mdm9x25/platform.c
index 0b38493..0c7d280 100644
--- a/platform/mdm9x25/platform.c
+++ b/platform/mdm9x25/platform.c
@@ -32,6 +32,51 @@
 #include <qtimer.h>
 #include <board.h>
 #include <qpic_nand.h>
+#include <mmu.h>
+#include <arch/arm/mmu.h>
+#include <platform/iomap.h>
+#include <target.h>
+#include <smem.h>
+#include <reg.h>
+
+extern struct smem_ram_ptable* target_smem_ram_ptable_init();
+
+#define MB                                  (1024*1024)
+
+#define MSM_IOMAP_SIZE                      ((MSM_IOMAP_END - MSM_IOMAP_BASE)/MB)
+
+/* LK memory - Strongly ordered, executable */
+#define LK_MEMORY                             (MMU_MEMORY_TYPE_STRONGLY_ORDERED | \
+                                              MMU_MEMORY_AP_READ_WRITE)
+/* Scratch memory - Strongly ordered, non-executable */
+#define SCRATCH_MEMORY                        (MMU_MEMORY_TYPE_STRONGLY_ORDERED | \
+                                              MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
+/* Peripherals - shared device */
+#define IOMAP_MEMORY                          (MMU_MEMORY_TYPE_DEVICE_SHARED | \
+                                              MMU_MEMORY_AP_READ_WRITE | MMU_MEMORY_XN)
+
+#define SCRATCH_REGION1_VIRT_START            (MEMBASE + MEMSIZE)
+#define SCRATCH_REGION2_VIRT_START            (SCRATCH_REGION1_VIRT_START + \
+                                              (SCRATCH_REGION1_SIZE))
+
+#define SDRAM_BANK0_LAST_FIXED_ADDR           (SCRATCH_REGION2 + SCRATCH_REGION2_SIZE)
+
+/* Map all the accesssible memory according to the following rules:
+ * 1. Map 1MB from MSM_SHARED_BASE with 1 -1 mapping.
+ * 2. Map MEMBASE - MEMSIZE with 1 -1 mapping.
+ * 3. Map all the scratch regions immediately after Appsbl memory.
+ *     Virtual addresses start right after Appsbl Virtual address.
+ * 4. Map all the IOMAP space with 1 - 1 mapping.
+ * 5. Map all the rest of the SDRAM/ IMEM regions as 1 -1.
+ */
+mmu_section_t mmu_section_table[] = {
+/*   Physical addr,         Virtual addr,               Size (in MB),              Flags   */
+	{MSM_SHARED_BASE,       MSM_SHARED_BASE,            1,                         SCRATCH_MEMORY},
+	{MEMBASE,               MEMBASE,                    MEMSIZE / MB,              LK_MEMORY},
+	{SCRATCH_REGION1,       SCRATCH_REGION1_VIRT_START, SCRATCH_REGION1_SIZE / MB, SCRATCH_MEMORY},
+	{SCRATCH_REGION2,       SCRATCH_REGION2_VIRT_START, SCRATCH_REGION2_SIZE / MB, SCRATCH_MEMORY},
+	{MSM_IOMAP_BASE,        MSM_IOMAP_BASE,             MSM_IOMAP_SIZE,            IOMAP_MEMORY},
+};
 
 void platform_early_init(void)
 {
@@ -58,3 +103,111 @@
 	qtimer_uninit();
 	qpic_nand_uninit();
 }
+
+void platform_init_mmu_mappings(void)
+{
+	struct smem_ram_ptable *ram_ptable;
+	uint32_t i;
+	uint32_t sections;
+	uint32_t table_size = ARRAY_SIZE(mmu_section_table);
+	uint32_t last_fixed_addr = SDRAM_BANK0_LAST_FIXED_ADDR;
+
+	ram_ptable = target_smem_ram_ptable_init();
+
+	/* Configure the MMU page entries for SDRAM and IMEM memory read
+	   from the smem ram table*/
+	for(i = 0; i < ram_ptable->len; i++)
+	{
+		if((ram_ptable->parts[i].category == IMEM) || (ram_ptable->parts[i].category == SDRAM))
+		{
+			/* First bank info is added according to the static table - mmu_section_table. */
+			if((ram_ptable->parts[i].start <= last_fixed_addr) &&
+			   ((ram_ptable->parts[i].start + ram_ptable->parts[i].size) >= last_fixed_addr))
+					continue;
+
+			/* Check to ensure that start address is 1MB aligned */
+			ASSERT((ram_ptable->parts[i].start & 0xFFFFF) == 0);
+
+			sections = (ram_ptable->parts[i].size) / MB;
+
+			while(sections--)
+			{
+				arm_mmu_map_section(ram_ptable->parts[i].start + sections * MB,
+									ram_ptable->parts[i].start + sections * MB,
+									SCRATCH_MEMORY);
+			}
+		}
+    }
+
+	/* Configure the MMU page entries for memory read from the
+	   mmu_section_table */
+	for (i = 0; i < table_size; i++)
+	{
+		sections = mmu_section_table[i].num_of_sections;
+
+		while (sections--)
+		{
+			arm_mmu_map_section(mmu_section_table[i].paddress + sections * MB,
+								mmu_section_table[i].vaddress + sections * MB,
+								mmu_section_table[i].flags);
+		}
+	}
+}
+
+addr_t platform_get_virt_to_phys_mapping(addr_t virt_addr)
+{
+	uint32_t paddr;
+	uint32_t table_size = ARRAY_SIZE(mmu_section_table);
+	uint32_t limit;
+
+	for (uint32_t i = 0; i < table_size; i++)
+	{
+		limit = (mmu_section_table[i].num_of_sections * MB) - 0x1;
+
+		if (virt_addr >= mmu_section_table[i].vaddress &&
+			virt_addr <= (mmu_section_table[i].vaddress + limit))
+		{
+				paddr = mmu_section_table[i].paddress + (virt_addr - mmu_section_table[i].vaddress);
+				return paddr;
+		}
+	}
+	/* No special mapping found.
+	 * Assume 1-1 mapping.
+	 */
+	 paddr = virt_addr;
+
+	return paddr;
+}
+
+addr_t platform_get_phys_to_virt_mapping(addr_t phys_addr)
+{
+	uint32_t vaddr;
+	uint32_t table_size = ARRAY_SIZE(mmu_section_table);
+	uint32_t limit;
+
+	for (uint32_t i = 0; i < table_size; i++)
+	{
+		limit = (mmu_section_table[i].num_of_sections * MB) - 0x1;
+
+		if (phys_addr >= mmu_section_table[i].paddress &&
+			phys_addr <= (mmu_section_table[i].paddress + limit))
+		{
+				vaddr = mmu_section_table[i].vaddress + (phys_addr - mmu_section_table[i].paddress);
+				return vaddr;
+		}
+	}
+
+	/* No special mapping found.
+	 * Assume 1-1 mapping.
+	 */
+	 vaddr = phys_addr;
+
+	return vaddr;
+}
+
+/* Do not use default identitiy mappings. */
+int platform_use_identity_mmu_mappings(void)
+{
+	return 0;
+}
+
diff --git a/platform/msm_shared/bam.c b/platform/msm_shared/bam.c
index 0903c9d..cb6fc4c 100644
--- a/platform/msm_shared/bam.c
+++ b/platform/msm_shared/bam.c
@@ -1,17 +1,17 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
-
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *   * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
@@ -30,6 +30,7 @@
 #include <reg.h>
 #include <debug.h>
 #include <stdlib.h>
+#include <platform.h>
 #include <platform/interrupts.h>
 #include <platform/iomap.h>
 #include <platform/irqs.h>
@@ -83,7 +84,7 @@
 		/* Wait for a interrupt on the right pipe */
 		do{
 			/* Determine the pipe causing the interrupt */
-			val = readl(BAM_IRQ_SRCS(bam->base));
+			val = readl(BAM_IRQ_SRCS(bam->base, bam->ee));
 			/* Flush out the right most global interrupt bit */
 		} while (!((val & 0x7FFF) & (1 << bam->pipe[pipe_num].pipe_num)));
 
@@ -140,9 +141,9 @@
 
 	/* Enable pipe interrups */
 	/* Do read-modify-write */
-	val = readl(BAM_IRQ_SRCS_MSK(bam->base));
+	val = readl(BAM_IRQ_SRCS_MSK(bam->base, bam->ee));
 	writel((1 << bam->pipe[pipe_num].pipe_num) | val,
-			BAM_IRQ_SRCS_MSK(bam->base));
+			BAM_IRQ_SRCS_MSK(bam->base, bam->ee));
 
 	/* Unmask the QGIC interrupts only in the case of
 	 * interrupt based transfer.
@@ -192,7 +193,6 @@
 int bam_pipe_fifo_init(struct bam_instance *bam,
                        uint8_t pipe_num)
 {
-
 	if (bam->pipe[pipe_num].fifo.size > 0x7FFF)
 	{
 		dprintf(CRITICAL,
@@ -201,7 +201,7 @@
 	}
 
 	/* Check if fifo start is 8-byte alligned */
-	ASSERT(!((uint32_t)bam->pipe[pipe_num].fifo.head & 0x7));
+	ASSERT(!((uint32_t)PA((addr_t)bam->pipe[pipe_num].fifo.head & 0x7)));
 
 	/* Check if fifo size is a power of 2.
 	 * The circular fifo logic in lk expects this.
@@ -215,7 +215,10 @@
 		BAM_P_FIFO_SIZESn(bam->pipe[pipe_num].pipe_num, bam->base));
 
 	/* Write descriptors FIFO base addr must be 8-byte aligned */
-	writel((uint32_t)bam->pipe[pipe_num].fifo.head,
+	/* Needs a physical address conversion as we are setting up
+	 * the base of the FIFO for the BAM state machine.
+	 */
+	writel((uint32_t)PA((addr_t)bam->pipe[pipe_num].fifo.head),
 		BAM_P_DESC_FIFO_ADDRn(bam->pipe[pipe_num].pipe_num, bam->base));
 
 	/* Initialize FIFO offset for the first read */
@@ -232,8 +235,6 @@
 void bam_sys_pipe_init(struct bam_instance *bam,
                        uint8_t pipe_num)
 {
-	uint32_t val = 0;
-
 	/* Reset the pipe to be allocated */
 	bam_pipe_reset(bam, pipe_num);
 
@@ -291,7 +292,7 @@
 	offset = readl(BAM_P_SW_OFSTSn(bam->pipe[pipe_num].pipe_num, bam->base));
 	offset &= 0xFFFF;
 
-	dprintf(INFO, "Offset value is %d \n", offset);
+	dprintf(SPEW, "Offset value is %d \n", offset);
 
 	/* Save the next offset to be written to. */
 		bam->pipe[pipe_num].fifo.current = (struct bam_desc*)
@@ -337,7 +338,7 @@
 	unsigned int n = 0;
 	unsigned int desc_flags;
 
-	dprintf(INFO, "Data length for BAM transfer is %u\n", data_len);
+	dprintf(SPEW, "Data length for BAM transfer is %u\n", data_len);
 
 	if (data_ptr == NULL || len == 0)
 	{
@@ -347,7 +348,7 @@
 	}
 
 	/* Check if we have enough space in FIFO */
-	if (len > (unsigned)bam->pipe[pipe_num].fifo.size * BAM_MAX_DESC_DATA_LEN)
+	if (len > (unsigned)bam->pipe[pipe_num].fifo.size * bam->max_desc_len)
 	{
 		dprintf(CRITICAL, "Data transfer exceeds desc fifo length.\n");
 		bam_ret = BAM_RESULT_FAILURE;
@@ -361,10 +362,10 @@
 		 * If more bits are needed, create more
 		 * descriptors.
 		 */
-		if (len > BAM_MAX_DESC_DATA_LEN)
+		if (len > bam->max_desc_len)
 		{
-			desc_len = BAM_MAX_DESC_DATA_LEN;
-			len -= BAM_MAX_DESC_DATA_LEN;
+			desc_len = bam->max_desc_len;
+			len -= bam->max_desc_len;
 			desc_flags = 0;
 		}
 		else
@@ -378,7 +379,7 @@
 		/* Write descriptor */
 		bam_add_one_desc(bam, pipe_num, data_ptr, desc_len, desc_flags);
 
-		data_ptr += BAM_MAX_DESC_DATA_LEN;
+		data_ptr += bam->max_desc_len;
 		n++;
 	}
 
@@ -441,10 +442,10 @@
 	}
 
 	/* Check for the length of the desc. */
-	if (len > BAM_MAX_DESC_DATA_LEN)
+	if (len > bam->max_desc_len)
 	{
 		dprintf(CRITICAL, "len of the desc exceeds max length"
-				" %d > %d\n", len, BAM_MAX_DESC_DATA_LEN);
+				" %d > %d\n", len, bam->max_desc_len);
 		bam_ret = BAM_RESULT_FAILURE;
 		goto bam_add_one_desc_error;
 	}
diff --git a/platform/msm_shared/hsusb.c b/platform/msm_shared/hsusb.c
index d8643f0..9dcc550 100644
--- a/platform/msm_shared/hsusb.c
+++ b/platform/msm_shared/hsusb.c
@@ -2,35 +2,38 @@
  * Copyright (c) 2008, Google Inc.
  * All rights reserved.
  *
- * Copyright (c) 2009-2012, Code Aurora Forum. All rights reserved.
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <string.h>
 #include <stdlib.h>
 #include <debug.h>
+#include <platform.h>
 #include <platform/iomap.h>
 #include <platform/irqs.h>
 #include <platform/interrupts.h>
@@ -281,7 +284,7 @@
 					  sizeof(struct ept_queue_head));
 	arch_clean_invalidate_cache_range((addr_t) ept->req,
 					  sizeof(struct usb_request));
-	arch_clean_invalidate_cache_range((addr_t) req->req.buf,
+	arch_clean_invalidate_cache_range((addr_t) VA(req->req.buf),
 					  req->req.length);
 	arch_clean_invalidate_cache_range((addr_t) ept->req->item,
 					  sizeof(struct ept_queue_item));
@@ -328,7 +331,7 @@
 		}
 		while (readl(&(item->info)) & INFO_ACTIVE);
 
-		arch_clean_invalidate_cache_range((addr_t) req->req.buf,
+		arch_clean_invalidate_cache_range(VA((addr_t) req->req.buf),
 						  req->req.length);
 
 		if (item->info & 0xff) {
@@ -423,6 +426,7 @@
 {
 	DBG("setup_tx %p %d\n", buf, len);
 	memcpy(ep0req->buf, buf, len);
+	ep0req->buf = PA((addr_t)ep0req->buf);
 	ep0req->complete = ep0in_complete;
 	ep0req->length = len;
 	udc_request_queue(ep0in, ep0req);
@@ -597,7 +601,7 @@
 	arch_clean_invalidate_cache_range((addr_t) epts,
 					  32 * sizeof(struct ept_queue_head));
 
-	writel((unsigned)epts, USB_ENDPOINTLISTADDR);
+	writel((unsigned)PA((addr_t)epts), USB_ENDPOINTLISTADDR);
 
 	/* select DEVICE mode */
 	writel(0x02, USB_USBMODE);
diff --git a/platform/msm_shared/include/bam.h b/platform/msm_shared/include/bam.h
index d06f7cd..84f9fb4 100644
--- a/platform/msm_shared/include/bam.h
+++ b/platform/msm_shared/include/bam.h
@@ -1,17 +1,17 @@
-/* Copyright (c) 2012, Code Aurora Forum. All rights reserved.
-
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
+ *
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions are
  * met:
- *   * Redistributions of source code must retain the above copyright
- *     notice, this list of conditions and the following disclaimer.
- *   * Redistributions in binary form must reproduce the above
- *     copyright notice, this list of conditions and the following
- *     disclaimer in the documentation and/or other materials provided
- *     with the distribution.
- *   * Neither the name of Code Aurora Forum, Inc. nor the names of its
- *     contributors may be used to endorse or promote products derived
- *     from this software without specific prior written permission.
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
  *
  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
@@ -44,8 +44,8 @@
 
 #define BAM_DESC_CNT_TRSHLD_REG(x)      (0x0008 + (x))
 #define COUNT_TRESHOLD_MASK             0xFF
-#define BAM_IRQ_SRCS(x)                 (0x0000000C + (x))
-#define BAM_IRQ_SRCS_MSK(x)             (0x00000010 + (x))
+#define BAM_IRQ_SRCS(x, n)                 (0x00000800 + (0x80 * (n)) + (x))
+#define BAM_IRQ_SRCS_MSK(x, n)             (0x00000804 + (0x80 * (n)) + (x))
 #define BAM_IRQ_MASK                    (1 << 31)
 #define P_IRQ_MASK                      (1)
 
@@ -206,7 +206,8 @@
  * pipe_pair:The pipe pairs to be used to access the BAM.
  * threshold:This Register holds a threshold value for the
  *           counter summing the Size of the Descriptors Provided.
- * init:Pipe initialization status for the BAM.
+ * ee:Execution Environment for the BAM.
+ * desc_len: Max desc length for the current BAM.
  */
 struct bam_instance {
 	uint32_t base;
@@ -215,6 +216,8 @@
 	uint8_t num_of_pipes;
 	struct bam_pipe pipe[3];
 	uint16_t threshold;
+	uint32_t ee;
+	uint16_t max_desc_len;
 	void (*callback)(int);
 };
 
diff --git a/platform/msm_shared/include/baseband.h b/platform/msm_shared/include/baseband.h
index 80f144a..eb4cc22 100644
--- a/platform/msm_shared/include/baseband.h
+++ b/platform/msm_shared/include/baseband.h
@@ -37,6 +37,7 @@
 	BASEBAND_SVLTE2A = 4,
 	BASEBAND_MDM = 5,
 	BASEBAND_SGLTE = 6,
+	BASEBAND_DSDA = 7,
 	BASEBAND_32BITS = 0x7FFFFFFF
 };
 
diff --git a/platform/msm_shared/include/qpic_nand.h b/platform/msm_shared/include/qpic_nand.h
index e64c20b..d807f04 100644
--- a/platform/msm_shared/include/qpic_nand.h
+++ b/platform/msm_shared/include/qpic_nand.h
@@ -84,9 +84,11 @@
 #define NAND_DEV_CMD6                                      NAND_REG(0x00DC)
 #define NAND_SFLASHC_BURST_CFG                             NAND_REG(0x00E0)
 #define NAND_ADDR6                                         NAND_REG(0x00E4)
+#define NAND_ERASED_CW_DETECT_CFG                          NAND_REG(0x00E8)
+#define NAND_ERASED_CW_DETECT_STATUS                       NAND_REG(0x00EC)
 #define NAND_EBI2_ECC_BUF_CFG                              NAND_REG(0x00F0)
-#define NAND_FLASH_BUFFER                                  NAND_REG(0x0100)
 #define NAND_HW_INFO                                       NAND_REG(0x00FC)
+#define NAND_FLASH_BUFFER                                  NAND_REG(0x0100)
 
 /* NANDc registers used during BAM transfer */
 #define NAND_READ_LOCATION_n(n)                            (NAND_REG(0xF20) + 4 * (n))
@@ -115,6 +117,15 @@
 #define NAND_DEV0_ECC_NUM_DATA_BYTES                       16
 #define NAND_DEV0_ECC_FORCE_CLK_OPEN_SHIFT                 30
 
+#define NAND_ERASED_CW_DETECT_STATUS_PAGE_ALL_ERASED       7
+#define NAND_ERASED_CW_DETECT_STATUS_CODEWORD_ALL_ERASED   6
+#define NAND_ERASED_CW_DETECT_STATUS_CODEWORD_ERASED       4
+
+#define NAND_ERASED_CW_DETECT_CFG_RESET_CTRL               1
+#define NAND_ERASED_CW_DETECT_CFG_ACTIVATE_CTRL            0
+#define NAND_ERASED_CW_DETECT_ERASED_CW_ECC_MASK           (1 << 1)
+#define NAND_ERASED_CW_DETECT_ERASED_CW_ECC_NO_MASK        (0 << 1)
+
 /* device commands */
 #define NAND_CMD_SOFT_RESET                                0x01
 #define NAND_CMD_PAGE_READ                                 0x32
@@ -135,13 +146,8 @@
 #define NAND_FLASH_OP_ERR                                  (1 << 4)
 
 #define NAND_FLASH_ERR                                     (NAND_FLASH_MPU_ERR | \
-                                                           NAND_FLASH_TIMEOUT_ERR)
-/* TODO: Add the check for operation error: NAND_FLASH_OP_ERR
- * This bit is also flagged for MPU errors, which is set for
- * blank page reads.
- * Also need to add a detect an empty page.
- */
-
+                                                           NAND_FLASH_TIMEOUT_ERR | \
+                                                           NAND_FLASH_OP_ERR)
 
 #define PROG_ERASE_OP_RESULT                               (1 << 7)
 
@@ -324,6 +330,8 @@
 {
 	uint32_t nand_base;
 	uint32_t bam_base;
+	uint32_t ee;
+	uint32_t max_desc_len;
 	struct qpic_nand_bam_pipes pipes;
 };
 
diff --git a/platform/msm_shared/nand.c b/platform/msm_shared/nand.c
index 08b68dd..fae7fbb 100644
--- a/platform/msm_shared/nand.c
+++ b/platform/msm_shared/nand.c
@@ -1,8 +1,7 @@
 /*
  * Copyright (c) 2008, Google Inc.
  * All rights reserved.
- * Copyright (c) 2009-2011, Code Aurora Forum. All rights reserved.
- *
+ * Copyright (c) 2009-2012, The Linux Foundation. All rights reserved.
  * Redistribution and use in source and binary forms, with or without
  * modification, are permitted provided that the following conditions
  * are met:
@@ -3165,6 +3164,7 @@
 {
 	int dev_found = 0;
 	unsigned index;
+	uint32_t hwinfo;
 
 	// Try to read id
 	flash_nand_read_id(cmdlist, ptrlist);
@@ -3217,8 +3217,11 @@
 		// Use this for getting the next/current blocks
 		num_pages_per_blk = flash_info.block_size / flash_pagesize;
 		num_pages_per_blk_mask = num_pages_per_blk - 1;
+
+		hwinfo = flash_ctrl_hwinfo(cmdlist, ptrlist);
+
 		//Look for 8bit BCH ECC Nand, TODO: ECC Correctability >= 8
-		if ((flash_ctrl_hwinfo(cmdlist, ptrlist) == 0x307)
+		if (((hwinfo == 0x307) || (hwinfo == 0x4030))
 		    && flash_info.id == 0x2600482c) {
 			enable_bch_ecc = 1;
 		}
diff --git a/platform/msm_shared/qpic_nand.c b/platform/msm_shared/qpic_nand.c
index fd9c388..fb14720 100644
--- a/platform/msm_shared/qpic_nand.c
+++ b/platform/msm_shared/qpic_nand.c
@@ -34,6 +34,7 @@
 #include <string.h>
 #include <malloc.h>
 #include <sys/types.h>
+#include <platform.h>
 #include <platform/clock.h>
 
 static uint32_t nand_base;
@@ -57,6 +58,8 @@
 static struct bam_instance bam;
 static uint8_t *bbtbl;
 
+static uint8_t* rdwr_buf;
+
 static struct flash_id supported_flash[] = {
 	/* Flash ID     ID Mask Density(MB)  Wid Pgsz   Blksz   oobsz onenand   Manuf */
 	{0x1590aa2c, 0xFFFFFFFF, (256 << 20), 0, 2048, (2048 << 6), 64, 0, 0},	/*Micr */
@@ -64,22 +67,6 @@
 	/* Note: Onenand flag is 0 for NAND Flash and 1 for OneNAND flash       */
 };
 
-static nand_result_t
-qpic_nand_check_status(uint32_t status)
-{
-	/* Check for errors */
-	if (status & NAND_FLASH_ERR)
-	{
-		dprintf(CRITICAL, "Nand Flash error for Fetch id cmd. Status = %d\n",
-					status);
-		if (status & NAND_FLASH_TIMEOUT_ERR)
-			return NANDC_RESULT_TIMEOUT;
-		else
-			return NANDC_RESULT_FAILURE;
-	}
-	return NANDC_RESULT_SUCCESS;
-}
-
 static void
 qpic_nand_wait_for_cmd_exec(uint32_t num_desc)
 {
@@ -110,12 +97,12 @@
 {
 	uint32_t val;
 
-	bam_add_cmd_element(cmd_list_ptr, reg_addr,	(uint32_t)&val, CE_READ_TYPE);
+	bam_add_cmd_element(cmd_list_ptr, reg_addr, (uint32_t)PA((addr_t)&val), CE_READ_TYPE);
 
 	/* Enqueue the desc for the above command */
 	bam_add_one_desc(&bam,
 					 CMD_PIPE_INDEX,
-					 (unsigned char*)cmd_list_ptr,
+					 (unsigned char*)PA((addr_t)cmd_list_ptr),
 					 BAM_CE_SIZE,
 					 BAM_DESC_CMD_FLAG| BAM_DESC_INT_FLAG | flags);
 
@@ -124,6 +111,81 @@
 	return val;
 }
 
+/* Assume the BAM is in a locked state. */
+void
+qpic_nand_erased_status_reset(struct cmd_element *cmd_list_ptr)
+{
+	uint32_t val = 0;
+
+	/* Reset the Erased Codeword/Page detection controller. */
+	val = NAND_ERASED_CW_DETECT_CFG_RESET_CTRL;
+
+	bam_add_cmd_element(cmd_list_ptr, NAND_ERASED_CW_DETECT_CFG, val, CE_WRITE_TYPE);
+
+	/* Enqueue the desc for the above command */
+	bam_add_one_desc(&bam,
+					 CMD_PIPE_INDEX,
+					 (unsigned char*)cmd_list_ptr,
+					 BAM_CE_SIZE,
+					 BAM_DESC_CMD_FLAG | BAM_DESC_INT_FLAG);
+
+	qpic_nand_wait_for_cmd_exec(1);
+
+	/* Enable the Erased Codeword/Page detection
+	 * controller to check the data as it arrives.
+	 * Also disable ECC reporting for an erased CW.
+	 */
+	val = NAND_ERASED_CW_DETECT_CFG_ACTIVATE_CTRL | NAND_ERASED_CW_DETECT_ERASED_CW_ECC_MASK;
+
+	bam_add_cmd_element(cmd_list_ptr, NAND_ERASED_CW_DETECT_CFG, val, CE_WRITE_TYPE);
+
+	/* Enqueue the desc for the above command */
+	bam_add_one_desc(&bam,
+					 CMD_PIPE_INDEX,
+					 (unsigned char*)cmd_list_ptr,
+					 BAM_CE_SIZE,
+					 BAM_DESC_CMD_FLAG | BAM_DESC_INT_FLAG);
+
+	qpic_nand_wait_for_cmd_exec(1);
+}
+
+static nand_result_t
+qpic_nand_check_status(uint32_t status)
+{
+	uint32_t erase_sts;
+
+	/* Check for errors */
+	if (status & NAND_FLASH_ERR)
+	{
+		/* Check if this is an ECC error on an erased page. */
+		if (status & NAND_FLASH_OP_ERR)
+		{
+			erase_sts = qpic_nand_read_reg(NAND_ERASED_CW_DETECT_STATUS, 0, ce_array);
+			if ((erase_sts & (1 << NAND_ERASED_CW_DETECT_STATUS_PAGE_ALL_ERASED)))
+			{
+				/* Mask the OP ERROR. */
+				status &= ~NAND_FLASH_OP_ERR;
+				qpic_nand_erased_status_reset(ce_array);
+			}
+		}
+
+		/* ECC error flagged on an erased page read.
+		 * Ignore and return success.
+		 */
+		if (!(status & NAND_FLASH_ERR))
+			return NANDC_RESULT_SUCCESS;
+
+		dprintf(CRITICAL, "Nand Flash error. Status = %d\n", status);
+
+		if (status & NAND_FLASH_TIMEOUT_ERR)
+			return NANDC_RESULT_TIMEOUT;
+		else
+			return NANDC_RESULT_FAILURE;
+	}
+
+	return NANDC_RESULT_SUCCESS;
+}
+
 static uint32_t
 qpic_nand_fetch_id(struct flash_info *flash)
 {
@@ -148,7 +210,7 @@
 	bam_add_one_desc(&bam,
 					 CMD_PIPE_INDEX,
 					 (unsigned char*)cmd_list_ptr_start,
-					 (uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start,
+					 PA((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start),
 					 BAM_DESC_LOCK_FLAG | BAM_DESC_INT_FLAG |
 					 BAM_DESC_NWD_FLAG | BAM_DESC_CMD_FLAG);
 
@@ -186,27 +248,27 @@
 }
 
 static int
-qpic_bam_init(uint32_t bam_base, struct qpic_nand_bam_pipes *pipes)
+qpic_bam_init(struct qpic_nand_init_config *config)
 {
 	uint32_t bam_ret = NANDC_RESULT_SUCCESS;
 
-	bam.base = bam_base;
+	bam.base = config->bam_base;
 	/* Set Read pipe params. */
-	bam.pipe[DATA_PRODUCER_PIPE_INDEX].pipe_num = pipes->read_pipe;
+	bam.pipe[DATA_PRODUCER_PIPE_INDEX].pipe_num = config->pipes.read_pipe;
 	/* System consumer */
 	bam.pipe[DATA_PRODUCER_PIPE_INDEX].trans_type = BAM2SYS;
 	bam.pipe[DATA_PRODUCER_PIPE_INDEX].fifo.size = QPIC_BAM_DATA_FIFO_SIZE;
 	bam.pipe[DATA_PRODUCER_PIPE_INDEX].fifo.head = data_desc_fifo;
 
 	/* Set Write pipe params. */
-	bam.pipe[DATA_CONSUMER_PIPE_INDEX].pipe_num = pipes->write_pipe;
+	bam.pipe[DATA_CONSUMER_PIPE_INDEX].pipe_num = config->pipes.write_pipe;
 	/* System producer */
 	bam.pipe[DATA_CONSUMER_PIPE_INDEX].trans_type = SYS2BAM;
 	bam.pipe[DATA_CONSUMER_PIPE_INDEX].fifo.size = QPIC_BAM_DATA_FIFO_SIZE;
 	bam.pipe[DATA_CONSUMER_PIPE_INDEX].fifo.head = data_desc_fifo;
 
 	/* Set Cmd pipe params. */
-	bam.pipe[CMD_PIPE_INDEX].pipe_num = pipes->cmd_pipe;
+	bam.pipe[CMD_PIPE_INDEX].pipe_num = config->pipes.cmd_pipe;
 	/* System consumer */
 	bam.pipe[CMD_PIPE_INDEX].trans_type = BAM2SYS;
 	bam.pipe[CMD_PIPE_INDEX].fifo.size = QPIC_BAM_CMD_FIFO_SIZE;
@@ -223,6 +285,12 @@
 	*/
 	bam.threshold = 32;
 
+	/* Set the EE.  */
+	bam.ee = config->ee;
+
+	/* Set the max desc length for this BAM. */
+	bam.max_desc_len = config->max_desc_len;
+
 	/* BAM Init. */
 	bam_init(&bam);
 
@@ -340,7 +408,7 @@
 	bam_add_one_desc(&bam,
 					 CMD_PIPE_INDEX,
 					 (unsigned char*)cmd_list_ptr_start,
-					 (uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start,
+					 PA((addr_t)(uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start),
 					 desc_flags);
 
 	cmd_list_ptr_start = cmd_list_ptr;
@@ -349,7 +417,7 @@
 	/* Add Data desc */
 	bam_add_desc(&bam,
 				 DATA_PRODUCER_PIPE_INDEX,
-				 (unsigned char *)data_ptr,
+				 (unsigned char *)PA((addr_t)data_ptr),
 				 data_len,
 				 BAM_DESC_INT_FLAG);
 
@@ -391,7 +459,7 @@
 	bam_add_one_desc(&bam,
 					 CMD_PIPE_INDEX,
 					 (unsigned char*)cmd_list_ptr_start,
-					 (uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start,
+					 PA((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start),
 					 BAM_DESC_UNLOCK_FLAG | BAM_DESC_CMD_FLAG| BAM_DESC_INT_FLAG);
 
 	qpic_nand_wait_for_cmd_exec(1);
@@ -658,7 +726,7 @@
 	flash_status_reset = NAND_FLASH_STATUS_RESET;
 	read_status_reset = NAND_READ_STATUS_RESET;
 
-	bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_STATUS, (uint32_t)flash_status_read, CE_READ_TYPE);
+	bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_STATUS, (uint32_t)PA((addr_t)flash_status_read), CE_READ_TYPE);
 	cmd_list_ptr++;
 	bam_add_cmd_element(cmd_list_ptr, NAND_FLASH_STATUS, (uint32_t)flash_status_reset, CE_WRITE_TYPE);
 	cmd_list_ptr++;
@@ -708,7 +776,7 @@
 	bam_add_one_desc(&bam,
 					 CMD_PIPE_INDEX,
 					 (unsigned char*)cmd_list_ptr_start,
-					 (uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start,
+					 PA((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start),
 					 desc_flags);
 
 	num_desc++;
@@ -716,15 +784,20 @@
 	/* Add Data desc */
 	bam_add_desc(&bam,
 				 DATA_PRODUCER_PIPE_INDEX,
-				 (unsigned char *)bad_block,
+				 (unsigned char *)PA((addr_t)bad_block),
 				 4,
 				 BAM_DESC_INT_FLAG);
 
 	qpic_nand_wait_for_cmd_exec(num_desc);
 
+	status = qpic_nand_read_reg(NAND_FLASH_STATUS, 0, cmd_list_ptr);
+
+	nand_ret = qpic_nand_check_status(status);
+
+	/* Dummy read to unlock pipe. */
 	status = qpic_nand_read_reg(NAND_FLASH_STATUS, BAM_DESC_UNLOCK_FLAG, cmd_list_ptr);
 
-	if ((nand_ret = qpic_nand_check_status(status)))
+	if (nand_ret)
 		return NANDC_RESULT_FAILURE;
 
 	qpic_nand_wait_for_data(DATA_PRODUCER_PIPE_INDEX);
@@ -733,16 +806,17 @@
 }
 
 static int
-qpic_nand_block_isbad(unsigned block)
+qpic_nand_block_isbad(unsigned page)
 {
 	unsigned cwperpage;
 	struct cfg_params params;
 	uint8_t bad_block[4];
 	unsigned nand_ret = NANDC_RESULT_SUCCESS;
+	uint32_t blk = page / flash.num_pages_per_blk;
 
-	if (bbtbl[block] == NAND_BAD_BLK_VALUE_IS_GOOD)
+	if (bbtbl[blk] == NAND_BAD_BLK_VALUE_IS_GOOD)
 		return NANDC_RESULT_SUCCESS;
-	else if (bbtbl[block] == NAND_BAD_BLK_VALUE_IS_BAD)
+	else if (bbtbl[blk] == NAND_BAD_BLK_VALUE_IS_BAD)
 		return NANDC_RESULT_BAD_BLOCK;
 	else
 	{
@@ -753,36 +827,21 @@
 		cwperpage = flash.cws_per_page;
 
 		/* Read page cmd */
-		params.cmd =  NAND_CMD_PAGE_READ;
+		params.cmd =  NAND_CMD_PAGE_READ_ECC;
 		/* Clear the CW per page bits */
 		params.cfg0 = cfg0_raw & ~(7U << NAND_DEV0_CFG0_CW_PER_PAGE_SHIFT);
 		params.cfg1 = cfg1_raw;
-		/* addr0 - Write column addr + few bits in row addr upto 32 bits.
-		 * Figure out the bad block status offset.
-		 */
-		if (flash.widebus)
-		{
-			if (flash.ecc_width == NAND_WITH_8_BIT_ECC)
-				params.addr0 = ((block << 16) | ((532 * (cwperpage - 1)) >> 1));
-			else
-				params.addr0 = ((block << 16) | ((528 * (cwperpage - 1)) >> 1));
-		}
-		else
-		{
-			if (flash.ecc_width == NAND_WITH_8_BIT_ECC)
-				params.addr0 = (block << 16) | (532 * (cwperpage - 1));
-			else
-				params.addr0 = (block << 16) | (528 * (cwperpage - 1));
-		}
+		/* addr0 - Write column addr + few bits in row addr upto 32 bits. */
+		params.addr0 = (page << 16) | (USER_DATA_BYTES_PER_CW * cwperpage);
 
 		/* addr1 - Write rest of row addr.
 		 * This will be all 0s.
 		 */
-		params.addr1 = (block >> 16) & 0xff;
+		params.addr1 = (page >> 16) & 0xff;
 		params.addr_loc_0 = NAND_RD_LOC_OFFSET(0);
 		params.addr_loc_0 |= NAND_RD_LOC_LAST_BIT(1);
 		params.addr_loc_0 |= NAND_RD_LOC_SIZE(4); /* Read 4 bytes */
-		params.ecc_cfg = ecc_bch_cfg & 0xFFFFFFFE; /* Disable ECC */
+		params.ecc_cfg = ecc_bch_cfg | 0x1; /* Disable ECC */
 		params.exec = 1;
 
 		if (qpic_nand_block_isbad_exec(&params, bad_block))
@@ -796,17 +855,17 @@
 		{
 			if (bad_block[0] != 0xFF && bad_block[1] != 0xFF)
 			{
-				bbtbl[block] = NAND_BAD_BLK_VALUE_IS_BAD;
+				bbtbl[blk] = NAND_BAD_BLK_VALUE_IS_BAD;
 				nand_ret = NANDC_RESULT_BAD_BLOCK;
 			}
 		}
 		else if (bad_block[0] != 0xFF)
 		{
-			bbtbl[block] = NAND_BAD_BLK_VALUE_IS_BAD;
+			bbtbl[blk] = NAND_BAD_BLK_VALUE_IS_BAD;
 			nand_ret = NANDC_RESULT_BAD_BLOCK;
 		}
 		else
-			bbtbl[block] = NAND_BAD_BLK_VALUE_IS_GOOD;
+			bbtbl[blk] = NAND_BAD_BLK_VALUE_IS_GOOD;
 
 		return nand_ret;
 	}
@@ -824,9 +883,10 @@
 	uint32_t status;
 	int num_desc = 0;
 	uint32_t blk_addr = page / flash.num_pages_per_blk;
+	int nand_ret;
 
 	/* Erase only if the block is not bad */
-	if (qpic_nand_block_isbad(blk_addr))
+	if (qpic_nand_block_isbad(page))
 	{
 		dprintf(CRITICAL,
 				"NAND Erase error: Block address belongs to bad block: %d\n",
@@ -849,7 +909,7 @@
 	bam_add_one_desc(&bam,
 					 CMD_PIPE_INDEX,
 					 (unsigned char*)cmd_list_ptr_start,
-					 (uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start,
+					 PA((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start),
 					 BAM_DESC_NWD_FLAG | BAM_DESC_CMD_FLAG | BAM_DESC_INT_FLAG | BAM_DESC_LOCK_FLAG);
 
 	cmd_list_ptr_start = cmd_list_ptr;
@@ -873,14 +933,19 @@
 	bam_add_one_desc(&bam,
 					 CMD_PIPE_INDEX,
 					 (unsigned char*)cmd_list_ptr_start,
-					 (uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start,
-					 BAM_DESC_INT_FLAG | BAM_DESC_CMD_FLAG | BAM_DESC_UNLOCK_FLAG) ;
+					 PA((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start),
+					 BAM_DESC_INT_FLAG | BAM_DESC_CMD_FLAG) ;
 
 	num_desc = 1;
 	qpic_nand_wait_for_cmd_exec(num_desc);
 
+	status = qpic_nand_check_status(status);
+
+	/* Dummy read to unlock pipe. */
+	nand_ret = qpic_nand_read_reg(NAND_FLASH_STATUS, BAM_DESC_UNLOCK_FLAG, cmd_list_ptr);
+
 	/* Check for status errors*/
-	if (qpic_nand_check_status(status))
+	if (status)
 	{
 		dprintf(CRITICAL,
 				"NAND Erase error: Block address belongs to bad block: %d\n",
@@ -896,7 +961,7 @@
 }
 
 /* Return num of desc added. */
-static int
+static void
 qpic_nand_add_wr_page_cws_cmd_desc(struct cfg_params *cfg,
 								   uint32_t status[],
 								   enum nand_cfg_value cfg_mode)
@@ -910,7 +975,7 @@
 	if (cfg_mode == NAND_CFG)
 		ecc = ecc_bch_cfg;
 	else
-		ecc = ecc_bch_cfg & 0xFFFFFFFE; /* Disable ECC */
+		ecc = ecc_bch_cfg | 0x1; /* Disable ECC */
 
 	/* Add ECC configuration */
 	bam_add_cmd_element(cmd_list_ptr, NAND_DEV0_ECC_CFG,
@@ -926,7 +991,7 @@
 	bam_add_one_desc(&bam,
 					 CMD_PIPE_INDEX,
 					 (unsigned char*)cmd_list_ptr_start,
-					 (uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start,
+					 PA((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start),
 					 BAM_DESC_CMD_FLAG | BAM_DESC_LOCK_FLAG);
 
 	num_desc++;
@@ -935,6 +1000,7 @@
 	for (unsigned i = 0; i < flash.cws_per_page; i++)
 	{
 		cmd_list_ptr_start = cmd_list_ptr;
+		int_flag = BAM_DESC_INT_FLAG;
 
 		bam_add_cmd_element(cmd_list_ptr, NAND_EXEC_CMD, (uint32_t)cfg->exec, CE_WRITE_TYPE);
 		cmd_list_ptr++;
@@ -943,7 +1009,7 @@
 		bam_add_one_desc(&bam,
 						 CMD_PIPE_INDEX,
 						 (unsigned char*)cmd_list_ptr_start,
-						 (uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start,
+						 PA((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start),
 						 BAM_DESC_NWD_FLAG | BAM_DESC_CMD_FLAG);
 
 		num_desc++;
@@ -955,7 +1021,6 @@
 			cmd_list_ptr = qpic_nand_add_read_n_reset_status_ce(cmd_list_ptr,
 																&status[i],
 																1);
-			int_flag = BAM_DESC_INT_FLAG | BAM_DESC_UNLOCK_FLAG;
 		}
 		else
 			cmd_list_ptr = qpic_nand_add_read_n_reset_status_ce(cmd_list_ptr,
@@ -966,11 +1031,17 @@
 		bam_add_one_desc(&bam,
 						 CMD_PIPE_INDEX,
 						 (unsigned char*)cmd_list_ptr_start,
-						 (uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start,
+						 PA((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start),
 						 int_flag | BAM_DESC_CMD_FLAG);
 		num_desc++;
+
+		qpic_nand_wait_for_cmd_exec(num_desc);
+
+		status[i] = qpic_nand_check_status(status[i]);
+
+		num_desc = 0;
 	}
-	return num_desc;
+	return;
 }
 
 void
@@ -1013,7 +1084,7 @@
 			len = flash.cw_size;
 			flags |= BAM_DESC_EOT_FLAG;
 		}
-		bam_add_one_desc(&bam, DATA_CONSUMER_PIPE_INDEX, (unsigned char*)start, len, flags);
+		bam_add_one_desc(&bam, DATA_CONSUMER_PIPE_INDEX, (unsigned char*)PA(start), len, flags);
 		num_desc++;
 
 		if ((i == (flash.cws_per_page - 1)) && (cfg_mode == NAND_CFG))
@@ -1022,7 +1093,7 @@
 			start = (uint32_t)spareaddr;
 			len = (flash.cws_per_page << 2);
 			flags = BAM_DESC_EOT_FLAG | BAM_DESC_INT_FLAG;
-			bam_add_one_desc(&bam, DATA_CONSUMER_PIPE_INDEX, (unsigned char*)start, len, flags);
+			bam_add_one_desc(&bam, DATA_CONSUMER_PIPE_INDEX, (unsigned char*)PA(start), len, flags);
 			num_desc++;
 		}
 	}
@@ -1038,7 +1109,6 @@
 {
 	struct cfg_params cfg;
 	uint32_t status[4];
-	int num_cmd_desc = 0;
 	int nand_ret = NANDC_RESULT_SUCCESS;
 
 	if (cfg_mode == NAND_CFG_RAW)
@@ -1058,12 +1128,9 @@
 	cfg.addr0 = pg_addr << 16;
 	cfg.addr1 = (pg_addr >> 16) & 0xff;
 
-	num_cmd_desc = qpic_nand_add_wr_page_cws_cmd_desc(&cfg, status, cfg_mode);
-
 	qpic_add_wr_page_cws_data_desc(buffer, cfg_mode, spareaddr);
 
-	/* Wait for the commands to be executed */
-	qpic_nand_wait_for_cmd_exec(num_cmd_desc);
+	qpic_nand_add_wr_page_cws_cmd_desc(&cfg, status, cfg_mode);
 
 	/* Check for errors */
 	for(unsigned i = 0; i < flash.cws_per_page; i++)
@@ -1180,7 +1247,7 @@
 
 	nand_base = config->nand_base;
 
-	qpic_bam_init(config->bam_base, &(config->pipes));
+	qpic_bam_init(config);
 
 	/* Do an ONFI probe. */
 	nand_ret = qpic_nand_onfi_probe(&flash);
@@ -1206,7 +1273,7 @@
 	}
 
 	/* Create a bad block table */
-	bbtbl = (unsigned int *)malloc(sizeof(uint8_t) * flash.num_blocks);
+	bbtbl = (uint8_t *) malloc(sizeof(uint8_t) * flash.num_blocks);
 
 	if (bbtbl == NULL)
 	{
@@ -1216,6 +1283,23 @@
 
 	for (i = 0; i < flash.num_blocks; i++)
 		bbtbl[i] = NAND_BAD_BLK_VALUE_NOT_READ;
+
+	/* Set aside contiguous memory for reads/writes.
+	 * This is needed as the BAM transfers only work with
+	 * physically contiguous buffers.
+	 * We will copy any data to be written/ to be read from
+	 * nand to this buffer and this buffer will be submitted to BAM.
+	 */
+	rdwr_buf = (uint8_t*) malloc(flash.page_size + flash.spare_size);
+
+	if (rdwr_buf == NULL)
+	{
+		dprintf(CRITICAL, "Failed to allocate memory for page reads or writes\n");
+		return;
+	}
+
+	/* Reset and Configure erased CW/page detection controller. */
+	qpic_nand_erased_status_reset(ce_array);
 }
 
 unsigned
@@ -1298,7 +1382,7 @@
 	addr_loc_1 |= NAND_RD_LOC_SIZE(oob_bytes);
 	addr_loc_1 |= NAND_RD_LOC_LAST_BIT(1);
 
-	status = qpic_nand_block_isbad(page / flash.num_pages_per_blk);
+	status = qpic_nand_block_isbad(page);
 
 	if (status)
 		return status;
@@ -1334,14 +1418,14 @@
 			/* Add Data desc */
 			bam_add_one_desc(&bam,
 							 DATA_PRODUCER_PIPE_INDEX,
-							 (unsigned char *)buffer,
+							 (unsigned char *)PA((addr_t)buffer),
 							 ud_bytes_in_last_cw,
 							 0);
 			num_data_desc++;
 
 			bam_add_one_desc(&bam,
 							 DATA_PRODUCER_PIPE_INDEX,
-							 (unsigned char *)spareaddr,
+							 (unsigned char *)PA((addr_t)spareaddr),
 							 oob_bytes,
 							 BAM_DESC_INT_FLAG);
 			num_data_desc++;
@@ -1353,7 +1437,7 @@
 			/* Add Data desc */
 			bam_add_one_desc(&bam,
 							 DATA_PRODUCER_PIPE_INDEX,
-							 (unsigned char *)buffer,
+							 (unsigned char *)PA((addr_t)buffer),
 							 DATA_BYTES_IN_IMG_PER_CW,
 							 BAM_DESC_INT_FLAG);
 			num_data_desc++;
@@ -1377,7 +1461,7 @@
 	bam_add_one_desc(&bam,
 					 CMD_PIPE_INDEX,
 					 (unsigned char*)cmd_list_ptr_start,
-					 (uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start,
+					 PA((uint32_t)cmd_list_ptr - (uint32_t)cmd_list_ptr_start),
 					 BAM_DESC_NWD_FLAG | BAM_DESC_CMD_FLAG | BAM_DESC_INT_FLAG | BAM_DESC_LOCK_FLAG);
 	num_cmd_desc++;
 
@@ -1389,6 +1473,8 @@
 	flash_sts[i] = qpic_nand_read_reg(NAND_FLASH_STATUS, 0, cmd_list_ptr++);
 	buffer_sts[i] = qpic_nand_read_reg(NAND_BUFFER_STATUS, 0, cmd_list_ptr++);
 
+	flash_sts[i] = qpic_nand_check_status(flash_sts[i]);
+
 	buffer += DATA_BYTES_IN_IMG_PER_CW;
 	}
 
@@ -1397,7 +1483,7 @@
 
 	/* Check status */
 	for (i = 0; i < flash.cws_per_page ; i ++)
-		if (qpic_nand_check_status(flash_sts[i]))
+		if (flash_sts[i])
 		{
 			nand_ret = NANDC_RESULT_BAD_PAGE;
 			dprintf(CRITICAL, "NAND page read failed. page: %x\n", page);
@@ -1454,7 +1540,7 @@
 		while (start_block_count
 			   && (start_block < (ptn->start + ptn->length)))
 		{
-			isbad = qpic_nand_block_isbad(start_block);
+			isbad = qpic_nand_block_isbad(page);
 			if (isbad)
 				page += flash.num_pages_per_blk;
 			else
@@ -1472,7 +1558,7 @@
 			return NANDC_RESULT_SUCCESS;
 		}
 
-		result = qpic_nand_read_page(page, image, (unsigned char *)spare);
+		result = qpic_nand_read_page(page, rdwr_buf, (unsigned char *)spare);
 
 		if (result == NANDC_RESULT_BAD_PAGE)
 		{
@@ -1489,6 +1575,9 @@
 			continue;
 		}
 
+		/* Copy the read page into correct location. */
+		memcpy(image, rdwr_buf, flash.page_size);
+
 		page++;
 		image += flash.page_size;
 		/* Copy spare bytes to image */
@@ -1505,8 +1594,6 @@
 int
 flash_erase(struct ptentry *ptn)
 {
-	uint32_t block = ptn->start;
-	uint32_t count = ptn->length;
 	int ret = 0;
 
 	ret = qpic_nand_blk_erase(ptn->start * flash.num_pages_per_blk);
@@ -1568,16 +1655,19 @@
 			}
 		}
 
+		memcpy(rdwr_buf, image, flash.page_size);
+
 		if (extra_per_page)
 		{
+			memcpy(rdwr_buf + flash.page_size, image + flash.page_size, extra_per_page);
 			r = qpic_nand_write_page(page,
 									 NAND_CFG,
-									 image,
-									 image + flash.page_size);
+									 rdwr_buf,
+									 rdwr_buf + flash.page_size);
 		}
 		else
 		{
-			r = qpic_nand_write_page(page, NAND_CFG, image, spare);
+			r = qpic_nand_write_page(page, NAND_CFG, rdwr_buf, spare);
 		}
 
 		if (r)
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 6c484e8..719193c 100644
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -126,6 +126,7 @@
 
 ifeq ($(PLATFORM),mdm9x25)
 	OBJS += $(LOCAL_DIR)/qgic.o \
+			$(LOCAL_DIR)/uart_dm.o \
 			$(LOCAL_DIR)/interrupts.o \
 			$(LOCAL_DIR)/qtimer.o \
 			$(LOCAL_DIR)/qtimer_mmap.o \
diff --git a/platform/msm_shared/smem.h b/platform/msm_shared/smem.h
index 74c507e..9c4d5e4 100755
--- a/platform/msm_shared/smem.h
+++ b/platform/msm_shared/smem.h
@@ -274,6 +274,7 @@
 	HW_PLATFORM_SUBTYPE_SVLTE1 = 2,
 	HW_PLATFORM_SUBTYPE_SVLTE2A = 3,
 	HW_PLATFORM_SUBTYPE_SGLTE = 6,
+	HW_PLATFORM_SUBTYPE_DSDA = 7,
 	HW_PLATFORM_SUBTYPE_32BITS = 0x7FFFFFFF
 };
 
diff --git a/project/mdm9625.mk b/project/mdm9625.mk
index 9f5f305..3f582bd 100644
--- a/project/mdm9625.mk
+++ b/project/mdm9625.mk
@@ -6,8 +6,10 @@
 
 MODULES += app/aboot
 
+DEBUG := 1
+
 #DEFINES += WITH_DEBUG_DCC=1
-#DEFINES += WITH_DEBUG_UART=1
+DEFINES += WITH_DEBUG_UART=1
 #DEFINES += WITH_DEBUG_FBCON=1
 DEFINES += DEVICE_TREE=1
 
diff --git a/target/copper/init.c b/target/copper/init.c
index 56acf93..6bbde18 100644
--- a/target/copper/init.c
+++ b/target/copper/init.c
@@ -1,31 +1,29 @@
-/*
- * Copyright (c) 2012, Code Aurora Forum. All rights reserved.
+/* Copyright (c) 2012, The Linux Foundation. All rights reserved.
  *
  * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions
- * are met:
- *  * Redistributions of source code must retain the above copyright
- *    notice, this list of conditions and the following disclaimer.
- *  * Redistributions in binary form must reproduce the above copyright
- *    notice, this list of conditions and the following disclaimer in
- *    the documentation and/or other materials provided with the
- *    distribution.
- *  * Neither the name of Google, Inc. nor the names of its contributors
- *    may be used to endorse or promote products derived from this
- *    software without specific prior written permission.
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *     * Redistributions of source code must retain the above copyright
+ *       notice, this list of conditions and the following disclaimer.
+ *     * Redistributions in binary form must reproduce the above
+ *       copyright notice, this list of conditions and the following
+ *       disclaimer in the documentation and/or other materials provided
+ *       with the distribution.
+ *     * Neither the name of The Linux Foundation nor the names of its
+ *       contributors may be used to endorse or promote products derived
+ *       from this software without specific prior written permission.
  *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS
- * FOR A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE
- * COPYRIGHT OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT,
- * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
- * BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS
- * OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED
- * AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY,
- * OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT
- * OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
- * SUCH DAMAGE.
+ * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESS OR IMPLIED
+ * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
+ * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NON-INFRINGEMENT
+ * ARE DISCLAIMED.  IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS
+ * BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
+ * CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
+ * SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR
+ * BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
+ * WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE
+ * OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN
+ * IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  */
 
 #include <debug.h>
@@ -47,6 +45,7 @@
 #define PMIC_ARB_CHANNEL_NUM    0
 #define PMIC_ARB_OWNER_ID       0
 
+#define WDOG_DEBUG_DISABLE_BIT  17
 
 static uint32_t mmc_sdc_base[] =
 	{ MSM_SDC1_BASE, MSM_SDC2_BASE, MSM_SDC3_BASE, MSM_SDC4_BASE };
@@ -186,6 +185,17 @@
 	/* Configure PMIC for warm reset */
 	pm8x41_reset_configure(PON_PSHOLD_WARM_RESET);
 
+	/* Disable Watchdog Debug.
+	 * Required becuase of a H/W bug which causes the system to
+	 * reset partially even for non watchdog resets.
+	 */
+	writel(readl(GCC_WDOG_DEBUG) & ~(1 << WDOG_DEBUG_DISABLE_BIT), GCC_WDOG_DEBUG);
+
+	dsb();
+
+	/* Wait until the write takes effect. */
+	while(readl(GCC_WDOG_DEBUG) & (1 << WDOG_DEBUG_DISABLE_BIT));
+
 	/* Drop PS_HOLD for MSM */
 	writel(0x00, MPM2_MPM_PS_HOLD);
 
diff --git a/target/copper/meminfo.c b/target/copper/meminfo.c
index e0feaa1..086c080 100644
--- a/target/copper/meminfo.c
+++ b/target/copper/meminfo.c
@@ -37,51 +37,6 @@
 #include <platform/iomap.h>
 #include <dev_tree.h>
 
-#define SIZE_1M             (1024 * 1024)
-
-typedef struct {
-	uint32_t size;
-	uint32_t start_addr;
-}mem_info;
-
-mem_info copper_default_fixed_memory[] = {
-	{	.size = (132 * SIZE_1M),
-		.start_addr = SDRAM_START_ADDR
-	},
-	{	.size = SIZE_1M,
-		.start_addr = SDRAM_START_ADDR +
-				(250 * SIZE_1M) +
-				(5 * SIZE_1M)
-	},
-	{	.size = (240 * SIZE_1M),
-		.start_addr = SDRAM_START_ADDR +
-				(16 * SIZE_1M) +
-				(256 * SIZE_1M)
-	},
-};
-
-int target_add_first_mem_bank(void *fdt,
-							  uint32_t offset,
-							  mem_info usable_mem_map[],
-							  uint32_t num_regions)
-{
-	uint32_t i;
-	int ret;
-
-	ASSERT(num_regions);
-
-	dprintf(SPEW, "Number of HLOS regions in 1st bank = %u\n", num_regions);
-
-	for (i = 0; i < num_regions; i++)
-	{
-           ret = dev_tree_add_mem_info(fdt,
-									   offset,
-									   usable_mem_map[i].start_addr,
-									   usable_mem_map[i].size);
-	}
-	return ret;
-}
-
 /* Funtion to add the ram partition entries into device tree.
  * The function assumes that all the entire fixed memory regions should
  * be listed in the first bank of the passed in ddr regions.
@@ -89,70 +44,31 @@
 uint32_t target_dev_tree_mem(void *fdt, uint32_t memory_node_offset)
 {
     struct smem_ram_ptable ram_ptable;
-    uint32_t last_fixed_addr;
-    int n;
     unsigned int i;
-	int ret;
+	int ret = 0;
 
 	/* Make sure RAM partition table is initialized */
 	ASSERT(smem_ram_ptable_init(&ram_ptable));
 
-    n = ARRAY_SIZE(copper_default_fixed_memory);
-
-    last_fixed_addr = copper_default_fixed_memory[n-1].start_addr +
-					copper_default_fixed_memory[n-1].size;
-
      /* Calculating the size of the mem_info_ptr */
     for (i = 0 ; i < ram_ptable.len; i++)
     {
         if((ram_ptable.parts[i].category == SDRAM) &&
            (ram_ptable.parts[i].type == SYS_MEMORY))
         {
-            if((ram_ptable.parts[i].start <= last_fixed_addr) &&
-			   ((ram_ptable.parts[i].start + ram_ptable.parts[i].size) >= last_fixed_addr))
-            {
 
-				/* Pass along all fixed memory regions to Linux */
-				 ret = target_add_first_mem_bank(fdt,
-												 memory_node_offset,
-												 copper_default_fixed_memory,
-												 ARRAY_SIZE(copper_default_fixed_memory));
+			/* Pass along all other usable memory regions to Linux */
+			ret = dev_tree_add_mem_info(fdt,
+										memory_node_offset,
+										ram_ptable.parts[i].start,
+										ram_ptable.parts[i].size);
 
-				if (ret)
-				{
-					dprintf(CRITICAL, "Failed to add first bank fixed memory addresses\n");
-					goto target_dev_tree_mem_err;
-				}
-
-				if((ram_ptable.parts[i].start + ram_ptable.parts[i].size) != last_fixed_addr)
-			    {
-			        /* Pass the memory beyond the fixed memory present in the partition */
-					ret = dev_tree_add_mem_info(fdt,
-												memory_node_offset,
-												ram_ptable.parts[i].start + last_fixed_addr,
-												ram_ptable.parts[i].size - last_fixed_addr);
-
-					if (ret)
-					{
-						dprintf(CRITICAL, "Failed to add first bank memory addresses\n");
-						goto target_dev_tree_mem_err;
-					}
-                }
-			}
-			else
+			if (ret)
 			{
-				/* Pass along all other usable memory regions to Linux */
-				ret = dev_tree_add_mem_info(fdt,
-											memory_node_offset,
-											ram_ptable.parts[i].start,
-											ram_ptable.parts[i].size);
-
-				if (ret)
-				{
-					dprintf(CRITICAL, "Failed to add secondary banks memory addresses\n");
-					goto target_dev_tree_mem_err;
-				}
+				dprintf(CRITICAL, "Failed to add secondary banks memory addresses\n");
+				goto target_dev_tree_mem_err;
 			}
+
        }
     }
 
diff --git a/target/mdm9625/init.c b/target/mdm9625/init.c
index f06406c..e17f796 100644
--- a/target/mdm9625/init.c
+++ b/target/mdm9625/init.c
@@ -46,14 +46,20 @@
 static struct ptable flash_ptable;
 
 /* PMIC config data */
-#define PMIC_ARB_CHANNEL_NUM    0
-#define PMIC_ARB_OWNER_ID       0
+#define PMIC_ARB_CHANNEL_NUM                          0
+#define PMIC_ARB_OWNER_ID                             0
 
 /* NANDc BAM pipe numbers */
 #define DATA_CONSUMER_PIPE                            0
 #define DATA_PRODUCER_PIPE                            1
 #define CMD_PIPE                                      2
 
+/* NANDc EE */
+#define QPIC_NAND_EE                                  0
+
+/* NANDc max desc length. */
+#define QPIC_NAND_MAX_DESC_LEN                        0x7FFF
+
 #define LAST_NAND_PTN_LEN_PATTERN                     0xFFFFFFFF
 
 struct qpic_nand_init_config config;
@@ -97,6 +103,14 @@
 	strcpy(boot_ptn->name, "aboot");
 }
 
+void target_early_init(void)
+{
+#if WITH_DEBUG_UART
+	uart_dm_init(3, 0, MSM_UART2_BASE);
+#endif
+}
+
+
 /* init */
 void target_init(void)
 {
@@ -110,6 +124,8 @@
 
 	config.bam_base = MSM_NAND_BAM_BASE;
 	config.nand_base = MSM_NAND_BASE;
+	config.ee = QPIC_NAND_EE;
+	config.max_desc_len = QPIC_NAND_MAX_DESC_LEN;
 
 	qpic_nand_init(&config);
 
@@ -169,3 +185,15 @@
 		ASSERT(0);
 	}
 }
+
+unsigned check_reboot_mode(void)
+{
+	unsigned restart_reason = 0;
+
+	/* Read reboot reason and scrub it */
+	restart_reason = readl(RESTART_REASON_ADDR);
+	writel(0x00, RESTART_REASON_ADDR);
+
+	return restart_reason;
+}
+
diff --git a/target/mdm9625/meminfo.c b/target/mdm9625/meminfo.c
index 96b1b5b..7f88b56 100644
--- a/target/mdm9625/meminfo.c
+++ b/target/mdm9625/meminfo.c
@@ -32,6 +32,7 @@
 #include <smem.h>
 #include <stdint.h>
 #include <libfdt.h>
+#include <platform.h>
 #include <platform/iomap.h>
 #include <dev_tree.h>
 
@@ -42,6 +43,8 @@
 	uint32_t start_addr;
 }mem_info;
 
+static struct smem_ram_ptable ram_ptable;
+
 mem_info mdm9625_default_fixed_memory[] = {
 	{	.size = (29 * SIZE_1M),
 		.start_addr = SDRAM_START_ADDR +
@@ -53,6 +56,14 @@
 	},
 };
 
+struct smem_ram_ptable* target_smem_ram_ptable_init()
+{
+   /* Make sure RAM partition table is initialized */
+   ASSERT(smem_ram_ptable_init(&ram_ptable));
+
+   return &ram_ptable;
+}
+
 int target_add_first_mem_bank(void *fdt,
 							  uint32_t offset,
 							  mem_info usable_mem_map[],
@@ -81,15 +92,11 @@
  */
 uint32_t target_dev_tree_mem(void *fdt, uint32_t memory_node_offset)
 {
-    struct smem_ram_ptable ram_ptable;
     uint32_t last_fixed_addr;
     int n;
     unsigned int i;
 	int ret;
 
-	/* Make sure RAM partition table is initialized */
-	ASSERT(smem_ram_ptable_init(&ram_ptable));
-
     n = ARRAY_SIZE(mdm9625_default_fixed_memory);
 
     last_fixed_addr = mdm9625_default_fixed_memory[n-1].start_addr +
@@ -155,10 +162,10 @@
 
 void *target_get_scratch_address(void)
 {
-	return ((void *)SCRATCH_ADDR);
+	return ((void *) VA((addr_t)SCRATCH_REGION1));
 }
 
 unsigned target_get_max_flash_size(void)
 {
-	return (28 * 1024 * 1024);
+	return (SCRATCH_REGION1_SIZE + SCRATCH_REGION2_SIZE);
 }
diff --git a/target/mdm9625/rules.mk b/target/mdm9625/rules.mk
index a784e6d..53892f4 100644
--- a/target/mdm9625/rules.mk
+++ b/target/mdm9625/rules.mk
@@ -4,11 +4,16 @@
 
 PLATFORM := mdm9x25
 
-MEMBASE          := 0x01E00000
-MEMSIZE          := 0x00100000 # 1MB
-SCRATCH_ADDR     := 0x00200000
+MEMBASE                             := 0x01E00000
+MEMSIZE                             := 0x00100000 # 1MB
+SCRATCH_ADDR                        := 0x00200000
+SCRATCH_REGION1                     := 0x00200000
+SCRATCH_REGION1_SIZE                := 0x01C00000 #28 MB
+SCRATCH_REGION2                     := 0x07600000
+SCRATCH_REGION2_SIZE                := 0x00A00000 #10 MB
 
 DEFINES += NO_KEYPAD_DRIVER=1
+DEFINES += PERIPH_BLK_BLSP=1
 
 MODULES += \
 	dev/keys \
@@ -18,7 +23,12 @@
 
 DEFINES += \
 	MEMBASE=$(MEMBASE) \
-	SCRATCH_ADDR=$(SCRATCH_ADDR)
+	SCRATCH_ADDR=$(SCRATCH_ADDR) \
+	SCRATCH_REGION1=$(SCRATCH_REGION1) \
+	SCRATCH_REGION2=$(SCRATCH_REGION2) \
+	MEMSIZE=$(MEMSIZE) \
+	SCRATCH_REGION1_SIZE=$(SCRATCH_REGION1_SIZE) \
+	SCRATCH_REGION2_SIZE=$(SCRATCH_REGION2_SIZE) \
 
 OBJS += \
 	$(LOCAL_DIR)/init.o \
diff --git a/target/msm8960/init.c b/target/msm8960/init.c
index 5273afb..9fed389 100755
--- a/target/msm8960/init.c
+++ b/target/msm8960/init.c
@@ -431,6 +431,8 @@
 		baseband = BASEBAND_MDM;
 	else if (platform_subtype == HW_PLATFORM_SUBTYPE_SGLTE)
 		baseband = BASEBAND_SGLTE;
+	else if (platform_subtype == HW_PLATFORM_SUBTYPE_DSDA)
+		baseband = BASEBAND_DSDA;
 	else {
 		switch(platform) {
 		case APQ8060: