diff options
-rw-r--r-- | arch/sparc/include/asm/oplib_32.h | 4 | ||||
-rw-r--r-- | arch/sparc/include/asm/oplib_64.h | 4 | ||||
-rw-r--r-- | arch/sparc/prom/console_32.c | 14 | ||||
-rw-r--r-- | arch/sparc/prom/console_64.c | 27 | ||||
-rw-r--r-- | arch/sparc/prom/printf.c | 32 |
5 files changed, 52 insertions, 29 deletions
diff --git a/arch/sparc/include/asm/oplib_32.h b/arch/sparc/include/asm/oplib_32.h index 40bc9efb1ac4..9e5c64084b86 100644 --- a/arch/sparc/include/asm/oplib_32.h +++ b/arch/sparc/include/asm/oplib_32.h | |||
@@ -102,8 +102,8 @@ extern int prom_getrev(void); | |||
102 | /* Get the prom firmware revision. */ | 102 | /* Get the prom firmware revision. */ |
103 | extern int prom_getprev(void); | 103 | extern int prom_getprev(void); |
104 | 104 | ||
105 | /* Blocking put character to console. */ | 105 | /* Write a buffer of characters to the console. */ |
106 | extern void prom_putchar(const char *buf); | 106 | extern void prom_console_write_buf(const char *buf, int len); |
107 | 107 | ||
108 | /* Prom's internal routines, don't use in kernel/boot code. */ | 108 | /* Prom's internal routines, don't use in kernel/boot code. */ |
109 | extern void prom_printf(const char *fmt, ...); | 109 | extern void prom_printf(const char *fmt, ...); |
diff --git a/arch/sparc/include/asm/oplib_64.h b/arch/sparc/include/asm/oplib_64.h index d4613738c537..8cd0df34e82b 100644 --- a/arch/sparc/include/asm/oplib_64.h +++ b/arch/sparc/include/asm/oplib_64.h | |||
@@ -94,8 +94,8 @@ extern void prom_halt_power_off(void) __attribute__ ((noreturn)); | |||
94 | */ | 94 | */ |
95 | extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); | 95 | extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); |
96 | 96 | ||
97 | /* Blocking put character to console. */ | 97 | /* Write a buffer of characters to the console. */ |
98 | extern void prom_putchar(const char *buf); | 98 | extern void prom_console_write_buf(const char *buf, int len); |
99 | 99 | ||
100 | /* Prom's internal routines, don't use in kernel/boot code. */ | 100 | /* Prom's internal routines, don't use in kernel/boot code. */ |
101 | extern void prom_printf(const char *fmt, ...); | 101 | extern void prom_printf(const char *fmt, ...); |
diff --git a/arch/sparc/prom/console_32.c b/arch/sparc/prom/console_32.c index 157019e29fd4..48863108a44c 100644 --- a/arch/sparc/prom/console_32.c +++ b/arch/sparc/prom/console_32.c | |||
@@ -43,12 +43,14 @@ static int prom_nbputchar(const char *buf) | |||
43 | return i; /* Ugh, we could spin forever on unsupported proms ;( */ | 43 | return i; /* Ugh, we could spin forever on unsupported proms ;( */ |
44 | } | 44 | } |
45 | 45 | ||
46 | /* Blocking version of put character routine above. */ | 46 | void prom_console_write_buf(const char *buf, int len) |
47 | void prom_putchar(const char *buf) | ||
48 | { | 47 | { |
49 | while (1) { | 48 | while (len) { |
50 | int err = prom_nbputchar(buf); | 49 | int n = prom_nbputchar(buf); |
51 | if (!err) | 50 | if (n) |
52 | break; | 51 | continue; |
52 | len--; | ||
53 | buf++; | ||
53 | } | 54 | } |
54 | } | 55 | } |
56 | |||
diff --git a/arch/sparc/prom/console_64.c b/arch/sparc/prom/console_64.c index 0da88d10beff..ed39e75828bd 100644 --- a/arch/sparc/prom/console_64.c +++ b/arch/sparc/prom/console_64.c | |||
@@ -15,35 +15,34 @@ | |||
15 | 15 | ||
16 | extern int prom_stdin, prom_stdout; | 16 | extern int prom_stdin, prom_stdout; |
17 | 17 | ||
18 | /* Non blocking put character to console device, returns -1 if | 18 | static int __prom_console_write_buf(const char *buf, int len) |
19 | * unsuccessful. | ||
20 | */ | ||
21 | static int prom_nbputchar(const char *buf) | ||
22 | { | 19 | { |
23 | unsigned long args[7]; | 20 | unsigned long args[7]; |
21 | int ret; | ||
24 | 22 | ||
25 | args[0] = (unsigned long) "write"; | 23 | args[0] = (unsigned long) "write"; |
26 | args[1] = 3; | 24 | args[1] = 3; |
27 | args[2] = 1; | 25 | args[2] = 1; |
28 | args[3] = (unsigned int) prom_stdout; | 26 | args[3] = (unsigned int) prom_stdout; |
29 | args[4] = (unsigned long) buf; | 27 | args[4] = (unsigned long) buf; |
30 | args[5] = 1; | 28 | args[5] = (unsigned int) len; |
31 | args[6] = (unsigned long) -1; | 29 | args[6] = (unsigned long) -1; |
32 | 30 | ||
33 | p1275_cmd_direct(args); | 31 | p1275_cmd_direct(args); |
34 | 32 | ||
35 | if (args[6] == 1) | 33 | ret = (int) args[6]; |
36 | return 0; | 34 | if (ret < 0) |
37 | else | ||
38 | return -1; | 35 | return -1; |
36 | return ret; | ||
39 | } | 37 | } |
40 | 38 | ||
41 | /* Blocking version of put character routine above. */ | 39 | void prom_console_write_buf(const char *buf, int len) |
42 | void prom_putchar(const char *buf) | ||
43 | { | 40 | { |
44 | while (1) { | 41 | while (len) { |
45 | int err = prom_nbputchar(buf); | 42 | int n = __prom_console_write_buf(buf, len); |
46 | if (!err) | 43 | if (n < 0) |
47 | break; | 44 | continue; |
45 | len -= n; | ||
46 | buf += len; | ||
48 | } | 47 | } |
49 | } | 48 | } |
diff --git a/arch/sparc/prom/printf.c b/arch/sparc/prom/printf.c index 24031971f806..d9682f06b3b0 100644 --- a/arch/sparc/prom/printf.c +++ b/arch/sparc/prom/printf.c | |||
@@ -15,23 +15,45 @@ | |||
15 | 15 | ||
16 | #include <linux/kernel.h> | 16 | #include <linux/kernel.h> |
17 | #include <linux/compiler.h> | 17 | #include <linux/compiler.h> |
18 | #include <linux/spinlock.h> | ||
18 | 19 | ||
19 | #include <asm/openprom.h> | 20 | #include <asm/openprom.h> |
20 | #include <asm/oplib.h> | 21 | #include <asm/oplib.h> |
21 | 22 | ||
23 | #define CONSOLE_WRITE_BUF_SIZE 1024 | ||
24 | |||
22 | static char ppbuf[1024]; | 25 | static char ppbuf[1024]; |
26 | static char console_write_buf[CONSOLE_WRITE_BUF_SIZE]; | ||
27 | static DEFINE_RAW_SPINLOCK(console_write_lock); | ||
23 | 28 | ||
24 | void notrace prom_write(const char *buf, unsigned int n) | 29 | void notrace prom_write(const char *buf, unsigned int n) |
25 | { | 30 | { |
31 | unsigned int dest_len; | ||
32 | unsigned long flags; | ||
33 | char *dest; | ||
34 | |||
35 | dest = console_write_buf; | ||
36 | raw_spin_lock_irqsave(&console_write_lock, flags); | ||
37 | |||
38 | dest_len = 0; | ||
26 | while (n-- != 0) { | 39 | while (n-- != 0) { |
27 | char ch = *buf; | 40 | char ch = *buf++; |
28 | if (ch == '\n') { | 41 | if (ch == '\n') { |
29 | char tmp = '\r'; | 42 | *dest++ = '\r'; |
30 | prom_putchar(&tmp); | 43 | dest_len++; |
44 | } | ||
45 | *dest++ = ch; | ||
46 | dest_len++; | ||
47 | if (dest_len >= CONSOLE_WRITE_BUF_SIZE - 1) { | ||
48 | prom_console_write_buf(console_write_buf, dest_len); | ||
49 | dest = console_write_buf; | ||
50 | dest_len = 0; | ||
31 | } | 51 | } |
32 | prom_putchar(buf); | ||
33 | buf++; | ||
34 | } | 52 | } |
53 | if (dest_len) | ||
54 | prom_console_write_buf(console_write_buf, dest_len); | ||
55 | |||
56 | raw_spin_unlock_irqrestore(&console_write_lock, flags); | ||
35 | } | 57 | } |
36 | 58 | ||
37 | void notrace prom_printf(const char *fmt, ...) | 59 | void notrace prom_printf(const char *fmt, ...) |