sh: sparsemem support.

This implements basic sparsemem support for SH. Presently this only
uses static sparsemem, and we still permit explicit selection of
flatmem. Those boards that want sparsemem can select it as usual.

Signed-off-by: Paul Mundt <lethal@linux-sh.org>
diff --git a/arch/sh/kernel/setup.c b/arch/sh/kernel/setup.c
index 6f1ea9b..3241a62 100644
--- a/arch/sh/kernel/setup.c
+++ b/arch/sh/kernel/setup.c
@@ -128,6 +128,7 @@
 	bootmap_size = init_bootmem_node(NODE_DATA(0), start_pfn,
 					 min_low_pfn, max_low_pfn);
 
+	add_active_range(0, min_low_pfn, max_low_pfn);
 	register_bootmem_low_pages();
 
 	node_set_online(0);
@@ -192,6 +193,7 @@
 	 */
 	start_pfn = PFN_UP(__pa(_end));
 	setup_bootmem_allocator(start_pfn);
+	sparse_memory_present_with_active_regions(0);
 }
 #else
 extern void __init setup_memory(void);
@@ -250,8 +252,9 @@
 	min_low_pfn = __MEMORY_START >> PAGE_SHIFT;
 
 	nodes_clear(node_online_map);
+
+	/* Setup bootmem with available RAM */
 	setup_memory();
-	paging_init();
 	sparse_init();
 
 #ifdef CONFIG_DUMMY_CONSOLE
@@ -261,8 +264,9 @@
 	/* Perform the machine specific initialisation */
 	if (likely(sh_mv.mv_setup))
 		sh_mv.mv_setup(cmdline_p);
-}
 
+	paging_init();
+}
 
 static const char *cpu_name[] = {
 	[CPU_SH7206]	= "SH7206",	[CPU_SH7619]	= "SH7619",
diff --git a/arch/sh/mm/Kconfig b/arch/sh/mm/Kconfig
index 00f64c4..46fd212 100644
--- a/arch/sh/mm/Kconfig
+++ b/arch/sh/mm/Kconfig
@@ -300,6 +300,13 @@
 config ARCH_FLATMEM_ENABLE
 	def_bool y
 
+config ARCH_SPARSEMEM_ENABLE
+	def_bool y
+	select SPARSEMEM_STATIC
+
+config ARCH_SPARSEMEM_DEFAULT
+	def_bool y
+
 config MAX_ACTIVE_REGIONS
 	int
 	default "1"
@@ -307,6 +314,9 @@
 config ARCH_POPULATES_NODE_MAP
 	def_bool y
 
+config ARCH_SELECT_MEMORY_MODEL
+	def_bool y
+
 choice
 	prompt "Kernel page size"
 	default PAGE_SIZE_4KB
diff --git a/arch/sh/mm/init.c b/arch/sh/mm/init.c
index e0e644f..1589466 100644
--- a/arch/sh/mm/init.c
+++ b/arch/sh/mm/init.c
@@ -36,14 +36,11 @@
 	show_free_areas();
 
 	for_each_online_pgdat(pgdat) {
-		struct page *page, *end;
-		unsigned long flags;
+		unsigned long flags, i;
 
 		pgdat_resize_lock(pgdat, &flags);
-		page = pgdat->node_mem_map;
-		end = page + pgdat->node_spanned_pages;
-
-		do {
+		for (i = 0; i < pgdat->node_spanned_pages; i++) {
+			struct page *page = pgdat_page_nr(pgdat, i);
 			total++;
 			if (PageReserved(page))
 				reserved++;
@@ -55,9 +52,7 @@
 				free++;
 			else
 				shared += page_count(page) - 1;
-			page++;
-		} while (page < end);
-
+		}
 		pgdat_resize_unlock(pgdat, &flags);
 	}
 
@@ -169,15 +164,11 @@
 		low = pgdat->bdata->node_low_pfn;
 
 		max_zone_pfns[ZONE_NORMAL] = low;
-		add_active_range(nid, start_pfn, low);
 
 		printk("Node %u: start_pfn = 0x%lx, low = 0x%lx\n",
 		       nid, start_pfn, low);
 
 		free_area_init_nodes(max_zone_pfns);
-
-		printk("Node %u: mem_map starts at %p\n",
-		       pgdat->node_id, pgdat->node_mem_map);
 	}
 }
 
@@ -185,16 +176,13 @@
 
 void __init mem_init(void)
 {
-	int codesize, reservedpages, datasize, initsize;
+	int codesize, datasize, initsize;
 	int nid;
 
-	reservedpages = 0;
-
 	for_each_online_node(nid) {
 		pg_data_t *pgdat = NODE_DATA(nid);
 		unsigned long node_pages = 0;
 		void *node_high_memory;
-		int i;
 
 		num_physpages += pgdat->node_present_pages;
 
@@ -203,10 +191,6 @@
 
 		totalram_pages += node_pages;
 
-		for (i = 0; i < node_pages; i++)
-			if (PageReserved(pgdat->node_mem_map + i))
-				reservedpages++;
-
 		node_high_memory = (void *)((pgdat->node_start_pfn +
 					     pgdat->node_spanned_pages) <<
 						PAGE_SHIFT);
@@ -239,11 +223,10 @@
 		   VMALLOC_END - VMALLOC_START);
 
 	printk(KERN_INFO "Memory: %luk/%luk available (%dk kernel code, "
-	       "%dk reserved, %dk data, %dk init)\n",
+	       "%dk data, %dk init)\n",
 		(unsigned long) nr_free_pages() << (PAGE_SHIFT-10),
 		totalram_pages << (PAGE_SHIFT-10),
 		codesize >> 10,
-		reservedpages << (PAGE_SHIFT-10),
 		datasize >> 10,
 		initsize >> 10);
 
diff --git a/include/asm-sh/sparsemem.h b/include/asm-sh/sparsemem.h
new file mode 100644
index 0000000..547a540
--- /dev/null
+++ b/include/asm-sh/sparsemem.h
@@ -0,0 +1,16 @@
+#ifndef __ASM_SH_SPARSEMEM_H
+#define __ASM_SH_SPARSEMEM_H
+
+#ifdef __KERNEL__
+/*
+ * SECTION_SIZE_BITS		2^N: how big each section will be
+ * MAX_PHYSADDR_BITS		2^N: how much physical address space we have
+ * MAX_PHYSMEM_BITS		2^N: how much memory we can have in that space
+ */
+#define SECTION_SIZE_BITS	26
+#define MAX_PHYSADDR_BITS	32
+#define MAX_PHYSMEM_BITS	32
+
+#endif
+
+#endif /* __ASM_SH_SPARSEMEM_H */