Merge tag 'scsi-misc' of git://git.kernel.org/pub/scm/linux/kernel/git/jejb/scsi...
[sfrench/cifs-2.6.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/haldefs.h>
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 {
25         uint64_t uartbase;
26         unsigned int value;
27
28         /* sign extend to 64 bits, if needed */
29         uartbase = (uint64_t)(long)p->membase;
30         value = nlm_read_reg(uartbase, offset);
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 {
43         uint64_t uartbase;
44
45         /* sign extend to 64 bits, if needed */
46         uartbase = (uint64_t)(long)p->membase;
47
48         /* See XLR/XLS errata */
49         if (offset == UART_MSR)
50                 value ^= 0xF0;
51         else if (offset == UART_MCR)
52                 value ^= 0x3;
53
54         nlm_write_reg(uartbase, offset, value);
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 {
86         unsigned long uartbase;
87
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);
91
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);
95
96         return platform_device_register(&uart_device);
97 }
98
99 arch_initcall(nlm_uart_init);