diff options
Diffstat (limited to 'arch/powerpc/boot/ns16550.c')
-rw-r--r-- | arch/powerpc/boot/ns16550.c | 74 |
1 files changed, 74 insertions, 0 deletions
diff --git a/arch/powerpc/boot/ns16550.c b/arch/powerpc/boot/ns16550.c new file mode 100644 index 000000000000..1ffe72e35cdc --- /dev/null +++ b/arch/powerpc/boot/ns16550.c | |||
@@ -0,0 +1,74 @@ | |||
1 | /* | ||
2 | * 16550 serial console support. | ||
3 | * | ||
4 | * Original copied from <file:arch/ppc/boot/common/ns16550.c> | ||
5 | * (which had no copyright) | ||
6 | * Modifications: 2006 (c) MontaVista Software, Inc. | ||
7 | * | ||
8 | * Modified by: Mark A. Greer <mgreer@mvista.com> | ||
9 | */ | ||
10 | #include <stdarg.h> | ||
11 | #include <stddef.h> | ||
12 | #include "types.h" | ||
13 | #include "string.h" | ||
14 | #include "stdio.h" | ||
15 | #include "io.h" | ||
16 | #include "ops.h" | ||
17 | |||
18 | #define UART_DLL 0 /* Out: Divisor Latch Low */ | ||
19 | #define UART_DLM 1 /* Out: Divisor Latch High */ | ||
20 | #define UART_FCR 2 /* Out: FIFO Control Register */ | ||
21 | #define UART_LCR 3 /* Out: Line Control Register */ | ||
22 | #define UART_MCR 4 /* Out: Modem Control Register */ | ||
23 | #define UART_LSR 5 /* In: Line Status Register */ | ||
24 | #define UART_LSR_THRE 0x20 /* Transmit-hold-register empty */ | ||
25 | #define UART_LSR_DR 0x01 /* Receiver data ready */ | ||
26 | #define UART_MSR 6 /* In: Modem Status Register */ | ||
27 | #define UART_SCR 7 /* I/O: Scratch Register */ | ||
28 | |||
29 | static unsigned char *reg_base; | ||
30 | static u32 reg_shift; | ||
31 | |||
32 | static int ns16550_open(void) | ||
33 | { | ||
34 | out_8(reg_base + (UART_FCR << reg_shift), 0x06); | ||
35 | return 0; | ||
36 | } | ||
37 | |||
38 | static void ns16550_putc(unsigned char c) | ||
39 | { | ||
40 | while ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_THRE) == 0); | ||
41 | out_8(reg_base, c); | ||
42 | } | ||
43 | |||
44 | static unsigned char ns16550_getc(void) | ||
45 | { | ||
46 | while ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_DR) == 0); | ||
47 | return in_8(reg_base); | ||
48 | } | ||
49 | |||
50 | static u8 ns16550_tstc(void) | ||
51 | { | ||
52 | return ((in_8(reg_base + (UART_LSR << reg_shift)) & UART_LSR_DR) != 0); | ||
53 | } | ||
54 | |||
55 | int ns16550_console_init(void *devp, struct serial_console_data *scdp) | ||
56 | { | ||
57 | int n; | ||
58 | |||
59 | n = getprop(devp, "virtual-reg", ®_base, sizeof(reg_base)); | ||
60 | if (n != sizeof(reg_base)) | ||
61 | return -1; | ||
62 | |||
63 | n = getprop(devp, "reg-shift", ®_shift, sizeof(reg_shift)); | ||
64 | if (n != sizeof(reg_shift)) | ||
65 | reg_shift = 0; | ||
66 | |||
67 | scdp->open = ns16550_open; | ||
68 | scdp->putc = ns16550_putc; | ||
69 | scdp->getc = ns16550_getc; | ||
70 | scdp->tstc = ns16550_tstc; | ||
71 | scdp->close = NULL; | ||
72 | |||
73 | return 0; | ||
74 | } | ||