diff options
Diffstat (limited to 'arch/ppc64/boot/prom.c')
| -rw-r--r-- | arch/ppc64/boot/prom.c | 28 |
1 files changed, 22 insertions, 6 deletions
diff --git a/arch/ppc64/boot/prom.c b/arch/ppc64/boot/prom.c index 7b607d1862cb..d5218b15824e 100644 --- a/arch/ppc64/boot/prom.c +++ b/arch/ppc64/boot/prom.c | |||
| @@ -11,6 +11,23 @@ | |||
| 11 | #include <linux/string.h> | 11 | #include <linux/string.h> |
| 12 | #include <linux/ctype.h> | 12 | #include <linux/ctype.h> |
| 13 | 13 | ||
| 14 | extern __u32 __div64_32(unsigned long long *dividend, __u32 divisor); | ||
| 15 | |||
| 16 | /* The unnecessary pointer compare is there | ||
| 17 | * to check for type safety (n must be 64bit) | ||
| 18 | */ | ||
| 19 | # define do_div(n,base) ({ \ | ||
| 20 | __u32 __base = (base); \ | ||
| 21 | __u32 __rem; \ | ||
| 22 | (void)(((typeof((n)) *)0) == ((unsigned long long *)0)); \ | ||
| 23 | if (((n) >> 32) == 0) { \ | ||
| 24 | __rem = (__u32)(n) % __base; \ | ||
| 25 | (n) = (__u32)(n) / __base; \ | ||
| 26 | } else \ | ||
| 27 | __rem = __div64_32(&(n), __base); \ | ||
| 28 | __rem; \ | ||
| 29 | }) | ||
| 30 | |||
| 14 | int (*prom)(void *); | 31 | int (*prom)(void *); |
| 15 | 32 | ||
| 16 | void *chosen_handle; | 33 | void *chosen_handle; |
| @@ -352,7 +369,7 @@ static int skip_atoi(const char **s) | |||
| 352 | #define SPECIAL 32 /* 0x */ | 369 | #define SPECIAL 32 /* 0x */ |
| 353 | #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ | 370 | #define LARGE 64 /* use 'ABCDEF' instead of 'abcdef' */ |
| 354 | 371 | ||
| 355 | static char * number(char * str, long num, int base, int size, int precision, int type) | 372 | static char * number(char * str, unsigned long long num, int base, int size, int precision, int type) |
| 356 | { | 373 | { |
| 357 | char c,sign,tmp[66]; | 374 | char c,sign,tmp[66]; |
| 358 | const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; | 375 | const char *digits="0123456789abcdefghijklmnopqrstuvwxyz"; |
| @@ -367,9 +384,9 @@ static char * number(char * str, long num, int base, int size, int precision, in | |||
| 367 | c = (type & ZEROPAD) ? '0' : ' '; | 384 | c = (type & ZEROPAD) ? '0' : ' '; |
| 368 | sign = 0; | 385 | sign = 0; |
| 369 | if (type & SIGN) { | 386 | if (type & SIGN) { |
| 370 | if (num < 0) { | 387 | if ((signed long long)num < 0) { |
| 371 | sign = '-'; | 388 | sign = '-'; |
| 372 | num = -num; | 389 | num = - (signed long long)num; |
| 373 | size--; | 390 | size--; |
| 374 | } else if (type & PLUS) { | 391 | } else if (type & PLUS) { |
| 375 | sign = '+'; | 392 | sign = '+'; |
| @@ -389,8 +406,7 @@ static char * number(char * str, long num, int base, int size, int precision, in | |||
| 389 | if (num == 0) | 406 | if (num == 0) |
| 390 | tmp[i++]='0'; | 407 | tmp[i++]='0'; |
| 391 | else while (num != 0) { | 408 | else while (num != 0) { |
| 392 | tmp[i++] = digits[num % base]; | 409 | tmp[i++] = digits[do_div(num, base)]; |
| 393 | num /= base; | ||
| 394 | } | 410 | } |
| 395 | if (i > precision) | 411 | if (i > precision) |
| 396 | precision = i; | 412 | precision = i; |
| @@ -426,7 +442,7 @@ int sprintf(char * buf, const char *fmt, ...); | |||
| 426 | int vsprintf(char *buf, const char *fmt, va_list args) | 442 | int vsprintf(char *buf, const char *fmt, va_list args) |
| 427 | { | 443 | { |
| 428 | int len; | 444 | int len; |
| 429 | unsigned long num; | 445 | unsigned long long num; |
| 430 | int i, base; | 446 | int i, base; |
| 431 | char * str; | 447 | char * str; |
| 432 | const char *s; | 448 | const char *s; |
