powerpc: make mem= work on iSeries again

By parsing the command line earlier, we can add the mem= value to the
flattened device tree and let the generic code sort out the memory limit
for us.

Signed-off-by: Stephen Rothwell <sfr@canb.auug.org.au>
diff --git a/arch/powerpc/kernel/setup_64.c b/arch/powerpc/kernel/setup_64.c
index 40c4810..19530ce 100644
--- a/arch/powerpc/kernel/setup_64.c
+++ b/arch/powerpc/kernel/setup_64.c
@@ -631,23 +631,6 @@
 	return NOTIFY_DONE;
 }
 
-#ifdef CONFIG_PPC_ISERIES
-/*
- * On iSeries we just parse the mem=X option from the command line.
- * On pSeries it's a bit more complicated, see prom_init_mem()
- */
-static int __init early_parsemem(char *p)
-{
-	if (!p)
-		return 0;
-
-	memory_limit = ALIGN(memparse(p, &p), PAGE_SIZE);
-
-	return 0;
-}
-early_param("mem", early_parsemem);
-#endif /* CONFIG_PPC_ISERIES */
-
 #ifdef CONFIG_IRQSTACKS
 static void __init irqstack_early_init(void)
 {
diff --git a/arch/powerpc/platforms/iseries/setup.c b/arch/powerpc/platforms/iseries/setup.c
index 1544c6f..06431e6 100644
--- a/arch/powerpc/platforms/iseries/setup.c
+++ b/arch/powerpc/platforms/iseries/setup.c
@@ -27,6 +27,7 @@
 #include <linux/kdev_t.h>
 #include <linux/major.h>
 #include <linux/root_dev.h>
+#include <linux/kernel.h>
 
 #include <asm/processor.h>
 #include <asm/machdep.h>
@@ -94,6 +95,8 @@
 
 static int mf_initialized;
 
+static unsigned long cmd_mem_limit;
+
 struct MemoryBlock {
 	unsigned long absStart;
 	unsigned long absEnd;
@@ -341,23 +344,6 @@
 	 */
 	iommu_init_early_iSeries();
 
-	iSeries_get_cmdline();
-
-	/* Save unparsed command line copy for /proc/cmdline */
-	strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
-
-	/* Parse early parameters, in particular mem=x */
-	parse_early_param();
-
-	if (memory_limit) {
-		if (memory_limit < systemcfg->physicalMemorySize)
-			systemcfg->physicalMemorySize = memory_limit;
-		else {
-			printk("Ignoring mem=%lu >= ram_top.\n", memory_limit);
-			memory_limit = 0;
-		}
-	}
-
 	/* Initialize machine-dependency vectors */
 #ifdef CONFIG_SMP
 	smp_init_iSeries();
@@ -971,6 +957,8 @@
 	/* /chosen */
 	dt_start_node(dt, "chosen");
 	dt_prop_u32(dt, "linux,platform", PLATFORM_ISERIES_LPAR);
+	if (cmd_mem_limit)
+		dt_prop_u64(dt, "linux,memory-limit", cmd_mem_limit);
 	dt_end_node(dt);
 
 	dt_cpus(dt);
@@ -990,7 +978,27 @@
 	 */
 	build_iSeries_Memory_Map();
 
+	iSeries_get_cmdline();
+
+	/* Save unparsed command line copy for /proc/cmdline */
+	strlcpy(saved_command_line, cmd_line, COMMAND_LINE_SIZE);
+
+	/* Parse early parameters, in particular mem=x */
+	parse_early_param();
+
 	build_flat_dt(&iseries_dt);
 
 	return (void *) __pa(&iseries_dt);
 }
+
+/*
+ * On iSeries we just parse the mem=X option from the command line.
+ * On pSeries it's a bit more complicated, see prom_init_mem()
+ */
+static int __init early_parsemem(char *p)
+{
+	if (p)
+		cmd_mem_limit = ALIGN(memparse(p, &p), PAGE_SIZE);
+	return 0;
+}
+early_param("mem", early_parsemem);