}
 }
 
-static int register_device(char *name, unsigned long start, unsigned long len)
+static int register_device(char *name, phys_addr_t start, size_t len)
 {
        struct phram_mtd_list *new;
        int ret = -ENOMEM;
        return ret;
 }
 
-static int ustrtoul(const char *cp, char **endp, unsigned int base)
+static int parse_num64(uint64_t *num64, char *token)
 {
-       unsigned long result = simple_strtoul(cp, endp, base);
-
-       switch (**endp) {
-       case 'G':
-               result *= 1024;
-       case 'M':
-               result *= 1024;
-       case 'k':
-               result *= 1024;
+       size_t len;
+       int shift = 0;
+       int ret;
+
+       len = strlen(token);
        /* By dwmw2 editorial decree, "ki", "Mi" or "Gi" are to be used. */
-               if ((*endp)[1] == 'i')
-                       (*endp) += 2;
+       if (len > 2) {
+               if (token[len - 1] == 'i') {
+                       switch (token[len - 2]) {
+                       case 'G':
+                               shift += 10;
+                       case 'M':
+                               shift += 10;
+                       case 'k':
+                               shift += 10;
+                               token[len - 2] = 0;
+                               break;
+                       default:
+                               return -EINVAL;
+                       }
+               }
        }
-       return result;
-}
 
-static int parse_num32(uint32_t *num32, const char *token)
-{
-       char *endp;
-       unsigned long n;
+       ret = kstrtou64(token, 0, num64);
+       *num64 <<= shift;
 
-       n = ustrtoul(token, &endp, 0);
-       if (*endp)
-               return -EINVAL;
-
-       *num32 = n;
-       return 0;
+       return ret;
 }
 
 static int parse_name(char **pname, const char *token)
  * This shall contain the module parameter if any. It is of the form:
  * - phram=<device>,<address>,<size> for module case
  * - phram.phram=<device>,<address>,<size> for built-in case
- * We leave 64 bytes for the device name, 12 for the address and 12 for the
+ * We leave 64 bytes for the device name, 20 for the address and 20 for the
  * size.
  * Example: phram.phram=rootfs,0xa0000000,512Mi
  */
-static __initdata char phram_paramline[64+12+12];
+static __initdata char phram_paramline[64 + 20 + 20];
 
 static int __init phram_setup(const char *val)
 {
-       char buf[64+12+12], *str = buf;
+       char buf[64 + 20 + 20], *str = buf;
        char *token[3];
        char *name;
-       uint32_t start;
-       uint32_t len;
+       uint64_t start;
+       uint64_t len;
        int i, ret;
 
        if (strnlen(val, sizeof(buf)) >= sizeof(buf))
        if (ret)
                return ret;
 
-       ret = parse_num32(&start, token[1]);
+       ret = parse_num64(&start, token[1]);
        if (ret) {
                kfree(name);
                parse_err("illegal start address\n");
        }
 
-       ret = parse_num32(&len, token[2]);
+       ret = parse_num64(&len, token[2]);
        if (ret) {
                kfree(name);
                parse_err("illegal device length\n");
 
        ret = register_device(name, start, len);
        if (!ret)
-               pr_info("%s device: %#x at %#x\n", name, len, start);
+               pr_info("%s device: %#llx at %#llx\n", name, len, start);
        else
                kfree(name);