| David Howells | b920de1 | 2008-02-08 04:19:31 -0800 | [diff] [blame] | 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 |  | 
| David Howells | b920de1 | 2008-02-08 04:19:31 -0800 | [diff] [blame] | 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 |  | 
|  | 39 | #include <asm/system.h> | 
|  | 40 | #include <asm/io.h> | 
|  | 41 | #include <asm/irq.h> | 
|  | 42 | #include <asm/bitops.h> | 
|  | 43 | #include <asm/serial-regs.h> | 
|  | 44 | #include <asm/unit/timex.h> | 
|  | 45 | #include "mn10300-serial.h" | 
|  | 46 |  | 
|  | 47 | static inline __attribute__((format(printf, 1, 2))) | 
|  | 48 | void no_printk(const char *fmt, ...) | 
|  | 49 | { | 
|  | 50 | } | 
|  | 51 |  | 
|  | 52 | #define kenter(FMT, ...) \ | 
|  | 53 | printk(KERN_DEBUG "-->%s(" FMT ")\n", __func__, ##__VA_ARGS__) | 
|  | 54 | #define _enter(FMT, ...) \ | 
|  | 55 | no_printk(KERN_DEBUG "-->%s(" FMT ")\n", __func__, ##__VA_ARGS__) | 
|  | 56 | #define kdebug(FMT, ...) \ | 
|  | 57 | printk(KERN_DEBUG "--- " FMT "\n", ##__VA_ARGS__) | 
|  | 58 | #define _debug(FMT, ...) \ | 
|  | 59 | no_printk(KERN_DEBUG "--- " FMT "\n", ##__VA_ARGS__) | 
|  | 60 | #define kproto(FMT, ...) \ | 
|  | 61 | printk(KERN_DEBUG "### MNSERIAL " FMT " ###\n", ##__VA_ARGS__) | 
|  | 62 | #define _proto(FMT, ...) \ | 
|  | 63 | no_printk(KERN_DEBUG "### MNSERIAL " FMT " ###\n", ##__VA_ARGS__) | 
|  | 64 |  | 
|  | 65 | #define NR_UARTS 3 | 
|  | 66 |  | 
|  | 67 | #ifdef CONFIG_MN10300_TTYSM_CONSOLE | 
|  | 68 | static void mn10300_serial_console_write(struct console *co, | 
|  | 69 | const char *s, unsigned count); | 
|  | 70 | static int __init mn10300_serial_console_setup(struct console *co, | 
|  | 71 | char *options); | 
|  | 72 |  | 
|  | 73 | static struct uart_driver mn10300_serial_driver; | 
|  | 74 | static struct console mn10300_serial_console = { | 
|  | 75 | .name		= "ttySM", | 
|  | 76 | .write		= mn10300_serial_console_write, | 
|  | 77 | .device		= uart_console_device, | 
|  | 78 | .setup		= mn10300_serial_console_setup, | 
|  | 79 | .flags		= CON_PRINTBUFFER, | 
|  | 80 | .index		= -1, | 
|  | 81 | .data		= &mn10300_serial_driver, | 
|  | 82 | }; | 
|  | 83 | #endif | 
|  | 84 |  | 
|  | 85 | static struct uart_driver mn10300_serial_driver = { | 
|  | 86 | .owner		= NULL, | 
|  | 87 | .driver_name	= "mn10300-serial", | 
|  | 88 | .dev_name	= "ttySM", | 
|  | 89 | .major		= TTY_MAJOR, | 
|  | 90 | .minor		= 128, | 
|  | 91 | .nr		= NR_UARTS, | 
|  | 92 | #ifdef CONFIG_MN10300_TTYSM_CONSOLE | 
|  | 93 | .cons		= &mn10300_serial_console, | 
|  | 94 | #endif | 
|  | 95 | }; | 
|  | 96 |  | 
|  | 97 | static unsigned int mn10300_serial_tx_empty(struct uart_port *); | 
|  | 98 | static void mn10300_serial_set_mctrl(struct uart_port *, unsigned int mctrl); | 
|  | 99 | static unsigned int mn10300_serial_get_mctrl(struct uart_port *); | 
|  | 100 | static void mn10300_serial_stop_tx(struct uart_port *); | 
|  | 101 | static void mn10300_serial_start_tx(struct uart_port *); | 
|  | 102 | static void mn10300_serial_send_xchar(struct uart_port *, char ch); | 
|  | 103 | static void mn10300_serial_stop_rx(struct uart_port *); | 
|  | 104 | static void mn10300_serial_enable_ms(struct uart_port *); | 
|  | 105 | static void mn10300_serial_break_ctl(struct uart_port *, int ctl); | 
|  | 106 | static int mn10300_serial_startup(struct uart_port *); | 
|  | 107 | static void mn10300_serial_shutdown(struct uart_port *); | 
|  | 108 | static void mn10300_serial_set_termios(struct uart_port *, | 
|  | 109 | struct ktermios *new, | 
|  | 110 | struct ktermios *old); | 
|  | 111 | static const char *mn10300_serial_type(struct uart_port *); | 
|  | 112 | static void mn10300_serial_release_port(struct uart_port *); | 
|  | 113 | static int mn10300_serial_request_port(struct uart_port *); | 
|  | 114 | static void mn10300_serial_config_port(struct uart_port *, int); | 
|  | 115 | static int mn10300_serial_verify_port(struct uart_port *, | 
|  | 116 | struct serial_struct *); | 
|  | 117 |  | 
|  | 118 | static const struct uart_ops mn10300_serial_ops = { | 
|  | 119 | .tx_empty	= mn10300_serial_tx_empty, | 
|  | 120 | .set_mctrl	= mn10300_serial_set_mctrl, | 
|  | 121 | .get_mctrl	= mn10300_serial_get_mctrl, | 
|  | 122 | .stop_tx	= mn10300_serial_stop_tx, | 
|  | 123 | .start_tx	= mn10300_serial_start_tx, | 
|  | 124 | .send_xchar	= mn10300_serial_send_xchar, | 
|  | 125 | .stop_rx	= mn10300_serial_stop_rx, | 
|  | 126 | .enable_ms	= mn10300_serial_enable_ms, | 
|  | 127 | .break_ctl	= mn10300_serial_break_ctl, | 
|  | 128 | .startup	= mn10300_serial_startup, | 
|  | 129 | .shutdown	= mn10300_serial_shutdown, | 
|  | 130 | .set_termios	= mn10300_serial_set_termios, | 
|  | 131 | .type		= mn10300_serial_type, | 
|  | 132 | .release_port	= mn10300_serial_release_port, | 
|  | 133 | .request_port	= mn10300_serial_request_port, | 
|  | 134 | .config_port	= mn10300_serial_config_port, | 
|  | 135 | .verify_port	= mn10300_serial_verify_port, | 
|  | 136 | }; | 
|  | 137 |  | 
|  | 138 | static irqreturn_t mn10300_serial_interrupt(int irq, void *dev_id); | 
|  | 139 |  | 
|  | 140 | /* | 
|  | 141 | * the first on-chip serial port: ttySM0 (aka SIF0) | 
|  | 142 | */ | 
|  | 143 | #ifdef CONFIG_MN10300_TTYSM0 | 
|  | 144 | struct mn10300_serial_port mn10300_serial_port_sif0 = { | 
|  | 145 | .uart.ops	= &mn10300_serial_ops, | 
|  | 146 | .uart.membase	= (void __iomem *) &SC0CTR, | 
|  | 147 | .uart.mapbase	= (unsigned long) &SC0CTR, | 
|  | 148 | .uart.iotype	= UPIO_MEM, | 
|  | 149 | .uart.irq	= 0, | 
|  | 150 | .uart.uartclk	= 0, /* MN10300_IOCLK, */ | 
|  | 151 | .uart.fifosize	= 1, | 
|  | 152 | .uart.flags	= UPF_BOOT_AUTOCONF, | 
|  | 153 | .uart.line	= 0, | 
|  | 154 | .uart.type	= PORT_MN10300, | 
|  | 155 | .uart.lock	= | 
|  | 156 | __SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif0.uart.lock), | 
|  | 157 | .name		= "ttySM0", | 
|  | 158 | ._iobase	= &SC0CTR, | 
|  | 159 | ._control	= &SC0CTR, | 
|  | 160 | ._status	= (volatile u8 *) &SC0STR, | 
|  | 161 | ._intr		= &SC0ICR, | 
|  | 162 | ._rxb		= &SC0RXB, | 
|  | 163 | ._txb		= &SC0TXB, | 
|  | 164 | .rx_name	= "ttySM0/Rx", | 
|  | 165 | .tx_name	= "ttySM0/Tx", | 
|  | 166 | #ifdef CONFIG_MN10300_TTYSM0_TIMER8 | 
|  | 167 | .tm_name	= "ttySM0/Timer8", | 
|  | 168 | ._tmxmd		= &TM8MD, | 
|  | 169 | ._tmxbr		= &TM8BR, | 
|  | 170 | ._tmicr		= &TM8ICR, | 
|  | 171 | .tm_irq		= TM8IRQ, | 
|  | 172 | .div_timer	= MNSCx_DIV_TIMER_16BIT, | 
|  | 173 | #else /* CONFIG_MN10300_TTYSM0_TIMER2 */ | 
|  | 174 | .tm_name	= "ttySM0/Timer2", | 
|  | 175 | ._tmxmd		= &TM2MD, | 
|  | 176 | ._tmxbr		= (volatile u16 *) &TM2BR, | 
|  | 177 | ._tmicr		= &TM2ICR, | 
|  | 178 | .tm_irq		= TM2IRQ, | 
|  | 179 | .div_timer	= MNSCx_DIV_TIMER_8BIT, | 
|  | 180 | #endif | 
|  | 181 | .rx_irq		= SC0RXIRQ, | 
|  | 182 | .tx_irq		= SC0TXIRQ, | 
|  | 183 | .rx_icr		= &GxICR(SC0RXIRQ), | 
|  | 184 | .tx_icr		= &GxICR(SC0TXIRQ), | 
|  | 185 | .clock_src	= MNSCx_CLOCK_SRC_IOCLK, | 
|  | 186 | .options	= 0, | 
|  | 187 | #ifdef CONFIG_GDBSTUB_ON_TTYSM0 | 
|  | 188 | .gdbstub	= 1, | 
|  | 189 | #endif | 
|  | 190 | }; | 
|  | 191 | #endif /* CONFIG_MN10300_TTYSM0 */ | 
|  | 192 |  | 
|  | 193 | /* | 
|  | 194 | * the second on-chip serial port: ttySM1 (aka SIF1) | 
|  | 195 | */ | 
|  | 196 | #ifdef CONFIG_MN10300_TTYSM1 | 
|  | 197 | struct mn10300_serial_port mn10300_serial_port_sif1 = { | 
|  | 198 | .uart.ops	= &mn10300_serial_ops, | 
|  | 199 | .uart.membase	= (void __iomem *) &SC1CTR, | 
|  | 200 | .uart.mapbase	= (unsigned long) &SC1CTR, | 
|  | 201 | .uart.iotype	= UPIO_MEM, | 
|  | 202 | .uart.irq	= 0, | 
|  | 203 | .uart.uartclk	= 0, /* MN10300_IOCLK, */ | 
|  | 204 | .uart.fifosize	= 1, | 
|  | 205 | .uart.flags	= UPF_BOOT_AUTOCONF, | 
|  | 206 | .uart.line	= 1, | 
|  | 207 | .uart.type	= PORT_MN10300, | 
|  | 208 | .uart.lock	= | 
|  | 209 | __SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif1.uart.lock), | 
|  | 210 | .name		= "ttySM1", | 
|  | 211 | ._iobase	= &SC1CTR, | 
|  | 212 | ._control	= &SC1CTR, | 
|  | 213 | ._status	= (volatile u8 *) &SC1STR, | 
|  | 214 | ._intr		= &SC1ICR, | 
|  | 215 | ._rxb		= &SC1RXB, | 
|  | 216 | ._txb		= &SC1TXB, | 
|  | 217 | .rx_name	= "ttySM1/Rx", | 
|  | 218 | .tx_name	= "ttySM1/Tx", | 
|  | 219 | #ifdef CONFIG_MN10300_TTYSM1_TIMER9 | 
|  | 220 | .tm_name	= "ttySM1/Timer9", | 
|  | 221 | ._tmxmd		= &TM9MD, | 
|  | 222 | ._tmxbr		= &TM9BR, | 
|  | 223 | ._tmicr		= &TM9ICR, | 
|  | 224 | .tm_irq		= TM9IRQ, | 
|  | 225 | .div_timer	= MNSCx_DIV_TIMER_16BIT, | 
|  | 226 | #else /* CONFIG_MN10300_TTYSM1_TIMER3 */ | 
|  | 227 | .tm_name	= "ttySM1/Timer3", | 
|  | 228 | ._tmxmd		= &TM3MD, | 
|  | 229 | ._tmxbr		= (volatile u16 *) &TM3BR, | 
|  | 230 | ._tmicr		= &TM3ICR, | 
|  | 231 | .tm_irq		= TM3IRQ, | 
|  | 232 | .div_timer	= MNSCx_DIV_TIMER_8BIT, | 
|  | 233 | #endif | 
|  | 234 | .rx_irq		= SC1RXIRQ, | 
|  | 235 | .tx_irq		= SC1TXIRQ, | 
|  | 236 | .rx_icr		= &GxICR(SC1RXIRQ), | 
|  | 237 | .tx_icr		= &GxICR(SC1TXIRQ), | 
|  | 238 | .clock_src	= MNSCx_CLOCK_SRC_IOCLK, | 
|  | 239 | .options	= 0, | 
|  | 240 | #ifdef CONFIG_GDBSTUB_ON_TTYSM1 | 
|  | 241 | .gdbstub	= 1, | 
|  | 242 | #endif | 
|  | 243 | }; | 
|  | 244 | #endif /* CONFIG_MN10300_TTYSM1 */ | 
|  | 245 |  | 
|  | 246 | /* | 
|  | 247 | * the third on-chip serial port: ttySM2 (aka SIF2) | 
|  | 248 | */ | 
|  | 249 | #ifdef CONFIG_MN10300_TTYSM2 | 
|  | 250 | struct mn10300_serial_port mn10300_serial_port_sif2 = { | 
|  | 251 | .uart.ops	= &mn10300_serial_ops, | 
|  | 252 | .uart.membase	= (void __iomem *) &SC2CTR, | 
|  | 253 | .uart.mapbase	= (unsigned long) &SC2CTR, | 
|  | 254 | .uart.iotype	= UPIO_MEM, | 
|  | 255 | .uart.irq	= 0, | 
|  | 256 | .uart.uartclk	= 0, /* MN10300_IOCLK, */ | 
|  | 257 | .uart.fifosize	= 1, | 
|  | 258 | .uart.flags	= UPF_BOOT_AUTOCONF, | 
|  | 259 | .uart.line	= 2, | 
|  | 260 | #ifdef CONFIG_MN10300_TTYSM2_CTS | 
|  | 261 | .uart.type	= PORT_MN10300_CTS, | 
|  | 262 | #else | 
|  | 263 | .uart.type	= PORT_MN10300, | 
|  | 264 | #endif | 
|  | 265 | .uart.lock	= | 
|  | 266 | __SPIN_LOCK_UNLOCKED(mn10300_serial_port_sif2.uart.lock), | 
|  | 267 | .name		= "ttySM2", | 
|  | 268 | .rx_name	= "ttySM2/Rx", | 
|  | 269 | .tx_name	= "ttySM2/Tx", | 
|  | 270 | .tm_name	= "ttySM2/Timer10", | 
|  | 271 | ._iobase	= &SC2CTR, | 
|  | 272 | ._control	= &SC2CTR, | 
|  | 273 | ._status	= &SC2STR, | 
|  | 274 | ._intr		= &SC2ICR, | 
|  | 275 | ._rxb		= &SC2RXB, | 
|  | 276 | ._txb		= &SC2TXB, | 
|  | 277 | ._tmxmd		= &TM10MD, | 
|  | 278 | ._tmxbr		= &TM10BR, | 
|  | 279 | ._tmicr		= &TM10ICR, | 
|  | 280 | .tm_irq		= TM10IRQ, | 
|  | 281 | .div_timer	= MNSCx_DIV_TIMER_16BIT, | 
|  | 282 | .rx_irq		= SC2RXIRQ, | 
|  | 283 | .tx_irq		= SC2TXIRQ, | 
|  | 284 | .rx_icr		= &GxICR(SC2RXIRQ), | 
|  | 285 | .tx_icr		= &GxICR(SC2TXIRQ), | 
|  | 286 | .clock_src	= MNSCx_CLOCK_SRC_IOCLK, | 
|  | 287 | #ifdef CONFIG_MN10300_TTYSM2_CTS | 
|  | 288 | .options	= MNSCx_OPT_CTS, | 
|  | 289 | #else | 
|  | 290 | .options	= 0, | 
|  | 291 | #endif | 
|  | 292 | #ifdef CONFIG_GDBSTUB_ON_TTYSM2 | 
|  | 293 | .gdbstub	= 1, | 
|  | 294 | #endif | 
|  | 295 | }; | 
|  | 296 | #endif /* CONFIG_MN10300_TTYSM2 */ | 
|  | 297 |  | 
|  | 298 |  | 
|  | 299 | /* | 
|  | 300 | * list of available serial ports | 
|  | 301 | */ | 
|  | 302 | struct mn10300_serial_port *mn10300_serial_ports[NR_UARTS + 1] = { | 
|  | 303 | #ifdef CONFIG_MN10300_TTYSM0 | 
|  | 304 | [0]	= &mn10300_serial_port_sif0, | 
|  | 305 | #endif | 
|  | 306 | #ifdef CONFIG_MN10300_TTYSM1 | 
|  | 307 | [1]	= &mn10300_serial_port_sif1, | 
|  | 308 | #endif | 
|  | 309 | #ifdef CONFIG_MN10300_TTYSM2 | 
|  | 310 | [2]	= &mn10300_serial_port_sif2, | 
|  | 311 | #endif | 
|  | 312 | [NR_UARTS] = NULL, | 
|  | 313 | }; | 
|  | 314 |  | 
|  | 315 |  | 
|  | 316 | /* | 
|  | 317 | * we abuse the serial ports' baud timers' interrupt lines to get the ability | 
|  | 318 | * to deliver interrupts to userspace as we use the ports' interrupt lines to | 
|  | 319 | * do virtual DMA on account of the ports having no hardware FIFOs | 
|  | 320 | * | 
|  | 321 | * we can generate an interrupt manually in the assembly stubs by writing to | 
|  | 322 | * the enable and detect bits in the interrupt control register, so all we need | 
|  | 323 | * to do here is disable the interrupt line | 
|  | 324 | * | 
|  | 325 | * note that we can't just leave the line enabled as the baud rate timer *also* | 
|  | 326 | * generates interrupts | 
|  | 327 | */ | 
|  | 328 | static void mn10300_serial_mask_ack(unsigned int irq) | 
|  | 329 | { | 
|  | 330 | u16 tmp; | 
|  | 331 | GxICR(irq) = GxICR_LEVEL_6; | 
|  | 332 | tmp = GxICR(irq); /* flush write buffer */ | 
|  | 333 | } | 
|  | 334 |  | 
|  | 335 | static void mn10300_serial_nop(unsigned int irq) | 
|  | 336 | { | 
|  | 337 | } | 
|  | 338 |  | 
|  | 339 | static struct irq_chip mn10300_serial_pic = { | 
|  | 340 | .name		= "mnserial", | 
|  | 341 | .ack		= mn10300_serial_mask_ack, | 
|  | 342 | .mask		= mn10300_serial_mask_ack, | 
|  | 343 | .mask_ack	= mn10300_serial_mask_ack, | 
|  | 344 | .unmask		= mn10300_serial_nop, | 
|  | 345 | .end		= mn10300_serial_nop, | 
|  | 346 | }; | 
|  | 347 |  | 
|  | 348 |  | 
|  | 349 | /* | 
|  | 350 | * serial virtual DMA interrupt jump table | 
|  | 351 | */ | 
|  | 352 | struct mn10300_serial_int mn10300_serial_int_tbl[NR_IRQS]; | 
|  | 353 |  | 
|  | 354 | static void mn10300_serial_dis_tx_intr(struct mn10300_serial_port *port) | 
|  | 355 | { | 
|  | 356 | u16 x; | 
|  | 357 | *port->tx_icr = GxICR_LEVEL_1 | GxICR_DETECT; | 
|  | 358 | x = *port->tx_icr; | 
|  | 359 | } | 
|  | 360 |  | 
|  | 361 | static void mn10300_serial_en_tx_intr(struct mn10300_serial_port *port) | 
|  | 362 | { | 
|  | 363 | u16 x; | 
|  | 364 | *port->tx_icr = GxICR_LEVEL_1 | GxICR_ENABLE; | 
|  | 365 | x = *port->tx_icr; | 
|  | 366 | } | 
|  | 367 |  | 
|  | 368 | static void mn10300_serial_dis_rx_intr(struct mn10300_serial_port *port) | 
|  | 369 | { | 
|  | 370 | u16 x; | 
|  | 371 | *port->rx_icr = GxICR_LEVEL_1 | GxICR_DETECT; | 
|  | 372 | x = *port->rx_icr; | 
|  | 373 | } | 
|  | 374 |  | 
|  | 375 | /* | 
|  | 376 | * multi-bit equivalent of test_and_clear_bit() | 
|  | 377 | */ | 
|  | 378 | static int mask_test_and_clear(volatile u8 *ptr, u8 mask) | 
|  | 379 | { | 
|  | 380 | u32 epsw; | 
|  | 381 | asm volatile("	bclr	%1,(%2)		\n" | 
|  | 382 | "	mov	epsw,%0		\n" | 
|  | 383 | : "=d"(epsw) : "d"(mask), "a"(ptr)); | 
|  | 384 | return !(epsw & EPSW_FLAG_Z); | 
|  | 385 | } | 
|  | 386 |  | 
|  | 387 | /* | 
|  | 388 | * receive chars from the ring buffer for this serial port | 
|  | 389 | * - must do break detection here (not done in the UART) | 
|  | 390 | */ | 
|  | 391 | static void mn10300_serial_receive_interrupt(struct mn10300_serial_port *port) | 
|  | 392 | { | 
|  | 393 | struct uart_icount *icount = &port->uart.icount; | 
| David Howells | 34492b5 | 2008-07-16 21:54:01 +0100 | [diff] [blame] | 394 | struct tty_struct *tty = port->uart.info->port.tty; | 
| David Howells | b920de1 | 2008-02-08 04:19:31 -0800 | [diff] [blame] | 395 | unsigned ix; | 
|  | 396 | int count; | 
|  | 397 | u8 st, ch, push, status, overrun; | 
|  | 398 |  | 
|  | 399 | _enter("%s", port->name); | 
|  | 400 |  | 
|  | 401 | push = 0; | 
|  | 402 |  | 
|  | 403 | count = CIRC_CNT(port->rx_inp, port->rx_outp, MNSC_BUFFER_SIZE); | 
|  | 404 | count = tty_buffer_request_room(tty, count); | 
|  | 405 | if (count == 0) { | 
|  | 406 | if (!tty->low_latency) | 
|  | 407 | tty_flip_buffer_push(tty); | 
|  | 408 | return; | 
|  | 409 | } | 
|  | 410 |  | 
|  | 411 | try_again: | 
|  | 412 | /* pull chars out of the hat */ | 
|  | 413 | ix = port->rx_outp; | 
|  | 414 | if (ix == port->rx_inp) { | 
|  | 415 | if (push && !tty->low_latency) | 
|  | 416 | tty_flip_buffer_push(tty); | 
|  | 417 | return; | 
|  | 418 | } | 
|  | 419 |  | 
|  | 420 | ch = port->rx_buffer[ix++]; | 
|  | 421 | st = port->rx_buffer[ix++]; | 
|  | 422 | smp_rmb(); | 
|  | 423 | port->rx_outp = ix & (MNSC_BUFFER_SIZE - 1); | 
|  | 424 | port->uart.icount.rx++; | 
|  | 425 |  | 
|  | 426 | st &= SC01STR_FEF | SC01STR_PEF | SC01STR_OEF; | 
|  | 427 | status = 0; | 
|  | 428 | overrun = 0; | 
|  | 429 |  | 
|  | 430 | /* the UART doesn't detect BREAK, so we have to do that ourselves | 
|  | 431 | * - it starts as a framing error on a NUL character | 
|  | 432 | * - then we count another two NUL characters before issuing TTY_BREAK | 
|  | 433 | * - then we end on a normal char or one that has all the bottom bits | 
|  | 434 | *   zero and the top bits set | 
|  | 435 | */ | 
|  | 436 | switch (port->rx_brk) { | 
|  | 437 | case 0: | 
|  | 438 | /* not breaking at the moment */ | 
|  | 439 | break; | 
|  | 440 |  | 
|  | 441 | case 1: | 
|  | 442 | if (st & SC01STR_FEF && ch == 0) { | 
|  | 443 | port->rx_brk = 2; | 
|  | 444 | goto try_again; | 
|  | 445 | } | 
|  | 446 | goto not_break; | 
|  | 447 |  | 
|  | 448 | case 2: | 
|  | 449 | if (st & SC01STR_FEF && ch == 0) { | 
|  | 450 | port->rx_brk = 3; | 
|  | 451 | _proto("Rx Break Detected"); | 
|  | 452 | icount->brk++; | 
|  | 453 | if (uart_handle_break(&port->uart)) | 
|  | 454 | goto ignore_char; | 
|  | 455 | status |= 1 << TTY_BREAK; | 
|  | 456 | goto insert; | 
|  | 457 | } | 
|  | 458 | goto not_break; | 
|  | 459 |  | 
|  | 460 | default: | 
|  | 461 | if (st & (SC01STR_FEF | SC01STR_PEF | SC01STR_OEF)) | 
|  | 462 | goto try_again; /* still breaking */ | 
|  | 463 |  | 
|  | 464 | port->rx_brk = 0; /* end of the break */ | 
|  | 465 |  | 
|  | 466 | switch (ch) { | 
|  | 467 | case 0xFF: | 
|  | 468 | case 0xFE: | 
|  | 469 | case 0xFC: | 
|  | 470 | case 0xF8: | 
|  | 471 | case 0xF0: | 
|  | 472 | case 0xE0: | 
|  | 473 | case 0xC0: | 
|  | 474 | case 0x80: | 
|  | 475 | case 0x00: | 
|  | 476 | /* discard char at probable break end */ | 
|  | 477 | goto try_again; | 
|  | 478 | } | 
|  | 479 | break; | 
|  | 480 | } | 
|  | 481 |  | 
|  | 482 | process_errors: | 
|  | 483 | /* handle framing error */ | 
|  | 484 | if (st & SC01STR_FEF) { | 
|  | 485 | if (ch == 0) { | 
|  | 486 | /* framing error with NUL char is probably a BREAK */ | 
|  | 487 | port->rx_brk = 1; | 
|  | 488 | goto try_again; | 
|  | 489 | } | 
|  | 490 |  | 
|  | 491 | _proto("Rx Framing Error"); | 
|  | 492 | icount->frame++; | 
|  | 493 | status |= 1 << TTY_FRAME; | 
|  | 494 | } | 
|  | 495 |  | 
|  | 496 | /* handle parity error */ | 
|  | 497 | if (st & SC01STR_PEF) { | 
|  | 498 | _proto("Rx Parity Error"); | 
|  | 499 | icount->parity++; | 
|  | 500 | status = TTY_PARITY; | 
|  | 501 | } | 
|  | 502 |  | 
|  | 503 | /* handle normal char */ | 
|  | 504 | if (status == 0) { | 
|  | 505 | if (uart_handle_sysrq_char(&port->uart, ch)) | 
|  | 506 | goto ignore_char; | 
|  | 507 | status = (1 << TTY_NORMAL); | 
|  | 508 | } | 
|  | 509 |  | 
|  | 510 | /* handle overrun error */ | 
|  | 511 | if (st & SC01STR_OEF) { | 
|  | 512 | if (port->rx_brk) | 
|  | 513 | goto try_again; | 
|  | 514 |  | 
|  | 515 | _proto("Rx Overrun Error"); | 
|  | 516 | icount->overrun++; | 
|  | 517 | overrun = 1; | 
|  | 518 | } | 
|  | 519 |  | 
|  | 520 | insert: | 
|  | 521 | status &= port->uart.read_status_mask; | 
|  | 522 |  | 
|  | 523 | if (!overrun && !(status & port->uart.ignore_status_mask)) { | 
|  | 524 | int flag; | 
|  | 525 |  | 
|  | 526 | if (status & (1 << TTY_BREAK)) | 
|  | 527 | flag = TTY_BREAK; | 
|  | 528 | else if (status & (1 << TTY_PARITY)) | 
|  | 529 | flag = TTY_PARITY; | 
|  | 530 | else if (status & (1 << TTY_FRAME)) | 
|  | 531 | flag = TTY_FRAME; | 
|  | 532 | else | 
|  | 533 | flag = TTY_NORMAL; | 
|  | 534 |  | 
|  | 535 | tty_insert_flip_char(tty, ch, flag); | 
|  | 536 | } | 
|  | 537 |  | 
|  | 538 | /* overrun is special, since it's reported immediately, and doesn't | 
|  | 539 | * affect the current character | 
|  | 540 | */ | 
|  | 541 | if (overrun) | 
|  | 542 | tty_insert_flip_char(tty, 0, TTY_OVERRUN); | 
|  | 543 |  | 
|  | 544 | count--; | 
|  | 545 | if (count <= 0) { | 
|  | 546 | if (!tty->low_latency) | 
|  | 547 | tty_flip_buffer_push(tty); | 
|  | 548 | return; | 
|  | 549 | } | 
|  | 550 |  | 
|  | 551 | ignore_char: | 
|  | 552 | push = 1; | 
|  | 553 | goto try_again; | 
|  | 554 |  | 
|  | 555 | not_break: | 
|  | 556 | port->rx_brk = 0; | 
|  | 557 | goto process_errors; | 
|  | 558 | } | 
|  | 559 |  | 
|  | 560 | /* | 
|  | 561 | * handle an interrupt from the serial transmission "virtual DMA" driver | 
|  | 562 | * - note: the interrupt routine will disable its own interrupts when the Tx | 
|  | 563 | *   buffer is empty | 
|  | 564 | */ | 
|  | 565 | static void mn10300_serial_transmit_interrupt(struct mn10300_serial_port *port) | 
|  | 566 | { | 
|  | 567 | _enter("%s", port->name); | 
|  | 568 |  | 
|  | 569 | if (uart_tx_stopped(&port->uart) || | 
|  | 570 | uart_circ_empty(&port->uart.info->xmit)) | 
|  | 571 | mn10300_serial_dis_tx_intr(port); | 
|  | 572 |  | 
|  | 573 | if (uart_circ_chars_pending(&port->uart.info->xmit) < WAKEUP_CHARS) | 
|  | 574 | uart_write_wakeup(&port->uart); | 
|  | 575 | } | 
|  | 576 |  | 
|  | 577 | /* | 
|  | 578 | * deal with a change in the status of the CTS line | 
|  | 579 | */ | 
|  | 580 | static void mn10300_serial_cts_changed(struct mn10300_serial_port *port, u8 st) | 
|  | 581 | { | 
|  | 582 | u16 ctr; | 
|  | 583 |  | 
|  | 584 | port->tx_cts = st; | 
|  | 585 | port->uart.icount.cts++; | 
|  | 586 |  | 
|  | 587 | /* flip the CTS state selector flag to interrupt when it changes | 
|  | 588 | * back */ | 
|  | 589 | ctr = *port->_control; | 
|  | 590 | ctr ^= SC2CTR_TWS; | 
|  | 591 | *port->_control = ctr; | 
|  | 592 |  | 
|  | 593 | uart_handle_cts_change(&port->uart, st & SC2STR_CTS); | 
|  | 594 | wake_up_interruptible(&port->uart.info->delta_msr_wait); | 
|  | 595 | } | 
|  | 596 |  | 
|  | 597 | /* | 
|  | 598 | * handle a virtual interrupt generated by the lower level "virtual DMA" | 
|  | 599 | * routines (irq is the baud timer interrupt) | 
|  | 600 | */ | 
|  | 601 | static irqreturn_t mn10300_serial_interrupt(int irq, void *dev_id) | 
|  | 602 | { | 
|  | 603 | struct mn10300_serial_port *port = dev_id; | 
|  | 604 | u8 st; | 
|  | 605 |  | 
|  | 606 | spin_lock(&port->uart.lock); | 
|  | 607 |  | 
|  | 608 | if (port->intr_flags) { | 
|  | 609 | _debug("INT %s: %x", port->name, port->intr_flags); | 
|  | 610 |  | 
|  | 611 | if (mask_test_and_clear(&port->intr_flags, MNSCx_RX_AVAIL)) | 
|  | 612 | mn10300_serial_receive_interrupt(port); | 
|  | 613 |  | 
|  | 614 | if (mask_test_and_clear(&port->intr_flags, | 
|  | 615 | MNSCx_TX_SPACE | MNSCx_TX_EMPTY)) | 
|  | 616 | mn10300_serial_transmit_interrupt(port); | 
|  | 617 | } | 
|  | 618 |  | 
|  | 619 | /* the only modem control line amongst the whole lot is CTS on | 
|  | 620 | * serial port 2 */ | 
|  | 621 | if (port->type == PORT_MN10300_CTS) { | 
|  | 622 | st = *port->_status; | 
|  | 623 | if ((port->tx_cts ^ st) & SC2STR_CTS) | 
|  | 624 | mn10300_serial_cts_changed(port, st); | 
|  | 625 | } | 
|  | 626 |  | 
|  | 627 | spin_unlock(&port->uart.lock); | 
|  | 628 |  | 
|  | 629 | return IRQ_HANDLED; | 
|  | 630 | } | 
|  | 631 |  | 
|  | 632 | /* | 
|  | 633 | * return indication of whether the hardware transmit buffer is empty | 
|  | 634 | */ | 
|  | 635 | static unsigned int mn10300_serial_tx_empty(struct uart_port *_port) | 
|  | 636 | { | 
|  | 637 | struct mn10300_serial_port *port = | 
|  | 638 | container_of(_port, struct mn10300_serial_port, uart); | 
|  | 639 |  | 
|  | 640 | _enter("%s", port->name); | 
|  | 641 |  | 
|  | 642 | return (*port->_status & (SC01STR_TXF | SC01STR_TBF)) ? | 
|  | 643 | 0 : TIOCSER_TEMT; | 
|  | 644 | } | 
|  | 645 |  | 
|  | 646 | /* | 
|  | 647 | * set the modem control lines (we don't have any) | 
|  | 648 | */ | 
|  | 649 | static void mn10300_serial_set_mctrl(struct uart_port *_port, | 
|  | 650 | unsigned int mctrl) | 
|  | 651 | { | 
|  | 652 | struct mn10300_serial_port *port = | 
|  | 653 | container_of(_port, struct mn10300_serial_port, uart); | 
|  | 654 |  | 
|  | 655 | _enter("%s,%x", port->name, mctrl); | 
|  | 656 | } | 
|  | 657 |  | 
|  | 658 | /* | 
|  | 659 | * get the modem control line statuses | 
|  | 660 | */ | 
|  | 661 | static unsigned int mn10300_serial_get_mctrl(struct uart_port *_port) | 
|  | 662 | { | 
|  | 663 | struct mn10300_serial_port *port = | 
|  | 664 | container_of(_port, struct mn10300_serial_port, uart); | 
|  | 665 |  | 
|  | 666 | _enter("%s", port->name); | 
|  | 667 |  | 
|  | 668 | if (port->type == PORT_MN10300_CTS && !(*port->_status & SC2STR_CTS)) | 
|  | 669 | return TIOCM_CAR | TIOCM_DSR; | 
|  | 670 |  | 
|  | 671 | return TIOCM_CAR | TIOCM_CTS | TIOCM_DSR; | 
|  | 672 | } | 
|  | 673 |  | 
|  | 674 | /* | 
|  | 675 | * stop transmitting characters | 
|  | 676 | */ | 
|  | 677 | static void mn10300_serial_stop_tx(struct uart_port *_port) | 
|  | 678 | { | 
|  | 679 | struct mn10300_serial_port *port = | 
|  | 680 | container_of(_port, struct mn10300_serial_port, uart); | 
|  | 681 |  | 
|  | 682 | _enter("%s", port->name); | 
|  | 683 |  | 
|  | 684 | /* disable the virtual DMA */ | 
|  | 685 | mn10300_serial_dis_tx_intr(port); | 
|  | 686 | } | 
|  | 687 |  | 
|  | 688 | /* | 
|  | 689 | * start transmitting characters | 
|  | 690 | * - jump-start transmission if it has stalled | 
|  | 691 | *   - enable the serial Tx interrupt (used by the virtual DMA controller) | 
|  | 692 | *   - force an interrupt to happen if necessary | 
|  | 693 | */ | 
|  | 694 | static void mn10300_serial_start_tx(struct uart_port *_port) | 
|  | 695 | { | 
|  | 696 | struct mn10300_serial_port *port = | 
|  | 697 | container_of(_port, struct mn10300_serial_port, uart); | 
|  | 698 |  | 
|  | 699 | u16 x; | 
|  | 700 |  | 
|  | 701 | _enter("%s{%lu}", | 
|  | 702 | port->name, | 
|  | 703 | CIRC_CNT(&port->uart.info->xmit.head, | 
|  | 704 | &port->uart.info->xmit.tail, | 
|  | 705 | UART_XMIT_SIZE)); | 
|  | 706 |  | 
|  | 707 | /* kick the virtual DMA controller */ | 
|  | 708 | x = *port->tx_icr; | 
|  | 709 | x |= GxICR_ENABLE; | 
|  | 710 |  | 
|  | 711 | if (*port->_status & SC01STR_TBF) | 
|  | 712 | x &= ~(GxICR_REQUEST | GxICR_DETECT); | 
|  | 713 | else | 
|  | 714 | x |= GxICR_REQUEST | GxICR_DETECT; | 
|  | 715 |  | 
|  | 716 | _debug("CTR=%04hx ICR=%02hx STR=%04x TMD=%02hx TBR=%04hx ICR=%04hx", | 
|  | 717 | *port->_control, *port->_intr, *port->_status, | 
|  | 718 | *port->_tmxmd, *port->_tmxbr, *port->tx_icr); | 
|  | 719 |  | 
|  | 720 | *port->tx_icr = x; | 
|  | 721 | x = *port->tx_icr; | 
|  | 722 | } | 
|  | 723 |  | 
|  | 724 | /* | 
|  | 725 | * transmit a high-priority XON/XOFF character | 
|  | 726 | */ | 
|  | 727 | static void mn10300_serial_send_xchar(struct uart_port *_port, char ch) | 
|  | 728 | { | 
|  | 729 | struct mn10300_serial_port *port = | 
|  | 730 | container_of(_port, struct mn10300_serial_port, uart); | 
|  | 731 |  | 
|  | 732 | _enter("%s,%02x", port->name, ch); | 
|  | 733 |  | 
|  | 734 | if (likely(port->gdbstub)) { | 
|  | 735 | port->tx_xchar = ch; | 
|  | 736 | if (ch) | 
|  | 737 | mn10300_serial_en_tx_intr(port); | 
|  | 738 | } | 
|  | 739 | } | 
|  | 740 |  | 
|  | 741 | /* | 
|  | 742 | * stop receiving characters | 
|  | 743 | * - called whilst the port is being closed | 
|  | 744 | */ | 
|  | 745 | static void mn10300_serial_stop_rx(struct uart_port *_port) | 
|  | 746 | { | 
|  | 747 | struct mn10300_serial_port *port = | 
|  | 748 | container_of(_port, struct mn10300_serial_port, uart); | 
|  | 749 |  | 
|  | 750 | u16 ctr; | 
|  | 751 |  | 
|  | 752 | _enter("%s", port->name); | 
|  | 753 |  | 
|  | 754 | ctr = *port->_control; | 
|  | 755 | ctr &= ~SC01CTR_RXE; | 
|  | 756 | *port->_control = ctr; | 
|  | 757 |  | 
|  | 758 | mn10300_serial_dis_rx_intr(port); | 
|  | 759 | } | 
|  | 760 |  | 
|  | 761 | /* | 
|  | 762 | * enable modem status interrupts | 
|  | 763 | */ | 
|  | 764 | static void mn10300_serial_enable_ms(struct uart_port *_port) | 
|  | 765 | { | 
|  | 766 | struct mn10300_serial_port *port = | 
|  | 767 | container_of(_port, struct mn10300_serial_port, uart); | 
|  | 768 |  | 
|  | 769 | u16 ctr, cts; | 
|  | 770 |  | 
|  | 771 | _enter("%s", port->name); | 
|  | 772 |  | 
|  | 773 | if (port->type == PORT_MN10300_CTS) { | 
|  | 774 | /* want to interrupt when CTS goes low if CTS is now high and | 
|  | 775 | * vice versa | 
|  | 776 | */ | 
|  | 777 | port->tx_cts = *port->_status; | 
|  | 778 |  | 
|  | 779 | cts = (port->tx_cts & SC2STR_CTS) ? | 
|  | 780 | SC2CTR_TWE : SC2CTR_TWE | SC2CTR_TWS; | 
|  | 781 |  | 
|  | 782 | ctr = *port->_control; | 
|  | 783 | ctr &= ~SC2CTR_TWS; | 
|  | 784 | ctr |= cts; | 
|  | 785 | *port->_control = ctr; | 
|  | 786 |  | 
|  | 787 | mn10300_serial_en_tx_intr(port); | 
|  | 788 | } | 
|  | 789 | } | 
|  | 790 |  | 
|  | 791 | /* | 
|  | 792 | * transmit or cease transmitting a break signal | 
|  | 793 | */ | 
|  | 794 | static void mn10300_serial_break_ctl(struct uart_port *_port, int ctl) | 
|  | 795 | { | 
|  | 796 | struct mn10300_serial_port *port = | 
|  | 797 | container_of(_port, struct mn10300_serial_port, uart); | 
|  | 798 |  | 
|  | 799 | _enter("%s,%d", port->name, ctl); | 
|  | 800 |  | 
|  | 801 | if (ctl) { | 
|  | 802 | /* tell the virtual DMA handler to assert BREAK */ | 
|  | 803 | port->tx_break = 1; | 
|  | 804 | mn10300_serial_en_tx_intr(port); | 
|  | 805 | } else { | 
|  | 806 | port->tx_break = 0; | 
|  | 807 | *port->_control &= ~SC01CTR_BKE; | 
|  | 808 | mn10300_serial_en_tx_intr(port); | 
|  | 809 | } | 
|  | 810 | } | 
|  | 811 |  | 
|  | 812 | /* | 
|  | 813 | * grab the interrupts and enable the port for reception | 
|  | 814 | */ | 
|  | 815 | static int mn10300_serial_startup(struct uart_port *_port) | 
|  | 816 | { | 
|  | 817 | struct mn10300_serial_port *port = | 
|  | 818 | container_of(_port, struct mn10300_serial_port, uart); | 
|  | 819 | struct mn10300_serial_int *pint; | 
|  | 820 |  | 
|  | 821 | _enter("%s{%d}", port->name, port->gdbstub); | 
|  | 822 |  | 
|  | 823 | if (unlikely(port->gdbstub)) | 
|  | 824 | return -EBUSY; | 
|  | 825 |  | 
|  | 826 | /* allocate an Rx buffer for the virtual DMA handler */ | 
|  | 827 | port->rx_buffer = kmalloc(MNSC_BUFFER_SIZE, GFP_KERNEL); | 
|  | 828 | if (!port->rx_buffer) | 
|  | 829 | return -ENOMEM; | 
|  | 830 |  | 
|  | 831 | port->rx_inp = port->rx_outp = 0; | 
|  | 832 |  | 
|  | 833 | /* finally, enable the device */ | 
|  | 834 | *port->_intr = SC01ICR_TI; | 
|  | 835 | *port->_control |= SC01CTR_TXE | SC01CTR_RXE; | 
|  | 836 |  | 
|  | 837 | pint = &mn10300_serial_int_tbl[port->rx_irq]; | 
|  | 838 | pint->port = port; | 
|  | 839 | pint->vdma = mn10300_serial_vdma_rx_handler; | 
|  | 840 | pint = &mn10300_serial_int_tbl[port->tx_irq]; | 
|  | 841 | pint->port = port; | 
|  | 842 | pint->vdma = mn10300_serial_vdma_tx_handler; | 
|  | 843 |  | 
|  | 844 | set_intr_level(port->rx_irq, GxICR_LEVEL_1); | 
|  | 845 | set_intr_level(port->tx_irq, GxICR_LEVEL_1); | 
|  | 846 | set_irq_chip(port->tm_irq, &mn10300_serial_pic); | 
|  | 847 |  | 
|  | 848 | if (request_irq(port->rx_irq, mn10300_serial_interrupt, | 
|  | 849 | IRQF_DISABLED, port->rx_name, port) < 0) | 
|  | 850 | goto error; | 
|  | 851 |  | 
|  | 852 | if (request_irq(port->tx_irq, mn10300_serial_interrupt, | 
|  | 853 | IRQF_DISABLED, port->tx_name, port) < 0) | 
|  | 854 | goto error2; | 
|  | 855 |  | 
|  | 856 | if (request_irq(port->tm_irq, mn10300_serial_interrupt, | 
|  | 857 | IRQF_DISABLED, port->tm_name, port) < 0) | 
|  | 858 | goto error3; | 
|  | 859 | mn10300_serial_mask_ack(port->tm_irq); | 
|  | 860 |  | 
|  | 861 | return 0; | 
|  | 862 |  | 
|  | 863 | error3: | 
|  | 864 | free_irq(port->tx_irq, port); | 
|  | 865 | error2: | 
|  | 866 | free_irq(port->rx_irq, port); | 
|  | 867 | error: | 
|  | 868 | kfree(port->rx_buffer); | 
|  | 869 | port->rx_buffer = NULL; | 
|  | 870 | return -EBUSY; | 
|  | 871 | } | 
|  | 872 |  | 
|  | 873 | /* | 
|  | 874 | * shutdown the port and release interrupts | 
|  | 875 | */ | 
|  | 876 | static void mn10300_serial_shutdown(struct uart_port *_port) | 
|  | 877 | { | 
|  | 878 | struct mn10300_serial_port *port = | 
|  | 879 | container_of(_port, struct mn10300_serial_port, uart); | 
|  | 880 |  | 
|  | 881 | _enter("%s", port->name); | 
|  | 882 |  | 
|  | 883 | /* disable the serial port and its baud rate timer */ | 
|  | 884 | port->tx_break = 0; | 
|  | 885 | *port->_control &= ~(SC01CTR_TXE | SC01CTR_RXE | SC01CTR_BKE); | 
|  | 886 | *port->_tmxmd = 0; | 
|  | 887 |  | 
|  | 888 | if (port->rx_buffer) { | 
|  | 889 | void *buf = port->rx_buffer; | 
|  | 890 | port->rx_buffer = NULL; | 
|  | 891 | kfree(buf); | 
|  | 892 | } | 
|  | 893 |  | 
|  | 894 | /* disable all intrs */ | 
|  | 895 | free_irq(port->tm_irq, port); | 
|  | 896 | free_irq(port->rx_irq, port); | 
|  | 897 | free_irq(port->tx_irq, port); | 
|  | 898 |  | 
|  | 899 | *port->rx_icr = GxICR_LEVEL_1; | 
|  | 900 | *port->tx_icr = GxICR_LEVEL_1; | 
|  | 901 | } | 
|  | 902 |  | 
|  | 903 | /* | 
|  | 904 | * this routine is called to set the UART divisor registers to match the | 
|  | 905 | * specified baud rate for a serial port. | 
|  | 906 | */ | 
|  | 907 | static void mn10300_serial_change_speed(struct mn10300_serial_port *port, | 
|  | 908 | struct ktermios *new, | 
|  | 909 | struct ktermios *old) | 
|  | 910 | { | 
|  | 911 | unsigned long flags; | 
|  | 912 | unsigned long ioclk = port->ioclk; | 
|  | 913 | unsigned cflag; | 
|  | 914 | int baud, bits, xdiv, tmp; | 
|  | 915 | u16 tmxbr, scxctr; | 
|  | 916 | u8 tmxmd, battempt; | 
|  | 917 | u8 div_timer = port->div_timer; | 
|  | 918 |  | 
|  | 919 | _enter("%s{%lu}", port->name, ioclk); | 
|  | 920 |  | 
|  | 921 | /* byte size and parity */ | 
|  | 922 | cflag = new->c_cflag; | 
|  | 923 | switch (cflag & CSIZE) { | 
|  | 924 | case CS7: scxctr = SC01CTR_CLN_7BIT; bits = 9;  break; | 
|  | 925 | case CS8: scxctr = SC01CTR_CLN_8BIT; bits = 10; break; | 
|  | 926 | default:  scxctr = SC01CTR_CLN_8BIT; bits = 10; break; | 
|  | 927 | } | 
|  | 928 |  | 
|  | 929 | if (cflag & CSTOPB) { | 
|  | 930 | scxctr |= SC01CTR_STB_2BIT; | 
|  | 931 | bits++; | 
|  | 932 | } | 
|  | 933 |  | 
|  | 934 | if (cflag & PARENB) { | 
|  | 935 | bits++; | 
|  | 936 | if (cflag & PARODD) | 
|  | 937 | scxctr |= SC01CTR_PB_ODD; | 
|  | 938 | #ifdef CMSPAR | 
|  | 939 | else if (cflag & CMSPAR) | 
|  | 940 | scxctr |= SC01CTR_PB_FIXED0; | 
|  | 941 | #endif | 
|  | 942 | else | 
|  | 943 | scxctr |= SC01CTR_PB_EVEN; | 
|  | 944 | } | 
|  | 945 |  | 
|  | 946 | /* Determine divisor based on baud rate */ | 
|  | 947 | battempt = 0; | 
|  | 948 |  | 
|  | 949 | if (div_timer == MNSCx_DIV_TIMER_16BIT) | 
|  | 950 | scxctr |= SC0CTR_CK_TM8UFLOW_8; /* ( == SC1CTR_CK_TM9UFLOW_8 | 
|  | 951 | *   == SC2CTR_CK_TM10UFLOW) */ | 
|  | 952 | else if (div_timer == MNSCx_DIV_TIMER_8BIT) | 
|  | 953 | scxctr |= SC0CTR_CK_TM2UFLOW_8; | 
|  | 954 |  | 
|  | 955 | try_alternative: | 
|  | 956 | baud = uart_get_baud_rate(&port->uart, new, old, 0, | 
|  | 957 | port->ioclk / 8); | 
|  | 958 |  | 
|  | 959 | _debug("ALT %d [baud %d]", battempt, baud); | 
|  | 960 |  | 
|  | 961 | if (!baud) | 
|  | 962 | baud = 9600;	/* B0 transition handled in rs_set_termios */ | 
|  | 963 | xdiv = 1; | 
|  | 964 | if (baud == 134) { | 
|  | 965 | baud = 269;	/* 134 is really 134.5 */ | 
|  | 966 | xdiv = 2; | 
|  | 967 | } | 
|  | 968 |  | 
|  | 969 | if (baud == 38400 && | 
|  | 970 | (port->uart.flags & UPF_SPD_MASK) == UPF_SPD_CUST | 
|  | 971 | ) { | 
|  | 972 | _debug("CUSTOM %u", port->uart.custom_divisor); | 
|  | 973 |  | 
|  | 974 | if (div_timer == MNSCx_DIV_TIMER_16BIT) { | 
|  | 975 | if (port->uart.custom_divisor <= 65535) { | 
|  | 976 | tmxmd = TM8MD_SRC_IOCLK; | 
|  | 977 | tmxbr = port->uart.custom_divisor; | 
|  | 978 | port->uart.uartclk = ioclk; | 
|  | 979 | goto timer_okay; | 
|  | 980 | } | 
|  | 981 | if (port->uart.custom_divisor / 8 <= 65535) { | 
|  | 982 | tmxmd = TM8MD_SRC_IOCLK_8; | 
|  | 983 | tmxbr = port->uart.custom_divisor / 8; | 
|  | 984 | port->uart.custom_divisor = tmxbr * 8; | 
|  | 985 | port->uart.uartclk = ioclk / 8; | 
|  | 986 | goto timer_okay; | 
|  | 987 | } | 
|  | 988 | if (port->uart.custom_divisor / 32 <= 65535) { | 
|  | 989 | tmxmd = TM8MD_SRC_IOCLK_32; | 
|  | 990 | tmxbr = port->uart.custom_divisor / 32; | 
|  | 991 | port->uart.custom_divisor = tmxbr * 32; | 
|  | 992 | port->uart.uartclk = ioclk / 32; | 
|  | 993 | goto timer_okay; | 
|  | 994 | } | 
|  | 995 |  | 
|  | 996 | } else if (div_timer == MNSCx_DIV_TIMER_8BIT) { | 
|  | 997 | if (port->uart.custom_divisor <= 255) { | 
|  | 998 | tmxmd = TM2MD_SRC_IOCLK; | 
|  | 999 | tmxbr = port->uart.custom_divisor; | 
|  | 1000 | port->uart.uartclk = ioclk; | 
|  | 1001 | goto timer_okay; | 
|  | 1002 | } | 
|  | 1003 | if (port->uart.custom_divisor / 8 <= 255) { | 
|  | 1004 | tmxmd = TM2MD_SRC_IOCLK_8; | 
|  | 1005 | tmxbr = port->uart.custom_divisor / 8; | 
|  | 1006 | port->uart.custom_divisor = tmxbr * 8; | 
|  | 1007 | port->uart.uartclk = ioclk / 8; | 
|  | 1008 | goto timer_okay; | 
|  | 1009 | } | 
|  | 1010 | if (port->uart.custom_divisor / 32 <= 255) { | 
|  | 1011 | tmxmd = TM2MD_SRC_IOCLK_32; | 
|  | 1012 | tmxbr = port->uart.custom_divisor / 32; | 
|  | 1013 | port->uart.custom_divisor = tmxbr * 32; | 
|  | 1014 | port->uart.uartclk = ioclk / 32; | 
|  | 1015 | goto timer_okay; | 
|  | 1016 | } | 
|  | 1017 | } | 
|  | 1018 | } | 
|  | 1019 |  | 
|  | 1020 | switch (div_timer) { | 
|  | 1021 | case MNSCx_DIV_TIMER_16BIT: | 
|  | 1022 | port->uart.uartclk = ioclk; | 
|  | 1023 | tmxmd = TM8MD_SRC_IOCLK; | 
|  | 1024 | tmxbr = tmp = (ioclk / (baud * xdiv) + 4) / 8 - 1; | 
|  | 1025 | if (tmp > 0 && tmp <= 65535) | 
|  | 1026 | goto timer_okay; | 
|  | 1027 |  | 
|  | 1028 | port->uart.uartclk = ioclk / 8; | 
|  | 1029 | tmxmd = TM8MD_SRC_IOCLK_8; | 
|  | 1030 | tmxbr = tmp = (ioclk / (baud * 8 * xdiv) + 4) / 8 - 1; | 
|  | 1031 | if (tmp > 0 && tmp <= 65535) | 
|  | 1032 | goto timer_okay; | 
|  | 1033 |  | 
|  | 1034 | port->uart.uartclk = ioclk / 32; | 
|  | 1035 | tmxmd = TM8MD_SRC_IOCLK_32; | 
|  | 1036 | tmxbr = tmp = (ioclk / (baud * 32 * xdiv) + 4) / 8 - 1; | 
|  | 1037 | if (tmp > 0 && tmp <= 65535) | 
|  | 1038 | goto timer_okay; | 
|  | 1039 | break; | 
|  | 1040 |  | 
|  | 1041 | case MNSCx_DIV_TIMER_8BIT: | 
|  | 1042 | port->uart.uartclk = ioclk; | 
|  | 1043 | tmxmd = TM2MD_SRC_IOCLK; | 
|  | 1044 | tmxbr = tmp = (ioclk / (baud * xdiv) + 4) / 8 - 1; | 
|  | 1045 | if (tmp > 0 && tmp <= 255) | 
|  | 1046 | goto timer_okay; | 
|  | 1047 |  | 
|  | 1048 | port->uart.uartclk = ioclk / 8; | 
|  | 1049 | tmxmd = TM2MD_SRC_IOCLK_8; | 
|  | 1050 | tmxbr = tmp = (ioclk / (baud * 8 * xdiv) + 4) / 8 - 1; | 
|  | 1051 | if (tmp > 0 && tmp <= 255) | 
|  | 1052 | goto timer_okay; | 
|  | 1053 |  | 
|  | 1054 | port->uart.uartclk = ioclk / 32; | 
|  | 1055 | tmxmd = TM2MD_SRC_IOCLK_32; | 
|  | 1056 | tmxbr = tmp = (ioclk / (baud * 32 * xdiv) + 4) / 8 - 1; | 
|  | 1057 | if (tmp > 0 && tmp <= 255) | 
|  | 1058 | goto timer_okay; | 
|  | 1059 | break; | 
|  | 1060 |  | 
|  | 1061 | default: | 
|  | 1062 | BUG(); | 
|  | 1063 | return; | 
|  | 1064 | } | 
|  | 1065 |  | 
|  | 1066 | /* refuse to change to a baud rate we can't support */ | 
|  | 1067 | _debug("CAN'T SUPPORT"); | 
|  | 1068 |  | 
|  | 1069 | switch (battempt) { | 
|  | 1070 | case 0: | 
|  | 1071 | if (old) { | 
|  | 1072 | new->c_cflag &= ~CBAUD; | 
|  | 1073 | new->c_cflag |= (old->c_cflag & CBAUD); | 
|  | 1074 | battempt = 1; | 
|  | 1075 | goto try_alternative; | 
|  | 1076 | } | 
|  | 1077 |  | 
|  | 1078 | case 1: | 
|  | 1079 | /* as a last resort, if the quotient is zero, default to 9600 | 
|  | 1080 | * bps */ | 
|  | 1081 | new->c_cflag &= ~CBAUD; | 
|  | 1082 | new->c_cflag |= B9600; | 
|  | 1083 | battempt = 2; | 
|  | 1084 | goto try_alternative; | 
|  | 1085 |  | 
|  | 1086 | default: | 
|  | 1087 | /* hmmm... can't seem to support 9600 either | 
|  | 1088 | * - we could try iterating through the speeds we know about to | 
|  | 1089 | *   find the lowest | 
|  | 1090 | */ | 
|  | 1091 | new->c_cflag &= ~CBAUD; | 
|  | 1092 | new->c_cflag |= B0; | 
|  | 1093 |  | 
|  | 1094 | if (div_timer == MNSCx_DIV_TIMER_16BIT) | 
|  | 1095 | tmxmd = TM8MD_SRC_IOCLK_32; | 
|  | 1096 | else if (div_timer == MNSCx_DIV_TIMER_8BIT) | 
|  | 1097 | tmxmd = TM2MD_SRC_IOCLK_32; | 
|  | 1098 | tmxbr = 1; | 
|  | 1099 |  | 
|  | 1100 | port->uart.uartclk = ioclk / 32; | 
|  | 1101 | break; | 
|  | 1102 | } | 
|  | 1103 | timer_okay: | 
|  | 1104 |  | 
|  | 1105 | _debug("UARTCLK: %u / %hu", port->uart.uartclk, tmxbr); | 
|  | 1106 |  | 
|  | 1107 | /* make the changes */ | 
|  | 1108 | spin_lock_irqsave(&port->uart.lock, flags); | 
|  | 1109 |  | 
|  | 1110 | uart_update_timeout(&port->uart, new->c_cflag, baud); | 
|  | 1111 |  | 
|  | 1112 | /* set the timer to produce the required baud rate */ | 
|  | 1113 | switch (div_timer) { | 
|  | 1114 | case MNSCx_DIV_TIMER_16BIT: | 
|  | 1115 | *port->_tmxmd = 0; | 
|  | 1116 | *port->_tmxbr = tmxbr; | 
|  | 1117 | *port->_tmxmd = TM8MD_INIT_COUNTER; | 
|  | 1118 | *port->_tmxmd = tmxmd | TM8MD_COUNT_ENABLE; | 
|  | 1119 | break; | 
|  | 1120 |  | 
|  | 1121 | case MNSCx_DIV_TIMER_8BIT: | 
|  | 1122 | *port->_tmxmd = 0; | 
|  | 1123 | *(volatile u8 *) port->_tmxbr = (u8) tmxbr; | 
|  | 1124 | *port->_tmxmd = TM2MD_INIT_COUNTER; | 
|  | 1125 | *port->_tmxmd = tmxmd | TM2MD_COUNT_ENABLE; | 
|  | 1126 | break; | 
|  | 1127 | } | 
|  | 1128 |  | 
|  | 1129 | /* CTS flow control flag and modem status interrupts */ | 
|  | 1130 | scxctr &= ~(SC2CTR_TWE | SC2CTR_TWS); | 
|  | 1131 |  | 
|  | 1132 | if (port->type == PORT_MN10300_CTS && cflag & CRTSCTS) { | 
|  | 1133 | /* want to interrupt when CTS goes low if CTS is now | 
|  | 1134 | * high and vice versa | 
|  | 1135 | */ | 
|  | 1136 | port->tx_cts = *port->_status; | 
|  | 1137 |  | 
|  | 1138 | if (port->tx_cts & SC2STR_CTS) | 
|  | 1139 | scxctr |= SC2CTR_TWE; | 
|  | 1140 | else | 
|  | 1141 | scxctr |= SC2CTR_TWE | SC2CTR_TWS; | 
|  | 1142 | } | 
|  | 1143 |  | 
|  | 1144 | /* set up parity check flag */ | 
|  | 1145 | port->uart.read_status_mask = (1 << TTY_NORMAL) | (1 << TTY_OVERRUN); | 
|  | 1146 | if (new->c_iflag & INPCK) | 
|  | 1147 | port->uart.read_status_mask |= | 
|  | 1148 | (1 << TTY_PARITY) | (1 << TTY_FRAME); | 
|  | 1149 | if (new->c_iflag & (BRKINT | PARMRK)) | 
|  | 1150 | port->uart.read_status_mask |= (1 << TTY_BREAK); | 
|  | 1151 |  | 
|  | 1152 | /* characters to ignore */ | 
|  | 1153 | port->uart.ignore_status_mask = 0; | 
|  | 1154 | if (new->c_iflag & IGNPAR) | 
|  | 1155 | port->uart.ignore_status_mask |= | 
|  | 1156 | (1 << TTY_PARITY) | (1 << TTY_FRAME); | 
|  | 1157 | if (new->c_iflag & IGNBRK) { | 
|  | 1158 | port->uart.ignore_status_mask |= (1 << TTY_BREAK); | 
|  | 1159 | /* | 
|  | 1160 | * If we're ignoring parity and break indicators, | 
|  | 1161 | * ignore overruns to (for real raw support). | 
|  | 1162 | */ | 
|  | 1163 | if (new->c_iflag & IGNPAR) | 
|  | 1164 | port->uart.ignore_status_mask |= (1 << TTY_OVERRUN); | 
|  | 1165 | } | 
|  | 1166 |  | 
|  | 1167 | /* Ignore all characters if CREAD is not set */ | 
|  | 1168 | if ((new->c_cflag & CREAD) == 0) | 
|  | 1169 | port->uart.ignore_status_mask |= (1 << TTY_NORMAL); | 
|  | 1170 |  | 
|  | 1171 | scxctr |= *port->_control & (SC01CTR_TXE | SC01CTR_RXE | SC01CTR_BKE); | 
|  | 1172 | *port->_control = scxctr; | 
|  | 1173 |  | 
|  | 1174 | spin_unlock_irqrestore(&port->uart.lock, flags); | 
|  | 1175 | } | 
|  | 1176 |  | 
|  | 1177 | /* | 
|  | 1178 | * set the terminal I/O parameters | 
|  | 1179 | */ | 
|  | 1180 | static void mn10300_serial_set_termios(struct uart_port *_port, | 
|  | 1181 | struct ktermios *new, | 
|  | 1182 | struct ktermios *old) | 
|  | 1183 | { | 
|  | 1184 | struct mn10300_serial_port *port = | 
|  | 1185 | container_of(_port, struct mn10300_serial_port, uart); | 
|  | 1186 |  | 
|  | 1187 | _enter("%s,%p,%p", port->name, new, old); | 
|  | 1188 |  | 
|  | 1189 | mn10300_serial_change_speed(port, new, old); | 
|  | 1190 |  | 
|  | 1191 | /* handle turning off CRTSCTS */ | 
|  | 1192 | if (!(new->c_cflag & CRTSCTS)) { | 
|  | 1193 | u16 ctr = *port->_control; | 
|  | 1194 | ctr &= ~SC2CTR_TWE; | 
|  | 1195 | *port->_control = ctr; | 
|  | 1196 | } | 
|  | 1197 | } | 
|  | 1198 |  | 
|  | 1199 | /* | 
|  | 1200 | * return description of port type | 
|  | 1201 | */ | 
|  | 1202 | static const char *mn10300_serial_type(struct uart_port *_port) | 
|  | 1203 | { | 
|  | 1204 | struct mn10300_serial_port *port = | 
|  | 1205 | container_of(_port, struct mn10300_serial_port, uart); | 
|  | 1206 |  | 
|  | 1207 | if (port->uart.type == PORT_MN10300_CTS) | 
|  | 1208 | return "MN10300 SIF_CTS"; | 
|  | 1209 |  | 
|  | 1210 | return "MN10300 SIF"; | 
|  | 1211 | } | 
|  | 1212 |  | 
|  | 1213 | /* | 
|  | 1214 | * release I/O and memory regions in use by port | 
|  | 1215 | */ | 
|  | 1216 | static void mn10300_serial_release_port(struct uart_port *_port) | 
|  | 1217 | { | 
|  | 1218 | struct mn10300_serial_port *port = | 
|  | 1219 | container_of(_port, struct mn10300_serial_port, uart); | 
|  | 1220 |  | 
|  | 1221 | _enter("%s", port->name); | 
|  | 1222 |  | 
|  | 1223 | release_mem_region((unsigned long) port->_iobase, 16); | 
|  | 1224 | } | 
|  | 1225 |  | 
|  | 1226 | /* | 
|  | 1227 | * request I/O and memory regions for port | 
|  | 1228 | */ | 
|  | 1229 | static int mn10300_serial_request_port(struct uart_port *_port) | 
|  | 1230 | { | 
|  | 1231 | struct mn10300_serial_port *port = | 
|  | 1232 | container_of(_port, struct mn10300_serial_port, uart); | 
|  | 1233 |  | 
|  | 1234 | _enter("%s", port->name); | 
|  | 1235 |  | 
|  | 1236 | request_mem_region((unsigned long) port->_iobase, 16, port->name); | 
|  | 1237 | return 0; | 
|  | 1238 | } | 
|  | 1239 |  | 
|  | 1240 | /* | 
|  | 1241 | * configure the type and reserve the ports | 
|  | 1242 | */ | 
|  | 1243 | static void mn10300_serial_config_port(struct uart_port *_port, int type) | 
|  | 1244 | { | 
|  | 1245 | struct mn10300_serial_port *port = | 
|  | 1246 | container_of(_port, struct mn10300_serial_port, uart); | 
|  | 1247 |  | 
|  | 1248 | _enter("%s", port->name); | 
|  | 1249 |  | 
|  | 1250 | port->uart.type = PORT_MN10300; | 
|  | 1251 |  | 
|  | 1252 | if (port->options & MNSCx_OPT_CTS) | 
|  | 1253 | port->uart.type = PORT_MN10300_CTS; | 
|  | 1254 |  | 
|  | 1255 | mn10300_serial_request_port(_port); | 
|  | 1256 | } | 
|  | 1257 |  | 
|  | 1258 | /* | 
|  | 1259 | * verify serial parameters are suitable for this port type | 
|  | 1260 | */ | 
|  | 1261 | static int mn10300_serial_verify_port(struct uart_port *_port, | 
|  | 1262 | struct serial_struct *ss) | 
|  | 1263 | { | 
|  | 1264 | struct mn10300_serial_port *port = | 
|  | 1265 | container_of(_port, struct mn10300_serial_port, uart); | 
|  | 1266 | void *mapbase = (void *) (unsigned long) port->uart.mapbase; | 
|  | 1267 |  | 
|  | 1268 | _enter("%s", port->name); | 
|  | 1269 |  | 
|  | 1270 | /* these things may not be changed */ | 
|  | 1271 | if (ss->irq		!= port->uart.irq	|| | 
|  | 1272 | ss->port		!= port->uart.iobase	|| | 
|  | 1273 | ss->io_type		!= port->uart.iotype	|| | 
|  | 1274 | ss->iomem_base	!= mapbase || | 
|  | 1275 | ss->iomem_reg_shift	!= port->uart.regshift	|| | 
|  | 1276 | ss->hub6		!= port->uart.hub6	|| | 
|  | 1277 | ss->xmit_fifo_size	!= port->uart.fifosize) | 
|  | 1278 | return -EINVAL; | 
|  | 1279 |  | 
|  | 1280 | /* type may be changed on a port that supports CTS */ | 
|  | 1281 | if (ss->type != port->uart.type) { | 
|  | 1282 | if (!(port->options & MNSCx_OPT_CTS)) | 
|  | 1283 | return -EINVAL; | 
|  | 1284 |  | 
|  | 1285 | if (ss->type != PORT_MN10300 && | 
|  | 1286 | ss->type != PORT_MN10300_CTS) | 
|  | 1287 | return -EINVAL; | 
|  | 1288 | } | 
|  | 1289 |  | 
|  | 1290 | return 0; | 
|  | 1291 | } | 
|  | 1292 |  | 
|  | 1293 | /* | 
|  | 1294 | * initialise the MN10300 on-chip UARTs | 
|  | 1295 | */ | 
|  | 1296 | static int __init mn10300_serial_init(void) | 
|  | 1297 | { | 
|  | 1298 | struct mn10300_serial_port *port; | 
|  | 1299 | int ret, i; | 
|  | 1300 |  | 
|  | 1301 | printk(KERN_INFO "%s version %s (%s)\n", | 
|  | 1302 | serial_name, serial_version, serial_revdate); | 
|  | 1303 |  | 
|  | 1304 | #ifdef CONFIG_MN10300_TTYSM2 | 
|  | 1305 | SC2TIM = 8; /* make the baud base of timer 2 IOCLK/8 */ | 
|  | 1306 | #endif | 
|  | 1307 |  | 
|  | 1308 | set_intr_stub(EXCEP_IRQ_LEVEL1, mn10300_serial_vdma_interrupt); | 
|  | 1309 |  | 
|  | 1310 | ret = uart_register_driver(&mn10300_serial_driver); | 
|  | 1311 | if (!ret) { | 
|  | 1312 | for (i = 0 ; i < NR_PORTS ; i++) { | 
|  | 1313 | port = mn10300_serial_ports[i]; | 
|  | 1314 | if (!port || port->gdbstub) | 
|  | 1315 | continue; | 
|  | 1316 |  | 
|  | 1317 | switch (port->clock_src) { | 
|  | 1318 | case MNSCx_CLOCK_SRC_IOCLK: | 
|  | 1319 | port->ioclk = MN10300_IOCLK; | 
|  | 1320 | break; | 
|  | 1321 |  | 
|  | 1322 | #ifdef MN10300_IOBCLK | 
|  | 1323 | case MNSCx_CLOCK_SRC_IOBCLK: | 
|  | 1324 | port->ioclk = MN10300_IOBCLK; | 
|  | 1325 | break; | 
|  | 1326 | #endif | 
|  | 1327 | default: | 
|  | 1328 | BUG(); | 
|  | 1329 | } | 
|  | 1330 |  | 
|  | 1331 | ret = uart_add_one_port(&mn10300_serial_driver, | 
|  | 1332 | &port->uart); | 
|  | 1333 |  | 
|  | 1334 | if (ret < 0) { | 
|  | 1335 | _debug("ERROR %d", -ret); | 
|  | 1336 | break; | 
|  | 1337 | } | 
|  | 1338 | } | 
|  | 1339 |  | 
|  | 1340 | if (ret) | 
|  | 1341 | uart_unregister_driver(&mn10300_serial_driver); | 
|  | 1342 | } | 
|  | 1343 |  | 
|  | 1344 | return ret; | 
|  | 1345 | } | 
|  | 1346 |  | 
|  | 1347 | __initcall(mn10300_serial_init); | 
|  | 1348 |  | 
|  | 1349 |  | 
|  | 1350 | #ifdef CONFIG_MN10300_TTYSM_CONSOLE | 
|  | 1351 |  | 
|  | 1352 | /* | 
|  | 1353 | * print a string to the serial port without disturbing the real user of the | 
|  | 1354 | * port too much | 
|  | 1355 | * - the console must be locked by the caller | 
|  | 1356 | */ | 
|  | 1357 | static void mn10300_serial_console_write(struct console *co, | 
|  | 1358 | const char *s, unsigned count) | 
|  | 1359 | { | 
|  | 1360 | struct mn10300_serial_port *port; | 
|  | 1361 | unsigned i; | 
|  | 1362 | u16 scxctr, txicr, tmp; | 
|  | 1363 | u8 tmxmd; | 
|  | 1364 |  | 
|  | 1365 | port = mn10300_serial_ports[co->index]; | 
|  | 1366 |  | 
|  | 1367 | /* firstly hijack the serial port from the "virtual DMA" controller */ | 
|  | 1368 | txicr = *port->tx_icr; | 
|  | 1369 | *port->tx_icr = GxICR_LEVEL_1; | 
|  | 1370 | tmp = *port->tx_icr; | 
|  | 1371 |  | 
|  | 1372 | /* the transmitter may be disabled */ | 
|  | 1373 | scxctr = *port->_control; | 
|  | 1374 | if (!(scxctr & SC01CTR_TXE)) { | 
|  | 1375 | /* restart the UART clock */ | 
|  | 1376 | tmxmd = *port->_tmxmd; | 
|  | 1377 |  | 
|  | 1378 | switch (port->div_timer) { | 
|  | 1379 | case MNSCx_DIV_TIMER_16BIT: | 
|  | 1380 | *port->_tmxmd = 0; | 
|  | 1381 | *port->_tmxmd = TM8MD_INIT_COUNTER; | 
|  | 1382 | *port->_tmxmd = tmxmd | TM8MD_COUNT_ENABLE; | 
|  | 1383 | break; | 
|  | 1384 |  | 
|  | 1385 | case MNSCx_DIV_TIMER_8BIT: | 
|  | 1386 | *port->_tmxmd = 0; | 
|  | 1387 | *port->_tmxmd = TM2MD_INIT_COUNTER; | 
|  | 1388 | *port->_tmxmd = tmxmd | TM2MD_COUNT_ENABLE; | 
|  | 1389 | break; | 
|  | 1390 | } | 
|  | 1391 |  | 
|  | 1392 | /* enable the transmitter */ | 
|  | 1393 | *port->_control = (scxctr & ~SC01CTR_BKE) | SC01CTR_TXE; | 
|  | 1394 |  | 
|  | 1395 | } else if (scxctr & SC01CTR_BKE) { | 
|  | 1396 | /* stop transmitting BREAK */ | 
|  | 1397 | *port->_control = (scxctr & ~SC01CTR_BKE); | 
|  | 1398 | } | 
|  | 1399 |  | 
|  | 1400 | /* send the chars into the serial port (with LF -> LFCR conversion) */ | 
|  | 1401 | for (i = 0; i < count; i++) { | 
|  | 1402 | char ch = *s++; | 
|  | 1403 |  | 
|  | 1404 | while (*port->_status & SC01STR_TBF) | 
|  | 1405 | continue; | 
|  | 1406 | *(u8 *) port->_txb = ch; | 
|  | 1407 |  | 
|  | 1408 | if (ch == 0x0a) { | 
|  | 1409 | while (*port->_status & SC01STR_TBF) | 
|  | 1410 | continue; | 
|  | 1411 | *(u8 *) port->_txb = 0xd; | 
|  | 1412 | } | 
|  | 1413 | } | 
|  | 1414 |  | 
|  | 1415 | /* can't let the transmitter be turned off if it's actually | 
|  | 1416 | * transmitting */ | 
|  | 1417 | while (*port->_status & (SC01STR_TXF | SC01STR_TBF)) | 
|  | 1418 | continue; | 
|  | 1419 |  | 
|  | 1420 | /* disable the transmitter if we re-enabled it */ | 
|  | 1421 | if (!(scxctr & SC01CTR_TXE)) | 
|  | 1422 | *port->_control = scxctr; | 
|  | 1423 |  | 
|  | 1424 | *port->tx_icr = txicr; | 
|  | 1425 | tmp = *port->tx_icr; | 
|  | 1426 | } | 
|  | 1427 |  | 
|  | 1428 | /* | 
|  | 1429 | * set up a serial port as a console | 
|  | 1430 | * - construct a cflag setting for the first rs_open() | 
|  | 1431 | * - initialize the serial port | 
|  | 1432 | * - return non-zero if we didn't find a serial port. | 
|  | 1433 | */ | 
|  | 1434 | static int __init mn10300_serial_console_setup(struct console *co, | 
|  | 1435 | char *options) | 
|  | 1436 | { | 
|  | 1437 | struct mn10300_serial_port *port; | 
|  | 1438 | int i, parity = 'n', baud = 9600, bits = 8, flow = 0; | 
|  | 1439 |  | 
|  | 1440 | for (i = 0 ; i < NR_PORTS ; i++) { | 
|  | 1441 | port = mn10300_serial_ports[i]; | 
|  | 1442 | if (port && !port->gdbstub && port->uart.line == co->index) | 
|  | 1443 | goto found_device; | 
|  | 1444 | } | 
|  | 1445 |  | 
|  | 1446 | return -ENODEV; | 
|  | 1447 |  | 
|  | 1448 | found_device: | 
|  | 1449 | switch (port->clock_src) { | 
|  | 1450 | case MNSCx_CLOCK_SRC_IOCLK: | 
|  | 1451 | port->ioclk = MN10300_IOCLK; | 
|  | 1452 | break; | 
|  | 1453 |  | 
|  | 1454 | #ifdef MN10300_IOBCLK | 
|  | 1455 | case MNSCx_CLOCK_SRC_IOBCLK: | 
|  | 1456 | port->ioclk = MN10300_IOBCLK; | 
|  | 1457 | break; | 
|  | 1458 | #endif | 
|  | 1459 | default: | 
|  | 1460 | BUG(); | 
|  | 1461 | } | 
|  | 1462 |  | 
|  | 1463 | if (options) | 
|  | 1464 | uart_parse_options(options, &baud, &parity, &bits, &flow); | 
|  | 1465 |  | 
|  | 1466 | return uart_set_options(&port->uart, co, baud, parity, bits, flow); | 
|  | 1467 | } | 
|  | 1468 |  | 
|  | 1469 | /* | 
|  | 1470 | * register console | 
|  | 1471 | */ | 
|  | 1472 | static int __init mn10300_serial_console_init(void) | 
|  | 1473 | { | 
|  | 1474 | register_console(&mn10300_serial_console); | 
|  | 1475 | return 0; | 
|  | 1476 | } | 
|  | 1477 |  | 
|  | 1478 | console_initcall(mn10300_serial_console_init); | 
|  | 1479 | #endif |