diff --git a/arch/mips/mti-sead3/sead3-dtshim.c b/arch/mips/mti-sead3/sead3-dtshim.c
index 6e32ceba533b50ff2b27557c5779ccd3546f678d..d6b0708d7a6f437a3e5b2fec0b38a1b484fd59f6 100644
--- a/arch/mips/mti-sead3/sead3-dtshim.c
+++ b/arch/mips/mti-sead3/sead3-dtshim.c
@@ -22,6 +22,73 @@
 
 static unsigned char fdt_buf[16 << 10] __initdata;
 
+static int append_memory(void *fdt)
+{
+	unsigned long phys_memsize, memsize;
+	__be32 mem_array[2];
+	int err, mem_off;
+	char *var;
+
+	/* find memory size from the bootloader environment */
+	var = fw_getenv("memsize");
+	if (var) {
+		err = kstrtoul(var, 0, &phys_memsize);
+		if (err) {
+			pr_err("Failed to read memsize env variable '%s'\n",
+			       var);
+			return -EINVAL;
+		}
+	} else {
+		pr_warn("The bootloader didn't provide memsize: defaulting to 32MB\n");
+		phys_memsize = 32 << 20;
+	}
+
+	/* default to using all available RAM */
+	memsize = phys_memsize;
+
+	/* allow the user to override the usable memory */
+	var = strstr(arcs_cmdline, "memsize=");
+	if (var)
+		memsize = memparse(var + strlen("memsize="), NULL);
+
+	/* if the user says there's more RAM than we thought, believe them */
+	phys_memsize = max_t(unsigned long, phys_memsize, memsize);
+
+	/* find or add a memory node */
+	mem_off = fdt_path_offset(fdt, "/memory");
+	if (mem_off == -FDT_ERR_NOTFOUND)
+		mem_off = fdt_add_subnode(fdt, 0, "memory");
+	if (mem_off < 0) {
+		pr_err("Unable to find or add memory DT node: %d\n", mem_off);
+		return mem_off;
+	}
+
+	err = fdt_setprop_string(fdt, mem_off, "device_type", "memory");
+	if (err) {
+		pr_err("Unable to set memory node device_type: %d\n", err);
+		return err;
+	}
+
+	mem_array[0] = 0;
+	mem_array[1] = cpu_to_be32(phys_memsize);
+	err = fdt_setprop(fdt, mem_off, "reg", mem_array, sizeof(mem_array));
+	if (err) {
+		pr_err("Unable to set memory regs property: %d\n", err);
+		return err;
+	}
+
+	mem_array[0] = 0;
+	mem_array[1] = cpu_to_be32(memsize);
+	err = fdt_setprop(fdt, mem_off, "linux,usable-memory",
+			  mem_array, sizeof(mem_array));
+	if (err) {
+		pr_err("Unable to set linux,usable-memory property: %d\n", err);
+		return err;
+	}
+
+	return 0;
+}
+
 static int remove_gic(void *fdt)
 {
 	const unsigned int cpu_ehci_int = 2;
@@ -205,6 +272,10 @@ void __init *sead3_dt_shim(void *fdt)
 	if (err)
 		panic("Unable to open FDT: %d", err);
 
+	err = append_memory(fdt_buf);
+	if (err)
+		panic("Unable to patch FDT: %d", err);
+
 	err = remove_gic(fdt_buf);
 	if (err)
 		panic("Unable to patch FDT: %d", err);
diff --git a/arch/mips/mti-sead3/sead3-setup.c b/arch/mips/mti-sead3/sead3-setup.c
index c4fc0c6d26543bfaccc1569adc62e38bb7189586..c915e54f10acef1de7cf76da1634ec5e3464347e 100644
--- a/arch/mips/mti-sead3/sead3-setup.c
+++ b/arch/mips/mti-sead3/sead3-setup.c
@@ -11,7 +11,6 @@
 #include <linux/of_fdt.h>
 
 #include <asm/prom.h>
-#include <asm/fw/fw.h>
 
 #include <asm/mach-sead3/sead3-dtshim.h>
 #include <asm/mips-boards/generic.h>
@@ -21,68 +20,6 @@ const char *get_system_type(void)
 	return "MIPS SEAD3";
 }
 
-static uint32_t get_memsize_from_cmdline(void)
-{
-	int memsize = 0;
-	char *p = arcs_cmdline;
-	char *s = "memsize=";
-
-	p = strstr(p, s);
-	if (p) {
-		p += strlen(s);
-		memsize = memparse(p, NULL);
-	}
-
-	return memsize;
-}
-
-static uint32_t get_memsize_from_env(void)
-{
-	int memsize = 0;
-	char *p;
-
-	p = fw_getenv("memsize");
-	if (p)
-		memsize = memparse(p, NULL);
-
-	return memsize;
-}
-
-static uint32_t get_memsize(void)
-{
-	uint32_t memsize;
-
-	memsize = get_memsize_from_cmdline();
-	if (memsize)
-		return memsize;
-
-	return get_memsize_from_env();
-}
-
-static void __init parse_memsize_param(void)
-{
-	int offset;
-	const uint64_t *prop_value;
-	int prop_len;
-	uint32_t memsize = get_memsize();
-
-	if (!memsize)
-		return;
-
-	offset = fdt_path_offset(__dtb_start, "/memory");
-	if (offset > 0) {
-		uint64_t new_value;
-		/*
-		 * reg contains 2 32-bits BE values, offset and size. We just
-		 * want to replace the size value without affecting the offset
-		 */
-		prop_value = fdt_getprop(__dtb_start, offset, "reg", &prop_len);
-		new_value = be64_to_cpu(*prop_value);
-		new_value =  (new_value & ~0xffffffffllu) | memsize;
-		fdt_setprop_inplace_u64(__dtb_start, offset, "reg", new_value);
-	}
-}
-
 void __init *plat_get_fdt(void)
 {
 	return (void *)__dtb_start;
@@ -92,9 +29,6 @@ void __init plat_mem_setup(void)
 {
 	void *fdt = plat_get_fdt();
 
-	/* allow command line/bootloader env to override memory size in DT */
-	parse_memsize_param();
-
 	fdt = sead3_dt_shim(fdt);
 	__dt_setup_arch(fdt);
 }