aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--arch/parisc/kernel/firmware.c27
-rw-r--r--arch/parisc/kernel/pdc_cons.c19
-rw-r--r--include/asm-parisc/pdc.h2
3 files changed, 35 insertions, 13 deletions
diff --git a/arch/parisc/kernel/firmware.c b/arch/parisc/kernel/firmware.c
index 4ab83d56974d..7177a6cd1b7f 100644
--- a/arch/parisc/kernel/firmware.c
+++ b/arch/parisc/kernel/firmware.c
@@ -1080,6 +1080,9 @@ void pdc_io_reset_devices(void)
1080 spin_unlock_irqrestore(&pdc_lock, flags); 1080 spin_unlock_irqrestore(&pdc_lock, flags);
1081} 1081}
1082 1082
1083/* locked by pdc_console_lock */
1084static int __attribute__((aligned(8))) iodc_retbuf[32];
1085static char __attribute__((aligned(64))) iodc_dbuf[4096];
1083 1086
1084/** 1087/**
1085 * pdc_iodc_print - Console print using IODC. 1088 * pdc_iodc_print - Console print using IODC.
@@ -1091,24 +1094,20 @@ void pdc_io_reset_devices(void)
1091 * Since the HP console requires CR+LF to perform a 'newline', we translate 1094 * Since the HP console requires CR+LF to perform a 'newline', we translate
1092 * "\n" to "\r\n". 1095 * "\n" to "\r\n".
1093 */ 1096 */
1094int pdc_iodc_print(unsigned char *str, unsigned count) 1097int pdc_iodc_print(const unsigned char *str, unsigned count)
1095{ 1098{
1096 /* XXX Should we spinlock posx usage */
1097 static int posx; /* for simple TAB-Simulation... */ 1099 static int posx; /* for simple TAB-Simulation... */
1098 int __attribute__((aligned(8))) iodc_retbuf[32];
1099 char __attribute__((aligned(64))) iodc_dbuf[4096];
1100 unsigned int i; 1100 unsigned int i;
1101 unsigned long flags; 1101 unsigned long flags;
1102 1102
1103 memset(iodc_dbuf, 0, 4096); 1103 for (i = 0; i < count && i < 79;) {
1104 for (i = 0; i < count && i < 2048;) {
1105 switch(str[i]) { 1104 switch(str[i]) {
1106 case '\n': 1105 case '\n':
1107 iodc_dbuf[i+0] = '\r'; 1106 iodc_dbuf[i+0] = '\r';
1108 iodc_dbuf[i+1] = '\n'; 1107 iodc_dbuf[i+1] = '\n';
1109 i += 2; 1108 i += 2;
1110 posx = 0; 1109 posx = 0;
1111 break; 1110 goto print;
1112 case '\t': 1111 case '\t':
1113 while (posx & 7) { 1112 while (posx & 7) {
1114 iodc_dbuf[i] = ' '; 1113 iodc_dbuf[i] = ' ';
@@ -1124,6 +1123,16 @@ int pdc_iodc_print(unsigned char *str, unsigned count)
1124 } 1123 }
1125 } 1124 }
1126 1125
1126 /* if we're at the end of line, and not already inserting a newline,
1127 * insert one anyway. iodc console doesn't claim to support >79 char
1128 * lines. don't account for this in the return value.
1129 */
1130 if (i == 79 && iodc_dbuf[i-1] != '\n') {
1131 iodc_dbuf[i+0] = '\r';
1132 iodc_dbuf[i+1] = '\n';
1133 }
1134
1135print:
1127 spin_lock_irqsave(&pdc_lock, flags); 1136 spin_lock_irqsave(&pdc_lock, flags);
1128 real32_call(PAGE0->mem_cons.iodc_io, 1137 real32_call(PAGE0->mem_cons.iodc_io,
1129 (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT, 1138 (unsigned long)PAGE0->mem_cons.hpa, ENTRY_IO_COUT,
@@ -1142,11 +1151,9 @@ int pdc_iodc_print(unsigned char *str, unsigned count)
1142 */ 1151 */
1143int pdc_iodc_getc(void) 1152int pdc_iodc_getc(void)
1144{ 1153{
1145 unsigned long flags;
1146 static int __attribute__((aligned(8))) iodc_retbuf[32];
1147 static char __attribute__((aligned(64))) iodc_dbuf[4096];
1148 int ch; 1154 int ch;
1149 int status; 1155 int status;
1156 unsigned long flags;
1150 1157
1151 /* Bail if no console input device. */ 1158 /* Bail if no console input device. */
1152 if (!PAGE0->mem_kbd.iodc_io) 1159 if (!PAGE0->mem_kbd.iodc_io)
diff --git a/arch/parisc/kernel/pdc_cons.c b/arch/parisc/kernel/pdc_cons.c
index e7afc899d717..ccb68090781e 100644
--- a/arch/parisc/kernel/pdc_cons.c
+++ b/arch/parisc/kernel/pdc_cons.c
@@ -52,15 +52,30 @@
52#include <linux/tty.h> 52#include <linux/tty.h>
53#include <asm/pdc.h> /* for iodc_call() proto and friends */ 53#include <asm/pdc.h> /* for iodc_call() proto and friends */
54 54
55static spinlock_t pdc_console_lock = SPIN_LOCK_UNLOCKED;
55 56
56static void pdc_console_write(struct console *co, const char *s, unsigned count) 57static void pdc_console_write(struct console *co, const char *s, unsigned count)
57{ 58{
58 pdc_iodc_print(s, count); 59 int i = 0;
60 unsigned long flags;
61
62 spin_lock_irqsave(&pdc_console_lock, flags);
63 do {
64 i += pdc_iodc_print(s + i, count - i);
65 } while (i < count);
66 spin_unlock_irqrestore(&pdc_console_lock, flags);
59} 67}
60 68
61int pdc_console_poll_key(struct console *co) 69int pdc_console_poll_key(struct console *co)
62{ 70{
63 return pdc_iodc_getc(); 71 int c;
72 unsigned long flags;
73
74 spin_lock_irqsave(&pdc_console_lock, flags);
75 c = pdc_iodc_getc();
76 spin_unlock_irqrestore(&pdc_console_lock, flags);
77
78 return c;
64} 79}
65 80
66static int pdc_console_setup(struct console *co, char *options) 81static int pdc_console_setup(struct console *co, char *options)
diff --git a/include/asm-parisc/pdc.h b/include/asm-parisc/pdc.h
index b340c42f6bbc..9eaa794c3e4a 100644
--- a/include/asm-parisc/pdc.h
+++ b/include/asm-parisc/pdc.h
@@ -645,7 +645,7 @@ int pdc_soft_power_button(int sw_control);
645void pdc_io_reset(void); 645void pdc_io_reset(void);
646void pdc_io_reset_devices(void); 646void pdc_io_reset_devices(void);
647int pdc_iodc_getc(void); 647int pdc_iodc_getc(void);
648int pdc_iodc_print(unsigned char *str, unsigned count); 648int pdc_iodc_print(const unsigned char *str, unsigned count);
649 649
650void pdc_emergency_unlock(void); 650void pdc_emergency_unlock(void);
651int pdc_sti_call(unsigned long func, unsigned long flags, 651int pdc_sti_call(unsigned long func, unsigned long flags,