aboutsummaryrefslogtreecommitdiffstats
path: root/arch/arm/mach-omap2/serial.c
diff options
context:
space:
mode:
authorTony Lindgren <tony@atomide.com>2005-11-10 09:26:51 -0500
committerRussell King <rmk+kernel@arm.linux.org.uk>2005-11-10 09:26:51 -0500
commit1dbae815a724303b46ab4663b5fc23c13e9d9690 (patch)
tree7979efc3eb2bc5c2f969020354b8c9b2954470f0 /arch/arm/mach-omap2/serial.c
parent1a8bfa1eb998af6e650ad26201f7cae9f2a2fdc8 (diff)
[ARM] 3145/1: OMAP 3a/5: Add support for omap24xx
Patch from Tony Lindgren This patch adds support for omap24xx series of processors. The files live in arch/arm/mach-omap2, and share common files with omap15xx and omap16xx processors in arch/arm/plat-omap. Omap24xx support was originally added for 2.6.9 by TI. This code was then improved and integrated to share common code with omap15xx and omap16xx processors by various omap developers, such as Paul Mundt, Juha Yrjola, Imre Deak, Tony Lindgren, Richard Woodruff, Nishant Menon, Komal Shah et al. Signed-off-by: Tony Lindgren <tony@atomide.com> Signed-off-by: Russell King <rmk+kernel@arm.linux.org.uk>
Diffstat (limited to 'arch/arm/mach-omap2/serial.c')
-rw-r--r--arch/arm/mach-omap2/serial.c180
1 files changed, 180 insertions, 0 deletions
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c
new file mode 100644
index 000000000000..f4df04fe1dd8
--- /dev/null
+++ b/arch/arm/mach-omap2/serial.c
@@ -0,0 +1,180 @@
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#include <asm/hardware/clock.h>
22
23#include <asm/arch/common.h>
24#include <asm/arch/board.h>
25
26static struct clk * uart1_ick = NULL;
27static struct clk * uart1_fck = NULL;
28static struct clk * uart2_ick = NULL;
29static struct clk * uart2_fck = NULL;
30static struct clk * uart3_ick = NULL;
31static struct clk * uart3_fck = NULL;
32
33static struct plat_serial8250_port serial_platform_data[] = {
34 {
35 .membase = (char *)IO_ADDRESS(OMAP_UART1_BASE),
36 .mapbase = (unsigned long)OMAP_UART1_BASE,
37 .irq = 72,
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_UART2_BASE),
44 .mapbase = (unsigned long)OMAP_UART2_BASE,
45 .irq = 73,
46 .flags = UPF_BOOT_AUTOCONF,
47 .iotype = UPIO_MEM,
48 .regshift = 2,
49 .uartclk = OMAP16XX_BASE_BAUD * 16,
50 }, {
51 .membase = (char *)IO_ADDRESS(OMAP_UART3_BASE),
52 .mapbase = (unsigned long)OMAP_UART3_BASE,
53 .irq = 74,
54 .flags = UPF_BOOT_AUTOCONF,
55 .iotype = UPIO_MEM,
56 .regshift = 2,
57 .uartclk = OMAP16XX_BASE_BAUD * 16,
58 }, {
59 .flags = 0
60 }
61};
62
63static inline unsigned int serial_read_reg(struct plat_serial8250_port *up,
64 int offset)
65{
66 offset <<= up->regshift;
67 return (unsigned int)__raw_readb(up->membase + offset);
68}
69
70static inline void serial_write_reg(struct plat_serial8250_port *p, int offset,
71 int value)
72{
73 offset <<= p->regshift;
74 __raw_writeb(value, (unsigned long)(p->membase + offset));
75}
76
77/*
78 * Internal UARTs need to be initialized for the 8250 autoconfig to work
79 * properly. Note that the TX watermark initialization may not be needed
80 * once the 8250.c watermark handling code is merged.
81 */
82static inline void __init omap_serial_reset(struct plat_serial8250_port *p)
83{
84 serial_write_reg(p, UART_OMAP_MDR1, 0x07);
85 serial_write_reg(p, UART_OMAP_SCR, 0x08);
86 serial_write_reg(p, UART_OMAP_MDR1, 0x00);
87 serial_write_reg(p, UART_OMAP_SYSC, 0x01);
88}
89
90void __init omap_serial_init()
91{
92 int i;
93 const struct omap_uart_config *info;
94
95 /*
96 * Make sure the serial ports are muxed on at this point.
97 * You have to mux them off in device drivers later on
98 * if not needed.
99 */
100
101 info = omap_get_config(OMAP_TAG_UART,
102 struct omap_uart_config);
103
104 if (info == NULL)
105 return;
106
107 for (i = 0; i < OMAP_MAX_NR_PORTS; i++) {
108 struct plat_serial8250_port *p = serial_platform_data + i;
109
110 if (!(info->enabled_uarts & (1 << i))) {
111 p->membase = 0;
112 p->mapbase = 0;
113 continue;
114 }
115
116 switch (i) {
117 case 0:
118 uart1_ick = clk_get(NULL, "uart1_ick");
119 if (IS_ERR(uart1_ick))
120 printk("Could not get uart1_ick\n");
121 else {
122 clk_use(uart1_ick);
123 }
124
125 uart1_fck = clk_get(NULL, "uart1_fck");
126 if (IS_ERR(uart1_fck))
127 printk("Could not get uart1_fck\n");
128 else {
129 clk_use(uart1_fck);
130 }
131 break;
132 case 1:
133 uart2_ick = clk_get(NULL, "uart2_ick");
134 if (IS_ERR(uart2_ick))
135 printk("Could not get uart2_ick\n");
136 else {
137 clk_use(uart2_ick);
138 }
139
140 uart2_fck = clk_get(NULL, "uart2_fck");
141 if (IS_ERR(uart2_fck))
142 printk("Could not get uart2_fck\n");
143 else {
144 clk_use(uart2_fck);
145 }
146 break;
147 case 2:
148 uart3_ick = clk_get(NULL, "uart3_ick");
149 if (IS_ERR(uart3_ick))
150 printk("Could not get uart3_ick\n");
151 else {
152 clk_use(uart3_ick);
153 }
154
155 uart3_fck = clk_get(NULL, "uart3_fck");
156 if (IS_ERR(uart3_fck))
157 printk("Could not get uart3_fck\n");
158 else {
159 clk_use(uart3_fck);
160 }
161 break;
162 }
163
164 omap_serial_reset(p);
165 }
166}
167
168static struct platform_device serial_device = {
169 .name = "serial8250",
170 .id = 0,
171 .dev = {
172 .platform_data = serial_platform_data,
173 },
174};
175
176static int __init omap_init(void)
177{
178 return platform_device_register(&serial_device);
179}
180arch_initcall(omap_init);