diff options
author | Kevin Hilman <khilman@deeprootsystems.com> | 2010-09-27 10:49:38 -0400 |
---|---|---|
committer | Kevin Hilman <khilman@deeprootsystems.com> | 2010-09-29 15:42:56 -0400 |
commit | 6f251e9db1093c187addc309b5f2f7fe3efd2995 (patch) | |
tree | becc3755857d797e6633c6a4a8e714c128aad097 /arch/arm/mach-omap2 | |
parent | 046465b76a41a32a8d56e691b167fb9ba7729970 (diff) |
OMAP: UART: omap_device conversions, remove implicit 8520 assumptions
Major rework of OMAP UART init for omap_device conversion as well as
use with either 8250 driver or new omap-serial driver.
In preparation for a new omap-serial driver, remove 8250 assumptions
and dependencies from the serial core.
Convert UART core and PM support to use omap_device layer. Also add
support for both console on 8250 or omap-serial driver.
omap_device conversion:
- Convert clock API calls to omap_device calls
- Remove all static platform_data setup and configuration. This is
all done by the omap_device build phase.
Signed-off-by: Govindraj.R <govindraj.raja@ti.com>
Signed-off-by: Kevin Hilman <khilman@deeprootsystems.com>
Diffstat (limited to 'arch/arm/mach-omap2')
-rw-r--r-- | arch/arm/mach-omap2/serial.c | 529 |
1 files changed, 260 insertions, 269 deletions
diff --git a/arch/arm/mach-omap2/serial.c b/arch/arm/mach-omap2/serial.c index 566e991ede81..e6c40273dafe 100644 --- a/arch/arm/mach-omap2/serial.c +++ b/arch/arm/mach-omap2/serial.c | |||
@@ -19,19 +19,29 @@ | |||
19 | */ | 19 | */ |
20 | #include <linux/kernel.h> | 20 | #include <linux/kernel.h> |
21 | #include <linux/init.h> | 21 | #include <linux/init.h> |
22 | #include <linux/serial_8250.h> | ||
23 | #include <linux/serial_reg.h> | 22 | #include <linux/serial_reg.h> |
24 | #include <linux/clk.h> | 23 | #include <linux/clk.h> |
25 | #include <linux/io.h> | 24 | #include <linux/io.h> |
26 | #include <linux/delay.h> | 25 | #include <linux/delay.h> |
26 | #include <linux/platform_device.h> | ||
27 | #include <linux/slab.h> | ||
28 | #include <linux/serial_8250.h> | ||
29 | |||
30 | #ifdef CONFIG_SERIAL_OMAP | ||
31 | #include <plat/omap-serial.h> | ||
32 | #endif | ||
27 | 33 | ||
28 | #include <plat/common.h> | 34 | #include <plat/common.h> |
29 | #include <plat/board.h> | 35 | #include <plat/board.h> |
30 | #include <plat/clock.h> | 36 | #include <plat/clock.h> |
31 | #include <plat/control.h> | 37 | #include <plat/control.h> |
38 | #include <plat/dma.h> | ||
39 | #include <plat/omap_hwmod.h> | ||
40 | #include <plat/omap_device.h> | ||
32 | 41 | ||
33 | #include "prm.h" | 42 | #include "prm.h" |
34 | #include "pm.h" | 43 | #include "pm.h" |
44 | #include "cm.h" | ||
35 | #include "prm-regbits-34xx.h" | 45 | #include "prm-regbits-34xx.h" |
36 | 46 | ||
37 | #define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV 0x52 | 47 | #define UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV 0x52 |
@@ -48,6 +58,8 @@ | |||
48 | */ | 58 | */ |
49 | #define DEFAULT_TIMEOUT 0 | 59 | #define DEFAULT_TIMEOUT 0 |
50 | 60 | ||
61 | #define MAX_UART_HWMOD_NAME_LEN 16 | ||
62 | |||
51 | struct omap_uart_state { | 63 | struct omap_uart_state { |
52 | int num; | 64 | int num; |
53 | int can_sleep; | 65 | int can_sleep; |
@@ -58,14 +70,21 @@ struct omap_uart_state { | |||
58 | void __iomem *wk_en; | 70 | void __iomem *wk_en; |
59 | u32 wk_mask; | 71 | u32 wk_mask; |
60 | u32 padconf; | 72 | u32 padconf; |
73 | u32 dma_enabled; | ||
61 | 74 | ||
62 | struct clk *ick; | 75 | struct clk *ick; |
63 | struct clk *fck; | 76 | struct clk *fck; |
64 | int clocked; | 77 | int clocked; |
65 | 78 | ||
66 | struct plat_serial8250_port *p; | 79 | int irq; |
80 | int regshift; | ||
81 | int irqflags; | ||
82 | void __iomem *membase; | ||
83 | resource_size_t mapbase; | ||
84 | |||
67 | struct list_head node; | 85 | struct list_head node; |
68 | struct platform_device pdev; | 86 | struct omap_hwmod *oh; |
87 | struct platform_device *pdev; | ||
69 | 88 | ||
70 | u32 errata; | 89 | u32 errata; |
71 | #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) | 90 | #if defined(CONFIG_ARCH_OMAP3) && defined(CONFIG_PM) |
@@ -83,75 +102,33 @@ struct omap_uart_state { | |||
83 | }; | 102 | }; |
84 | 103 | ||
85 | static LIST_HEAD(uart_list); | 104 | static LIST_HEAD(uart_list); |
105 | static u8 num_uarts; | ||
86 | 106 | ||
87 | static struct plat_serial8250_port serial_platform_data0[] = { | ||
88 | { | ||
89 | .irq = 72, | ||
90 | .flags = UPF_BOOT_AUTOCONF, | ||
91 | .iotype = UPIO_MEM, | ||
92 | .regshift = 2, | ||
93 | .uartclk = OMAP24XX_BASE_BAUD * 16, | ||
94 | }, { | ||
95 | .flags = 0 | ||
96 | } | ||
97 | }; | ||
98 | |||
99 | static struct plat_serial8250_port serial_platform_data1[] = { | ||
100 | { | ||
101 | .irq = 73, | ||
102 | .flags = UPF_BOOT_AUTOCONF, | ||
103 | .iotype = UPIO_MEM, | ||
104 | .regshift = 2, | ||
105 | .uartclk = OMAP24XX_BASE_BAUD * 16, | ||
106 | }, { | ||
107 | .flags = 0 | ||
108 | } | ||
109 | }; | ||
110 | |||
111 | static struct plat_serial8250_port serial_platform_data2[] = { | ||
112 | { | ||
113 | .irq = 74, | ||
114 | .flags = UPF_BOOT_AUTOCONF, | ||
115 | .iotype = UPIO_MEM, | ||
116 | .regshift = 2, | ||
117 | .uartclk = OMAP24XX_BASE_BAUD * 16, | ||
118 | }, { | ||
119 | .flags = 0 | ||
120 | } | ||
121 | }; | ||
122 | |||
123 | static struct plat_serial8250_port serial_platform_data3[] = { | ||
124 | { | ||
125 | .irq = 70, | ||
126 | .flags = UPF_BOOT_AUTOCONF, | ||
127 | .iotype = UPIO_MEM, | ||
128 | .regshift = 2, | ||
129 | .uartclk = OMAP24XX_BASE_BAUD * 16, | ||
130 | }, { | ||
131 | .flags = 0 | ||
132 | } | ||
133 | }; | ||
134 | 107 | ||
135 | void __init omap2_set_globals_uart(struct omap_globals *omap2_globals) | 108 | void __init omap2_set_globals_uart(struct omap_globals *omap2_globals) |
136 | { | 109 | { |
137 | serial_platform_data0[0].mapbase = omap2_globals->uart1_phys; | ||
138 | serial_platform_data1[0].mapbase = omap2_globals->uart2_phys; | ||
139 | serial_platform_data2[0].mapbase = omap2_globals->uart3_phys; | ||
140 | serial_platform_data3[0].mapbase = omap2_globals->uart4_phys; | ||
141 | } | 110 | } |
142 | 111 | ||
112 | static struct omap_device_pm_latency omap_uart_latency[] = { | ||
113 | { | ||
114 | .deactivate_func = omap_device_idle_hwmods, | ||
115 | .activate_func = omap_device_enable_hwmods, | ||
116 | .flags = OMAP_DEVICE_LATENCY_AUTO_ADJUST, | ||
117 | }, | ||
118 | }; | ||
119 | |||
143 | static inline unsigned int __serial_read_reg(struct uart_port *up, | 120 | static inline unsigned int __serial_read_reg(struct uart_port *up, |
144 | int offset) | 121 | int offset) |
145 | { | 122 | { |
146 | offset <<= up->regshift; | 123 | offset <<= up->regshift; |
147 | return (unsigned int)__raw_readb(up->membase + offset); | 124 | return (unsigned int)__raw_readb(up->membase + offset); |
148 | } | 125 | } |
149 | 126 | ||
150 | static inline unsigned int serial_read_reg(struct plat_serial8250_port *up, | 127 | static inline unsigned int serial_read_reg(struct omap_uart_state *uart, |
151 | int offset) | 128 | int offset) |
152 | { | 129 | { |
153 | offset <<= up->regshift; | 130 | offset <<= uart->regshift; |
154 | return (unsigned int)__raw_readb(up->membase + offset); | 131 | return (unsigned int)__raw_readb(uart->membase + offset); |
155 | } | 132 | } |
156 | 133 | ||
157 | static inline void __serial_write_reg(struct uart_port *up, int offset, | 134 | static inline void __serial_write_reg(struct uart_port *up, int offset, |
@@ -161,11 +138,11 @@ static inline void __serial_write_reg(struct uart_port *up, int offset, | |||
161 | __raw_writeb(value, up->membase + offset); | 138 | __raw_writeb(value, up->membase + offset); |
162 | } | 139 | } |
163 | 140 | ||
164 | static inline void serial_write_reg(struct plat_serial8250_port *p, int offset, | 141 | static inline void serial_write_reg(struct omap_uart_state *uart, int offset, |
165 | int value) | 142 | int value) |
166 | { | 143 | { |
167 | offset <<= p->regshift; | 144 | offset <<= uart->regshift; |
168 | __raw_writeb(value, p->membase + offset); | 145 | __raw_writeb(value, uart->membase + offset); |
169 | } | 146 | } |
170 | 147 | ||
171 | /* | 148 | /* |
@@ -173,14 +150,12 @@ static inline void serial_write_reg(struct plat_serial8250_port *p, int offset, | |||
173 | * properly. Note that the TX watermark initialization may not be needed | 150 | * properly. Note that the TX watermark initialization may not be needed |
174 | * once the 8250.c watermark handling code is merged. | 151 | * once the 8250.c watermark handling code is merged. |
175 | */ | 152 | */ |
153 | |||
176 | static inline void __init omap_uart_reset(struct omap_uart_state *uart) | 154 | static inline void __init omap_uart_reset(struct omap_uart_state *uart) |
177 | { | 155 | { |
178 | struct plat_serial8250_port *p = uart->p; | 156 | serial_write_reg(uart, UART_OMAP_MDR1, 0x07); |
179 | 157 | serial_write_reg(uart, UART_OMAP_SCR, 0x08); | |
180 | serial_write_reg(p, UART_OMAP_MDR1, 0x07); | 158 | serial_write_reg(uart, UART_OMAP_MDR1, 0x00); |
181 | serial_write_reg(p, UART_OMAP_SCR, 0x08); | ||
182 | serial_write_reg(p, UART_OMAP_MDR1, 0x00); | ||
183 | serial_write_reg(p, UART_OMAP_SYSC, (0x02 << 3) | (1 << 2) | (1 << 0)); | ||
184 | } | 159 | } |
185 | 160 | ||
186 | #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) | 161 | #if defined(CONFIG_PM) && defined(CONFIG_ARCH_OMAP3) |
@@ -197,24 +172,23 @@ static inline void __init omap_uart_reset(struct omap_uart_state *uart) | |||
197 | static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val, | 172 | static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val, |
198 | u8 fcr_val) | 173 | u8 fcr_val) |
199 | { | 174 | { |
200 | struct plat_serial8250_port *p = uart->p; | ||
201 | u8 timeout = 255; | 175 | u8 timeout = 255; |
202 | 176 | ||
203 | serial_write_reg(p, UART_OMAP_MDR1, mdr1_val); | 177 | serial_write_reg(uart, UART_OMAP_MDR1, mdr1_val); |
204 | udelay(2); | 178 | udelay(2); |
205 | serial_write_reg(p, UART_FCR, fcr_val | UART_FCR_CLEAR_XMIT | | 179 | serial_write_reg(uart, UART_FCR, fcr_val | UART_FCR_CLEAR_XMIT | |
206 | UART_FCR_CLEAR_RCVR); | 180 | UART_FCR_CLEAR_RCVR); |
207 | /* | 181 | /* |
208 | * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and | 182 | * Wait for FIFO to empty: when empty, RX_FIFO_E bit is 0 and |
209 | * TX_FIFO_E bit is 1. | 183 | * TX_FIFO_E bit is 1. |
210 | */ | 184 | */ |
211 | while (UART_LSR_THRE != (serial_read_reg(p, UART_LSR) & | 185 | while (UART_LSR_THRE != (serial_read_reg(uart, UART_LSR) & |
212 | (UART_LSR_THRE | UART_LSR_DR))) { | 186 | (UART_LSR_THRE | UART_LSR_DR))) { |
213 | timeout--; | 187 | timeout--; |
214 | if (!timeout) { | 188 | if (!timeout) { |
215 | /* Should *never* happen. we warn and carry on */ | 189 | /* Should *never* happen. we warn and carry on */ |
216 | dev_crit(&uart->pdev.dev, "Errata i202: timedout %x\n", | 190 | dev_crit(&uart->pdev->dev, "Errata i202: timedout %x\n", |
217 | serial_read_reg(p, UART_LSR)); | 191 | serial_read_reg(uart, UART_LSR)); |
218 | break; | 192 | break; |
219 | } | 193 | } |
220 | udelay(1); | 194 | udelay(1); |
@@ -224,23 +198,22 @@ static void omap_uart_mdr1_errataset(struct omap_uart_state *uart, u8 mdr1_val, | |||
224 | static void omap_uart_save_context(struct omap_uart_state *uart) | 198 | static void omap_uart_save_context(struct omap_uart_state *uart) |
225 | { | 199 | { |
226 | u16 lcr = 0; | 200 | u16 lcr = 0; |
227 | struct plat_serial8250_port *p = uart->p; | ||
228 | 201 | ||
229 | if (!enable_off_mode) | 202 | if (!enable_off_mode) |
230 | return; | 203 | return; |
231 | 204 | ||
232 | lcr = serial_read_reg(p, UART_LCR); | 205 | lcr = serial_read_reg(uart, UART_LCR); |
233 | serial_write_reg(p, UART_LCR, 0xBF); | 206 | serial_write_reg(uart, UART_LCR, 0xBF); |
234 | uart->dll = serial_read_reg(p, UART_DLL); | 207 | uart->dll = serial_read_reg(uart, UART_DLL); |
235 | uart->dlh = serial_read_reg(p, UART_DLM); | 208 | uart->dlh = serial_read_reg(uart, UART_DLM); |
236 | serial_write_reg(p, UART_LCR, lcr); | 209 | serial_write_reg(uart, UART_LCR, lcr); |
237 | uart->ier = serial_read_reg(p, UART_IER); | 210 | uart->ier = serial_read_reg(uart, UART_IER); |
238 | uart->sysc = serial_read_reg(p, UART_OMAP_SYSC); | 211 | uart->sysc = serial_read_reg(uart, UART_OMAP_SYSC); |
239 | uart->scr = serial_read_reg(p, UART_OMAP_SCR); | 212 | uart->scr = serial_read_reg(uart, UART_OMAP_SCR); |
240 | uart->wer = serial_read_reg(p, UART_OMAP_WER); | 213 | uart->wer = serial_read_reg(uart, UART_OMAP_WER); |
241 | serial_write_reg(p, UART_LCR, 0x80); | 214 | serial_write_reg(uart, UART_LCR, 0x80); |
242 | uart->mcr = serial_read_reg(p, UART_MCR); | 215 | uart->mcr = serial_read_reg(uart, UART_MCR); |
243 | serial_write_reg(p, UART_LCR, lcr); | 216 | serial_write_reg(uart, UART_LCR, lcr); |
244 | 217 | ||
245 | uart->context_valid = 1; | 218 | uart->context_valid = 1; |
246 | } | 219 | } |
@@ -248,7 +221,6 @@ static void omap_uart_save_context(struct omap_uart_state *uart) | |||
248 | static void omap_uart_restore_context(struct omap_uart_state *uart) | 221 | static void omap_uart_restore_context(struct omap_uart_state *uart) |
249 | { | 222 | { |
250 | u16 efr = 0; | 223 | u16 efr = 0; |
251 | struct plat_serial8250_port *p = uart->p; | ||
252 | 224 | ||
253 | if (!enable_off_mode) | 225 | if (!enable_off_mode) |
254 | return; | 226 | return; |
@@ -261,29 +233,30 @@ static void omap_uart_restore_context(struct omap_uart_state *uart) | |||
261 | if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS) | 233 | if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS) |
262 | omap_uart_mdr1_errataset(uart, 0x07, 0xA0); | 234 | omap_uart_mdr1_errataset(uart, 0x07, 0xA0); |
263 | else | 235 | else |
264 | serial_write_reg(p, UART_OMAP_MDR1, 0x7); | 236 | serial_write_reg(uart, UART_OMAP_MDR1, 0x7); |
265 | serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */ | 237 | serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */ |
266 | efr = serial_read_reg(p, UART_EFR); | 238 | efr = serial_read_reg(uart, UART_EFR); |
267 | serial_write_reg(p, UART_EFR, UART_EFR_ECB); | 239 | serial_write_reg(uart, UART_EFR, UART_EFR_ECB); |
268 | serial_write_reg(p, UART_LCR, 0x0); /* Operational mode */ | 240 | serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */ |
269 | serial_write_reg(p, UART_IER, 0x0); | 241 | serial_write_reg(uart, UART_IER, 0x0); |
270 | serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */ | 242 | serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */ |
271 | serial_write_reg(p, UART_DLL, uart->dll); | 243 | serial_write_reg(uart, UART_DLL, uart->dll); |
272 | serial_write_reg(p, UART_DLM, uart->dlh); | 244 | serial_write_reg(uart, UART_DLM, uart->dlh); |
273 | serial_write_reg(p, UART_LCR, 0x0); /* Operational mode */ | 245 | serial_write_reg(uart, UART_LCR, 0x0); /* Operational mode */ |
274 | serial_write_reg(p, UART_IER, uart->ier); | 246 | serial_write_reg(uart, UART_IER, uart->ier); |
275 | serial_write_reg(p, UART_LCR, 0x80); | 247 | serial_write_reg(uart, UART_LCR, 0x80); |
276 | serial_write_reg(p, UART_MCR, uart->mcr); | 248 | serial_write_reg(uart, UART_MCR, uart->mcr); |
277 | serial_write_reg(p, UART_LCR, 0xBF); /* Config B mode */ | 249 | serial_write_reg(uart, UART_LCR, 0xBF); /* Config B mode */ |
278 | serial_write_reg(p, UART_EFR, efr); | 250 | serial_write_reg(uart, UART_EFR, efr); |
279 | serial_write_reg(p, UART_LCR, UART_LCR_WLEN8); | 251 | serial_write_reg(uart, UART_LCR, UART_LCR_WLEN8); |
280 | serial_write_reg(p, UART_OMAP_SCR, uart->scr); | 252 | serial_write_reg(uart, UART_OMAP_SCR, uart->scr); |
281 | serial_write_reg(p, UART_OMAP_WER, uart->wer); | 253 | serial_write_reg(uart, UART_OMAP_WER, uart->wer); |
282 | serial_write_reg(p, UART_OMAP_SYSC, uart->sysc); | 254 | serial_write_reg(uart, UART_OMAP_SYSC, uart->sysc); |
283 | if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS) | 255 | if (uart->errata & UART_ERRATA_i202_MDR1_ACCESS) |
284 | omap_uart_mdr1_errataset(uart, 0x00, 0xA1); | 256 | omap_uart_mdr1_errataset(uart, 0x00, 0xA1); |
285 | else | 257 | else |
286 | serial_write_reg(p, UART_OMAP_MDR1, 0x00); /* UART 16x mode */ | 258 | /* UART 16x mode */ |
259 | serial_write_reg(uart, UART_OMAP_MDR1, 0x00); | ||
287 | } | 260 | } |
288 | #else | 261 | #else |
289 | static inline void omap_uart_save_context(struct omap_uart_state *uart) {} | 262 | static inline void omap_uart_save_context(struct omap_uart_state *uart) {} |
@@ -295,8 +268,7 @@ static inline void omap_uart_enable_clocks(struct omap_uart_state *uart) | |||
295 | if (uart->clocked) | 268 | if (uart->clocked) |
296 | return; | 269 | return; |
297 | 270 | ||
298 | clk_enable(uart->ick); | 271 | omap_device_enable(uart->pdev); |
299 | clk_enable(uart->fck); | ||
300 | uart->clocked = 1; | 272 | uart->clocked = 1; |
301 | omap_uart_restore_context(uart); | 273 | omap_uart_restore_context(uart); |
302 | } | 274 | } |
@@ -310,8 +282,7 @@ static inline void omap_uart_disable_clocks(struct omap_uart_state *uart) | |||
310 | 282 | ||
311 | omap_uart_save_context(uart); | 283 | omap_uart_save_context(uart); |
312 | uart->clocked = 0; | 284 | uart->clocked = 0; |
313 | clk_disable(uart->ick); | 285 | omap_device_idle(uart->pdev); |
314 | clk_disable(uart->fck); | ||
315 | } | 286 | } |
316 | 287 | ||
317 | static void omap_uart_enable_wakeup(struct omap_uart_state *uart) | 288 | static void omap_uart_enable_wakeup(struct omap_uart_state *uart) |
@@ -349,18 +320,24 @@ static void omap_uart_disable_wakeup(struct omap_uart_state *uart) | |||
349 | } | 320 | } |
350 | 321 | ||
351 | static void omap_uart_smart_idle_enable(struct omap_uart_state *uart, | 322 | static void omap_uart_smart_idle_enable(struct omap_uart_state *uart, |
352 | int enable) | 323 | int enable) |
353 | { | 324 | { |
354 | struct plat_serial8250_port *p = uart->p; | 325 | u8 idlemode; |
355 | u16 sysc; | ||
356 | 326 | ||
357 | sysc = serial_read_reg(p, UART_OMAP_SYSC) & 0x7; | 327 | if (enable) { |
358 | if (enable) | 328 | /** |
359 | sysc |= 0x2 << 3; | 329 | * Errata 2.15: [UART]:Cannot Acknowledge Idle Requests |
360 | else | 330 | * in Smartidle Mode When Configured for DMA Operations. |
361 | sysc |= 0x1 << 3; | 331 | */ |
332 | if (uart->dma_enabled) | ||
333 | idlemode = HWMOD_IDLEMODE_FORCE; | ||
334 | else | ||
335 | idlemode = HWMOD_IDLEMODE_SMART; | ||
336 | } else { | ||
337 | idlemode = HWMOD_IDLEMODE_NO; | ||
338 | } | ||
362 | 339 | ||
363 | serial_write_reg(p, UART_OMAP_SYSC, sysc); | 340 | omap_hwmod_set_slave_idlemode(uart->oh, idlemode); |
364 | } | 341 | } |
365 | 342 | ||
366 | static void omap_uart_block_sleep(struct omap_uart_state *uart) | 343 | static void omap_uart_block_sleep(struct omap_uart_state *uart) |
@@ -377,7 +354,7 @@ static void omap_uart_block_sleep(struct omap_uart_state *uart) | |||
377 | 354 | ||
378 | static void omap_uart_allow_sleep(struct omap_uart_state *uart) | 355 | static void omap_uart_allow_sleep(struct omap_uart_state *uart) |
379 | { | 356 | { |
380 | if (device_may_wakeup(&uart->pdev.dev)) | 357 | if (device_may_wakeup(&uart->pdev->dev)) |
381 | omap_uart_enable_wakeup(uart); | 358 | omap_uart_enable_wakeup(uart); |
382 | else | 359 | else |
383 | omap_uart_disable_wakeup(uart); | 360 | omap_uart_disable_wakeup(uart); |
@@ -472,6 +449,7 @@ int omap_uart_can_sleep(void) | |||
472 | * UART will not idle or sleep for its timeout period. | 449 | * UART will not idle or sleep for its timeout period. |
473 | * | 450 | * |
474 | **/ | 451 | **/ |
452 | /* static int first_interrupt; */ | ||
475 | static irqreturn_t omap_uart_interrupt(int irq, void *dev_id) | 453 | static irqreturn_t omap_uart_interrupt(int irq, void *dev_id) |
476 | { | 454 | { |
477 | struct omap_uart_state *uart = dev_id; | 455 | struct omap_uart_state *uart = dev_id; |
@@ -483,7 +461,6 @@ static irqreturn_t omap_uart_interrupt(int irq, void *dev_id) | |||
483 | 461 | ||
484 | static void omap_uart_idle_init(struct omap_uart_state *uart) | 462 | static void omap_uart_idle_init(struct omap_uart_state *uart) |
485 | { | 463 | { |
486 | struct plat_serial8250_port *p = uart->p; | ||
487 | int ret; | 464 | int ret; |
488 | 465 | ||
489 | uart->can_sleep = 0; | 466 | uart->can_sleep = 0; |
@@ -546,9 +523,9 @@ static void omap_uart_idle_init(struct omap_uart_state *uart) | |||
546 | uart->padconf = 0; | 523 | uart->padconf = 0; |
547 | } | 524 | } |
548 | 525 | ||
549 | p->irqflags |= IRQF_SHARED; | 526 | uart->irqflags |= IRQF_SHARED; |
550 | ret = request_irq(p->irq, omap_uart_interrupt, IRQF_SHARED, | 527 | ret = request_threaded_irq(uart->irq, NULL, omap_uart_interrupt, |
551 | "serial idle", (void *)uart); | 528 | IRQF_SHARED, "serial idle", (void *)uart); |
552 | WARN_ON(ret); | 529 | WARN_ON(ret); |
553 | } | 530 | } |
554 | 531 | ||
@@ -559,10 +536,13 @@ void omap_uart_enable_irqs(int enable) | |||
559 | 536 | ||
560 | list_for_each_entry(uart, &uart_list, node) { | 537 | list_for_each_entry(uart, &uart_list, node) { |
561 | if (enable) | 538 | if (enable) |
562 | ret = request_irq(uart->p->irq, omap_uart_interrupt, | 539 | ret = request_threaded_irq(uart->irq, NULL, |
563 | IRQF_SHARED, "serial idle", (void *)uart); | 540 | omap_uart_interrupt, |
541 | IRQF_SHARED, | ||
542 | "serial idle", | ||
543 | (void *)uart); | ||
564 | else | 544 | else |
565 | free_irq(uart->p->irq, (void *)uart); | 545 | free_irq(uart->irq, (void *)uart); |
566 | } | 546 | } |
567 | } | 547 | } |
568 | 548 | ||
@@ -570,10 +550,9 @@ static ssize_t sleep_timeout_show(struct device *dev, | |||
570 | struct device_attribute *attr, | 550 | struct device_attribute *attr, |
571 | char *buf) | 551 | char *buf) |
572 | { | 552 | { |
573 | struct platform_device *pdev = container_of(dev, | 553 | struct platform_device *pdev = to_platform_device(dev); |
574 | struct platform_device, dev); | 554 | struct omap_device *odev = to_omap_device(pdev); |
575 | struct omap_uart_state *uart = container_of(pdev, | 555 | struct omap_uart_state *uart = odev->hwmods[0]->dev_attr; |
576 | struct omap_uart_state, pdev); | ||
577 | 556 | ||
578 | return sprintf(buf, "%u\n", uart->timeout / HZ); | 557 | return sprintf(buf, "%u\n", uart->timeout / HZ); |
579 | } | 558 | } |
@@ -582,10 +561,9 @@ static ssize_t sleep_timeout_store(struct device *dev, | |||
582 | struct device_attribute *attr, | 561 | struct device_attribute *attr, |
583 | const char *buf, size_t n) | 562 | const char *buf, size_t n) |
584 | { | 563 | { |
585 | struct platform_device *pdev = container_of(dev, | 564 | struct platform_device *pdev = to_platform_device(dev); |
586 | struct platform_device, dev); | 565 | struct omap_device *odev = to_omap_device(pdev); |
587 | struct omap_uart_state *uart = container_of(pdev, | 566 | struct omap_uart_state *uart = odev->hwmods[0]->dev_attr; |
588 | struct omap_uart_state, pdev); | ||
589 | unsigned int value; | 567 | unsigned int value; |
590 | 568 | ||
591 | if (sscanf(buf, "%u", &value) != 1) { | 569 | if (sscanf(buf, "%u", &value) != 1) { |
@@ -608,48 +586,11 @@ static DEVICE_ATTR(sleep_timeout, 0644, sleep_timeout_show, | |||
608 | #define DEV_CREATE_FILE(dev, attr) WARN_ON(device_create_file(dev, attr)) | 586 | #define DEV_CREATE_FILE(dev, attr) WARN_ON(device_create_file(dev, attr)) |
609 | #else | 587 | #else |
610 | static inline void omap_uart_idle_init(struct omap_uart_state *uart) {} | 588 | static inline void omap_uart_idle_init(struct omap_uart_state *uart) {} |
589 | static void omap_uart_block_sleep(struct omap_uart_state *uart) {} | ||
611 | #define DEV_CREATE_FILE(dev, attr) | 590 | #define DEV_CREATE_FILE(dev, attr) |
612 | #endif /* CONFIG_PM */ | 591 | #endif /* CONFIG_PM */ |
613 | 592 | ||
614 | static struct omap_uart_state omap_uart[] = { | 593 | #ifndef CONFIG_SERIAL_OMAP |
615 | { | ||
616 | .pdev = { | ||
617 | .name = "serial8250", | ||
618 | .id = PLAT8250_DEV_PLATFORM, | ||
619 | .dev = { | ||
620 | .platform_data = serial_platform_data0, | ||
621 | }, | ||
622 | }, | ||
623 | }, { | ||
624 | .pdev = { | ||
625 | .name = "serial8250", | ||
626 | .id = PLAT8250_DEV_PLATFORM1, | ||
627 | .dev = { | ||
628 | .platform_data = serial_platform_data1, | ||
629 | }, | ||
630 | }, | ||
631 | }, { | ||
632 | .pdev = { | ||
633 | .name = "serial8250", | ||
634 | .id = PLAT8250_DEV_PLATFORM2, | ||
635 | .dev = { | ||
636 | .platform_data = serial_platform_data2, | ||
637 | }, | ||
638 | }, | ||
639 | }, | ||
640 | #if defined(CONFIG_ARCH_OMAP3) || defined(CONFIG_ARCH_OMAP4) | ||
641 | { | ||
642 | .pdev = { | ||
643 | .name = "serial8250", | ||
644 | .id = 3, | ||
645 | .dev = { | ||
646 | .platform_data = serial_platform_data3, | ||
647 | }, | ||
648 | }, | ||
649 | }, | ||
650 | #endif | ||
651 | }; | ||
652 | |||
653 | /* | 594 | /* |
654 | * Override the default 8250 read handler: mem_serial_in() | 595 | * Override the default 8250 read handler: mem_serial_in() |
655 | * Empty RX fifo read causes an abort on omap3630 and omap4 | 596 | * Empty RX fifo read causes an abort on omap3630 and omap4 |
@@ -682,71 +623,44 @@ static void serial_out_override(struct uart_port *up, int offset, int value) | |||
682 | } | 623 | } |
683 | __serial_write_reg(up, offset, value); | 624 | __serial_write_reg(up, offset, value); |
684 | } | 625 | } |
626 | #endif | ||
627 | |||
685 | void __init omap_serial_early_init(void) | 628 | void __init omap_serial_early_init(void) |
686 | { | 629 | { |
687 | int i, nr_ports; | 630 | int i = 0; |
688 | char name[16]; | ||
689 | 631 | ||
690 | if (!(cpu_is_omap3630() || cpu_is_omap4430())) | 632 | do { |
691 | nr_ports = 3; | 633 | char oh_name[MAX_UART_HWMOD_NAME_LEN]; |
692 | else | 634 | struct omap_hwmod *oh; |
693 | nr_ports = ARRAY_SIZE(omap_uart); | 635 | struct omap_uart_state *uart; |
694 | 636 | ||
695 | /* | 637 | snprintf(oh_name, MAX_UART_HWMOD_NAME_LEN, |
696 | * Make sure the serial ports are muxed on at this point. | 638 | "uart%d", i + 1); |
697 | * You have to mux them off in device drivers later on | 639 | oh = omap_hwmod_lookup(oh_name); |
698 | * if not needed. | 640 | if (!oh) |
699 | */ | 641 | break; |
642 | |||
643 | uart = kzalloc(sizeof(struct omap_uart_state), GFP_KERNEL); | ||
644 | if (WARN_ON(!uart)) | ||
645 | return; | ||
700 | 646 | ||
701 | for (i = 0; i < nr_ports; i++) { | 647 | uart->oh = oh; |
702 | struct omap_uart_state *uart = &omap_uart[i]; | 648 | uart->num = i++; |
703 | struct platform_device *pdev = &uart->pdev; | 649 | list_add_tail(&uart->node, &uart_list); |
704 | struct device *dev = &pdev->dev; | 650 | num_uarts++; |
705 | struct plat_serial8250_port *p = dev->platform_data; | ||
706 | 651 | ||
707 | /* Don't map zero-based physical address */ | ||
708 | if (p->mapbase == 0) { | ||
709 | dev_warn(dev, "no physical address for uart#%d," | ||
710 | " so skipping early_init...\n", i); | ||
711 | continue; | ||
712 | } | ||
713 | /* | 652 | /* |
714 | * Module 4KB + L4 interconnect 4KB | 653 | * NOTE: omap_hwmod_init() has not yet been called, |
715 | * Static mapping, never released | 654 | * so no hwmod functions will work yet. |
716 | */ | 655 | */ |
717 | p->membase = ioremap(p->mapbase, SZ_8K); | ||
718 | if (!p->membase) { | ||
719 | dev_err(dev, "ioremap failed for uart%i\n", i + 1); | ||
720 | continue; | ||
721 | } | ||
722 | |||
723 | sprintf(name, "uart%d_ick", i + 1); | ||
724 | uart->ick = clk_get(NULL, name); | ||
725 | if (IS_ERR(uart->ick)) { | ||
726 | dev_err(dev, "Could not get uart%d_ick\n", i + 1); | ||
727 | uart->ick = NULL; | ||
728 | } | ||
729 | 656 | ||
730 | sprintf(name, "uart%d_fck", i+1); | 657 | /* |
731 | uart->fck = clk_get(NULL, name); | 658 | * During UART early init, device need to be probed |
732 | if (IS_ERR(uart->fck)) { | 659 | * to determine SoC specific init before omap_device |
733 | dev_err(dev, "Could not get uart%d_fck\n", i + 1); | 660 | * is ready. Therefore, don't allow idle here |
734 | uart->fck = NULL; | 661 | */ |
735 | } | 662 | uart->oh->flags |= HWMOD_INIT_NO_IDLE | HWMOD_INIT_NO_RESET; |
736 | 663 | } while (1); | |
737 | /* FIXME: Remove this once the clkdev is ready */ | ||
738 | if (!cpu_is_omap44xx()) { | ||
739 | if (!uart->ick || !uart->fck) | ||
740 | continue; | ||
741 | } | ||
742 | |||
743 | uart->num = i; | ||
744 | p->private_data = uart; | ||
745 | uart->p = p; | ||
746 | |||
747 | if (cpu_is_omap44xx()) | ||
748 | p->irq += 32; | ||
749 | } | ||
750 | } | 664 | } |
751 | 665 | ||
752 | /** | 666 | /** |
@@ -763,53 +677,135 @@ void __init omap_serial_early_init(void) | |||
763 | void __init omap_serial_init_port(int port) | 677 | void __init omap_serial_init_port(int port) |
764 | { | 678 | { |
765 | struct omap_uart_state *uart; | 679 | struct omap_uart_state *uart; |
766 | struct platform_device *pdev; | 680 | struct omap_hwmod *oh; |
767 | struct device *dev; | 681 | struct omap_device *od; |
768 | 682 | void *pdata = NULL; | |
769 | BUG_ON(port < 0); | 683 | u32 pdata_size = 0; |
770 | BUG_ON(port >= ARRAY_SIZE(omap_uart)); | 684 | char *name; |
771 | 685 | #ifndef CONFIG_SERIAL_OMAP | |
772 | uart = &omap_uart[port]; | 686 | struct plat_serial8250_port ports[2] = { |
773 | pdev = &uart->pdev; | 687 | {}, |
774 | dev = &pdev->dev; | 688 | {.flags = 0}, |
689 | }; | ||
690 | struct plat_serial8250_port *p = &ports[0]; | ||
691 | #else | ||
692 | struct omap_uart_port_info omap_up; | ||
693 | #endif | ||
775 | 694 | ||
776 | /* Don't proceed if there's no clocks available */ | 695 | if (WARN_ON(port < 0)) |
777 | if (unlikely(!uart->ick || !uart->fck)) { | 696 | return; |
778 | WARN(1, "%s: can't init uart%d, no clocks available\n", | 697 | if (WARN_ON(port >= num_uarts)) |
779 | kobject_name(&dev->kobj), port); | ||
780 | return; | 698 | return; |
781 | } | ||
782 | |||
783 | omap_uart_enable_clocks(uart); | ||
784 | |||
785 | omap_uart_reset(uart); | ||
786 | omap_uart_idle_init(uart); | ||
787 | 699 | ||
788 | list_add_tail(&uart->node, &uart_list); | 700 | list_for_each_entry(uart, &uart_list, node) |
701 | if (port == uart->num) | ||
702 | break; | ||
789 | 703 | ||
790 | if (WARN_ON(platform_device_register(pdev))) | 704 | oh = uart->oh; |
791 | return; | 705 | uart->dma_enabled = 0; |
706 | #ifndef CONFIG_SERIAL_OMAP | ||
707 | name = "serial8250"; | ||
792 | 708 | ||
793 | if ((cpu_is_omap34xx() && uart->padconf) || | 709 | /* |
794 | (uart->wk_en && uart->wk_mask)) { | 710 | * !! 8250 driver does not use standard IORESOURCE* It |
795 | device_init_wakeup(dev, true); | 711 | * has it's own custom pdata that can be taken from |
796 | DEV_CREATE_FILE(dev, &dev_attr_sleep_timeout); | 712 | * the hwmod resource data. But, this needs to be |
797 | } | 713 | * done after the build. |
714 | * | ||
715 | * ?? does it have to be done before the register ?? | ||
716 | * YES, because platform_device_data_add() copies | ||
717 | * pdata, it does not use a pointer. | ||
718 | */ | ||
719 | p->flags = UPF_BOOT_AUTOCONF; | ||
720 | p->iotype = UPIO_MEM; | ||
721 | p->regshift = 2; | ||
722 | p->uartclk = OMAP24XX_BASE_BAUD * 16; | ||
723 | p->irq = oh->mpu_irqs[0].irq; | ||
724 | p->mapbase = oh->slaves[0]->addr->pa_start; | ||
725 | p->membase = omap_hwmod_get_mpu_rt_va(oh); | ||
726 | p->irqflags = IRQF_SHARED; | ||
727 | p->private_data = uart; | ||
798 | 728 | ||
799 | /* | 729 | /* |
800 | * omap44xx: Never read empty UART fifo | 730 | * omap44xx: Never read empty UART fifo |
801 | * omap3xxx: Never read empty UART fifo on UARTs | 731 | * omap3xxx: Never read empty UART fifo on UARTs |
802 | * with IP rev >=0x52 | 732 | * with IP rev >=0x52 |
803 | */ | 733 | */ |
734 | uart->regshift = p->regshift; | ||
735 | uart->membase = p->membase; | ||
804 | if (cpu_is_omap44xx()) | 736 | if (cpu_is_omap44xx()) |
805 | uart->errata |= UART_ERRATA_FIFO_FULL_ABORT; | 737 | uart->errata |= UART_ERRATA_FIFO_FULL_ABORT; |
806 | else if ((serial_read_reg(uart->p, UART_OMAP_MVER) & 0xFF) | 738 | else if ((serial_read_reg(uart, UART_OMAP_MVER) & 0xFF) |
807 | >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV) | 739 | >= UART_OMAP_NO_EMPTY_FIFO_READ_IP_REV) |
808 | uart->errata |= UART_ERRATA_FIFO_FULL_ABORT; | 740 | uart->errata |= UART_ERRATA_FIFO_FULL_ABORT; |
809 | 741 | ||
810 | if (uart->errata & UART_ERRATA_FIFO_FULL_ABORT) { | 742 | if (uart->errata & UART_ERRATA_FIFO_FULL_ABORT) { |
811 | uart->p->serial_in = serial_in_override; | 743 | p->serial_in = serial_in_override; |
812 | uart->p->serial_out = serial_out_override; | 744 | p->serial_out = serial_out_override; |
745 | } | ||
746 | |||
747 | pdata = &ports[0]; | ||
748 | pdata_size = 2 * sizeof(struct plat_serial8250_port); | ||
749 | #else | ||
750 | |||
751 | name = DRIVER_NAME; | ||
752 | |||
753 | omap_up.dma_enabled = uart->dma_enabled; | ||
754 | omap_up.uartclk = OMAP24XX_BASE_BAUD * 16; | ||
755 | omap_up.mapbase = oh->slaves[0]->addr->pa_start; | ||
756 | omap_up.membase = omap_hwmod_get_mpu_rt_va(oh); | ||
757 | omap_up.irqflags = IRQF_SHARED; | ||
758 | omap_up.flags = UPF_BOOT_AUTOCONF | UPF_SHARE_IRQ; | ||
759 | |||
760 | pdata = &omap_up; | ||
761 | pdata_size = sizeof(struct omap_uart_port_info); | ||
762 | #endif | ||
763 | |||
764 | if (WARN_ON(!oh)) | ||
765 | return; | ||
766 | |||
767 | od = omap_device_build(name, uart->num, oh, pdata, pdata_size, | ||
768 | omap_uart_latency, | ||
769 | ARRAY_SIZE(omap_uart_latency), false); | ||
770 | WARN(IS_ERR(od), "Could not build omap_device for %s: %s.\n", | ||
771 | name, oh->name); | ||
772 | |||
773 | uart->irq = oh->mpu_irqs[0].irq; | ||
774 | uart->regshift = 2; | ||
775 | uart->mapbase = oh->slaves[0]->addr->pa_start; | ||
776 | uart->membase = omap_hwmod_get_mpu_rt_va(oh); | ||
777 | uart->pdev = &od->pdev; | ||
778 | |||
779 | oh->dev_attr = uart; | ||
780 | |||
781 | /* | ||
782 | * Because of early UART probing, UART did not get idled | ||
783 | * on init. Now that omap_device is ready, ensure full idle | ||
784 | * before doing omap_device_enable(). | ||
785 | */ | ||
786 | omap_hwmod_idle(uart->oh); | ||
787 | |||
788 | omap_device_enable(uart->pdev); | ||
789 | omap_uart_idle_init(uart); | ||
790 | omap_uart_reset(uart); | ||
791 | omap_hwmod_enable_wakeup(uart->oh); | ||
792 | omap_device_idle(uart->pdev); | ||
793 | |||
794 | /* | ||
795 | * Need to block sleep long enough for interrupt driven | ||
796 | * driver to start. Console driver is in polling mode | ||
797 | * so device needs to be kept enabled while polling driver | ||
798 | * is in use. | ||
799 | */ | ||
800 | if (uart->timeout) | ||
801 | uart->timeout = (30 * HZ); | ||
802 | omap_uart_block_sleep(uart); | ||
803 | uart->timeout = DEFAULT_TIMEOUT; | ||
804 | |||
805 | if ((cpu_is_omap34xx() && uart->padconf) || | ||
806 | (uart->wk_en && uart->wk_mask)) { | ||
807 | device_init_wakeup(&od->pdev.dev, true); | ||
808 | DEV_CREATE_FILE(&od->pdev.dev, &dev_attr_sleep_timeout); | ||
813 | } | 809 | } |
814 | 810 | ||
815 | /* Enable the MDR1 errata for OMAP3 */ | 811 | /* Enable the MDR1 errata for OMAP3 */ |
@@ -826,13 +822,8 @@ void __init omap_serial_init_port(int port) | |||
826 | */ | 822 | */ |
827 | void __init omap_serial_init(void) | 823 | void __init omap_serial_init(void) |
828 | { | 824 | { |
829 | int i, nr_ports; | 825 | struct omap_uart_state *uart; |
830 | |||
831 | if (!(cpu_is_omap3630() || cpu_is_omap4430())) | ||
832 | nr_ports = 3; | ||
833 | else | ||
834 | nr_ports = ARRAY_SIZE(omap_uart); | ||
835 | 826 | ||
836 | for (i = 0; i < nr_ports; i++) | 827 | list_for_each_entry(uart, &uart_list, node) |
837 | omap_serial_init_port(i); | 828 | omap_serial_init_port(uart->num); |
838 | } | 829 | } |