1 #include <linux/config.h>
2 #include <linux/kernel.h>
3 #include <linux/console.h>
4 #include <linux/string.h>
5 #include <linux/init.h>
6 #include <linux/delay.h>
7 #include <linux/interrupt.h>
10 #include <asm/system.h>
11 #include <asm/pdc.h> /* for iodc_call() proto and friends */
14 static int __attribute__((aligned(8))) iodc_retbuf
[32];
15 static char __attribute__((aligned(64))) iodc_dbuf
[4096];
19 * Console character print using IODC.
21 * Note that only these special chars are architected for console IODC io:
22 * BEL, BS, CR, and LF. Others are passed through.
23 * Since the HP console requires CR+LF to perform a 'newline', we translate
27 static int posx
; /* for simple TAB-Simulation... */
29 /* XXX Should we spinlock posx usage */
31 void pdc_putc(unsigned char c
)
45 while (posx
& 7) /* expand TAB */
47 return; /* return since IODC can't handle this */
57 real32_call(PAGE0
->mem_cons
.iodc_io
,
58 (unsigned long)PAGE0
->mem_cons
.hpa
, ENTRY_IO_COUT
,
59 PAGE0
->mem_cons
.spa
, __pa(PAGE0
->mem_cons
.dp
.layers
),
60 __pa(iodc_retbuf
), 0, __pa(iodc_dbuf
), n
, 0);
64 static void pdc_console_write(struct console
*co
, const char *s
, unsigned count
)
70 int pdc_console_wait_key(struct console
*co
)
75 /* Bail if no console input device. */
76 if (!PAGE0
->mem_kbd
.iodc_io
)
79 /* wait for a keyboard (rs232)-input */
85 status
= real32_call(PAGE0
->mem_kbd
.iodc_io
,
86 (unsigned long)PAGE0
->mem_kbd
.hpa
, ENTRY_IO_CIN
,
87 PAGE0
->mem_kbd
.spa
, __pa(PAGE0
->mem_kbd
.dp
.layers
),
88 __pa(iodc_retbuf
), 0, __pa(iodc_dbuf
), 1, 0);
90 ch
= *iodc_dbuf
; /* save the character directly to ch */
91 } while (*iodc_retbuf
== 0); /* wait for a key */
97 return pdc_console_wait_key(NULL
);
100 static int pdc_console_setup(struct console
*co
, char *options
)
105 static struct console pdc_cons
= {
107 write
: pdc_console_write
,
110 wait_key
: pdc_console_wait_key
,
112 setup
: pdc_console_setup
,
113 flags
: CON_PRINTBUFFER
|CON_ENABLED
, // |CON_CONSDEV,
117 static int pdc_console_initialized
;
119 void pdc_console_init(void)
121 if (pdc_console_initialized
)
123 ++pdc_console_initialized
;
125 /* If the console is duplex then copy the COUT parameters to CIN. */
126 if (PAGE0
->mem_cons
.cl_class
== CL_DUPLEX
)
127 memcpy(&PAGE0
->mem_kbd
, &PAGE0
->mem_cons
, sizeof(PAGE0
->mem_cons
));
129 pdc_console_write(0, "PDC Console Initialized\n", 24);
130 /* register the pdc console */
131 register_console(&pdc_cons
);
135 /* Unregister the pdc console with the printk console layer */
136 void pdc_console_die(void)
138 printk("Switching from PDC console\n");
139 if (!pdc_console_initialized
)
141 --pdc_console_initialized
;
143 #ifdef CONFIG_VT_CONSOLE
145 /* fixme (needed?): Wait for console-tasklet to finish !*/
146 extern struct tasklet_struct console_tasklet
;
147 tasklet_schedule(&console_tasklet
);
151 unregister_console(&pdc_cons
);
156 * Used for emergencies. Currently only used if an HPMC occurs. If an
157 * HPMC occurs, it is possible that the current console may not be
158 * properly initialed after the PDC IO reset. This routine unregisters all
159 * of the current consoles, reinitializes the pdc console and
163 void pdc_console_restart(void)
165 struct console
*console
;
168 if (pdc_console_initialized
)
171 while ((console
= console_drivers
) != (struct console
*)0)
172 unregister_console(console_drivers
);
176 printk("Switched to PDC console\n");