diff options
author | Alexander Sverdlin <alexander.sverdlin@nsn.com> | 2013-10-02 12:42:29 -0400 |
---|---|---|
committer | Brian Norris <computersforpeace@gmail.com> | 2013-11-07 02:32:37 -0500 |
commit | 2a46f83570380ee2f5893a5bb2402ce2945f4f23 (patch) | |
tree | 451c8f1e71f80b5ee25744125da7ad25d6570e00 /drivers/mtd | |
parent | 14a95b8a23133f1b21bb3e8b05d24d03ab5722c0 (diff) |
mtd: phram: Make phram 64-bit compatible
phram was 32-bit limited by design. Machines are growing up, but phram
module is still useful. Update it. The patch is bigger than minimum,
because simple_strtoul() is obsolete.
Tested on MIPS64 and compile-tested for PPC (32 bit).
Signed-off-by: Alexander Sverdlin <alexander.sverdlin@nsn.com>
Reviewed-by: Joern Engel <joern@logfs.org>
Signed-off-by: Brian Norris <computersforpeace@gmail.com>
Diffstat (limited to 'drivers/mtd')
-rw-r--r-- | drivers/mtd/devices/phram.c | 66 |
1 files changed, 33 insertions, 33 deletions
diff --git a/drivers/mtd/devices/phram.c b/drivers/mtd/devices/phram.c index 67823de68db6..e1f2aebaa489 100644 --- a/drivers/mtd/devices/phram.c +++ b/drivers/mtd/devices/phram.c | |||
@@ -94,7 +94,7 @@ static void unregister_devices(void) | |||
94 | } | 94 | } |
95 | } | 95 | } |
96 | 96 | ||
97 | static int register_device(char *name, unsigned long start, unsigned long len) | 97 | static int register_device(char *name, phys_addr_t start, size_t len) |
98 | { | 98 | { |
99 | struct phram_mtd_list *new; | 99 | struct phram_mtd_list *new; |
100 | int ret = -ENOMEM; | 100 | int ret = -ENOMEM; |
@@ -141,35 +141,35 @@ out0: | |||
141 | return ret; | 141 | return ret; |
142 | } | 142 | } |
143 | 143 | ||
144 | static int ustrtoul(const char *cp, char **endp, unsigned int base) | 144 | static int parse_num64(uint64_t *num64, char *token) |
145 | { | 145 | { |
146 | unsigned long result = simple_strtoul(cp, endp, base); | 146 | size_t len; |
147 | 147 | int shift = 0; | |
148 | switch (**endp) { | 148 | int ret; |
149 | case 'G': | 149 | |
150 | result *= 1024; | 150 | len = strlen(token); |
151 | case 'M': | ||
152 | result *= 1024; | ||
153 | case 'k': | ||
154 | result *= 1024; | ||
155 | /* By dwmw2 editorial decree, "ki", "Mi" or "Gi" are to be used. */ | 151 | /* By dwmw2 editorial decree, "ki", "Mi" or "Gi" are to be used. */ |
156 | if ((*endp)[1] == 'i') | 152 | if (len > 2) { |
157 | (*endp) += 2; | 153 | if (token[len - 1] == 'i') { |
154 | switch (token[len - 2]) { | ||
155 | case 'G': | ||
156 | shift += 10; | ||
157 | case 'M': | ||
158 | shift += 10; | ||
159 | case 'k': | ||
160 | shift += 10; | ||
161 | token[len - 2] = 0; | ||
162 | break; | ||
163 | default: | ||
164 | return -EINVAL; | ||
165 | } | ||
166 | } | ||
158 | } | 167 | } |
159 | return result; | ||
160 | } | ||
161 | 168 | ||
162 | static int parse_num32(uint32_t *num32, const char *token) | 169 | ret = kstrtou64(token, 0, num64); |
163 | { | 170 | *num64 <<= shift; |
164 | char *endp; | ||
165 | unsigned long n; | ||
166 | 171 | ||
167 | n = ustrtoul(token, &endp, 0); | 172 | return ret; |
168 | if (*endp) | ||
169 | return -EINVAL; | ||
170 | |||
171 | *num32 = n; | ||
172 | return 0; | ||
173 | } | 173 | } |
174 | 174 | ||
175 | static int parse_name(char **pname, const char *token) | 175 | static int parse_name(char **pname, const char *token) |
@@ -209,19 +209,19 @@ static inline void kill_final_newline(char *str) | |||
209 | * This shall contain the module parameter if any. It is of the form: | 209 | * This shall contain the module parameter if any. It is of the form: |
210 | * - phram=<device>,<address>,<size> for module case | 210 | * - phram=<device>,<address>,<size> for module case |
211 | * - phram.phram=<device>,<address>,<size> for built-in case | 211 | * - phram.phram=<device>,<address>,<size> for built-in case |
212 | * We leave 64 bytes for the device name, 12 for the address and 12 for the | 212 | * We leave 64 bytes for the device name, 20 for the address and 20 for the |
213 | * size. | 213 | * size. |
214 | * Example: phram.phram=rootfs,0xa0000000,512Mi | 214 | * Example: phram.phram=rootfs,0xa0000000,512Mi |
215 | */ | 215 | */ |
216 | static __initdata char phram_paramline[64+12+12]; | 216 | static __initdata char phram_paramline[64 + 20 + 20]; |
217 | 217 | ||
218 | static int __init phram_setup(const char *val) | 218 | static int __init phram_setup(const char *val) |
219 | { | 219 | { |
220 | char buf[64+12+12], *str = buf; | 220 | char buf[64 + 20 + 20], *str = buf; |
221 | char *token[3]; | 221 | char *token[3]; |
222 | char *name; | 222 | char *name; |
223 | uint32_t start; | 223 | uint64_t start; |
224 | uint32_t len; | 224 | uint64_t len; |
225 | int i, ret; | 225 | int i, ret; |
226 | 226 | ||
227 | if (strnlen(val, sizeof(buf)) >= sizeof(buf)) | 227 | if (strnlen(val, sizeof(buf)) >= sizeof(buf)) |
@@ -243,13 +243,13 @@ static int __init phram_setup(const char *val) | |||
243 | if (ret) | 243 | if (ret) |
244 | return ret; | 244 | return ret; |
245 | 245 | ||
246 | ret = parse_num32(&start, token[1]); | 246 | ret = parse_num64(&start, token[1]); |
247 | if (ret) { | 247 | if (ret) { |
248 | kfree(name); | 248 | kfree(name); |
249 | parse_err("illegal start address\n"); | 249 | parse_err("illegal start address\n"); |
250 | } | 250 | } |
251 | 251 | ||
252 | ret = parse_num32(&len, token[2]); | 252 | ret = parse_num64(&len, token[2]); |
253 | if (ret) { | 253 | if (ret) { |
254 | kfree(name); | 254 | kfree(name); |
255 | parse_err("illegal device length\n"); | 255 | parse_err("illegal device length\n"); |
@@ -257,7 +257,7 @@ static int __init phram_setup(const char *val) | |||
257 | 257 | ||
258 | ret = register_device(name, start, len); | 258 | ret = register_device(name, start, len); |
259 | if (!ret) | 259 | if (!ret) |
260 | pr_info("%s device: %#x at %#x\n", name, len, start); | 260 | pr_info("%s device: %#llx at %#llx\n", name, len, start); |
261 | else | 261 | else |
262 | kfree(name); | 262 | kfree(name); |
263 | 263 | ||