aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/sparc/include/asm/oplib_32.h4
-rw-r--r--arch/sparc/include/asm/oplib_64.h4
-rw-r--r--arch/sparc/prom/console_32.c14
-rw-r--r--arch/sparc/prom/console_64.c27
-rw-r--r--arch/sparc/prom/printf.c32
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. */
103extern int prom_getprev(void); 103extern int prom_getprev(void);
104 104
105/* Blocking put character to console. */ 105/* Write a buffer of characters to the console. */
106extern void prom_putchar(const char *buf); 106extern 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. */
109extern void prom_printf(const char *fmt, ...); 109extern 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 */
95extern unsigned char prom_get_idprom(char *idp_buffer, int idpbuf_size); 95extern 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. */
98extern void prom_putchar(const char *buf); 98extern 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. */
101extern void prom_printf(const char *fmt, ...); 101extern 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. */ 46void prom_console_write_buf(const char *buf, int len)
47void 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
16extern int prom_stdin, prom_stdout; 16extern int prom_stdin, prom_stdout;
17 17
18/* Non blocking put character to console device, returns -1 if 18static int __prom_console_write_buf(const char *buf, int len)
19 * unsuccessful.
20 */
21static 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. */ 39void prom_console_write_buf(const char *buf, int len)
42void 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
22static char ppbuf[1024]; 25static char ppbuf[1024];
26static char console_write_buf[CONSOLE_WRITE_BUF_SIZE];
27static DEFINE_RAW_SPINLOCK(console_write_lock);
23 28
24void notrace prom_write(const char *buf, unsigned int n) 29void 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
37void notrace prom_printf(const char *fmt, ...) 59void notrace prom_printf(const char *fmt, ...)