diff options
author | Kars de Jong <jongk@linux-m68k.org> | 2008-11-20 13:47:18 +0100 |
---|---|---|
committer | Geert Uytterhoeven <geert@linux-m68k.org> | 2011-12-10 19:52:45 +0100 |
commit | f9994894953d6bd9d5ed2719a34d027a4e0c2131 (patch) | |
tree | 07c0ba833ae382e95dd391a598b3117bef27f6a8 | |
parent | f8bd9de913fc004705002f7bd6e840b1c685b188 (diff) | |
download | op-kernel-dev-f9994894953d6bd9d5ed2719a34d027a4e0c2131.zip op-kernel-dev-f9994894953d6bd9d5ed2719a34d027a4e0c2131.tar.gz |
m68k/mvme16x: Add support for EARLY_PRINTK
Added support for EARLY_PRINTK when running on an MVME16x board.
Signed-off-by: Kars de Jong <jongk@linux-m68k.org>
Signed-off-by: Geert Uytterhoeven <geert@linux-m68k.org>
-rw-r--r-- | arch/m68k/Kconfig.debug | 11 | ||||
-rw-r--r-- | arch/m68k/mvme16x/config.c | 160 |
2 files changed, 171 insertions, 0 deletions
diff --git a/arch/m68k/Kconfig.debug b/arch/m68k/Kconfig.debug index 2bdb1b0..8702dc6 100644 --- a/arch/m68k/Kconfig.debug +++ b/arch/m68k/Kconfig.debug @@ -2,6 +2,17 @@ menu "Kernel hacking" source "lib/Kconfig.debug" +config EARLY_PRINTK + bool "Early printk" if EMBEDDED + depends on MVME16x + default y + help + Write kernel log output directly to a serial port. + + This is useful for kernel debugging when your machine crashes very + early before the console code is initialized. + You should normally say N here, unless you want to debug such a crash. + if !MMU config FULLDEBUG diff --git a/arch/m68k/mvme16x/config.c b/arch/m68k/mvme16x/config.c index 31a66d9..c3fb3bd 100644 --- a/arch/m68k/mvme16x/config.c +++ b/arch/m68k/mvme16x/config.c @@ -124,6 +124,163 @@ static void __init mvme16x_init_IRQ (void) #define PccSCCMICR 0x1d #define PccSCCTICR 0x1e #define PccSCCRICR 0x1f +#define PccTPIACKR 0x25 + +#ifdef CONFIG_EARLY_PRINTK + +/**** cd2401 registers ****/ +#define CD2401_ADDR (0xfff45000) + +#define CyGFRCR (0x81) +#define CyCCR (0x13) +#define CyCLR_CHAN (0x40) +#define CyINIT_CHAN (0x20) +#define CyCHIP_RESET (0x10) +#define CyENB_XMTR (0x08) +#define CyDIS_XMTR (0x04) +#define CyENB_RCVR (0x02) +#define CyDIS_RCVR (0x01) +#define CyCAR (0xee) +#define CyIER (0x11) +#define CyMdmCh (0x80) +#define CyRxExc (0x20) +#define CyRxData (0x08) +#define CyTxMpty (0x02) +#define CyTxRdy (0x01) +#define CyLICR (0x26) +#define CyRISR (0x89) +#define CyTIMEOUT (0x80) +#define CySPECHAR (0x70) +#define CyOVERRUN (0x08) +#define CyPARITY (0x04) +#define CyFRAME (0x02) +#define CyBREAK (0x01) +#define CyREOIR (0x84) +#define CyTEOIR (0x85) +#define CyMEOIR (0x86) +#define CyNOTRANS (0x08) +#define CyRFOC (0x30) +#define CyRDR (0xf8) +#define CyTDR (0xf8) +#define CyMISR (0x8b) +#define CyRISR (0x89) +#define CyTISR (0x8a) +#define CyMSVR1 (0xde) +#define CyMSVR2 (0xdf) +#define CyDSR (0x80) +#define CyDCD (0x40) +#define CyCTS (0x20) +#define CyDTR (0x02) +#define CyRTS (0x01) +#define CyRTPRL (0x25) +#define CyRTPRH (0x24) +#define CyCOR1 (0x10) +#define CyPARITY_NONE (0x00) +#define CyPARITY_E (0x40) +#define CyPARITY_O (0xC0) +#define Cy_5_BITS (0x04) +#define Cy_6_BITS (0x05) +#define Cy_7_BITS (0x06) +#define Cy_8_BITS (0x07) +#define CyCOR2 (0x17) +#define CyETC (0x20) +#define CyCtsAE (0x02) +#define CyCOR3 (0x16) +#define Cy_1_STOP (0x02) +#define Cy_2_STOP (0x04) +#define CyCOR4 (0x15) +#define CyREC_FIFO (0x0F) /* Receive FIFO threshold */ +#define CyCOR5 (0x14) +#define CyCOR6 (0x18) +#define CyCOR7 (0x07) +#define CyRBPR (0xcb) +#define CyRCOR (0xc8) +#define CyTBPR (0xc3) +#define CyTCOR (0xc0) +#define CySCHR1 (0x1f) +#define CySCHR2 (0x1e) +#define CyTPR (0xda) +#define CyPILR1 (0xe3) +#define CyPILR2 (0xe0) +#define CyPILR3 (0xe1) +#define CyCMR (0x1b) +#define CyASYNC (0x02) +#define CyLICR (0x26) +#define CyLIVR (0x09) +#define CySCRL (0x23) +#define CySCRH (0x22) +#define CyTFTC (0x80) + +static void cons_write(struct console *co, const char *str, unsigned count) +{ + volatile unsigned char *base_addr = (u_char *)CD2401_ADDR; + volatile u_char sink; + u_char ier; + int port; + u_char do_lf = 0; + int i = 0; + + /* Ensure transmitter is enabled! */ + + port = 0; + base_addr[CyCAR] = (u_char)port; + while (base_addr[CyCCR]) + ; + base_addr[CyCCR] = CyENB_XMTR; + + ier = base_addr[CyIER]; + base_addr[CyIER] = CyTxMpty; + + while (1) { + if (pcc2chip[PccSCCTICR] & 0x20) + { + /* We have a Tx int. Acknowledge it */ + sink = pcc2chip[PccTPIACKR]; + if ((base_addr[CyLICR] >> 2) == port) { + if (i == count) { + /* Last char of string is now output */ + base_addr[CyTEOIR] = CyNOTRANS; + break; + } + if (do_lf) { + base_addr[CyTDR] = '\n'; + str++; + i++; + do_lf = 0; + } + else if (*str == '\n') { + base_addr[CyTDR] = '\r'; + do_lf = 1; + } + else { + base_addr[CyTDR] = *str++; + i++; + } + base_addr[CyTEOIR] = 0; + } + else + base_addr[CyTEOIR] = CyNOTRANS; + } + } + + base_addr[CyIER] = ier; +} + +static struct console cons_info = +{ + .name = "sercon", + .write = cons_write, + .flags = CON_PRINTBUFFER | CON_BOOT, + .index = -1, +}; + +static void __init mvme16x_early_console(void) +{ + register_console(&cons_info); + + printk(KERN_INFO "MVME16x: early console registered\n"); +} +#endif void __init config_mvme16x(void) { @@ -183,6 +340,9 @@ void __init config_mvme16x(void) pcc2chip[PccSCCMICR] = 0x10; pcc2chip[PccSCCTICR] = 0x10; pcc2chip[PccSCCRICR] = 0x10; +#ifdef CONFIG_EARLY_PRINTK + mvme16x_early_console(); +#endif } } |