Merge branch 'for-linus' of git://oss.sgi.com/xfs/xfs
[pandora-kernel.git] / arch / mips / netlogic / xlr / platform.c
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
18 #include <asm/netlogic/xlr/iomap.h>
19 #include <asm/netlogic/xlr/pic.h>
20 #include <asm/netlogic/xlr/xlr.h>
21
22 unsigned int nlm_xlr_uart_in(struct uart_port *p, int offset)
23 {
24         nlm_reg_t *mmio;
25         unsigned int value;
26
27         /* XLR uart does not need any mapping of regs */
28         mmio = (nlm_reg_t *)(p->membase + (offset << p->regshift));
29         value = netlogic_read_reg(mmio, 0);
30
31         /* See XLR/XLS errata */
32         if (offset == UART_MSR)
33                 value ^= 0xF0;
34         else if (offset == UART_MCR)
35                 value ^= 0x3;
36
37         return value;
38 }
39
40 void nlm_xlr_uart_out(struct uart_port *p, int offset, int value)
41 {
42         nlm_reg_t *mmio;
43
44         /* XLR uart does not need any mapping of regs */
45         mmio = (nlm_reg_t *)(p->membase + (offset << p->regshift));
46
47         /* See XLR/XLS errata */
48         if (offset == UART_MSR)
49                 value ^= 0xF0;
50         else if (offset == UART_MCR)
51                 value ^= 0x3;
52
53         netlogic_write_reg(mmio, 0, value);
54 }
55
56 #define PORT(_irq)                                      \
57         {                                               \
58                 .irq            = _irq,                 \
59                 .regshift       = 2,                    \
60                 .iotype         = UPIO_MEM32,           \
61                 .flags          = (UPF_SKIP_TEST |      \
62                          UPF_FIXED_TYPE | UPF_BOOT_AUTOCONF),\
63                 .uartclk        = PIC_CLKS_PER_SEC,     \
64                 .type           = PORT_16550A,          \
65                 .serial_in      = nlm_xlr_uart_in,      \
66                 .serial_out     = nlm_xlr_uart_out,     \
67         }
68
69 static struct plat_serial8250_port xlr_uart_data[] = {
70         PORT(PIC_UART_0_IRQ),
71         PORT(PIC_UART_1_IRQ),
72         {},
73 };
74
75 static struct platform_device uart_device = {
76         .name           = "serial8250",
77         .id             = PLAT8250_DEV_PLATFORM,
78         .dev = {
79                 .platform_data = xlr_uart_data,
80         },
81 };
82
83 static int __init nlm_uart_init(void)
84 {
85         nlm_reg_t *mmio;
86
87         mmio = netlogic_io_mmio(NETLOGIC_IO_UART_0_OFFSET);
88         xlr_uart_data[0].membase = (void __iomem *)mmio;
89         xlr_uart_data[0].mapbase = CPHYSADDR((unsigned long)mmio);
90
91         mmio = netlogic_io_mmio(NETLOGIC_IO_UART_1_OFFSET);
92         xlr_uart_data[1].membase = (void __iomem *)mmio;
93         xlr_uart_data[1].mapbase = CPHYSADDR((unsigned long)mmio);
94
95         return platform_device_register(&uart_device);
96 }
97
98 arch_initcall(nlm_uart_init);