Merge "msm8974: Add dynamic ram partitions based on smem."
diff --git a/target/copper/meminfo.c b/target/copper/meminfo.c
index c8460bb..fae3aea 100644
--- a/target/copper/meminfo.c
+++ b/target/copper/meminfo.c
@@ -58,9 +58,6 @@
 				(16 * SIZE_1M) +
 				(256 * SIZE_1M)
 	},
-	{	.size = (512 * SIZE_1M),
-		.start_addr = (512 * SIZE_1M),
-	}
 };
 
 uint32_t *target_mem_dev_tree_create(uint32_t *ptr, uint32_t size, uint32_t addr)
@@ -93,24 +90,86 @@
 uint32_t* target_dev_tree_mem(uint32_t *num_of_entries)
 {
     struct smem_ram_ptable ram_ptable;
-	uint32_t *meminfo_ptr;
-	uint32_t num_of_sections;
-	uint32_t *ptr;
+    uint32_t *meminfo_ptr;
+    uint32_t num_of_sections = 0;
+    uint32_t *ptr;
+    uint32_t last_fixed_add;
+    int n;
+    int i;
+    int index = 0;
+    int count = 0;
+    int overflow = 0;
 
 	/* Make sure RAM partition table is initialized */
 	ASSERT(smem_ram_ptable_init(&ram_ptable));
 
-	num_of_sections = ARRAY_SIZE(copper_default_fixed_memory);
-	*num_of_entries = num_of_sections;
+    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;
 
-	meminfo_ptr = (uint32_t*) malloc(sizeof(uint32_t) * num_of_sections * 2);
-	ptr = meminfo_ptr;
+    /* 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++;
+    }
 
-	target_dev_tree_create(ptr,
-						   copper_default_fixed_memory,
-						   ARRAY_SIZE(copper_default_fixed_memory));
+    /* 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_add) &&
+               ((ram_ptable.parts[i].start + ram_ptable.parts[i].size) >= last_fixed_add))
+            {
+                if((ram_ptable.parts[i].start + ram_ptable.parts[i].size) == last_fixed_add)
+                {
+                    num_of_sections = n + (count - i - 1);
+                }
+                else
+                {
+                    num_of_sections = n + (count - i );
+                    overflow = 1;
+                }
+                index = i+1;
+                break;
+            }
+        }
+    }
 
-    return meminfo_ptr;
+    *num_of_entries = num_of_sections;
+    meminfo_ptr = (uint32_t*) malloc(sizeof(uint32_t) * num_of_sections * 2);
+    ptr = meminfo_ptr;
+
+    /* 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;
 }
 
 void *target_get_scratch_address(void)