Commit | Line | Data |
---|---|---|
5c642506 J |
1 | /* |
2 | * Copyright 2011, Netlogic Microsystems. | |
3 | * Copyright 2004, Matt Porter <mporter@kernel.crashing.org> | |
4 | * | |
5 | * This file is licensed under the terms of the GNU General Public | |
6 | * License version 2. This program is licensed "as is" without any | |
7 | * warranty of any kind, whether express or implied. | |
8 | */ | |
9 | ||
10 | #include <linux/device.h> | |
11 | #include <linux/platform_device.h> | |
12 | #include <linux/kernel.h> | |
13 | #include <linux/init.h> | |
14 | #include <linux/resource.h> | |
15 | #include <linux/serial_8250.h> | |
16 | #include <linux/serial_reg.h> | |
17 | ||
0c965407 | 18 | #include <asm/netlogic/haldefs.h> |
5c642506 J |
19 | #include <asm/netlogic/xlr/iomap.h> |
20 | #include <asm/netlogic/xlr/pic.h> | |
21 | #include <asm/netlogic/xlr/xlr.h> | |
22 | ||
23 | unsigned int nlm_xlr_uart_in(struct uart_port *p, int offset) | |
24 | { | |
0c965407 | 25 | uint64_t uartbase; |
5c642506 J |
26 | unsigned int value; |
27 | ||
0c965407 J |
28 | /* sign extend to 64 bits, if needed */ |
29 | uartbase = (uint64_t)(long)p->membase; | |
30 | value = nlm_read_reg(uartbase, offset); | |
5c642506 J |
31 | |
32 | /* See XLR/XLS errata */ | |
33 | if (offset == UART_MSR) | |
34 | value ^= 0xF0; | |
35 | else if (offset == UART_MCR) | |
36 | value ^= 0x3; | |
37 | ||
38 | return value; | |
39 | } | |
40 | ||
41 | void nlm_xlr_uart_out(struct uart_port *p, int offset, int value) | |
42 | { | |
0c965407 | 43 | uint64_t uartbase; |
5c642506 | 44 | |
0c965407 J |
45 | /* sign extend to 64 bits, if needed */ |
46 | uartbase = (uint64_t)(long)p->membase; | |
5c642506 J |
47 | |
48 | /* See XLR/XLS errata */ | |
49 | if (offset == UART_MSR) | |
50 | value ^= 0xF0; | |
51 | else if (offset == UART_MCR) | |
52 | value ^= 0x3; | |
53 | ||
0c965407 | 54 | nlm_write_reg(uartbase, offset, value); |
5c642506 J |
55 | } |
56 | ||
57 | #define PORT(_irq) \ | |
58 | { \ | |
59 | .irq = _irq, \ | |
60 | .regshift = 2, \ | |
61 | .iotype = UPIO_MEM32, \ | |
62 | .flags = (UPF_SKIP_TEST | \ | |
63 | UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF),\ | |
64 | .uartclk = PIC_CLKS_PER_SEC, \ | |
65 | .type = PORT_16550A, \ | |
66 | .serial_in = nlm_xlr_uart_in, \ | |
67 | .serial_out = nlm_xlr_uart_out, \ | |
68 | } | |
69 | ||
70 | static struct plat_serial8250_port xlr_uart_data[] = { | |
71 | PORT(PIC_UART_0_IRQ), | |
72 | PORT(PIC_UART_1_IRQ), | |
73 | {}, | |
74 | }; | |
75 | ||
76 | static struct platform_device uart_device = { | |
77 | .name = "serial8250", | |
78 | .id = PLAT8250_DEV_PLATFORM, | |
79 | .dev = { | |
80 | .platform_data = xlr_uart_data, | |
81 | }, | |
82 | }; | |
83 | ||
84 | static int __init nlm_uart_init(void) | |
85 | { | |
0c965407 | 86 | unsigned long uartbase; |
5c642506 | 87 | |
0c965407 J |
88 | uartbase = (unsigned long)nlm_mmio_base(NETLOGIC_IO_UART_0_OFFSET); |
89 | xlr_uart_data[0].membase = (void __iomem *)uartbase; | |
90 | xlr_uart_data[0].mapbase = CPHYSADDR(uartbase); | |
5c642506 | 91 | |
0c965407 J |
92 | uartbase = (unsigned long)nlm_mmio_base(NETLOGIC_IO_UART_1_OFFSET); |
93 | xlr_uart_data[1].membase = (void __iomem *)uartbase; | |
94 | xlr_uart_data[1].mapbase = CPHYSADDR(uartbase); | |
5c642506 J |
95 | |
96 | return platform_device_register(&uart_device); | |
97 | } | |
98 | ||
99 | arch_initcall(nlm_uart_init); |