Commit | Line | Data |
---|---|---|
b920de1b DH |
1 | /* MN10300 On-chip serial port UART driver |
2 | * | |
3 | * Copyright (C) 2007 Red Hat, Inc. All Rights Reserved. | |
4 | * Written by David Howells (dhowells@redhat.com) | |
5 | * | |
6 | * This program is free software; you can redistribute it and/or | |
7 | * modify it under the terms of the GNU General Public Licence | |
8 | * as published by the Free Software Foundation; either version | |
9 | * 2 of the Licence, or (at your option) any later version. | |
10 | */ | |
11 | ||
12 | static const char serial_name[] = "MN10300 Serial driver"; | |
13 | static const char serial_version[] = "mn10300_serial-1.0"; | |
14 | static const char serial_revdate[] = "2007-11-06"; | |
15 | ||
16 | #if defined(CONFIG_MN10300_TTYSM_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) | |
17 | #define SUPPORT_SYSRQ | |
18 | #endif | |
19 | ||
b920de1b DH |
20 | #include <linux/module.h> |
21 | #include <linux/serial.h> | |
22 | #include <linux/circ_buf.h> | |
23 | #include <linux/errno.h> | |
24 | #include <linux/signal.h> | |
25 | #include <linux/sched.h> | |
26 | #include <linux/timer.h> | |
27 | #include <linux/interrupt.h> | |
28 | #include <linux/tty.h> | |
29 | #include <linux/tty_flip.h> | |
30 | #include <linux/major.h> | |
31 | #include <linux/string.h> | |
32 | #include <linux/ioport.h> | |
33 | #include <linux/mm.h> | |
34 | #include <linux/slab.h> | |
35 | #include <linux/init.h> | |
36 | #include <linux/console.h> | |
37 | #include <linux/sysrq.h> | |
38 | ||
b920de1b DH |
39 | #include <asm/io.h> |
40 | #include <asm/irq.h> | |
41 | #include <asm/bitops.h> | |
42 | #include <asm/serial-regs.h> | |
2f2a2132 | 43 | #include <unit/timex.h> |
b920de1b DH |
44 | #include "mn10300-serial.h" |
45 | ||
368dd5ac AT |
46 | #ifdef CONFIG_SMP |
47 | #undef GxICR | |
48 | #define GxICR(X) CROSS_GxICR(X, 0) | |
49 | #endif /* CONFIG_SMP */ | |
50 | ||
b920de1b DH |
51 | #define kenter(FMT, ...) \ |
52 | printk(KERN_DEBUG "-->%s(" FMT ")\n", __func__, ##__VA_ARGS__) | |
53 | #define _enter(FMT, ...) \ | |
54 | no_printk(KERN_DEBUG "-->%s(" FMT ")\n", __func__, ##__VA_ARGS__) | |
55 | #define kdebug(FMT, ...) \ | |
56 | printk(KERN_DEBUG "--- " FMT "\n", ##__VA_ARGS__) | |
57 | #define _debug(FMT, ...) \ | |
58 | no_printk(KERN_DEBUG "--- " FMT "\n", ##__VA_ARGS__) | |
59 | #define kproto(FMT, ...) \ | |
60 | printk(KERN_DEBUG "### MNSERIAL " FMT " ###\n", ##__VA_ARGS__) | |
61 | #define _proto(FMT, ...) \ | |
62 | no_printk(KERN_DEBUG "### MNSERIAL " FMT " ###\n", ##__VA_ARGS__) | |
63 | ||
368dd5ac AT |
64 | #ifndef CODMSB |
65 | /* c_cflag bit meaning */ | |
66 | #define CODMSB 004000000000 /* change Transfer bit-order */ | |
67 | #endif | |
68 | ||
b920de1b DH |
69 | #define NR_UARTS 3 |
70 | ||
71 | #ifdef CONFIG_MN10300_TTYSM_CONSOLE | |
72 | static void mn10300_serial_console_write(struct console *co, | |
73 | const char *s, unsigned count); | |
74 | static int __init mn10300_serial_console_setup(struct console *co, | |
75 | char *options); | |
76 | ||
77 | static struct uart_driver mn10300_serial_driver; | |
78 | static struct console mn10300_serial_console = { | |
79 | .name = "ttySM", | |
80 | .write = mn10300_serial_console_write, | |
81 | .device = uart_console_device, | |
82 | .setup = mn10300_serial_console_setup, | |
83 | .flags = CON_PRINTBUFFER, | |
84 | .index = -1, | |
85 | .data = &mn10300_serial_driver, | |
86 | }; | |
87 | #endif | |
88 | ||
89 | static struct uart_driver mn10300_serial_driver = { | |
90 | .owner = NULL, | |
91 | .driver_name = "mn10300-serial", | |
92 | .dev_name = "ttySM", | |
93 | .major = TTY_MAJOR, | |
94 | .minor = 128, | |
95 | .nr = NR_UARTS, | |
96 | #ifdef CONFIG_MN10300_TTYSM_CONSOLE | |
97 | .cons = &mn10300_serial_console, | |
98 | #endif | |
99 | }; | |
100 | ||
101 | static unsigned int mn10300_serial_tx_empty(struct uart_port *); | |
102 | static void mn10300_serial_set_mctrl(struct uart_port *, unsigned int mctrl); | |
103 | static unsigned int mn10300_serial_get_mctrl(struct uart_port *); | |
104 | static void mn10300_serial_stop_tx(struct uart_port *); | |
105 | static void mn10300_serial_start_tx(struct uart_port *); | |
106 | static void mn10300_serial_send_xchar(struct uart_port *, char ch); | |
107 | static void mn10300_serial_stop_rx(struct uart_port *); | |
108 | static void mn10300_serial_enable_ms(struct uart_port *); | |
109 | static void mn10300_serial_break_ctl(struct uart_port *, int ctl); | |
110 | static int mn10300_serial_startup(struct uart_port *); | |
111 | static void mn10300_serial_shutdown(struct uart_port *); | |
112 | static void mn10300_serial_set_termios(struct uart_port *, | |
113 | struct ktermios *new, | |
114 | struct ktermios *old); | |
115 | static const char *mn10300_serial_type(struct uart_port *); | |
116 | static void mn10300_serial_release_port(struct uart_port *); | |
117 | static int mn10300_serial_request_port(struct uart_port *); | |
118 | static void mn10300_serial_config_port(struct uart_port *, int); | |
119 | static int mn10300_serial_verify_port(struct uart_port *, | |
120 | struct serial_struct *); | |
52885b32 DH |
121 | #ifdef CONFIG_CONSOLE_POLL |
122 | static void mn10300_serial_poll_put_char(struct uart_port *, unsigned char); | |
123 | static int mn10300_serial_poll_get_char(struct uart_port *); | |
124 | #endif | |
b920de1b DH |
125 | |
126 | static const struct uart_ops mn10300_serial_ops = { | |
127 | .tx_empty = mn10300_serial_tx_empty, | |
128 | .set_mctrl = mn10300_serial_set_mctrl, | |
129 | .get_mctrl = mn10300_serial_get_mctrl, | |
130 | .stop_tx = mn10300_serial_stop_tx, | |
131 | .start_tx = mn10300_serial_start_tx, | |
132 | .send_xchar = mn10300_serial_send_xchar, | |
133 | .stop_rx = mn10300_serial_stop_rx, | |
134 | .enable_ms = mn10300_serial_enable_ms, | |
135 | .break_ctl = mn10300_serial_break_ctl, | |
136 | .startup = mn10300_serial_startup, | |
137 | .shutdown = mn10300_serial_shutdown, | |
138 | .set_termios = mn10300_serial_set_termios, | |
139 | .type = mn10300_serial_type, | |
140 | .release_port = mn10300_serial_release_port, | |
141 | .request_port = mn10300_serial_request_port, | |
142 | .config_port = mn10300_serial_config_port, | |
143 | .verify_port = mn10300_serial_verify_port, | |
52885b32 DH |
144 | #ifdef CONFIG_CONSOLE_POLL |
145 | .poll_put_char = mn10300_serial_poll_put_char, | |
146 | .poll_get_char = mn10300_serial_poll_get_char, | |
147 | #endif | |
b920de1b DH |
148 | }; |
149 | ||
150 | static irqreturn_t mn10300_serial_interrupt(int irq, void *dev_id); | |
151 | ||
152 | /* | |
153 | * the first on-chip serial port: ttySM0 (aka SIF0) | |
154 | */ | |
155 | #ifdef CONFIG_MN10300_TTYSM0 | |
156 | struct mn10300_serial_port mn10300_serial_port_sif0 = { | |
157 | .uart.ops = &mn10300_serial_ops, | |
158 | .uart.membase = (void __iomem *) &SC0CTR, | |
159 | .uart.mapbase = (unsigned long) &SC0CTR, | |
160 | .uart.iotype = UPIO_MEM, | |
161 | .uart.irq = 0, | |
162 | .uart.uartclk = 0, /* MN10300_IOCLK, */ | |
163 | .uart.fifosize = 1, | |
164 | .uart.flags = UPF_BOOT_AUTOCONF, | |
165 | .uart.line = 0, | |
166 | .uart.type = PORT_MN10300, | |
167 | .uart.lock = | |
168 | __SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif0.uart.lock), | |
169 | .name = "ttySM0", | |
170 | ._iobase = &SC0CTR, | |
171 | ._control = &SC0CTR, | |
368dd5ac | 172 | ._status = (volatile u8 *)&SC0STR, |
b920de1b DH |
173 | ._intr = &SC0ICR, |
174 | ._rxb = &SC0RXB, | |
175 | ._txb = &SC0TXB, | |
a4128b03 DH |
176 | .rx_name = "ttySM0:Rx", |
177 | .tx_name = "ttySM0:Tx", | |
368dd5ac | 178 | #if defined(CONFIG_MN10300_TTYSM0_TIMER8) |
a4128b03 | 179 | .tm_name = "ttySM0:Timer8", |
b920de1b DH |
180 | ._tmxmd = &TM8MD, |
181 | ._tmxbr = &TM8BR, | |
182 | ._tmicr = &TM8ICR, | |
183 | .tm_irq = TM8IRQ, | |
184 | .div_timer = MNSCx_DIV_TIMER_16BIT, | |
368dd5ac AT |
185 | #elif defined(CONFIG_MN10300_TTYSM0_TIMER0) |
186 | .tm_name = "ttySM0:Timer0", | |
187 | ._tmxmd = &TM0MD, | |
188 | ._tmxbr = (volatile u16 *)&TM0BR, | |
189 | ._tmicr = &TM0ICR, | |
190 | .tm_irq = TM0IRQ, | |
191 | .div_timer = MNSCx_DIV_TIMER_8BIT, | |
192 | #elif defined(CONFIG_MN10300_TTYSM0_TIMER2) | |
a4128b03 | 193 | .tm_name = "ttySM0:Timer2", |
b920de1b | 194 | ._tmxmd = &TM2MD, |
368dd5ac | 195 | ._tmxbr = (volatile u16 *)&TM2BR, |
b920de1b DH |
196 | ._tmicr = &TM2ICR, |
197 | .tm_irq = TM2IRQ, | |
198 | .div_timer = MNSCx_DIV_TIMER_8BIT, | |
368dd5ac AT |
199 | #else |
200 | #error "Unknown config for ttySM0" | |
b920de1b DH |
201 | #endif |
202 | .rx_irq = SC0RXIRQ, | |
203 | .tx_irq = SC0TXIRQ, | |
204 | .rx_icr = &GxICR(SC0RXIRQ), | |
205 | .tx_icr = &GxICR(SC0TXIRQ), | |
206 | .clock_src = MNSCx_CLOCK_SRC_IOCLK, | |
207 | .options = 0, | |
208 | #ifdef CONFIG_GDBSTUB_ON_TTYSM0 | |
209 | .gdbstub = 1, | |
210 | #endif | |
211 | }; | |
212 | #endif /* CONFIG_MN10300_TTYSM0 */ | |
213 | ||
214 | /* | |
215 | * the second on-chip serial port: ttySM1 (aka SIF1) | |
216 | */ | |
217 | #ifdef CONFIG_MN10300_TTYSM1 | |
218 | struct mn10300_serial_port mn10300_serial_port_sif1 = { | |
219 | .uart.ops = &mn10300_serial_ops, | |
220 | .uart.membase = (void __iomem *) &SC1CTR, | |
221 | .uart.mapbase = (unsigned long) &SC1CTR, | |
222 | .uart.iotype = UPIO_MEM, | |
223 | .uart.irq = 0, | |
224 | .uart.uartclk = 0, /* MN10300_IOCLK, */ | |
225 | .uart.fifosize = 1, | |
226 | .uart.flags = UPF_BOOT_AUTOCONF, | |
227 | .uart.line = 1, | |
228 | .uart.type = PORT_MN10300, | |
229 | .uart.lock = | |
230 | __SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif1.uart.lock), | |
231 | .name = "ttySM1", | |
232 | ._iobase = &SC1CTR, | |
233 | ._control = &SC1CTR, | |
368dd5ac | 234 | ._status = (volatile u8 *)&SC1STR, |
b920de1b DH |
235 | ._intr = &SC1ICR, |
236 | ._rxb = &SC1RXB, | |
237 | ._txb = &SC1TXB, | |
a4128b03 DH |
238 | .rx_name = "ttySM1:Rx", |
239 | .tx_name = "ttySM1:Tx", | |
368dd5ac | 240 | #if defined(CONFIG_MN10300_TTYSM1_TIMER9) |
a4128b03 | 241 | .tm_name = "ttySM1:Timer9", |
b920de1b DH |
242 | ._tmxmd = &TM9MD, |
243 | ._tmxbr = &TM9BR, | |
244 | ._tmicr = &TM9ICR, | |
245 | .tm_irq = TM9IRQ, | |
246 | .div_timer = MNSCx_DIV_TIMER_16BIT, | |
368dd5ac | 247 | #elif defined(CONFIG_MN10300_TTYSM1_TIMER3) |
a4128b03 | 248 | .tm_name = "ttySM1:Timer3", |
b920de1b | 249 | ._tmxmd = &TM3MD, |
368dd5ac | 250 | ._tmxbr = (volatile u16 *)&TM3BR, |
b920de1b DH |
251 | ._tmicr = &TM3ICR, |
252 | .tm_irq = TM3IRQ, | |
253 | .div_timer = MNSCx_DIV_TIMER_8BIT, | |
368dd5ac AT |
254 | #elif defined(CONFIG_MN10300_TTYSM1_TIMER12) |
255 | .tm_name = "ttySM1/Timer12", | |
256 | ._tmxmd = &TM12MD, | |
257 | ._tmxbr = &TM12BR, | |
258 | ._tmicr = &TM12ICR, | |
259 | .tm_irq = TM12IRQ, | |
260 | .div_timer = MNSCx_DIV_TIMER_16BIT, | |
261 | #else | |
262 | #error "Unknown config for ttySM1" | |
b920de1b DH |
263 | #endif |
264 | .rx_irq = SC1RXIRQ, | |
265 | .tx_irq = SC1TXIRQ, | |
266 | .rx_icr = &GxICR(SC1RXIRQ), | |
267 | .tx_icr = &GxICR(SC1TXIRQ), | |
268 | .clock_src = MNSCx_CLOCK_SRC_IOCLK, | |
269 | .options = 0, | |
270 | #ifdef CONFIG_GDBSTUB_ON_TTYSM1 | |
271 | .gdbstub = 1, | |
272 | #endif | |
273 | }; | |
274 | #endif /* CONFIG_MN10300_TTYSM1 */ | |
275 | ||
276 | /* | |
277 | * the third on-chip serial port: ttySM2 (aka SIF2) | |
278 | */ | |
279 | #ifdef CONFIG_MN10300_TTYSM2 | |
280 | struct mn10300_serial_port mn10300_serial_port_sif2 = { | |
281 | .uart.ops = &mn10300_serial_ops, | |
282 | .uart.membase = (void __iomem *) &SC2CTR, | |
283 | .uart.mapbase = (unsigned long) &SC2CTR, | |
284 | .uart.iotype = UPIO_MEM, | |
285 | .uart.irq = 0, | |
286 | .uart.uartclk = 0, /* MN10300_IOCLK, */ | |
287 | .uart.fifosize = 1, | |
288 | .uart.flags = UPF_BOOT_AUTOCONF, | |
289 | .uart.line = 2, | |
290 | #ifdef CONFIG_MN10300_TTYSM2_CTS | |
291 | .uart.type = PORT_MN10300_CTS, | |
292 | #else | |
293 | .uart.type = PORT_MN10300, | |
294 | #endif | |
295 | .uart.lock = | |
296 | __SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif2.uart.lock), | |
297 | .name = "ttySM2", | |
b920de1b DH |
298 | ._iobase = &SC2CTR, |
299 | ._control = &SC2CTR, | |
368dd5ac | 300 | ._status = (volatile u8 *)&SC2STR, |
b920de1b DH |
301 | ._intr = &SC2ICR, |
302 | ._rxb = &SC2RXB, | |
303 | ._txb = &SC2TXB, | |
368dd5ac AT |
304 | .rx_name = "ttySM2:Rx", |
305 | .tx_name = "ttySM2:Tx", | |
306 | #if defined(CONFIG_MN10300_TTYSM2_TIMER10) | |
307 | .tm_name = "ttySM2/Timer10", | |
b920de1b DH |
308 | ._tmxmd = &TM10MD, |
309 | ._tmxbr = &TM10BR, | |
310 | ._tmicr = &TM10ICR, | |
311 | .tm_irq = TM10IRQ, | |
312 | .div_timer = MNSCx_DIV_TIMER_16BIT, | |
368dd5ac AT |
313 | #elif defined(CONFIG_MN10300_TTYSM2_TIMER9) |
314 | .tm_name = "ttySM2/Timer9", | |
315 | ._tmxmd = &TM9MD, | |
316 | ._tmxbr = &TM9BR, | |
317 | ._tmicr = &TM9ICR, | |
318 | .tm_irq = TM9IRQ, | |
319 | .div_timer = MNSCx_DIV_TIMER_16BIT, | |
320 | #elif defined(CONFIG_MN10300_TTYSM2_TIMER1) | |
321 | .tm_name = "ttySM2/Timer1", | |
322 | ._tmxmd = &TM1MD, | |
323 | ._tmxbr = (volatile u16 *)&TM1BR, | |
324 | ._tmicr = &TM1ICR, | |
325 | .tm_irq = TM1IRQ, | |
326 | .div_timer = MNSCx_DIV_TIMER_8BIT, | |
327 | #elif defined(CONFIG_MN10300_TTYSM2_TIMER3) | |
328 | .tm_name = "ttySM2/Timer3", | |
329 | ._tmxmd = &TM3MD, | |
330 | ._tmxbr = (volatile u16 *)&TM3BR, | |
331 | ._tmicr = &TM3ICR, | |
332 | .tm_irq = TM3IRQ, | |
333 | .div_timer = MNSCx_DIV_TIMER_8BIT, | |
334 | #else | |
335 | #error "Unknown config for ttySM2" | |
336 | #endif | |
b920de1b DH |
337 | .rx_irq = SC2RXIRQ, |
338 | .tx_irq = SC2TXIRQ, | |
339 | .rx_icr = &GxICR(SC2RXIRQ), | |
340 | .tx_icr = &GxICR(SC2TXIRQ), | |
341 | .clock_src = MNSCx_CLOCK_SRC_IOCLK, | |
342 | #ifdef CONFIG_MN10300_TTYSM2_CTS | |
343 | .options = MNSCx_OPT_CTS, | |
344 | #else | |
345 | .options = 0, | |
346 | #endif | |
347 | #ifdef CONFIG_GDBSTUB_ON_TTYSM2 | |
348 | .gdbstub = 1, | |
349 | #endif | |
350 | }; | |
351 | #endif /* CONFIG_MN10300_TTYSM2 */ | |
352 | ||
353 | ||
354 | /* | |
355 | * list of available serial ports | |
356 | */ | |
357 | struct mn10300_serial_port *mn10300_serial_ports[NR_UARTS + 1] = { | |
358 | #ifdef CONFIG_MN10300_TTYSM0 | |
359 | [0] = &mn10300_serial_port_sif0, | |
360 | #endif | |
361 | #ifdef CONFIG_MN10300_TTYSM1 | |
362 | [1] = &mn10300_serial_port_sif1, | |
363 | #endif | |
364 | #ifdef CONFIG_MN10300_TTYSM2 | |
365 | [2] = &mn10300_serial_port_sif2, | |
366 | #endif | |
367 | [NR_UARTS] = NULL, | |
368 | }; | |
369 | ||
370 | ||
371 | /* | |
372 | * we abuse the serial ports' baud timers' interrupt lines to get the ability | |
373 | * to deliver interrupts to userspace as we use the ports' interrupt lines to | |
374 | * do virtual DMA on account of the ports having no hardware FIFOs | |
375 | * | |
376 | * we can generate an interrupt manually in the assembly stubs by writing to | |
377 | * the enable and detect bits in the interrupt control register, so all we need | |
378 | * to do here is disable the interrupt line | |
379 | * | |
380 | * note that we can't just leave the line enabled as the baud rate timer *also* | |
381 | * generates interrupts | |
382 | */ | |
383 | static void mn10300_serial_mask_ack(unsigned int irq) | |
384 | { | |
368dd5ac | 385 | unsigned long flags; |
b920de1b | 386 | u16 tmp; |
368dd5ac AT |
387 | |
388 | flags = arch_local_cli_save(); | |
b920de1b DH |
389 | GxICR(irq) = GxICR_LEVEL_6; |
390 | tmp = GxICR(irq); /* flush write buffer */ | |
368dd5ac | 391 | arch_local_irq_restore(flags); |
b920de1b DH |
392 | } |
393 | ||
b023ba59 TG |
394 | static void mn10300_serial_chip_mask_ack(struct irq_data *d) |
395 | { | |
396 | mn10300_serial_mask_ack(d->irq); | |
397 | } | |
398 | ||
399 | static void mn10300_serial_nop(struct irq_data *d) | |
b920de1b DH |
400 | { |
401 | } | |
402 | ||
403 | static struct irq_chip mn10300_serial_pic = { | |
404 | .name = "mnserial", | |
b023ba59 TG |
405 | .irq_ack = mn10300_serial_chip_mask_ack, |
406 | .irq_mask = mn10300_serial_chip_mask_ack, | |
407 | .irq_mask_ack = mn10300_serial_chip_mask_ack, | |
408 | .irq_unmask = mn10300_serial_nop, | |
b920de1b DH |
409 | }; |
410 | ||
8d160027 MS |
411 | static void mn10300_serial_low_mask(struct irq_data *d) |
412 | { | |
413 | unsigned long flags; | |
414 | u16 tmp; | |
415 | ||
416 | flags = arch_local_cli_save(); | |
417 | GxICR(d->irq) = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL); | |
418 | tmp = GxICR(d->irq); /* flush write buffer */ | |
419 | arch_local_irq_restore(flags); | |
420 | } | |
421 | ||
422 | static void mn10300_serial_low_unmask(struct irq_data *d) | |
423 | { | |
424 | unsigned long flags; | |
425 | u16 tmp; | |
426 | ||
427 | flags = arch_local_cli_save(); | |
428 | GxICR(d->irq) = | |
429 | NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL) | GxICR_ENABLE; | |
430 | tmp = GxICR(d->irq); /* flush write buffer */ | |
431 | arch_local_irq_restore(flags); | |
432 | } | |
433 | ||
434 | static struct irq_chip mn10300_serial_low_pic = { | |
435 | .name = "mnserial-low", | |
436 | .irq_mask = mn10300_serial_low_mask, | |
437 | .irq_unmask = mn10300_serial_low_unmask, | |
438 | }; | |
b920de1b DH |
439 | |
440 | /* | |
441 | * serial virtual DMA interrupt jump table | |
442 | */ | |
443 | struct mn10300_serial_int mn10300_serial_int_tbl[NR_IRQS]; | |
444 | ||
445 | static void mn10300_serial_dis_tx_intr(struct mn10300_serial_port *port) | |
446 | { | |
8f0bcbca | 447 | int retries = 100; |
b920de1b | 448 | u16 x; |
368dd5ac | 449 | |
8f0bcbca MS |
450 | /* nothing to do if irq isn't set up */ |
451 | if (!mn10300_serial_int_tbl[port->tx_irq].port) | |
452 | return; | |
453 | ||
454 | port->tx_flags |= MNSCx_TX_STOP; | |
455 | mb(); | |
456 | ||
457 | /* | |
458 | * Here we wait for the irq to be disabled. Either it already is | |
459 | * disabled or we wait some number of retries for the VDMA handler | |
460 | * to disable it. The retries give the VDMA handler enough time to | |
461 | * run to completion if it was already in progress. If the VDMA IRQ | |
462 | * is enabled but the handler is not yet running when arrive here, | |
463 | * the STOP flag will prevent the handler from conflicting with the | |
464 | * driver code following this loop. | |
465 | */ | |
466 | while ((*port->tx_icr & GxICR_ENABLE) && retries-- > 0) | |
467 | ; | |
468 | if (retries <= 0) { | |
469 | *port->tx_icr = | |
470 | NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL); | |
471 | x = *port->tx_icr; | |
472 | } | |
b920de1b DH |
473 | } |
474 | ||
475 | static void mn10300_serial_en_tx_intr(struct mn10300_serial_port *port) | |
476 | { | |
477 | u16 x; | |
368dd5ac | 478 | |
8f0bcbca MS |
479 | /* nothing to do if irq isn't set up */ |
480 | if (!mn10300_serial_int_tbl[port->tx_irq].port) | |
481 | return; | |
482 | ||
483 | /* stop vdma irq if not already stopped */ | |
484 | if (!(port->tx_flags & MNSCx_TX_STOP)) | |
485 | mn10300_serial_dis_tx_intr(port); | |
486 | ||
487 | port->tx_flags &= ~MNSCx_TX_STOP; | |
488 | mb(); | |
489 | ||
368dd5ac | 490 | *port->tx_icr = |
8f0bcbca MS |
491 | NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL) | |
492 | GxICR_ENABLE | GxICR_REQUEST | GxICR_DETECT; | |
b920de1b DH |
493 | x = *port->tx_icr; |
494 | } | |
495 | ||
496 | static void mn10300_serial_dis_rx_intr(struct mn10300_serial_port *port) | |
497 | { | |
368dd5ac | 498 | unsigned long flags; |
b920de1b | 499 | u16 x; |
368dd5ac AT |
500 | |
501 | flags = arch_local_cli_save(); | |
502 | *port->rx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL); | |
b920de1b | 503 | x = *port->rx_icr; |
368dd5ac | 504 | arch_local_irq_restore(flags); |
b920de1b DH |
505 | } |
506 | ||
507 | /* | |
508 | * multi-bit equivalent of test_and_clear_bit() | |
509 | */ | |
510 | static int mask_test_and_clear(volatile u8 *ptr, u8 mask) | |
511 | { | |
512 | u32 epsw; | |
513 | asm volatile(" bclr %1,(%2) \n" | |
514 | " mov epsw,%0 \n" | |
d6bb7a1a MS |
515 | : "=d"(epsw) : "d"(mask), "a"(ptr) |
516 | : "cc", "memory"); | |
b920de1b DH |
517 | return !(epsw & EPSW_FLAG_Z); |
518 | } | |
519 | ||
520 | /* | |
521 | * receive chars from the ring buffer for this serial port | |
522 | * - must do break detection here (not done in the UART) | |
523 | */ | |
524 | static void mn10300_serial_receive_interrupt(struct mn10300_serial_port *port) | |
525 | { | |
526 | struct uart_icount *icount = &port->uart.icount; | |
59c5f924 | 527 | struct tty_port *tport = &port->uart.state->port; |
b920de1b DH |
528 | unsigned ix; |
529 | int count; | |
530 | u8 st, ch, push, status, overrun; | |
531 | ||
532 | _enter("%s", port->name); | |
533 | ||
534 | push = 0; | |
535 | ||
536 | count = CIRC_CNT(port->rx_inp, port->rx_outp, MNSC_BUFFER_SIZE); | |
59c5f924 | 537 | count = tty_buffer_request_room(tport, count); |
b920de1b | 538 | if (count == 0) { |
59c5f924 JS |
539 | if (!tport->low_latency) |
540 | tty_flip_buffer_push(tport); | |
b920de1b DH |
541 | return; |
542 | } | |
543 | ||
544 | try_again: | |
545 | /* pull chars out of the hat */ | |
6aa7de05 | 546 | ix = READ_ONCE(port->rx_outp); |
c98c406e | 547 | if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0) { |
59c5f924 JS |
548 | if (push && !tport->low_latency) |
549 | tty_flip_buffer_push(tport); | |
b920de1b DH |
550 | return; |
551 | } | |
552 | ||
a4bd78ed | 553 | /* READ_ONCE() enforces dependency, but dangerous through integer!!! */ |
b920de1b DH |
554 | ch = port->rx_buffer[ix++]; |
555 | st = port->rx_buffer[ix++]; | |
c98c406e | 556 | smp_mb(); |
b920de1b DH |
557 | port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1); |
558 | port->uart.icount.rx++; | |
559 | ||
560 | st &= SC01STR_FEF | SC01STR_PEF | SC01STR_OEF; | |
561 | status = 0; | |
562 | overrun = 0; | |
563 | ||
564 | /* the UART doesn't detect BREAK, so we have to do that ourselves | |
565 | * - it starts as a framing error on a NUL character | |
566 | * - then we count another two NUL characters before issuing TTY_BREAK | |
567 | * - then we end on a normal char or one that has all the bottom bits | |
568 | * zero and the top bits set | |
569 | */ | |
570 | switch (port->rx_brk) { | |
571 | case 0: | |
572 | /* not breaking at the moment */ | |
573 | break; | |
574 | ||
575 | case 1: | |
576 | if (st & SC01STR_FEF && ch == 0) { | |
577 | port->rx_brk = 2; | |
578 | goto try_again; | |
579 | } | |
580 | goto not_break; | |
581 | ||
582 | case 2: | |
583 | if (st & SC01STR_FEF && ch == 0) { | |
584 | port->rx_brk = 3; | |
585 | _proto("Rx Break Detected"); | |
586 | icount->brk++; | |
587 | if (uart_handle_break(&port->uart)) | |
588 | goto ignore_char; | |
589 | status |= 1 << TTY_BREAK; | |
590 | goto insert; | |
591 | } | |
592 | goto not_break; | |
593 | ||
594 | default: | |
595 | if (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF)) | |
596 | goto try_again; /* still breaking */ | |
597 | ||
598 | port->rx_brk = 0; /* end of the break */ | |
599 | ||
600 | switch (ch) { | |
601 | case 0xFF: | |
602 | case 0xFE: | |
603 | case 0xFC: | |
604 | case 0xF8: | |
605 | case 0xF0: | |
606 | case 0xE0: | |
607 | case 0xC0: | |
608 | case 0x80: | |
609 | case 0x00: | |
610 | /* discard char at probable break end */ | |
611 | goto try_again; | |
612 | } | |
613 | break; | |
614 | } | |
615 | ||
616 | process_errors: | |
617 | /* handle framing error */ | |
618 | if (st & SC01STR_FEF) { | |
619 | if (ch == 0) { | |
620 | /* framing error with NUL char is probably a BREAK */ | |
621 | port->rx_brk = 1; | |
622 | goto try_again; | |
623 | } | |
624 | ||
625 | _proto("Rx Framing Error"); | |
626 | icount->frame++; | |
627 | status |= 1 << TTY_FRAME; | |
628 | } | |
629 | ||
630 | /* handle parity error */ | |
631 | if (st & SC01STR_PEF) { | |
632 | _proto("Rx Parity Error"); | |
633 | icount->parity++; | |
634 | status = TTY_PARITY; | |
635 | } | |
636 | ||
637 | /* handle normal char */ | |
638 | if (status == 0) { | |
639 | if (uart_handle_sysrq_char(&port->uart, ch)) | |
640 | goto ignore_char; | |
641 | status = (1 << TTY_NORMAL); | |
642 | } | |
643 | ||
644 | /* handle overrun error */ | |
645 | if (st & SC01STR_OEF) { | |
646 | if (port->rx_brk) | |
647 | goto try_again; | |
648 | ||
649 | _proto("Rx Overrun Error"); | |
650 | icount->overrun++; | |
651 | overrun = 1; | |
652 | } | |
653 | ||
654 | insert: | |
655 | status &= port->uart.read_status_mask; | |
656 | ||
657 | if (!overrun && !(status & port->uart.ignore_status_mask)) { | |
658 | int flag; | |
659 | ||
660 | if (status & (1 << TTY_BREAK)) | |
661 | flag = TTY_BREAK; | |
662 | else if (status & (1 << TTY_PARITY)) | |
663 | flag = TTY_PARITY; | |
664 | else if (status & (1 << TTY_FRAME)) | |
665 | flag = TTY_FRAME; | |
666 | else | |
667 | flag = TTY_NORMAL; | |
668 | ||
59c5f924 | 669 | tty_insert_flip_char(tport, ch, flag); |
b920de1b DH |
670 | } |
671 | ||
672 | /* overrun is special, since it's reported immediately, and doesn't | |
673 | * affect the current character | |
674 | */ | |
675 | if (overrun) | |
59c5f924 | 676 | tty_insert_flip_char(tport, 0, TTY_OVERRUN); |
b920de1b DH |
677 | |
678 | count--; | |
679 | if (count <= 0) { | |
59c5f924 JS |
680 | if (!tport->low_latency) |
681 | tty_flip_buffer_push(tport); | |
b920de1b DH |
682 | return; |
683 | } | |
684 | ||
685 | ignore_char: | |
686 | push = 1; | |
687 | goto try_again; | |
688 | ||
689 | not_break: | |
690 | port->rx_brk = 0; | |
691 | goto process_errors; | |
692 | } | |
693 | ||
694 | /* | |
695 | * handle an interrupt from the serial transmission "virtual DMA" driver | |
696 | * - note: the interrupt routine will disable its own interrupts when the Tx | |
697 | * buffer is empty | |
698 | */ | |
699 | static void mn10300_serial_transmit_interrupt(struct mn10300_serial_port *port) | |
700 | { | |
701 | _enter("%s", port->name); | |
702 | ||
70430786 | 703 | if (!port->uart.state || !port->uart.state->port.tty) { |
a8893fb3 AT |
704 | mn10300_serial_dis_tx_intr(port); |
705 | return; | |
706 | } | |
707 | ||
b920de1b | 708 | if (uart_tx_stopped(&port->uart) || |
70430786 | 709 | uart_circ_empty(&port->uart.state->xmit)) |
b920de1b DH |
710 | mn10300_serial_dis_tx_intr(port); |
711 | ||
70430786 | 712 | if (uart_circ_chars_pending(&port->uart.state->xmit) < WAKEUP_CHARS) |
b920de1b DH |
713 | uart_write_wakeup(&port->uart); |
714 | } | |
715 | ||
716 | /* | |
717 | * deal with a change in the status of the CTS line | |
718 | */ | |
719 | static void mn10300_serial_cts_changed(struct mn10300_serial_port *port, u8 st) | |
720 | { | |
721 | u16 ctr; | |
722 | ||
723 | port->tx_cts = st; | |
724 | port->uart.icount.cts++; | |
725 | ||
726 | /* flip the CTS state selector flag to interrupt when it changes | |
727 | * back */ | |
728 | ctr = *port->_control; | |
729 | ctr ^= SC2CTR_TWS; | |
730 | *port->_control = ctr; | |
731 | ||
732 | uart_handle_cts_change(&port->uart, st & SC2STR_CTS); | |
70430786 | 733 | wake_up_interruptible(&port->uart.state->port.delta_msr_wait); |
b920de1b DH |
734 | } |
735 | ||
736 | /* | |
737 | * handle a virtual interrupt generated by the lower level "virtual DMA" | |
738 | * routines (irq is the baud timer interrupt) | |
739 | */ | |
740 | static irqreturn_t mn10300_serial_interrupt(int irq, void *dev_id) | |
741 | { | |
742 | struct mn10300_serial_port *port = dev_id; | |
743 | u8 st; | |
744 | ||
745 | spin_lock(&port->uart.lock); | |
746 | ||
747 | if (port->intr_flags) { | |
748 | _debug("INT %s: %x", port->name, port->intr_flags); | |
749 | ||
750 | if (mask_test_and_clear(&port->intr_flags, MNSCx_RX_AVAIL)) | |
751 | mn10300_serial_receive_interrupt(port); | |
752 | ||
753 | if (mask_test_and_clear(&port->intr_flags, | |
754 | MNSCx_TX_SPACE | MNSCx_TX_EMPTY)) | |
755 | mn10300_serial_transmit_interrupt(port); | |
756 | } | |
757 | ||
758 | /* the only modem control line amongst the whole lot is CTS on | |
759 | * serial port 2 */ | |
760 | if (port->type == PORT_MN10300_CTS) { | |
761 | st = *port->_status; | |
762 | if ((port->tx_cts ^ st) & SC2STR_CTS) | |
763 | mn10300_serial_cts_changed(port, st); | |
764 | } | |
765 | ||
766 | spin_unlock(&port->uart.lock); | |
767 | ||
768 | return IRQ_HANDLED; | |
769 | } | |
770 | ||
771 | /* | |
772 | * return indication of whether the hardware transmit buffer is empty | |
773 | */ | |
774 | static unsigned int mn10300_serial_tx_empty(struct uart_port *_port) | |
775 | { | |
776 | struct mn10300_serial_port *port = | |
777 | container_of(_port, struct mn10300_serial_port, uart); | |
778 | ||
779 | _enter("%s", port->name); | |
780 | ||
781 | return (*port->_status & (SC01STR_TXF | SC01STR_TBF)) ? | |
782 | 0 : TIOCSER_TEMT; | |
783 | } | |
784 | ||
785 | /* | |
786 | * set the modem control lines (we don't have any) | |
787 | */ | |
788 | static void mn10300_serial_set_mctrl(struct uart_port *_port, | |
789 | unsigned int mctrl) | |
790 | { | |
368dd5ac | 791 | struct mn10300_serial_port *port __attribute__ ((unused)) = |
b920de1b DH |
792 | container_of(_port, struct mn10300_serial_port, uart); |
793 | ||
794 | _enter("%s,%x", port->name, mctrl); | |
795 | } | |
796 | ||
797 | /* | |
798 | * get the modem control line statuses | |
799 | */ | |
800 | static unsigned int mn10300_serial_get_mctrl(struct uart_port *_port) | |
801 | { | |
802 | struct mn10300_serial_port *port = | |
803 | container_of(_port, struct mn10300_serial_port, uart); | |
804 | ||
805 | _enter("%s", port->name); | |
806 | ||
807 | if (port->type == PORT_MN10300_CTS && !(*port->_status & SC2STR_CTS)) | |
808 | return TIOCM_CAR | TIOCM_DSR; | |
809 | ||
810 | return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; | |
811 | } | |
812 | ||
813 | /* | |
814 | * stop transmitting characters | |
815 | */ | |
816 | static void mn10300_serial_stop_tx(struct uart_port *_port) | |
817 | { | |
818 | struct mn10300_serial_port *port = | |
819 | container_of(_port, struct mn10300_serial_port, uart); | |
820 | ||
821 | _enter("%s", port->name); | |
822 | ||
823 | /* disable the virtual DMA */ | |
824 | mn10300_serial_dis_tx_intr(port); | |
825 | } | |
826 | ||
827 | /* | |
828 | * start transmitting characters | |
829 | * - jump-start transmission if it has stalled | |
830 | * - enable the serial Tx interrupt (used by the virtual DMA controller) | |
831 | * - force an interrupt to happen if necessary | |
832 | */ | |
833 | static void mn10300_serial_start_tx(struct uart_port *_port) | |
834 | { | |
835 | struct mn10300_serial_port *port = | |
836 | container_of(_port, struct mn10300_serial_port, uart); | |
837 | ||
b920de1b DH |
838 | _enter("%s{%lu}", |
839 | port->name, | |
70430786 DH |
840 | CIRC_CNT(&port->uart.state->xmit.head, |
841 | &port->uart.state->xmit.tail, | |
b920de1b DH |
842 | UART_XMIT_SIZE)); |
843 | ||
844 | /* kick the virtual DMA controller */ | |
8f0bcbca | 845 | mn10300_serial_en_tx_intr(port); |
b920de1b DH |
846 | |
847 | _debug("CTR=%04hx ICR=%02hx STR=%04x TMD=%02hx TBR=%04hx ICR=%04hx", | |
848 | *port->_control, *port->_intr, *port->_status, | |
368dd5ac AT |
849 | *port->_tmxmd, |
850 | (port->div_timer == MNSCx_DIV_TIMER_8BIT) ? | |
851 | *(volatile u8 *)port->_tmxbr : *port->_tmxbr, | |
852 | *port->tx_icr); | |
b920de1b DH |
853 | } |
854 | ||
855 | /* | |
856 | * transmit a high-priority XON/XOFF character | |
857 | */ | |
858 | static void mn10300_serial_send_xchar(struct uart_port *_port, char ch) | |
859 | { | |
860 | struct mn10300_serial_port *port = | |
861 | container_of(_port, struct mn10300_serial_port, uart); | |
8f0bcbca | 862 | unsigned long flags; |
b920de1b DH |
863 | |
864 | _enter("%s,%02x", port->name, ch); | |
865 | ||
866 | if (likely(port->gdbstub)) { | |
867 | port->tx_xchar = ch; | |
8f0bcbca MS |
868 | if (ch) { |
869 | spin_lock_irqsave(&port->uart.lock, flags); | |
b920de1b | 870 | mn10300_serial_en_tx_intr(port); |
8f0bcbca MS |
871 | spin_unlock_irqrestore(&port->uart.lock, flags); |
872 | } | |
b920de1b DH |
873 | } |
874 | } | |
875 | ||
876 | /* | |
877 | * stop receiving characters | |
878 | * - called whilst the port is being closed | |
879 | */ | |
880 | static void mn10300_serial_stop_rx(struct uart_port *_port) | |
881 | { | |
882 | struct mn10300_serial_port *port = | |
883 | container_of(_port, struct mn10300_serial_port, uart); | |
884 | ||
885 | u16 ctr; | |
886 | ||
887 | _enter("%s", port->name); | |
888 | ||
889 | ctr = *port->_control; | |
890 | ctr &= ~SC01CTR_RXE; | |
891 | *port->_control = ctr; | |
892 | ||
893 | mn10300_serial_dis_rx_intr(port); | |
894 | } | |
895 | ||
896 | /* | |
897 | * enable modem status interrupts | |
898 | */ | |
899 | static void mn10300_serial_enable_ms(struct uart_port *_port) | |
900 | { | |
901 | struct mn10300_serial_port *port = | |
902 | container_of(_port, struct mn10300_serial_port, uart); | |
903 | ||
904 | u16 ctr, cts; | |
905 | ||
906 | _enter("%s", port->name); | |
907 | ||
908 | if (port->type == PORT_MN10300_CTS) { | |
909 | /* want to interrupt when CTS goes low if CTS is now high and | |
910 | * vice versa | |
911 | */ | |
912 | port->tx_cts = *port->_status; | |
913 | ||
914 | cts = (port->tx_cts & SC2STR_CTS) ? | |
915 | SC2CTR_TWE : SC2CTR_TWE | SC2CTR_TWS; | |
916 | ||
917 | ctr = *port->_control; | |
918 | ctr &= ~SC2CTR_TWS; | |
919 | ctr |= cts; | |
920 | *port->_control = ctr; | |
921 | ||
922 | mn10300_serial_en_tx_intr(port); | |
923 | } | |
924 | } | |
925 | ||
926 | /* | |
927 | * transmit or cease transmitting a break signal | |
928 | */ | |
929 | static void mn10300_serial_break_ctl(struct uart_port *_port, int ctl) | |
930 | { | |
931 | struct mn10300_serial_port *port = | |
932 | container_of(_port, struct mn10300_serial_port, uart); | |
8f0bcbca | 933 | unsigned long flags; |
b920de1b DH |
934 | |
935 | _enter("%s,%d", port->name, ctl); | |
936 | ||
8f0bcbca | 937 | spin_lock_irqsave(&port->uart.lock, flags); |
b920de1b DH |
938 | if (ctl) { |
939 | /* tell the virtual DMA handler to assert BREAK */ | |
8f0bcbca | 940 | port->tx_flags |= MNSCx_TX_BREAK; |
b920de1b DH |
941 | mn10300_serial_en_tx_intr(port); |
942 | } else { | |
8f0bcbca | 943 | port->tx_flags &= ~MNSCx_TX_BREAK; |
b920de1b DH |
944 | *port->_control &= ~SC01CTR_BKE; |
945 | mn10300_serial_en_tx_intr(port); | |
946 | } | |
8f0bcbca | 947 | spin_unlock_irqrestore(&port->uart.lock, flags); |
b920de1b DH |
948 | } |
949 | ||
950 | /* | |
951 | * grab the interrupts and enable the port for reception | |
952 | */ | |
953 | static int mn10300_serial_startup(struct uart_port *_port) | |
954 | { | |
955 | struct mn10300_serial_port *port = | |
956 | container_of(_port, struct mn10300_serial_port, uart); | |
957 | struct mn10300_serial_int *pint; | |
958 | ||
959 | _enter("%s{%d}", port->name, port->gdbstub); | |
960 | ||
961 | if (unlikely(port->gdbstub)) | |
962 | return -EBUSY; | |
963 | ||
964 | /* allocate an Rx buffer for the virtual DMA handler */ | |
965 | port->rx_buffer = kmalloc(MNSC_BUFFER_SIZE, GFP_KERNEL); | |
966 | if (!port->rx_buffer) | |
967 | return -ENOMEM; | |
968 | ||
969 | port->rx_inp = port->rx_outp = 0; | |
8f0bcbca | 970 | port->tx_flags = 0; |
b920de1b DH |
971 | |
972 | /* finally, enable the device */ | |
973 | *port->_intr = SC01ICR_TI; | |
974 | *port->_control |= SC01CTR_TXE | SC01CTR_RXE; | |
975 | ||
976 | pint = &mn10300_serial_int_tbl[port->rx_irq]; | |
977 | pint->port = port; | |
978 | pint->vdma = mn10300_serial_vdma_rx_handler; | |
979 | pint = &mn10300_serial_int_tbl[port->tx_irq]; | |
980 | pint->port = port; | |
981 | pint->vdma = mn10300_serial_vdma_tx_handler; | |
982 | ||
8d160027 MS |
983 | irq_set_chip(port->rx_irq, &mn10300_serial_low_pic); |
984 | irq_set_chip(port->tx_irq, &mn10300_serial_low_pic); | |
f4c547eb | 985 | irq_set_chip(port->tm_irq, &mn10300_serial_pic); |
b920de1b DH |
986 | |
987 | if (request_irq(port->rx_irq, mn10300_serial_interrupt, | |
322a126a | 988 | IRQF_NOBALANCING, |
7d361cb7 | 989 | port->rx_name, port) < 0) |
b920de1b DH |
990 | goto error; |
991 | ||
992 | if (request_irq(port->tx_irq, mn10300_serial_interrupt, | |
322a126a | 993 | IRQF_NOBALANCING, |
7d361cb7 | 994 | port->tx_name, port) < 0) |
b920de1b DH |
995 | goto error2; |
996 | ||
997 | if (request_irq(port->tm_irq, mn10300_serial_interrupt, | |
322a126a | 998 | IRQF_NOBALANCING, |
7d361cb7 | 999 | port->tm_name, port) < 0) |
b920de1b DH |
1000 | goto error3; |
1001 | mn10300_serial_mask_ack(port->tm_irq); | |
1002 | ||
1003 | return 0; | |
1004 | ||
1005 | error3: | |
1006 | free_irq(port->tx_irq, port); | |
1007 | error2: | |
1008 | free_irq(port->rx_irq, port); | |
1009 | error: | |
1010 | kfree(port->rx_buffer); | |
1011 | port->rx_buffer = NULL; | |
1012 | return -EBUSY; | |
1013 | } | |
1014 | ||
1015 | /* | |
1016 | * shutdown the port and release interrupts | |
1017 | */ | |
1018 | static void mn10300_serial_shutdown(struct uart_port *_port) | |
1019 | { | |
8f0bcbca | 1020 | unsigned long flags; |
368dd5ac | 1021 | u16 x; |
b920de1b DH |
1022 | struct mn10300_serial_port *port = |
1023 | container_of(_port, struct mn10300_serial_port, uart); | |
1024 | ||
1025 | _enter("%s", port->name); | |
1026 | ||
8f0bcbca MS |
1027 | spin_lock_irqsave(&_port->lock, flags); |
1028 | mn10300_serial_dis_tx_intr(port); | |
1029 | ||
1030 | *port->rx_icr = NUM2GxICR_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL); | |
1031 | x = *port->rx_icr; | |
1032 | port->tx_flags = 0; | |
1033 | spin_unlock_irqrestore(&_port->lock, flags); | |
1034 | ||
b920de1b | 1035 | /* disable the serial port and its baud rate timer */ |
b920de1b DH |
1036 | *port->_control &= ~(SC01CTR_TXE | SC01CTR_RXE | SC01CTR_BKE); |
1037 | *port->_tmxmd = 0; | |
1038 | ||
1039 | if (port->rx_buffer) { | |
1040 | void *buf = port->rx_buffer; | |
1041 | port->rx_buffer = NULL; | |
1042 | kfree(buf); | |
1043 | } | |
1044 | ||
1045 | /* disable all intrs */ | |
1046 | free_irq(port->tm_irq, port); | |
1047 | free_irq(port->rx_irq, port); | |
1048 | free_irq(port->tx_irq, port); | |
1049 | ||
8f0bcbca MS |
1050 | mn10300_serial_int_tbl[port->tx_irq].port = NULL; |
1051 | mn10300_serial_int_tbl[port->rx_irq].port = NULL; | |
b920de1b DH |
1052 | } |
1053 | ||
1054 | /* | |
1055 | * this routine is called to set the UART divisor registers to match the | |
1056 | * specified baud rate for a serial port. | |
1057 | */ | |
1058 | static void mn10300_serial_change_speed(struct mn10300_serial_port *port, | |
1059 | struct ktermios *new, | |
1060 | struct ktermios *old) | |
1061 | { | |
1062 | unsigned long flags; | |
1063 | unsigned long ioclk = port->ioclk; | |
1064 | unsigned cflag; | |
1065 | int baud, bits, xdiv, tmp; | |
1066 | u16 tmxbr, scxctr; | |
1067 | u8 tmxmd, battempt; | |
1068 | u8 div_timer = port->div_timer; | |
1069 | ||
1070 | _enter("%s{%lu}", port->name, ioclk); | |
1071 | ||
1072 | /* byte size and parity */ | |
1073 | cflag = new->c_cflag; | |
1074 | switch (cflag & CSIZE) { | |
1075 | case CS7: scxctr = SC01CTR_CLN_7BIT; bits = 9; break; | |
1076 | case CS8: scxctr = SC01CTR_CLN_8BIT; bits = 10; break; | |
1077 | default: scxctr = SC01CTR_CLN_8BIT; bits = 10; break; | |
1078 | } | |
1079 | ||
1080 | if (cflag & CSTOPB) { | |
1081 | scxctr |= SC01CTR_STB_2BIT; | |
1082 | bits++; | |
1083 | } | |
1084 | ||
1085 | if (cflag & PARENB) { | |
1086 | bits++; | |
1087 | if (cflag & PARODD) | |
1088 | scxctr |= SC01CTR_PB_ODD; | |
1089 | #ifdef CMSPAR | |
1090 | else if (cflag & CMSPAR) | |
1091 | scxctr |= SC01CTR_PB_FIXED0; | |
1092 | #endif | |
1093 | else | |
1094 | scxctr |= SC01CTR_PB_EVEN; | |
1095 | } | |
1096 | ||
1097 | /* Determine divisor based on baud rate */ | |
1098 | battempt = 0; | |
1099 | ||
368dd5ac AT |
1100 | switch (port->uart.line) { |
1101 | #ifdef CONFIG_MN10300_TTYSM0 | |
1102 | case 0: /* ttySM0 */ | |
1103 | #if defined(CONFIG_MN10300_TTYSM0_TIMER8) | |
1104 | scxctr |= SC0CTR_CK_TM8UFLOW_8; | |
1105 | #elif defined(CONFIG_MN10300_TTYSM0_TIMER0) | |
1106 | scxctr |= SC0CTR_CK_TM0UFLOW_8; | |
1107 | #elif defined(CONFIG_MN10300_TTYSM0_TIMER2) | |
b920de1b | 1108 | scxctr |= SC0CTR_CK_TM2UFLOW_8; |
368dd5ac AT |
1109 | #else |
1110 | #error "Unknown config for ttySM0" | |
1111 | #endif | |
1112 | break; | |
1113 | #endif /* CONFIG_MN10300_TTYSM0 */ | |
1114 | ||
1115 | #ifdef CONFIG_MN10300_TTYSM1 | |
1116 | case 1: /* ttySM1 */ | |
1117 | #if defined(CONFIG_AM33_2) || defined(CONFIG_AM33_3) | |
1118 | #if defined(CONFIG_MN10300_TTYSM1_TIMER9) | |
1119 | scxctr |= SC1CTR_CK_TM9UFLOW_8; | |
1120 | #elif defined(CONFIG_MN10300_TTYSM1_TIMER3) | |
1121 | scxctr |= SC1CTR_CK_TM3UFLOW_8; | |
1122 | #else | |
1123 | #error "Unknown config for ttySM1" | |
1124 | #endif | |
1125 | #else /* CONFIG_AM33_2 || CONFIG_AM33_3 */ | |
1126 | #if defined(CONFIG_MN10300_TTYSM1_TIMER12) | |
1127 | scxctr |= SC1CTR_CK_TM12UFLOW_8; | |
1128 | #else | |
1129 | #error "Unknown config for ttySM1" | |
1130 | #endif | |
1131 | #endif /* CONFIG_AM33_2 || CONFIG_AM33_3 */ | |
1132 | break; | |
1133 | #endif /* CONFIG_MN10300_TTYSM1 */ | |
1134 | ||
1135 | #ifdef CONFIG_MN10300_TTYSM2 | |
1136 | case 2: /* ttySM2 */ | |
1137 | #if defined(CONFIG_AM33_2) | |
1138 | #if defined(CONFIG_MN10300_TTYSM2_TIMER10) | |
1139 | scxctr |= SC2CTR_CK_TM10UFLOW; | |
1140 | #else | |
1141 | #error "Unknown config for ttySM2" | |
1142 | #endif | |
1143 | #else /* CONFIG_AM33_2 */ | |
1144 | #if defined(CONFIG_MN10300_TTYSM2_TIMER9) | |
1145 | scxctr |= SC2CTR_CK_TM9UFLOW_8; | |
1146 | #elif defined(CONFIG_MN10300_TTYSM2_TIMER1) | |
1147 | scxctr |= SC2CTR_CK_TM1UFLOW_8; | |
1148 | #elif defined(CONFIG_MN10300_TTYSM2_TIMER3) | |
1149 | scxctr |= SC2CTR_CK_TM3UFLOW_8; | |
1150 | #else | |
1151 | #error "Unknown config for ttySM2" | |
1152 | #endif | |
1153 | #endif /* CONFIG_AM33_2 */ | |
1154 | break; | |
1155 | #endif /* CONFIG_MN10300_TTYSM2 */ | |
1156 | ||
1157 | default: | |
1158 | break; | |
1159 | } | |
b920de1b DH |
1160 | |
1161 | try_alternative: | |
1162 | baud = uart_get_baud_rate(&port->uart, new, old, 0, | |
1163 | port->ioclk / 8); | |
1164 | ||
1165 | _debug("ALT %d [baud %d]", battempt, baud); | |
1166 | ||
1167 | if (!baud) | |
1168 | baud = 9600; /* B0 transition handled in rs_set_termios */ | |
1169 | xdiv = 1; | |
1170 | if (baud == 134) { | |
1171 | baud = 269; /* 134 is really 134.5 */ | |
1172 | xdiv = 2; | |
1173 | } | |
1174 | ||
1175 | if (baud == 38400 && | |
1176 | (port->uart.flags & UPF_SPD_MASK) == UPF_SPD_CUST | |
1177 | ) { | |
1178 | _debug("CUSTOM %u", port->uart.custom_divisor); | |
1179 | ||
1180 | if (div_timer == MNSCx_DIV_TIMER_16BIT) { | |
1181 | if (port->uart.custom_divisor <= 65535) { | |
1182 | tmxmd = TM8MD_SRC_IOCLK; | |
1183 | tmxbr = port->uart.custom_divisor; | |
1184 | port->uart.uartclk = ioclk; | |
1185 | goto timer_okay; | |
1186 | } | |
1187 | if (port->uart.custom_divisor / 8 <= 65535) { | |
1188 | tmxmd = TM8MD_SRC_IOCLK_8; | |
1189 | tmxbr = port->uart.custom_divisor / 8; | |
1190 | port->uart.custom_divisor = tmxbr * 8; | |
1191 | port->uart.uartclk = ioclk / 8; | |
1192 | goto timer_okay; | |
1193 | } | |
1194 | if (port->uart.custom_divisor / 32 <= 65535) { | |
1195 | tmxmd = TM8MD_SRC_IOCLK_32; | |
1196 | tmxbr = port->uart.custom_divisor / 32; | |
1197 | port->uart.custom_divisor = tmxbr * 32; | |
1198 | port->uart.uartclk = ioclk / 32; | |
1199 | goto timer_okay; | |
1200 | } | |
1201 | ||
1202 | } else if (div_timer == MNSCx_DIV_TIMER_8BIT) { | |
1203 | if (port->uart.custom_divisor <= 255) { | |
1204 | tmxmd = TM2MD_SRC_IOCLK; | |
1205 | tmxbr = port->uart.custom_divisor; | |
1206 | port->uart.uartclk = ioclk; | |
1207 | goto timer_okay; | |
1208 | } | |
1209 | if (port->uart.custom_divisor / 8 <= 255) { | |
1210 | tmxmd = TM2MD_SRC_IOCLK_8; | |
1211 | tmxbr = port->uart.custom_divisor / 8; | |
1212 | port->uart.custom_divisor = tmxbr * 8; | |
1213 | port->uart.uartclk = ioclk / 8; | |
1214 | goto timer_okay; | |
1215 | } | |
1216 | if (port->uart.custom_divisor / 32 <= 255) { | |
1217 | tmxmd = TM2MD_SRC_IOCLK_32; | |
1218 | tmxbr = port->uart.custom_divisor / 32; | |
1219 | port->uart.custom_divisor = tmxbr * 32; | |
1220 | port->uart.uartclk = ioclk / 32; | |
1221 | goto timer_okay; | |
1222 | } | |
1223 | } | |
1224 | } | |
1225 | ||
1226 | switch (div_timer) { | |
1227 | case MNSCx_DIV_TIMER_16BIT: | |
1228 | port->uart.uartclk = ioclk; | |
1229 | tmxmd = TM8MD_SRC_IOCLK; | |
1230 | tmxbr = tmp = (ioclk / (baud * xdiv) + 4) / 8 - 1; | |
1231 | if (tmp > 0 && tmp <= 65535) | |
1232 | goto timer_okay; | |
1233 | ||
1234 | port->uart.uartclk = ioclk / 8; | |
1235 | tmxmd = TM8MD_SRC_IOCLK_8; | |
1236 | tmxbr = tmp = (ioclk / (baud * 8 * xdiv) + 4) / 8 - 1; | |
1237 | if (tmp > 0 && tmp <= 65535) | |
1238 | goto timer_okay; | |
1239 | ||
1240 | port->uart.uartclk = ioclk / 32; | |
1241 | tmxmd = TM8MD_SRC_IOCLK_32; | |
1242 | tmxbr = tmp = (ioclk / (baud * 32 * xdiv) + 4) / 8 - 1; | |
1243 | if (tmp > 0 && tmp <= 65535) | |
1244 | goto timer_okay; | |
1245 | break; | |
1246 | ||
1247 | case MNSCx_DIV_TIMER_8BIT: | |
1248 | port->uart.uartclk = ioclk; | |
1249 | tmxmd = TM2MD_SRC_IOCLK; | |
1250 | tmxbr = tmp = (ioclk / (baud * xdiv) + 4) / 8 - 1; | |
1251 | if (tmp > 0 && tmp <= 255) | |
1252 | goto timer_okay; | |
1253 | ||
1254 | port->uart.uartclk = ioclk / 8; | |
1255 | tmxmd = TM2MD_SRC_IOCLK_8; | |
1256 | tmxbr = tmp = (ioclk / (baud * 8 * xdiv) + 4) / 8 - 1; | |
1257 | if (tmp > 0 && tmp <= 255) | |
1258 | goto timer_okay; | |
1259 | ||
1260 | port->uart.uartclk = ioclk / 32; | |
1261 | tmxmd = TM2MD_SRC_IOCLK_32; | |
1262 | tmxbr = tmp = (ioclk / (baud * 32 * xdiv) + 4) / 8 - 1; | |
1263 | if (tmp > 0 && tmp <= 255) | |
1264 | goto timer_okay; | |
1265 | break; | |
1266 | ||
1267 | default: | |
1268 | BUG(); | |
1269 | return; | |
1270 | } | |
1271 | ||
1272 | /* refuse to change to a baud rate we can't support */ | |
1273 | _debug("CAN'T SUPPORT"); | |
1274 | ||
1275 | switch (battempt) { | |
1276 | case 0: | |
1277 | if (old) { | |
1278 | new->c_cflag &= ~CBAUD; | |
1279 | new->c_cflag |= (old->c_cflag & CBAUD); | |
1280 | battempt = 1; | |
1281 | goto try_alternative; | |
1282 | } | |
1283 | ||
1284 | case 1: | |
1285 | /* as a last resort, if the quotient is zero, default to 9600 | |
1286 | * bps */ | |
1287 | new->c_cflag &= ~CBAUD; | |
1288 | new->c_cflag |= B9600; | |
1289 | battempt = 2; | |
1290 | goto try_alternative; | |
1291 | ||
1292 | default: | |
1293 | /* hmmm... can't seem to support 9600 either | |
1294 | * - we could try iterating through the speeds we know about to | |
1295 | * find the lowest | |
1296 | */ | |
1297 | new->c_cflag &= ~CBAUD; | |
1298 | new->c_cflag |= B0; | |
1299 | ||
1300 | if (div_timer == MNSCx_DIV_TIMER_16BIT) | |
1301 | tmxmd = TM8MD_SRC_IOCLK_32; | |
1302 | else if (div_timer == MNSCx_DIV_TIMER_8BIT) | |
1303 | tmxmd = TM2MD_SRC_IOCLK_32; | |
1304 | tmxbr = 1; | |
1305 | ||
1306 | port->uart.uartclk = ioclk / 32; | |
1307 | break; | |
1308 | } | |
1309 | timer_okay: | |
1310 | ||
1311 | _debug("UARTCLK: %u / %hu", port->uart.uartclk, tmxbr); | |
1312 | ||
1313 | /* make the changes */ | |
1314 | spin_lock_irqsave(&port->uart.lock, flags); | |
1315 | ||
1316 | uart_update_timeout(&port->uart, new->c_cflag, baud); | |
1317 | ||
1318 | /* set the timer to produce the required baud rate */ | |
1319 | switch (div_timer) { | |
1320 | case MNSCx_DIV_TIMER_16BIT: | |
1321 | *port->_tmxmd = 0; | |
1322 | *port->_tmxbr = tmxbr; | |
1323 | *port->_tmxmd = TM8MD_INIT_COUNTER; | |
1324 | *port->_tmxmd = tmxmd | TM8MD_COUNT_ENABLE; | |
1325 | break; | |
1326 | ||
1327 | case MNSCx_DIV_TIMER_8BIT: | |
1328 | *port->_tmxmd = 0; | |
1329 | *(volatile u8 *) port->_tmxbr = (u8) tmxbr; | |
1330 | *port->_tmxmd = TM2MD_INIT_COUNTER; | |
1331 | *port->_tmxmd = tmxmd | TM2MD_COUNT_ENABLE; | |
1332 | break; | |
1333 | } | |
1334 | ||
1335 | /* CTS flow control flag and modem status interrupts */ | |
1336 | scxctr &= ~(SC2CTR_TWE | SC2CTR_TWS); | |
1337 | ||
1338 | if (port->type == PORT_MN10300_CTS && cflag & CRTSCTS) { | |
1339 | /* want to interrupt when CTS goes low if CTS is now | |
1340 | * high and vice versa | |
1341 | */ | |
1342 | port->tx_cts = *port->_status; | |
1343 | ||
1344 | if (port->tx_cts & SC2STR_CTS) | |
1345 | scxctr |= SC2CTR_TWE; | |
1346 | else | |
1347 | scxctr |= SC2CTR_TWE | SC2CTR_TWS; | |
1348 | } | |
1349 | ||
1350 | /* set up parity check flag */ | |
1351 | port->uart.read_status_mask = (1 << TTY_NORMAL) | (1 << TTY_OVERRUN); | |
1352 | if (new->c_iflag & INPCK) | |
1353 | port->uart.read_status_mask |= | |
1354 | (1 << TTY_PARITY) | (1 << TTY_FRAME); | |
1355 | if (new->c_iflag & (BRKINT | PARMRK)) | |
1356 | port->uart.read_status_mask |= (1 << TTY_BREAK); | |
1357 | ||
1358 | /* characters to ignore */ | |
1359 | port->uart.ignore_status_mask = 0; | |
1360 | if (new->c_iflag & IGNPAR) | |
1361 | port->uart.ignore_status_mask |= | |
1362 | (1 << TTY_PARITY) | (1 << TTY_FRAME); | |
1363 | if (new->c_iflag & IGNBRK) { | |
1364 | port->uart.ignore_status_mask |= (1 << TTY_BREAK); | |
1365 | /* | |
1366 | * If we're ignoring parity and break indicators, | |
1367 | * ignore overruns to (for real raw support). | |
1368 | */ | |
1369 | if (new->c_iflag & IGNPAR) | |
1370 | port->uart.ignore_status_mask |= (1 << TTY_OVERRUN); | |
1371 | } | |
1372 | ||
1373 | /* Ignore all characters if CREAD is not set */ | |
1374 | if ((new->c_cflag & CREAD) == 0) | |
1375 | port->uart.ignore_status_mask |= (1 << TTY_NORMAL); | |
1376 | ||
0369c360 MS |
1377 | scxctr |= SC01CTR_TXE | SC01CTR_RXE; |
1378 | scxctr |= *port->_control & SC01CTR_BKE; | |
b920de1b DH |
1379 | *port->_control = scxctr; |
1380 | ||
1381 | spin_unlock_irqrestore(&port->uart.lock, flags); | |
1382 | } | |
1383 | ||
1384 | /* | |
1385 | * set the terminal I/O parameters | |
1386 | */ | |
1387 | static void mn10300_serial_set_termios(struct uart_port *_port, | |
1388 | struct ktermios *new, | |
1389 | struct ktermios *old) | |
1390 | { | |
1391 | struct mn10300_serial_port *port = | |
1392 | container_of(_port, struct mn10300_serial_port, uart); | |
1393 | ||
1394 | _enter("%s,%p,%p", port->name, new, old); | |
1395 | ||
1396 | mn10300_serial_change_speed(port, new, old); | |
1397 | ||
1398 | /* handle turning off CRTSCTS */ | |
1399 | if (!(new->c_cflag & CRTSCTS)) { | |
1400 | u16 ctr = *port->_control; | |
1401 | ctr &= ~SC2CTR_TWE; | |
1402 | *port->_control = ctr; | |
1403 | } | |
368dd5ac AT |
1404 | |
1405 | /* change Transfer bit-order (LSB/MSB) */ | |
1406 | if (new->c_cflag & CODMSB) | |
1407 | *port->_control |= SC01CTR_OD_MSBFIRST; /* MSB MODE */ | |
1408 | else | |
1409 | *port->_control &= ~SC01CTR_OD_MSBFIRST; /* LSB MODE */ | |
b920de1b DH |
1410 | } |
1411 | ||
1412 | /* | |
1413 | * return description of port type | |
1414 | */ | |
1415 | static const char *mn10300_serial_type(struct uart_port *_port) | |
1416 | { | |
1417 | struct mn10300_serial_port *port = | |
1418 | container_of(_port, struct mn10300_serial_port, uart); | |
1419 | ||
1420 | if (port->uart.type == PORT_MN10300_CTS) | |
1421 | return "MN10300 SIF_CTS"; | |
1422 | ||
1423 | return "MN10300 SIF"; | |
1424 | } | |
1425 | ||
1426 | /* | |
1427 | * release I/O and memory regions in use by port | |
1428 | */ | |
1429 | static void mn10300_serial_release_port(struct uart_port *_port) | |
1430 | { | |
1431 | struct mn10300_serial_port *port = | |
1432 | container_of(_port, struct mn10300_serial_port, uart); | |
1433 | ||
1434 | _enter("%s", port->name); | |
1435 | ||
1436 | release_mem_region((unsigned long) port->_iobase, 16); | |
1437 | } | |
1438 | ||
1439 | /* | |
1440 | * request I/O and memory regions for port | |
1441 | */ | |
1442 | static int mn10300_serial_request_port(struct uart_port *_port) | |
1443 | { | |
1444 | struct mn10300_serial_port *port = | |
1445 | container_of(_port, struct mn10300_serial_port, uart); | |
1446 | ||
1447 | _enter("%s", port->name); | |
1448 | ||
1449 | request_mem_region((unsigned long) port->_iobase, 16, port->name); | |
1450 | return 0; | |
1451 | } | |
1452 | ||
1453 | /* | |
1454 | * configure the type and reserve the ports | |
1455 | */ | |
1456 | static void mn10300_serial_config_port(struct uart_port *_port, int type) | |
1457 | { | |
1458 | struct mn10300_serial_port *port = | |
1459 | container_of(_port, struct mn10300_serial_port, uart); | |
1460 | ||
1461 | _enter("%s", port->name); | |
1462 | ||
1463 | port->uart.type = PORT_MN10300; | |
1464 | ||
1465 | if (port->options & MNSCx_OPT_CTS) | |
1466 | port->uart.type = PORT_MN10300_CTS; | |
1467 | ||
1468 | mn10300_serial_request_port(_port); | |
1469 | } | |
1470 | ||
1471 | /* | |
1472 | * verify serial parameters are suitable for this port type | |
1473 | */ | |
1474 | static int mn10300_serial_verify_port(struct uart_port *_port, | |
1475 | struct serial_struct *ss) | |
1476 | { | |
1477 | struct mn10300_serial_port *port = | |
1478 | container_of(_port, struct mn10300_serial_port, uart); | |
1479 | void *mapbase = (void *) (unsigned long) port->uart.mapbase; | |
1480 | ||
1481 | _enter("%s", port->name); | |
1482 | ||
1483 | /* these things may not be changed */ | |
1484 | if (ss->irq != port->uart.irq || | |
1485 | ss->port != port->uart.iobase || | |
1486 | ss->io_type != port->uart.iotype || | |
1487 | ss->iomem_base != mapbase || | |
1488 | ss->iomem_reg_shift != port->uart.regshift || | |
1489 | ss->hub6 != port->uart.hub6 || | |
1490 | ss->xmit_fifo_size != port->uart.fifosize) | |
1491 | return -EINVAL; | |
1492 | ||
1493 | /* type may be changed on a port that supports CTS */ | |
1494 | if (ss->type != port->uart.type) { | |
1495 | if (!(port->options & MNSCx_OPT_CTS)) | |
1496 | return -EINVAL; | |
1497 | ||
1498 | if (ss->type != PORT_MN10300 && | |
1499 | ss->type != PORT_MN10300_CTS) | |
1500 | return -EINVAL; | |
1501 | } | |
1502 | ||
1503 | return 0; | |
1504 | } | |
1505 | ||
1506 | /* | |
1507 | * initialise the MN10300 on-chip UARTs | |
1508 | */ | |
1509 | static int __init mn10300_serial_init(void) | |
1510 | { | |
1511 | struct mn10300_serial_port *port; | |
1512 | int ret, i; | |
1513 | ||
1514 | printk(KERN_INFO "%s version %s (%s)\n", | |
1515 | serial_name, serial_version, serial_revdate); | |
1516 | ||
368dd5ac AT |
1517 | #if defined(CONFIG_MN10300_TTYSM2) && defined(CONFIG_AM33_2) |
1518 | { | |
1519 | int tmp; | |
1520 | SC2TIM = 8; /* make the baud base of timer 2 IOCLK/8 */ | |
1521 | tmp = SC2TIM; | |
1522 | } | |
b920de1b DH |
1523 | #endif |
1524 | ||
368dd5ac AT |
1525 | set_intr_stub(NUM2EXCEP_IRQ_LEVEL(CONFIG_MN10300_SERIAL_IRQ_LEVEL), |
1526 | mn10300_serial_vdma_interrupt); | |
b920de1b DH |
1527 | |
1528 | ret = uart_register_driver(&mn10300_serial_driver); | |
1529 | if (!ret) { | |
1530 | for (i = 0 ; i < NR_PORTS ; i++) { | |
1531 | port = mn10300_serial_ports[i]; | |
1532 | if (!port || port->gdbstub) | |
1533 | continue; | |
1534 | ||
1535 | switch (port->clock_src) { | |
1536 | case MNSCx_CLOCK_SRC_IOCLK: | |
1537 | port->ioclk = MN10300_IOCLK; | |
1538 | break; | |
1539 | ||
1540 | #ifdef MN10300_IOBCLK | |
1541 | case MNSCx_CLOCK_SRC_IOBCLK: | |
1542 | port->ioclk = MN10300_IOBCLK; | |
1543 | break; | |
1544 | #endif | |
1545 | default: | |
1546 | BUG(); | |
1547 | } | |
1548 | ||
1549 | ret = uart_add_one_port(&mn10300_serial_driver, | |
1550 | &port->uart); | |
1551 | ||
1552 | if (ret < 0) { | |
1553 | _debug("ERROR %d", -ret); | |
1554 | break; | |
1555 | } | |
1556 | } | |
1557 | ||
1558 | if (ret) | |
1559 | uart_unregister_driver(&mn10300_serial_driver); | |
1560 | } | |
1561 | ||
1562 | return ret; | |
1563 | } | |
1564 | ||
1565 | __initcall(mn10300_serial_init); | |
1566 | ||
1567 | ||
1568 | #ifdef CONFIG_MN10300_TTYSM_CONSOLE | |
1569 | ||
1570 | /* | |
1571 | * print a string to the serial port without disturbing the real user of the | |
1572 | * port too much | |
1573 | * - the console must be locked by the caller | |
1574 | */ | |
1575 | static void mn10300_serial_console_write(struct console *co, | |
1576 | const char *s, unsigned count) | |
1577 | { | |
1578 | struct mn10300_serial_port *port; | |
1579 | unsigned i; | |
8f0bcbca | 1580 | u16 scxctr; |
b920de1b | 1581 | u8 tmxmd; |
8f0bcbca MS |
1582 | unsigned long flags; |
1583 | int locked = 1; | |
b920de1b DH |
1584 | |
1585 | port = mn10300_serial_ports[co->index]; | |
1586 | ||
8f0bcbca MS |
1587 | local_irq_save(flags); |
1588 | if (port->uart.sysrq) { | |
1589 | /* mn10300_serial_interrupt() already took the lock */ | |
1590 | locked = 0; | |
1591 | } else if (oops_in_progress) { | |
1592 | locked = spin_trylock(&port->uart.lock); | |
1593 | } else | |
1594 | spin_lock(&port->uart.lock); | |
1595 | ||
b920de1b | 1596 | /* firstly hijack the serial port from the "virtual DMA" controller */ |
8f0bcbca | 1597 | mn10300_serial_dis_tx_intr(port); |
b920de1b DH |
1598 | |
1599 | /* the transmitter may be disabled */ | |
1600 | scxctr = *port->_control; | |
1601 | if (!(scxctr & SC01CTR_TXE)) { | |
1602 | /* restart the UART clock */ | |
1603 | tmxmd = *port->_tmxmd; | |
1604 | ||
1605 | switch (port->div_timer) { | |
1606 | case MNSCx_DIV_TIMER_16BIT: | |
1607 | *port->_tmxmd = 0; | |
1608 | *port->_tmxmd = TM8MD_INIT_COUNTER; | |
1609 | *port->_tmxmd = tmxmd | TM8MD_COUNT_ENABLE; | |
1610 | break; | |
1611 | ||
1612 | case MNSCx_DIV_TIMER_8BIT: | |
1613 | *port->_tmxmd = 0; | |
1614 | *port->_tmxmd = TM2MD_INIT_COUNTER; | |
1615 | *port->_tmxmd = tmxmd | TM2MD_COUNT_ENABLE; | |
1616 | break; | |
1617 | } | |
1618 | ||
1619 | /* enable the transmitter */ | |
1620 | *port->_control = (scxctr & ~SC01CTR_BKE) | SC01CTR_TXE; | |
1621 | ||
1622 | } else if (scxctr & SC01CTR_BKE) { | |
1623 | /* stop transmitting BREAK */ | |
1624 | *port->_control = (scxctr & ~SC01CTR_BKE); | |
1625 | } | |
1626 | ||
1627 | /* send the chars into the serial port (with LF -> LFCR conversion) */ | |
1628 | for (i = 0; i < count; i++) { | |
1629 | char ch = *s++; | |
1630 | ||
1631 | while (*port->_status & SC01STR_TBF) | |
1632 | continue; | |
97a70b14 | 1633 | *port->_txb = ch; |
b920de1b DH |
1634 | |
1635 | if (ch == 0x0a) { | |
1636 | while (*port->_status & SC01STR_TBF) | |
1637 | continue; | |
97a70b14 | 1638 | *port->_txb = 0xd; |
b920de1b DH |
1639 | } |
1640 | } | |
1641 | ||
1642 | /* can't let the transmitter be turned off if it's actually | |
1643 | * transmitting */ | |
1644 | while (*port->_status & (SC01STR_TXF | SC01STR_TBF)) | |
1645 | continue; | |
1646 | ||
1647 | /* disable the transmitter if we re-enabled it */ | |
1648 | if (!(scxctr & SC01CTR_TXE)) | |
1649 | *port->_control = scxctr; | |
1650 | ||
8f0bcbca MS |
1651 | mn10300_serial_en_tx_intr(port); |
1652 | ||
1653 | if (locked) | |
1654 | spin_unlock(&port->uart.lock); | |
1655 | local_irq_restore(flags); | |
b920de1b DH |
1656 | } |
1657 | ||
1658 | /* | |
1659 | * set up a serial port as a console | |
1660 | * - construct a cflag setting for the first rs_open() | |
1661 | * - initialize the serial port | |
1662 | * - return non-zero if we didn't find a serial port. | |
1663 | */ | |
1664 | static int __init mn10300_serial_console_setup(struct console *co, | |
1665 | char *options) | |
1666 | { | |
1667 | struct mn10300_serial_port *port; | |
1668 | int i, parity = 'n', baud = 9600, bits = 8, flow = 0; | |
1669 | ||
1670 | for (i = 0 ; i < NR_PORTS ; i++) { | |
1671 | port = mn10300_serial_ports[i]; | |
1672 | if (port && !port->gdbstub && port->uart.line == co->index) | |
1673 | goto found_device; | |
1674 | } | |
1675 | ||
1676 | return -ENODEV; | |
1677 | ||
1678 | found_device: | |
1679 | switch (port->clock_src) { | |
1680 | case MNSCx_CLOCK_SRC_IOCLK: | |
1681 | port->ioclk = MN10300_IOCLK; | |
1682 | break; | |
1683 | ||
1684 | #ifdef MN10300_IOBCLK | |
1685 | case MNSCx_CLOCK_SRC_IOBCLK: | |
1686 | port->ioclk = MN10300_IOBCLK; | |
1687 | break; | |
1688 | #endif | |
1689 | default: | |
1690 | BUG(); | |
1691 | } | |
1692 | ||
1693 | if (options) | |
1694 | uart_parse_options(options, &baud, &parity, &bits, &flow); | |
1695 | ||
1696 | return uart_set_options(&port->uart, co, baud, parity, bits, flow); | |
1697 | } | |
1698 | ||
1699 | /* | |
1700 | * register console | |
1701 | */ | |
1702 | static int __init mn10300_serial_console_init(void) | |
1703 | { | |
1704 | register_console(&mn10300_serial_console); | |
1705 | return 0; | |
1706 | } | |
1707 | ||
1708 | console_initcall(mn10300_serial_console_init); | |
1709 | #endif | |
52885b32 DH |
1710 | |
1711 | #ifdef CONFIG_CONSOLE_POLL | |
1712 | /* | |
1713 | * Polled character reception for the kernel debugger | |
1714 | */ | |
1715 | static int mn10300_serial_poll_get_char(struct uart_port *_port) | |
1716 | { | |
1717 | struct mn10300_serial_port *port = | |
1718 | container_of(_port, struct mn10300_serial_port, uart); | |
1719 | unsigned ix; | |
1720 | u8 st, ch; | |
1721 | ||
1722 | _enter("%s", port->name); | |
1723 | ||
0369c360 MS |
1724 | if (mn10300_serial_int_tbl[port->rx_irq].port != NULL) { |
1725 | do { | |
1726 | /* pull chars out of the hat */ | |
6aa7de05 | 1727 | ix = READ_ONCE(port->rx_outp); |
0369c360 MS |
1728 | if (CIRC_CNT(port->rx_inp, ix, MNSC_BUFFER_SIZE) == 0) |
1729 | return NO_POLL_CHAR; | |
52885b32 | 1730 | |
a4bd78ed PM |
1731 | /* |
1732 | * READ_ONCE() enforces dependency, but dangerous | |
1733 | * through integer!!! | |
1734 | */ | |
0369c360 MS |
1735 | ch = port->rx_buffer[ix++]; |
1736 | st = port->rx_buffer[ix++]; | |
1737 | smp_mb(); | |
1738 | port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1); | |
52885b32 | 1739 | |
0369c360 MS |
1740 | } while (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF)); |
1741 | } else { | |
1742 | do { | |
1743 | st = *port->_status; | |
1744 | if (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF)) | |
1745 | continue; | |
1746 | } while (!(st & SC01STR_RBF)); | |
1747 | ||
1748 | ch = *port->_rxb; | |
1749 | } | |
52885b32 DH |
1750 | |
1751 | return ch; | |
1752 | } | |
1753 | ||
1754 | ||
1755 | /* | |
1756 | * Polled character transmission for the kernel debugger | |
1757 | */ | |
1758 | static void mn10300_serial_poll_put_char(struct uart_port *_port, | |
1759 | unsigned char ch) | |
1760 | { | |
1761 | struct mn10300_serial_port *port = | |
1762 | container_of(_port, struct mn10300_serial_port, uart); | |
1763 | u8 intr, tmp; | |
1764 | ||
1765 | /* wait for the transmitter to finish anything it might be doing (and | |
1766 | * this includes the virtual DMA handler, so it might take a while) */ | |
1767 | while (*port->_status & (SC01STR_TBF | SC01STR_TXF)) | |
1768 | continue; | |
1769 | ||
1770 | /* disable the Tx ready interrupt */ | |
1771 | intr = *port->_intr; | |
1772 | *port->_intr = intr & ~SC01ICR_TI; | |
1773 | tmp = *port->_intr; | |
1774 | ||
1775 | if (ch == 0x0a) { | |
97a70b14 | 1776 | *port->_txb = 0x0d; |
52885b32 DH |
1777 | while (*port->_status & SC01STR_TBF) |
1778 | continue; | |
1779 | } | |
1780 | ||
97a70b14 | 1781 | *port->_txb = ch; |
52885b32 DH |
1782 | while (*port->_status & SC01STR_TBF) |
1783 | continue; | |
1784 | ||
1785 | /* restore the Tx interrupt flag */ | |
1786 | *port->_intr = intr; | |
1787 | tmp = *port->_intr; | |
1788 | } | |
1789 | ||
1790 | #endif /* CONFIG_CONSOLE_POLL */ |