]> www.pilppa.org Git - linux-2.6-omap-h63xx.git/blob - arch/arm/mach-omap2/serial.c
[PATCH] ARM: OMAP: Fix problem UART index != UART line, clean up serial init
[linux-2.6-omap-h63xx.git] / arch / arm / mach-omap2 / serial.c
1 /*
2  * arch/arm/mach-omap/omap2/serial.c
3  *
4  * OMAP2 serial support.
5  *
6  * Copyright (C) 2005 Nokia Corporation
7  * Author: Paul Mundt <paul.mundt@nokia.com>
8  *
9  * Based off of arch/arm/mach-omap/omap1/serial.c
10  *
11  * This file is subject to the terms and conditions of the GNU General Public
12  * License. See the file "COPYING" in the main directory of this archive
13  * for more details.
14  */
15 #include <linux/kernel.h>
16 #include <linux/init.h>
17 #include <linux/serial_8250.h>
18 #include <linux/serial_reg.h>
19
20 #include <asm/io.h>
21
22 #include <asm/arch/common.h>
23 #include <asm/arch/board.h>
24
25 static struct plat_serial8250_port serial_platform_data[] = {
26         {
27                 .membase        = (char *)IO_ADDRESS(OMAP_UART1_BASE),
28                 .mapbase        = (unsigned long)OMAP_UART1_BASE,
29                 .irq            = 72,
30                 .flags          = UPF_BOOT_AUTOCONF,
31                 .iotype         = UPIO_MEM,
32                 .regshift       = 2,
33                 .uartclk        = OMAP16XX_BASE_BAUD * 16,
34         }, {
35                 .membase        = (char *)IO_ADDRESS(OMAP_UART2_BASE),
36                 .mapbase        = (unsigned long)OMAP_UART2_BASE,
37                 .irq            = 73,
38                 .flags          = UPF_BOOT_AUTOCONF,
39                 .iotype         = UPIO_MEM,
40                 .regshift       = 2,
41                 .uartclk        = OMAP16XX_BASE_BAUD * 16,
42         }, {
43                 .membase        = (char *)IO_ADDRESS(OMAP_UART3_BASE),
44                 .mapbase        = (unsigned long)OMAP_UART3_BASE,
45                 .irq            = 74,
46                 .flags          = UPF_BOOT_AUTOCONF,
47                 .iotype         = UPIO_MEM,
48                 .regshift       = 2,
49                 .uartclk        = OMAP16XX_BASE_BAUD * 16,
50         }, {
51                 .flags          = 0
52         }
53 };
54
55 static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
56                                            int offset)
57 {
58         offset <<= up->regshift;
59         return (unsigned int)__raw_readb(up->membase + offset);
60 }
61
62 static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
63                                     int value)
64 {
65         offset <<= p->regshift;
66         __raw_writeb(value, (unsigned long)(p->membase + offset));
67 }
68
69 /*
70  * Internal UARTs need to be initialized for the 8250 autoconfig to work
71  * properly. Note that the TX watermark initialization may not be needed
72  * once the 8250.c watermark handling code is merged.
73  */
74 static inline void __init omap_serial_reset(struct plat_serial8250_port *p)
75 {
76         serial_write_reg(p, UART_OMAP_MDR1, 0x07);
77         serial_write_reg(p, UART_OMAP_SCR, 0x08);
78         serial_write_reg(p, UART_OMAP_MDR1, 0x00);
79         serial_write_reg(p, UART_OMAP_SYSC, 0x01);
80 }
81
82 void __init omap_serial_init()
83 {
84         int i;
85         const struct omap_uart_config *info;
86
87         /*
88          * Make sure the serial ports are muxed on at this point.
89          * You have to mux them off in device drivers later on
90          * if not needed.
91          */
92
93         info = omap_get_config(OMAP_TAG_UART,
94                                struct omap_uart_config);
95
96         if (info == NULL)
97                 return;
98
99         for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
100                 struct plat_serial8250_port *p = serial_platform_data + i;
101
102                 if (!(info->enabled_uarts & (1 << i))) {
103                         p->membase = 0;
104                         p->mapbase = 0;
105                         continue;
106                 }
107
108                 omap_serial_reset(p);
109         }
110 }
111
112 static struct platform_device serial_device = {
113         .name                   = "serial8250",
114         .id                     = 0,
115         .dev                    = {
116                 .platform_data  = serial_platform_data,
117         },
118 };
119
120 static int __init omap_init(void)
121 {
122         return platform_device_register(&serial_device);
123 }
124 arch_initcall(omap_init);