Merge "aboot: Add dtree support for flash targets."
diff --git a/app/aboot/aboot.c b/app/aboot/aboot.c
index 910cd08..f6d6e50 100644
--- a/app/aboot/aboot.c
+++ b/app/aboot/aboot.c
@@ -2,7 +2,7 @@
  * Copyright (c) 2009, 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:
@@ -11,7 +11,7 @@
  *     * 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
+ *     * 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.
@@ -48,9 +48,11 @@
 #include <partition_parser.h>
 #include <platform.h>
 #include <crypto_hash.h>
+#include <malloc.h>
 
 #if DEVICE_TREE
 #include <libfdt.h>
+#include <dev_tree.h>
 #endif
 
 #include "image_verify.h"
@@ -64,6 +66,14 @@
 
 #include "scm.h"
 
+extern  bool target_use_signed_kernel(void);
+extern void dsb();
+extern void isb();
+extern void platform_uninit(void);
+
+void write_device_info_mmc(device_info *dev);
+void write_device_info_flash(device_info *dev);
+
 #define EXPAND(NAME) #NAME
 #define TARGET(NAME) EXPAND(NAME)
 #define DEFAULT_CMDLINE "mem=100M console=null";
@@ -77,31 +87,6 @@
 #define RECOVERY_MODE   0x77665502
 #define FASTBOOT_MODE   0x77665500
 
-#if DEVICE_TREE
-#define DEV_TREE_SUCCESS        0
-#define DEV_TREE_MAGIC          "QCDT"
-#define DEV_TREE_VERSION        1
-#define DEV_TREE_HEADER_SIZE    12
-
-
-struct dt_entry{
-	uint32_t platform_id;
-	uint32_t variant_id;
-	uint32_t soc_rev;
-	uint32_t offset;
-	uint32_t size;
-};
-
-struct dt_table{
-	uint32_t magic;
-	uint32_t version;
-	unsigned num_entries;
-};
-
-struct dt_entry * get_device_tree_ptr(struct dt_table *);
-int update_device_tree(const void *, char *, void *, unsigned);
-#endif
-
 static const char *emmc_cmdline = " androidboot.emmc=true";
 static const char *usb_sn_cmdline = " androidboot.serialno=";
 static const char *battchg_pause = " androidboot.mode=charger";
@@ -213,8 +198,8 @@
 
 	if (cmdline_len > 0) {
 		const char *src;
-		char *dst = malloc((cmdline_len + 4) & (~3));
-		assert(dst != NULL);
+		unsigned char *dst = (unsigned char*) malloc((cmdline_len + 4) & (~3));
+		ASSERT(dst != NULL);
 
 		/* Save start ptr for debug print */
 		cmdline_final = dst;
@@ -321,8 +306,8 @@
 	struct ptable *ptable;
 
 	if ((ptable = flash_get_ptable()) && (ptable->count != 0)) {
-        	*(*ptr_addr)++ = 2 + (ptable->count * (sizeof(struct atag_ptbl_entry) /
-					  		sizeof(unsigned)));
+		*(*ptr_addr)++ = 2 + (ptable->count * (sizeof(struct atag_ptbl_entry) /
+							sizeof(unsigned)));
 		*(*ptr_addr)++ = 0x4d534d70;
 		for (i = 0; i < ptable->count; ++i)
 			ptentry_to_tag(ptr_addr, ptable_get(ptable, i));
@@ -343,13 +328,13 @@
 		dprintf(INFO, "cmdline: %s\n", cmdline_final);
 	}
 
-	cmdline_length =strlen(cmdline_final);
+	cmdline_length =strlen((const char*)cmdline_final);
 	n = (cmdline_length + 4) & (~3);
 
 	*ptr++ = (n / 4) + 2;
 	*ptr++ = 0x54410009;
 	dest = (char *) ptr;
-	while (*dest++ = *cmdline_final++);
+	while ((*dest++ = *cmdline_final++));
 	ptr += (n / 4);
 
 	return ptr;
@@ -390,7 +375,7 @@
 
 #if DEVICE_TREE
 	/* Update the Device Tree */
-	ret = update_device_tree(tags, cmdline, ramdisk, ramdisk_size);
+	ret = update_device_tree((void *)tags, cmdline, ramdisk, ramdisk_size);
 	if(ret)
 	{
 		dprintf(CRITICAL, "ERROR: Updating Device Tree Failed \n");
@@ -405,19 +390,12 @@
 		kernel, ramdisk, ramdisk_size);
 
 	enter_critical_section();
+
 	/* do any platform specific cleanup before kernel entry */
 	platform_uninit();
+
 	arch_disable_cache(UCACHE);
-	/* NOTE:
-	 * The value of "entry" is getting corrupted at this point.
-	 * The value is in R4 and gets pushed to stack on entry into
-	 * disable_cache(), however, on return it is not the same.
-	 * Not entirely sure why this dsb() seems to take of this.
-	 * The stack pop operation on return from disable_cache()
-	 * should restore R4 properly, but that is not happening.
-	 * Will need to revisit to find the root cause.
-	 */
-	dsb();
+
 #if ARM_WITH_MMU
 	arch_disable_mmu();
 #endif
@@ -540,7 +518,7 @@
 		#if DEVICE_TREE
 		if(hdr->dt_size) {
 			table = (struct dt_table*) dt_buf;
-			dt_table_offset = (image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
+			dt_table_offset = ((uint32_t)image_addr + page_size + kernel_actual + ramdisk_actual + second_actual);
 
 			memmove((void *) dt_buf, (char *)dt_table_offset, page_size);
 
@@ -554,7 +532,7 @@
 			}
 
 			/* Find index of device tree within device tree table */
-			if((dt_entry_ptr = get_device_tree_ptr(table)) == NULL){
+			if((dt_entry_ptr = dev_tree_get_entry_ptr(table)) == NULL){
 				dprintf(CRITICAL, "ERROR: Device Tree Blob cannot be found\n");
 				return -1;
 			}
@@ -621,7 +599,7 @@
 			}
 
 			/* Calculate the offset of device tree within device tree table */
-			if((dt_entry_ptr = get_device_tree_ptr(table)) == NULL){
+			if((dt_entry_ptr = dev_tree_get_entry_ptr(table)) == NULL){
 				dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
 				return -1;
 			}
@@ -671,6 +649,12 @@
 	unsigned ramdisk_actual;
 	unsigned imagesize_actual;
 
+#if DEVICE_TREE
+	struct dt_table *table;
+	struct dt_entry *dt_entry_ptr;
+#endif
+
+
 	if (target_is_emmc_boot()) {
 		hdr = (struct boot_img_hdr *)EMMC_BOOT_IMG_HEADER_ADDR;
 		if (memcmp(hdr->magic, BOOT_MAGIC, BOOT_MAGIC_SIZE)) {
@@ -689,6 +673,7 @@
 	if(!boot_into_recovery)
 	{
 	        ptn = ptable_find(ptable, "boot");
+
 	        if (ptn == NULL) {
 		        dprintf(CRITICAL, "ERROR: No boot partition found\n");
 		        return -1;
@@ -790,6 +775,47 @@
 			return -1;
 		}
 		offset += n;
+
+		if(hdr->second_size != 0) {
+			n = ROUND_TO_PAGE(hdr->second_size, page_mask);
+			offset += n;
+		}
+
+#if DEVICE_TREE
+		if(hdr->dt_size != 0) {
+
+			/* Read the device tree table into buffer */
+			if(flash_read(ptn, offset, (void *) dt_buf, page_size)) {
+				dprintf(CRITICAL, "ERROR: Cannot read the Device Tree Table\n");
+				return -1;
+			}
+
+			table = (struct dt_table*) dt_buf;
+
+			/* Restriction that the device tree entry table should be less than a page*/
+			ASSERT(((table->num_entries * sizeof(struct dt_entry))+ DEV_TREE_HEADER_SIZE) < hdr->page_size);
+
+			/* Validate the device tree table header */
+			if((table->magic != DEV_TREE_MAGIC) && (table->version != DEV_TREE_VERSION)) {
+				dprintf(CRITICAL, "ERROR: Cannot validate Device Tree Table \n");
+				return -1;
+			}
+
+			/* Calculate the offset of device tree within device tree table */
+			if((dt_entry_ptr = dev_tree_get_entry_ptr(table)) == NULL){
+				dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
+				return -1;
+			}
+
+			/* Read device device tree in the "tags_add */
+			if(flash_read(ptn, offset + dt_entry_ptr->offset,
+						 (void *)hdr->tags_addr, dt_entry_ptr->size)) {
+				dprintf(CRITICAL, "ERROR: Cannot read device tree\n");
+				return -1;
+			}
+		}
+#endif
+
 	}
 continue_boot:
 	dprintf(INFO, "\nkernel  @ %x (%d bytes)\n", hdr->kernel_addr,
@@ -983,11 +1009,9 @@
 	uint32_t n;
 	struct dt_table *table;
 	struct dt_entry *dt_entry_ptr;
-	unsigned dt_table_offset;
 
 	struct boot_img_hdr *hdr = (struct boot_img_hdr *) (boot_image_start);
 
-
 	if(hdr->dt_size != 0) {
 
 		/* add kernel offset */
@@ -1006,7 +1030,7 @@
 		}
 
 		/* offset now point to start of dt.img */
-		table = boot_image_start + dt_image_offset;
+		table = (struct dt_table*)(boot_image_start + dt_image_offset);
 
 		/* Restriction that the device tree entry table should be less than a page*/
 		ASSERT(((table->num_entries * sizeof(struct dt_entry))+ DEV_TREE_HEADER_SIZE) < hdr->page_size);
@@ -1018,7 +1042,7 @@
 		}
 
 		/* Calculate the offset of device tree within device tree table */
-		if((dt_entry_ptr = get_device_tree_ptr(table)) == NULL){
+		if((dt_entry_ptr = dev_tree_get_entry_ptr(table)) == NULL){
 			dprintf(CRITICAL, "ERROR: Getting device tree address failed\n");
 			return -1;
 		}
@@ -1075,8 +1099,8 @@
 	fastboot_okay("");
 	udc_stop();
 
-	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(),
@@ -1576,87 +1600,3 @@
 APP_START(aboot)
 	.init = aboot_init,
 APP_END
-
-#if DEVICE_TREE
-struct dt_entry * get_device_tree_ptr(struct dt_table *table)
-{
-	unsigned i;
-	struct dt_entry *dt_entry_ptr;
-
-	dt_entry_ptr = (char *)table + DEV_TREE_HEADER_SIZE ;
-
-	for(i = 0; i < table->num_entries; i++)
-	{
-		if((dt_entry_ptr->platform_id == board_platform_id()) &&
-		   (dt_entry_ptr->variant_id == board_hardware_id()) &&
-		   (dt_entry_ptr->soc_rev == 0)){
-				return dt_entry_ptr;
-		}
-		dt_entry_ptr++;
-	}
-	return NULL;
-}
-
-int update_device_tree(const void * fdt, char *cmdline,
-					   void *ramdisk, unsigned ramdisk_size)
-{
-	int ret = 0;
-	int offset;
-	uint32_t *memory_reg;
-	unsigned char *final_cmdline;
-	uint32_t len;
-
-	/* Check the device tree header */
-	ret = fdt_check_header(fdt);
-	if(ret)
-	{
-		dprintf(CRITICAL, "Invalid device tree header \n");
-		return ret;
-	}
-
-	/* Get offset of the memory node */
-	offset = fdt_path_offset(fdt,"/memory");
-
-	memory_reg = target_dev_tree_mem(&len);
-
-	/* Adding the memory values to the reg property */
-	ret = fdt_setprop(fdt, offset, "reg", memory_reg, sizeof(uint32_t) * len * 2);
-	if(ret)
-	{
-		dprintf(CRITICAL, "ERROR: Cannot update memory node\n");
-		return ret;
-	}
-
-	/* Get offset of the chosen node */
-	offset = fdt_path_offset(fdt, "/chosen");
-
-	/* Adding the cmdline to the chosen node */
-	final_cmdline = update_cmdline(cmdline);
-	ret = fdt_setprop_string(fdt, offset, "bootargs", final_cmdline);
-	if(ret)
-	{
-		dprintf(CRITICAL, "ERROR: Cannot update chosen node [bootargs]\n");
-		return ret;
-	}
-
-	/* Adding the initrd-start to the chosen node */
-	ret = fdt_setprop_cell(fdt, offset, "linux,initrd-start", ramdisk);
-	if(ret)
-	{
-		dprintf(CRITICAL, "ERROR: Cannot update chosen node [linux,initrd-start]\n");
-		return ret;
-	}
-
-	/* Adding the initrd-end to the chosen node */
-	ret = fdt_setprop_cell(fdt, offset, "linux,initrd-end", (ramdisk + ramdisk_size));
-	if(ret)
-	{
-		dprintf(CRITICAL, "ERROR: Cannot update chosen node [linux,initrd-end]\n");
-		return ret;
-	}
-
-	fdt_pack(fdt);
-
-	return ret;
-}
-#endif
diff --git a/arch/arm/mmu.c b/arch/arm/mmu.c
index cc74534..bbc5451 100644
--- a/arch/arm/mmu.c
+++ b/arch/arm/mmu.c
@@ -93,7 +93,7 @@
 void arch_disable_mmu(void)
 {
 	arm_write_cr1(arm_read_cr1() & ~(1<<0));
+	arm_invalidate_tlb();
 }
 
 #endif // ARM_WITH_MMU
-
diff --git a/platform/mdm9x25/include/platform/iomap.h b/platform/mdm9x25/include/platform/iomap.h
index 154fa0e..8b30758 100644
--- a/platform/mdm9x25/include/platform/iomap.h
+++ b/platform/mdm9x25/include/platform/iomap.h
@@ -1,36 +1,37 @@
-/*
- * 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.
  */
 
 #ifndef _PLATFORM_MDM9625_IOMAP_H_
 #define _PLATFORM_MDM9625_IOMAP_H_
 
+/*SDRAM start address */
+#define SDRAM_START_ADDR           0x0
+
 /* TBD: shared base is not defined yet */
 #define MSM_SHARED_BASE           0x00000000
 
@@ -52,8 +53,8 @@
 #define QTMR_BASE                  APCS_F0_QTMR_V1_BASE
 
 /* GPIO */
-#define GPIO_CONFIG_ADDR(x)       (TLMM_BASE_ADDR + 0x1000 + (x)*0x10)
-#define GPIO_IN_OUT_ADDR(x)       (TLMM_BASE_ADDR + 0x1004 + (x)*0x10)
+#define GPIO_CONFIG_ADDR(x)       (TLMM_BASE_ADDR + 0x10000 + 0x1000 + (x)*0x10)
+#define GPIO_IN_OUT_ADDR(x)       (TLMM_BASE_ADDR + 0x10000 + 0x1004 + (x)*0x10)
 
 /* USB */
 #define MSM_USB_BASE              (PERIPH_SS_BASE + 0x00255000)
@@ -63,5 +64,4 @@
 /* NAND BAM */
 #define MSM_NAND_BAM_BASE          0xF9AC4000
 
-
 #endif
diff --git a/platform/mdm9x25/platform.c b/platform/mdm9x25/platform.c
index 21d5705..7f61100 100644
--- a/platform/mdm9x25/platform.c
+++ b/platform/mdm9x25/platform.c
@@ -1,5 +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
@@ -10,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 nor the names of its
  *       contributors may be used to endorse or promote products derived
  *       from this software without specific prior written permission.
  *
@@ -26,15 +25,17 @@
  * 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>
 #include <platform.h>
 #include <qgic.h>
 #include <qtimer.h>
+#include <board.h>
 
 void platform_early_init(void)
 {
 	/* Initialize board identifier data */
-	//board_init();
+	board_init();
 
 	/* Initialize interrupt controller */
 	qgic_init();
diff --git a/platform/msm_shared/dev_tree.c b/platform/msm_shared/dev_tree.c
new file mode 100644
index 0000000..29cce69
--- /dev/null
+++ b/platform/msm_shared/dev_tree.c
@@ -0,0 +1,424 @@
+/* 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 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
+ * 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 <libfdt.h>
+#include <dev_tree.h>
+#include <lib/ptable.h>
+#include <malloc.h>
+#include <qpic_nand.h>
+#include <stdlib.h>
+#include <string.h>
+#include <platform.h>
+#include <board.h>
+
+extern unsigned char *update_cmdline(const char * cmdline);
+extern int target_is_emmc_boot(void);
+extern uint32_t target_dev_tree_mem(void *fdt, uint32_t memory_node_offset);
+
+/* Function to return the pointer to the start of the correct device tree
+ *  based on the platform data.
+ */
+struct dt_entry * dev_tree_get_entry_ptr(struct dt_table *table)
+{
+	uint32_t i;
+	struct dt_entry *dt_entry_ptr;
+
+	dt_entry_ptr = (struct dt_entry *)((char *)table + DEV_TREE_HEADER_SIZE);
+
+	for(i = 0; i < table->num_entries; i++)
+	{
+		/* TODO: Add support to pass soc rev correctly.
+		 * Currently, the code does not support different soc revisions.
+		 */
+		if((dt_entry_ptr->platform_id == board_platform_id()) &&
+		   (dt_entry_ptr->variant_id == board_hardware_id()) &&
+		   (dt_entry_ptr->soc_rev == 0))
+			{
+				return dt_entry_ptr;
+			}
+		dt_entry_ptr++;
+	}
+	return NULL;
+}
+
+/* Function to return the offset of flash node - "/qcom,mtd-partitions".
+ * The function creates this node if it does not exist.
+ */
+static uint32_t dev_tree_get_flash_node_offset(void *fdt)
+{
+	uint32_t offset;
+	int ret = DT_OP_SUCCESS;
+
+	/* Find the mtd node. */
+	ret = fdt_path_offset(fdt, "/qcom,mtd-partitions");
+
+	if (ret & FDT_ERR_NOTFOUND)
+	{
+		/* Node not found.
+		 * Add node as sub node of root.
+		 */
+		ret = fdt_path_offset(fdt, "/");
+
+		if (ret < 0)
+		{
+			dprintf(CRITICAL, "Unable to calculate root offset\n");
+			ret = DT_OP_FAILURE;
+			goto dev_tree_get_flash_node_offset_err;
+		}
+
+		offset = ret;
+		/* Add flash partition node. */
+		ret = fdt_add_subnode(fdt, offset, "qcom,mtd-partitions");
+
+		if (ret < 0)
+		{
+			dprintf(CRITICAL, "Unable to add partition node. \n");
+			ret = DT_OP_FAILURE;
+			goto dev_tree_get_flash_node_offset_err;
+		}
+
+		/* Save the offset of the added node. */
+		offset = fdt_path_offset(fdt, "/qcom,mtd-partitions");
+	}
+	else if (ret != 0)
+	{
+		dprintf(CRITICAL, "Unable to calculate partition node offset\n");
+		ret = DT_OP_FAILURE;
+		goto dev_tree_get_flash_node_offset_err;
+	}
+
+dev_tree_get_flash_node_offset_err:
+
+	return offset;
+}
+
+/* Function to add the individual nand partition nodes to the device tree.
+ * Pre-condition: The function assumes the presence of
+ * "/qcom,mtd-partitions" device node.
+ */
+static int dev_tree_add_ptable_nodes(void *fdt, uint32_t parent_offset)
+{
+	struct ptable *ptable;
+	int n;
+	unsigned char array[100];
+	unsigned char *ptn_name_array;
+	int dt_ret = DT_OP_SUCCESS;
+	int ret;
+	int i;
+	uint32_t node_offset;
+	uint32_t blk_size;
+
+	n = sizeof("partition@");
+
+	/* Allocate bytes to save partition name:
+	 * Since address is of uint uint32_t,
+	 * allocate twice this size for string
+	 * as 1 digit occupies 1 byte is ASCII.
+	 */
+	ptn_name_array = (unsigned char*) malloc(sizeof(uint32_t) * 2 + n + 1);
+
+	if (ptn_name_array == NULL)
+	{
+		dprintf(CRITICAL, "Failed to allocate memory for flash partition name\n");
+		return -1;
+	}
+
+	strcpy((char*)ptn_name_array, (const char*)"partition@");
+
+	/* Add ptable nodes. */
+	ptable = flash_get_ptable();
+	/* Get block size. */
+	blk_size = flash_block_size();
+
+	/* Need to add partitions in reverse order since libfdt adds
+	 * new nodes on the top.
+	 * Kernel looks to mount the partitions in the order specified in
+	 * the partition.xml in the meta build.
+	 */
+	for (i = (ptable->count - 1); i >= 0; i--)
+	{
+		/* Add the partition node. */
+		if (itoa(ptable->parts[i].start * blk_size, ptn_name_array + n - 1, sizeof(uint32_t) * 2 + 1, 16) < 0)
+		{
+			dprintf(CRITICAL, "String len exceeded for itoa\n");
+			return -1;
+		}
+
+		strcpy((char *)array, (const char*)"/qcom,mtd-partitions/");
+		strcat((char*)array, (const char*)ptn_name_array);
+
+		ret = fdt_add_subnode(fdt, parent_offset, (const char*)ptn_name_array);
+
+		if (ret < 0)
+		{
+			dprintf(CRITICAL, "Unable to add partition node: %s.\n",
+					ptn_name_array);
+			dt_ret = DT_OP_FAILURE;
+			goto dev_tree_add_ptable_nodes_err;
+		}
+
+		dt_ret = fdt_path_offset(fdt, (const char*)array);
+
+		if (dt_ret < 0)
+		{
+			dprintf(CRITICAL, "Unable to calculate parition node offset: %s\n",
+					ptn_name_array);
+			dt_ret = DT_OP_FAILURE;
+			goto dev_tree_add_ptable_nodes_err;
+		}
+
+		node_offset = dt_ret;
+
+		/* Add the partition name as label. */
+		ret = fdt_setprop_string(fdt, node_offset, (const char*)"label", (const char*)ptable->parts[i].name);
+
+		if (ret != 0)
+		{
+			dprintf(CRITICAL, "Unable to add label property: %s.\n",
+					ptable->parts[i].name);
+			dt_ret = DT_OP_FAILURE;
+			goto dev_tree_add_ptable_nodes_err;
+		}
+
+		/* Add the reg values. */
+		ret = fdt_setprop_u32(fdt, node_offset, (const char*)"reg", ptable->parts[i].start * blk_size);
+
+		if (ret != 0)
+		{
+			dprintf(CRITICAL, "Unable to add reg property. %s\n",
+					ptable->parts[i].name);
+			dt_ret = DT_OP_FAILURE;
+			goto dev_tree_add_ptable_nodes_err;
+		}
+
+		ret = fdt_appendprop_u32(fdt, node_offset, (const char*)"reg", ptable->parts[i].length * blk_size);
+
+		if (ret != 0)
+		{
+			dprintf(CRITICAL, "Unable to add reg property. %s\n",
+					ptable->parts[i].name);
+			dt_ret = DT_OP_FAILURE;
+			goto dev_tree_add_ptable_nodes_err;
+		}
+
+	}
+
+dev_tree_add_ptable_nodes_err:
+	free(ptn_name_array);
+	return dt_ret;
+}
+
+/* Top level function to add flash ptable info to the device tree. */
+static int dev_tree_add_flash_ptable(void *fdt)
+{
+	uint32_t offset;
+	int ret;
+	int dt_ret = DT_OP_SUCCESS;
+
+	dt_ret = dev_tree_get_flash_node_offset(fdt);
+
+	if (dt_ret < 0)
+	{
+		dt_ret = DT_OP_FAILURE;
+		goto dev_tree_add_flash_ptable_err;
+	}
+
+	offset = dt_ret;
+
+	/* Add address and size cell properties. */
+	ret = fdt_setprop_u32(fdt, offset, (const char*)"#address-cells", 1);
+
+	if (ret != 0)
+	{
+		dprintf(CRITICAL, "Unable to add #address-cells property. \n");
+		dt_ret = DT_OP_FAILURE;
+		goto dev_tree_add_flash_ptable_err;
+	}
+
+	ret = fdt_setprop_u32(fdt, offset, (const char*)"#size-cells", 1);
+
+	if (ret != 0)
+	{
+		dprintf(CRITICAL, "Unable to add #size-cells property. \n");
+		dt_ret = DT_OP_FAILURE;
+		goto dev_tree_add_flash_ptable_err;
+	}
+
+	ret = dev_tree_add_ptable_nodes(fdt, offset);
+
+	if (ret < 0)
+	{
+		dprintf(CRITICAL, "Unable to add #size-cells property. \n");
+		dt_ret = DT_OP_FAILURE;
+		goto dev_tree_add_flash_ptable_err;
+	}
+
+dev_tree_add_flash_ptable_err:
+	return dt_ret;
+}
+
+/* Function to add the first RAM partition info to the device tree.
+ * Note: The function replaces the reg property in the "/memory" node
+ * with the addr and size provided.
+ */
+int dev_tree_add_first_mem_info(uint32_t *fdt, uint32_t offset, uint32_t addr, uint32_t size)
+{
+	int ret;
+
+	ret = fdt_setprop_u32(fdt, offset, "reg", addr);
+
+	if (ret)
+	{
+		dprintf(CRITICAL, "Failed to add the memory information addr: %d\n",
+				ret);
+	}
+
+
+	ret = fdt_appendprop_u32(fdt, offset, "reg", size);
+
+	if (ret)
+	{
+		dprintf(CRITICAL, "Failed to add the memory information size: %d\n",
+				ret);
+	}
+
+	return ret;
+}
+
+/* Function to add the subsequent RAM partition info to the device tree. */
+int dev_tree_add_mem_info(void *fdt, uint32_t offset, uint32_t addr, uint32_t size)
+{
+	static int mem_info_cnt = 0;
+	int ret;
+
+	if (!mem_info_cnt)
+	{
+		/* Replace any other reg prop in the memory node. */
+		ret = fdt_setprop_u32(fdt, offset, "reg", addr);
+		mem_info_cnt = 1;
+	}
+	else
+	{
+		/* Append the mem info to the reg prop for subsequent nodes.  */
+		ret = fdt_appendprop_u32(fdt, offset, "reg", addr);
+	}
+
+	if (ret)
+	{
+		dprintf(CRITICAL, "Failed to add the memory information addr: %d\n",
+				ret);
+	}
+
+
+	ret = fdt_appendprop_u32(fdt, offset, "reg", size);
+
+	if (ret)
+	{
+		dprintf(CRITICAL, "Failed to add the memory information size: %d\n",
+				ret);
+	}
+
+	return ret;
+}
+
+/* Top level function that updates the device tree. */
+int update_device_tree(void *fdt, const char *cmdline,
+					   void *ramdisk, uint32_t ramdisk_size)
+{
+	int ret = 0;
+	uint32_t offset;
+	unsigned char *final_cmdline;
+
+	/* Check the device tree header */
+	ret = fdt_check_header(fdt);
+	if (ret)
+	{
+		dprintf(CRITICAL, "Invalid device tree header \n");
+		return ret;
+	}
+
+	/* Get offset of the memory node */
+	ret = fdt_path_offset(fdt, "/memory");
+	if (ret < 0)
+	{
+		dprintf(CRITICAL, "Could not find memory node.\n");
+		return ret;
+	}
+
+	offset = ret;
+
+	ret = target_dev_tree_mem(fdt, offset);
+	if(ret)
+	{
+		dprintf(CRITICAL, "ERROR: Cannot update memory node\n");
+		return ret;
+	}
+
+	/* Skip NAND partition nodes for eMMC boot */
+	if (!target_is_emmc_boot()){
+		dev_tree_add_flash_ptable(fdt);
+	}
+
+	/* Get offset of the chosen node */
+	ret = fdt_path_offset(fdt, "/chosen");
+	if (ret < 0)
+	{
+		dprintf(CRITICAL, "Could not find chosen node.\n");
+		return ret;
+	}
+
+	offset = ret;
+	/* Adding the cmdline to the chosen node */
+	final_cmdline = update_cmdline((const char*)cmdline);
+	ret = fdt_setprop_string(fdt, offset, (const char*)"bootargs", (const void*)final_cmdline);
+	if (ret)
+	{
+		dprintf(CRITICAL, "ERROR: Cannot update chosen node [bootargs]\n");
+		return ret;
+	}
+
+	/* Adding the initrd-start to the chosen node */
+	ret = fdt_setprop_u32(fdt, offset, "linux,initrd-start", (uint32_t)ramdisk);
+	if (ret)
+	{
+		dprintf(CRITICAL, "ERROR: Cannot update chosen node [linux,initrd-start]\n");
+		return ret;
+	}
+
+	/* Adding the initrd-end to the chosen node */
+	ret = fdt_setprop_u32(fdt, offset, "linux,initrd-end", ((uint32_t)ramdisk + ramdisk_size));
+	if (ret)
+	{
+		dprintf(CRITICAL, "ERROR: Cannot update chosen node [linux,initrd-end]\n");
+		return ret;
+	}
+
+	fdt_pack(fdt);
+
+	return ret;
+}
diff --git a/platform/msm_shared/include/dev_tree.h b/platform/msm_shared/include/dev_tree.h
new file mode 100644
index 0000000..5c58b38
--- /dev/null
+++ b/platform/msm_shared/include/dev_tree.h
@@ -0,0 +1,66 @@
+/* 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 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
+ * 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>
+
+#ifndef __DEVICE_TREE__
+#define __DEVICE_TREE__
+
+#define DEV_TREE_SUCCESS        0
+#define DEV_TREE_MAGIC          0x54444351 /* "QCDT" */
+#define DEV_TREE_MAGIC_LEN      4
+#define DEV_TREE_VERSION        1
+#define DEV_TREE_HEADER_SIZE    12
+
+struct dt_entry
+{
+	uint32_t platform_id;
+	uint32_t variant_id;
+	uint32_t soc_rev;
+	uint32_t offset;
+	uint32_t size;
+};
+
+struct dt_table
+{
+	uint32_t magic;
+	uint32_t version;
+	uint32_t num_entries;
+};
+
+enum dt_err_codes
+{
+	DT_OP_SUCCESS,
+	DT_OP_FAILURE = -1,
+};
+
+struct dt_entry * dev_tree_get_entry_ptr(struct dt_table *);
+int update_device_tree(void *, const char *, void *, unsigned);
+int dev_tree_add_mem_info(void *fdt, uint32_t offset, uint32_t size, uint32_t addr);
+
+#endif
diff --git a/platform/msm_shared/include/qpic_nand.h b/platform/msm_shared/include/qpic_nand.h
index 3431981..47224df 100644
--- a/platform/msm_shared/include/qpic_nand.h
+++ b/platform/msm_shared/include/qpic_nand.h
@@ -324,5 +324,8 @@
 
 void
 qpic_nand_init(struct qpic_nand_init_config *config);
+unsigned
+flash_block_size(void);
+
 
 #endif
diff --git a/platform/msm_shared/qpic_nand.c b/platform/msm_shared/qpic_nand.c
index faef7cd..693ecf2 100644
--- a/platform/msm_shared/qpic_nand.c
+++ b/platform/msm_shared/qpic_nand.c
@@ -1215,17 +1215,27 @@
 		bbtbl[i] = NAND_BAD_BLK_VALUE_NOT_READ;
 }
 
-unsigned flash_page_size(void)
+unsigned
+flash_page_size(void)
 {
 	return flash.page_size;
 }
 
-struct ptable *flash_get_ptable(void)
+unsigned
+flash_block_size(void)
+{
+    return flash.block_size;
+}
+
+
+struct ptable *
+flash_get_ptable(void)
 {
 	return flash_ptable;
 }
 
-void flash_set_ptable(struct ptable *new_ptable)
+void
+flash_set_ptable(struct ptable *new_ptable)
 {
 	ASSERT(flash_ptable == NULL && new_ptable != NULL);
 	flash_ptable = new_ptable;
diff --git a/platform/msm_shared/rules.mk b/platform/msm_shared/rules.mk
index 53da1cc..6101a02 100644
--- a/platform/msm_shared/rules.mk
+++ b/platform/msm_shared/rules.mk
@@ -71,7 +71,8 @@
 			$(LOCAL_DIR)/board.o \
 			$(LOCAL_DIR)/spmi.o \
 			$(LOCAL_DIR)/bam.o \
-			$(LOCAL_DIR)/nand.o
+			$(LOCAL_DIR)/qpic_nand.o \
+			$(LOCAL_DIR)/dev_tree.o
 endif
 
 ifeq ($(PLATFORM),msm7x27a)
@@ -130,5 +131,6 @@
 			$(LOCAL_DIR)/qtimer_mmap.o \
 			$(LOCAL_DIR)/board.o \
 			$(LOCAL_DIR)/qpic_nand.o \
-			$(LOCAL_DIR)/bam.o
+			$(LOCAL_DIR)/bam.o \
+			$(LOCAL_DIR)/dev_tree.o
 endif
diff --git a/project/mdm9625.mk b/project/mdm9625.mk
index e450f6a..9f5f305 100644
--- a/project/mdm9625.mk
+++ b/project/mdm9625.mk
@@ -9,6 +9,7 @@
 #DEFINES += WITH_DEBUG_DCC=1
 #DEFINES += WITH_DEBUG_UART=1
 #DEFINES += WITH_DEBUG_FBCON=1
+DEFINES += DEVICE_TREE=1
 
 #disable Thumb mode for the codesourcery/arm-2011.03 toolchain
 ENABLE_THUMB := false
diff --git a/target/copper/meminfo.c b/target/copper/meminfo.c
index fae3aea..e0feaa1 100644
--- a/target/copper/meminfo.c
+++ b/target/copper/meminfo.c
@@ -1,29 +1,29 @@
-/* Copyright (c) 2009-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:
+ * 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.
+ *     * 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.
  */
 
 #if DEVICE_TREE /* If using device tree */
@@ -35,6 +35,7 @@
 #include <stdint.h>
 #include <libfdt.h>
 #include <platform/iomap.h>
+#include <dev_tree.h>
 
 #define SIZE_1M             (1024 * 1024)
 
@@ -43,7 +44,6 @@
 	uint32_t start_addr;
 }mem_info;
 
-
 mem_info copper_default_fixed_memory[] = {
 	{	.size = (132 * SIZE_1M),
 		.start_addr = SDRAM_START_ADDR
@@ -60,19 +60,13 @@
 	},
 };
 
-uint32_t *target_mem_dev_tree_create(uint32_t *ptr, uint32_t size, uint32_t addr)
-{
-	*ptr++ = cpu_to_fdt32(addr);
-	*ptr++ = cpu_to_fdt32(size);
-
-	return ptr;
-}
-
-uint32_t *target_dev_tree_create(uint32_t *ptr,
-								 mem_info usable_mem_map[],
-								 uint32_t num_regions)
+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);
 
@@ -80,96 +74,91 @@
 
 	for (i = 0; i < num_regions; i++)
 	{
-            ptr = target_mem_dev_tree_create(ptr,
-                            usable_mem_map[i].size,
-                            usable_mem_map[i].start_addr);
+           ret = dev_tree_add_mem_info(fdt,
+									   offset,
+									   usable_mem_map[i].start_addr,
+									   usable_mem_map[i].size);
 	}
-	return ptr;
+	return ret;
 }
 
-uint32_t* target_dev_tree_mem(uint32_t *num_of_entries)
+/* 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.
+ */
+uint32_t target_dev_tree_mem(void *fdt, uint32_t memory_node_offset)
 {
     struct smem_ram_ptable ram_ptable;
-    uint32_t *meminfo_ptr;
-    uint32_t num_of_sections = 0;
-    uint32_t *ptr;
-    uint32_t last_fixed_add;
+    uint32_t last_fixed_addr;
     int n;
-    int i;
-    int index = 0;
-    int count = 0;
-    int overflow = 0;
+    unsigned int i;
+	int ret;
 
 	/* Make sure RAM partition table is initialized */
 	ASSERT(smem_ram_ptable_init(&ram_ptable));
 
     n = ARRAY_SIZE(copper_default_fixed_memory);
-    last_fixed_add = copper_default_fixed_memory[n-1].start_addr +
-                     copper_default_fixed_memory[n-1].size;
 
-    /* Find the number of parts in ram_ptable of category SDRAM and type SYS_MEMORY */
-    for(i = 0; i < ram_ptable.len; i++)
-    {   if((ram_ptable.parts[i].category ==SDRAM) &&
-           (ram_ptable.parts[i].type == SYS_MEMORY))
-            count++;
-    }
+    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 */
+     /* Calculating the size of the mem_info_ptr */
     for (i = 0 ; i < ram_ptable.len; i++)
     {
-        if((ram_ptable.parts[i].category ==SDRAM) &&
+        if((ram_ptable.parts[i].category == SDRAM) &&
            (ram_ptable.parts[i].type == SYS_MEMORY))
         {
-            if((ram_ptable.parts[i].start <= last_fixed_add) &&
-               ((ram_ptable.parts[i].start + ram_ptable.parts[i].size) >= last_fixed_add))
+            if((ram_ptable.parts[i].start <= last_fixed_addr) &&
+			   ((ram_ptable.parts[i].start + ram_ptable.parts[i].size) >= last_fixed_addr))
             {
-                if((ram_ptable.parts[i].start + ram_ptable.parts[i].size) == last_fixed_add)
-                {
-                    num_of_sections = n + (count - i - 1);
+
+				/* 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));
+
+				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
-                {
-                    num_of_sections = n + (count - i );
-                    overflow = 1;
-                }
-                index = i+1;
-                break;
-            }
-        }
+			}
+			else
+			{
+				/* 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;
+				}
+			}
+       }
     }
 
-    *num_of_entries = num_of_sections;
-    meminfo_ptr = (uint32_t*) malloc(sizeof(uint32_t) * num_of_sections * 2);
-    ptr = meminfo_ptr;
+target_dev_tree_mem_err:
 
-    /* Assumption that the fixed memory region always starts from the first ram_ptable part */
-    ASSERT((ram_ptable.parts[0].category ==SDRAM) &&
-           (ram_ptable.parts[0].type == SYS_MEMORY) &&
-           (ram_ptable.parts[0].start == SDRAM_START_ADDR));
-
-    /* Pass along all fixed memory regions to Linux */
-    meminfo_ptr = target_dev_tree_create(meminfo_ptr, copper_default_fixed_memory,
-                                          ARRAY_SIZE(copper_default_fixed_memory));
-
-    if(overflow)
-    {
-        /* Pass the memory beyond the fixed memory present in the partition */
-        meminfo_ptr = target_mem_dev_tree_create(meminfo_ptr,
-                                                 ram_ptable.parts[i].size - last_fixed_add,
-                                                 ram_ptable.parts[i].start + last_fixed_add);
-    }
-    for( i = index ; i < ram_ptable.len ; i ++)
-    {
-        if((ram_ptable.parts[i].category ==SDRAM) &&
-           (ram_ptable.parts[i].type == SYS_MEMORY))
-        {
-            /* Pass along all other usable memory regions to Linux */
-            meminfo_ptr = target_mem_dev_tree_create(meminfo_ptr,
-                                                      ram_ptable.parts[i].size,
-                                                      ram_ptable.parts[i].start);
-        }
-    }
-    return ptr;
+    return ret;
 }
 
 void *target_get_scratch_address(void)
@@ -182,4 +171,3 @@
 	return (512 * 1024 * 1024);
 }
 #endif /* DEVICE_TREE */
-
diff --git a/target/mdm9625/init.c b/target/mdm9625/init.c
index 81a1c27..d9d7e9c 100644
--- a/target/mdm9625/init.c
+++ b/target/mdm9625/init.c
@@ -1,5 +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
@@ -10,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 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 +25,7 @@
  * 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>
 #include <board.h>
 #include <platform.h>
@@ -34,6 +34,11 @@
 #include <baseband.h>
 #include <lib/ptable.h>
 #include <qpic_nand.h>
+#include <ctype.h>
+#include <string.h>
+
+extern void smem_ptable_init(void);
+extern void smem_add_modem_partitions(struct ptable *flash_ptable);
 
 static struct ptable flash_ptable;
 
@@ -43,6 +48,34 @@
 #define CMD_PIPE                                      2
 
 struct qpic_nand_init_config config;
+
+void update_ptable_names(void)
+{
+	uint32_t ptn_index;
+	struct ptentry *ptentry_ptr = flash_ptable.parts;
+	struct ptentry *boot_ptn;
+	unsigned i;
+	uint32_t len;
+
+	/* Change all names to lower case. */
+	for (ptn_index = 0; ptn_index != (uint32_t)flash_ptable.count; ptn_index++)
+	{
+		len = strlen(ptentry_ptr[ptn_index].name);
+
+		for (i = 0; i < len; i++)
+		{
+			if (isupper(ptentry_ptr[ptn_index].name[i]))
+			{
+				ptentry_ptr[ptn_index].name[i] = tolower(ptentry_ptr[ptn_index].name[i]);
+			}
+		}
+	}
+
+	/* Rename apps ptn to boot. */
+	boot_ptn = ptable_find(&flash_ptable, "apps");
+	strcpy(boot_ptn->name, "boot");
+}
+
 /* init */
 void target_init(void)
 {
@@ -57,14 +90,15 @@
 
 	qpic_nand_init(&config);
 
-	/* Below lines are to be removed once the bootchain is available */
-
 	ptable_init(&flash_ptable);
 
-	flash_set_ptable(&flash_ptable);
+	smem_ptable_init();
 
-	/* Add boot ptn..until the bootchain adds it */
-	ptable_add(&flash_ptable, "boot", 0x347, 0x52, 0, TYPE_APPS_PARTITION, PERM_WRITEABLE);
+	smem_add_modem_partitions(&flash_ptable);
+
+	update_ptable_names();
+
+	flash_set_ptable(&flash_ptable);
 }
 
 /* reboot */
@@ -80,25 +114,25 @@
 	return 0;
 }
 
-/* Create ATAGs for this target */
-unsigned* target_atag_mem(unsigned* ptr)
-{
-	return ptr;
-}
-
-/* mach type */
-unsigned board_machtype(void)
-{
-	//return board_target_id();
-}
-
 /* Identify the current target */
 void target_detect(struct board_data *board)
 {
 }
 
+unsigned board_machtype(void)
+{
+	return  board_target_id();
+}
+
 /* Identify the baseband being used */
 void target_baseband_detect(struct board_data *board)
 {
-
+	/* Check for baseband variants. Default to MSM */
+	if (board->platform_subtype == HW_PLATFORM_SUBTYPE_MDM)
+		board->baseband = BASEBAND_MDM;
+	else
+	{
+		dprintf(CRITICAL, "Could not detect baseband id\n");
+		ASSERT(0);
+	}
 }
diff --git a/target/mdm9625/meminfo.c b/target/mdm9625/meminfo.c
new file mode 100644
index 0000000..96b1b5b
--- /dev/null
+++ b/target/mdm9625/meminfo.c
@@ -0,0 +1,164 @@
+/* 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 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
+ * 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 <malloc.h>
+#include <smem.h>
+#include <stdint.h>
+#include <libfdt.h>
+#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 mdm9625_default_fixed_memory[] = {
+	{	.size = (29 * SIZE_1M),
+		.start_addr = SDRAM_START_ADDR +
+				(2 * SIZE_1M)
+	},
+	{	.size = (10 * SIZE_1M),
+		.start_addr = SDRAM_START_ADDR +
+				(118 * 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.
+ */
+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 +
+					mdm9625_default_fixed_memory[n-1].size;
+
+    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,
+												 mdm9625_default_fixed_memory,
+												 ARRAY_SIZE(mdm9625_default_fixed_memory));
+
+				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
+			{
+				/* 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;
+				}
+			}
+        }
+    }
+
+target_dev_tree_mem_err:
+
+    return ret;
+}
+
+void *target_get_scratch_address(void)
+{
+	return ((void *)SCRATCH_ADDR);
+}
+
+unsigned target_get_max_flash_size(void)
+{
+	return (28 * 1024 * 1024);
+}
diff --git a/target/mdm9625/rules.mk b/target/mdm9625/rules.mk
index d577380..9e54221 100755
--- a/target/mdm9625/rules.mk
+++ b/target/mdm9625/rules.mk
@@ -12,11 +12,13 @@
 
 MODULES += \
 	dev/keys \
-	lib/ptable
+	lib/ptable \
+	lib/libfdt
 
 DEFINES += \
 	MEMBASE=$(MEMBASE) \
 	SCRATCH_ADDR=$(SCRATCH_ADDR)
 
 OBJS += \
-	$(LOCAL_DIR)/init.o
+	$(LOCAL_DIR)/init.o \
+	$(LOCAL_DIR)/meminfo.o