diff options
author | Manuel Lauss <manuel.lauss@googlemail.com> | 2011-05-08 04:42:17 -0400 |
---|---|---|
committer | Ralf Baechle <ralf@linux-mips.org> | 2011-05-19 04:55:45 -0400 |
commit | 80130204b43ce9c3b50924e4c2d44e9f2881f8c3 (patch) | |
tree | b136768ee20f226dbe0c55e1957f19e882784a5b /arch/mips/alchemy/common/platform.c | |
parent | adcb86279f1e4d7a1a9f267b49441aecf4a5110a (diff) |
MIPS: Alchemy: Rewrite UART setup and constants.
Detect CPU type at runtime and setup uarts accordingly; also clean up the
uart base address mess in the process as far as possible.
Signed-off-by: Manuel Lauss <manuel.lauss@googlemail.com>
To: Linux-MIPS <linux-mips@linux-mips.org>
Cc: Florian Fainelli <florian@openwrt.org>
Cc: Wolfgang Grandegger <wg@grandegger.com>
Patchwork: https://patchwork.linux-mips.org/patch/2352/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org
Diffstat (limited to 'arch/mips/alchemy/common/platform.c')
-rw-r--r-- | arch/mips/alchemy/common/platform.c | 93 |
1 files changed, 51 insertions, 42 deletions
diff --git a/arch/mips/alchemy/common/platform.c b/arch/mips/alchemy/common/platform.c index 9e7814db3d03..36489fb184a2 100644 --- a/arch/mips/alchemy/common/platform.c +++ b/arch/mips/alchemy/common/platform.c | |||
@@ -30,21 +30,12 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state, | |||
30 | #ifdef CONFIG_SERIAL_8250 | 30 | #ifdef CONFIG_SERIAL_8250 |
31 | switch (state) { | 31 | switch (state) { |
32 | case 0: | 32 | case 0: |
33 | if ((__raw_readl(port->membase + UART_MOD_CNTRL) & 3) != 3) { | 33 | alchemy_uart_enable(CPHYSADDR(port->membase)); |
34 | /* power-on sequence as suggested in the databooks */ | ||
35 | __raw_writel(0, port->membase + UART_MOD_CNTRL); | ||
36 | wmb(); | ||
37 | __raw_writel(1, port->membase + UART_MOD_CNTRL); | ||
38 | wmb(); | ||
39 | } | ||
40 | __raw_writel(3, port->membase + UART_MOD_CNTRL); /* full on */ | ||
41 | wmb(); | ||
42 | serial8250_do_pm(port, state, old_state); | 34 | serial8250_do_pm(port, state, old_state); |
43 | break; | 35 | break; |
44 | case 3: /* power off */ | 36 | case 3: /* power off */ |
45 | serial8250_do_pm(port, state, old_state); | 37 | serial8250_do_pm(port, state, old_state); |
46 | __raw_writel(0, port->membase + UART_MOD_CNTRL); | 38 | alchemy_uart_disable(CPHYSADDR(port->membase)); |
47 | wmb(); | ||
48 | break; | 39 | break; |
49 | default: | 40 | default: |
50 | serial8250_do_pm(port, state, old_state); | 41 | serial8250_do_pm(port, state, old_state); |
@@ -65,38 +56,60 @@ static void alchemy_8250_pm(struct uart_port *port, unsigned int state, | |||
65 | .pm = alchemy_8250_pm, \ | 56 | .pm = alchemy_8250_pm, \ |
66 | } | 57 | } |
67 | 58 | ||
68 | static struct plat_serial8250_port au1x00_uart_data[] = { | 59 | static struct plat_serial8250_port au1x00_uart_data[][4] __initdata = { |
69 | #if defined(CONFIG_SOC_AU1000) | 60 | [ALCHEMY_CPU_AU1000] = { |
70 | PORT(UART0_PHYS_ADDR, AU1000_UART0_INT), | 61 | PORT(AU1000_UART0_PHYS_ADDR, AU1000_UART0_INT), |
71 | PORT(UART1_PHYS_ADDR, AU1000_UART1_INT), | 62 | PORT(AU1000_UART1_PHYS_ADDR, AU1000_UART1_INT), |
72 | PORT(UART2_PHYS_ADDR, AU1000_UART2_INT), | 63 | PORT(AU1000_UART2_PHYS_ADDR, AU1000_UART2_INT), |
73 | PORT(UART3_PHYS_ADDR, AU1000_UART3_INT), | 64 | PORT(AU1000_UART3_PHYS_ADDR, AU1000_UART3_INT), |
74 | #elif defined(CONFIG_SOC_AU1500) | 65 | }, |
75 | PORT(UART0_PHYS_ADDR, AU1500_UART0_INT), | 66 | [ALCHEMY_CPU_AU1500] = { |
76 | PORT(UART3_PHYS_ADDR, AU1500_UART3_INT), | 67 | PORT(AU1000_UART0_PHYS_ADDR, AU1500_UART0_INT), |
77 | #elif defined(CONFIG_SOC_AU1100) | 68 | PORT(AU1000_UART3_PHYS_ADDR, AU1500_UART3_INT), |
78 | PORT(UART0_PHYS_ADDR, AU1100_UART0_INT), | 69 | }, |
79 | PORT(UART1_PHYS_ADDR, AU1100_UART1_INT), | 70 | [ALCHEMY_CPU_AU1100] = { |
80 | PORT(UART3_PHYS_ADDR, AU1100_UART3_INT), | 71 | PORT(AU1000_UART0_PHYS_ADDR, AU1100_UART0_INT), |
81 | #elif defined(CONFIG_SOC_AU1550) | 72 | PORT(AU1000_UART1_PHYS_ADDR, AU1100_UART1_INT), |
82 | PORT(UART0_PHYS_ADDR, AU1550_UART0_INT), | 73 | PORT(AU1000_UART3_PHYS_ADDR, AU1100_UART3_INT), |
83 | PORT(UART1_PHYS_ADDR, AU1550_UART1_INT), | 74 | }, |
84 | PORT(UART3_PHYS_ADDR, AU1550_UART3_INT), | 75 | [ALCHEMY_CPU_AU1550] = { |
85 | #elif defined(CONFIG_SOC_AU1200) | 76 | PORT(AU1000_UART0_PHYS_ADDR, AU1550_UART0_INT), |
86 | PORT(UART0_PHYS_ADDR, AU1200_UART0_INT), | 77 | PORT(AU1000_UART1_PHYS_ADDR, AU1550_UART1_INT), |
87 | PORT(UART1_PHYS_ADDR, AU1200_UART1_INT), | 78 | PORT(AU1000_UART3_PHYS_ADDR, AU1550_UART3_INT), |
88 | #endif | 79 | }, |
89 | { }, | 80 | [ALCHEMY_CPU_AU1200] = { |
81 | PORT(AU1000_UART0_PHYS_ADDR, AU1200_UART0_INT), | ||
82 | PORT(AU1000_UART1_PHYS_ADDR, AU1200_UART1_INT), | ||
83 | }, | ||
90 | }; | 84 | }; |
91 | 85 | ||
92 | static struct platform_device au1xx0_uart_device = { | 86 | static struct platform_device au1xx0_uart_device = { |
93 | .name = "serial8250", | 87 | .name = "serial8250", |
94 | .id = PLAT8250_DEV_AU1X00, | 88 | .id = PLAT8250_DEV_AU1X00, |
95 | .dev = { | ||
96 | .platform_data = au1x00_uart_data, | ||
97 | }, | ||
98 | }; | 89 | }; |
99 | 90 | ||
91 | static void __init alchemy_setup_uarts(int ctype) | ||
92 | { | ||
93 | unsigned int uartclk = get_au1x00_uart_baud_base() * 16; | ||
94 | int s = sizeof(struct plat_serial8250_port); | ||
95 | int c = alchemy_get_uarts(ctype); | ||
96 | struct plat_serial8250_port *ports; | ||
97 | |||
98 | ports = kzalloc(s * (c + 1), GFP_KERNEL); | ||
99 | if (!ports) { | ||
100 | printk(KERN_INFO "Alchemy: no memory for UART data\n"); | ||
101 | return; | ||
102 | } | ||
103 | memcpy(ports, au1x00_uart_data[ctype], s * c); | ||
104 | au1xx0_uart_device.dev.platform_data = ports; | ||
105 | |||
106 | /* Fill up uartclk. */ | ||
107 | for (s = 0; s < c; s++) | ||
108 | ports[s].uartclk = uartclk; | ||
109 | if (platform_device_register(&au1xx0_uart_device)) | ||
110 | printk(KERN_INFO "Alchemy: failed to register UARTs\n"); | ||
111 | } | ||
112 | |||
100 | /* OHCI (USB full speed host controller) */ | 113 | /* OHCI (USB full speed host controller) */ |
101 | static struct resource au1xxx_usb_ohci_resources[] = { | 114 | static struct resource au1xxx_usb_ohci_resources[] = { |
102 | [0] = { | 115 | [0] = { |
@@ -442,7 +455,6 @@ void __init au1xxx_override_eth_cfg(unsigned int port, | |||
442 | } | 455 | } |
443 | 456 | ||
444 | static struct platform_device *au1xxx_platform_devices[] __initdata = { | 457 | static struct platform_device *au1xxx_platform_devices[] __initdata = { |
445 | &au1xx0_uart_device, | ||
446 | &au1xxx_usb_ohci_device, | 458 | &au1xxx_usb_ohci_device, |
447 | #ifdef CONFIG_FB_AU1100 | 459 | #ifdef CONFIG_FB_AU1100 |
448 | &au1100_lcd_device, | 460 | &au1100_lcd_device, |
@@ -465,13 +477,10 @@ static struct platform_device *au1xxx_platform_devices[] __initdata = { | |||
465 | 477 | ||
466 | static int __init au1xxx_platform_init(void) | 478 | static int __init au1xxx_platform_init(void) |
467 | { | 479 | { |
468 | unsigned int uartclk = get_au1x00_uart_baud_base() * 16; | 480 | int err, i, ctype = alchemy_get_cputype(); |
469 | int err, i; | ||
470 | unsigned char ethaddr[6]; | 481 | unsigned char ethaddr[6]; |
471 | 482 | ||
472 | /* Fill up uartclk. */ | 483 | alchemy_setup_uarts(ctype); |
473 | for (i = 0; au1x00_uart_data[i].flags; i++) | ||
474 | au1x00_uart_data[i].uartclk = uartclk; | ||
475 | 484 | ||
476 | /* use firmware-provided mac addr if available and necessary */ | 485 | /* use firmware-provided mac addr if available and necessary */ |
477 | i = prom_get_ethernet_addr(ethaddr); | 486 | i = prom_get_ethernet_addr(ethaddr); |