ia64/linux-2.6.18-xen.hg

annotate drivers/serial/at91_serial.c @ 893:f994bfe9b93b

linux/blktap2: reduce TLB flush scope

c/s 885 added very coarse TLB flushing. Since these flushes always
follow single page updates, single page flushes (when available) are
sufficient.

Signed-off-by: Jan Beulich <jbeulich@novell.com>
author Keir Fraser <keir.fraser@citrix.com>
date Thu Jun 04 10:32:57 2009 +0100 (2009-06-04)
parents 831230e53067
children
rev   line source
ian@0 1 /*
ian@0 2 * linux/drivers/char/at91_serial.c
ian@0 3 *
ian@0 4 * Driver for Atmel AT91RM9200 Serial ports
ian@0 5 * Copyright (C) 2003 Rick Bronson
ian@0 6 *
ian@0 7 * Based on drivers/char/serial_sa1100.c, by Deep Blue Solutions Ltd.
ian@0 8 * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
ian@0 9 *
ian@0 10 * This program is free software; you can redistribute it and/or modify
ian@0 11 * it under the terms of the GNU General Public License as published by
ian@0 12 * the Free Software Foundation; either version 2 of the License, or
ian@0 13 * (at your option) any later version.
ian@0 14 *
ian@0 15 * This program is distributed in the hope that it will be useful,
ian@0 16 * but WITHOUT ANY WARRANTY; without even the implied warranty of
ian@0 17 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
ian@0 18 * GNU General Public License for more details.
ian@0 19 *
ian@0 20 * You should have received a copy of the GNU General Public License
ian@0 21 * along with this program; if not, write to the Free Software
ian@0 22 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA
ian@0 23 *
ian@0 24 */
ian@0 25 #include <linux/module.h>
ian@0 26 #include <linux/tty.h>
ian@0 27 #include <linux/ioport.h>
ian@0 28 #include <linux/slab.h>
ian@0 29 #include <linux/init.h>
ian@0 30 #include <linux/serial.h>
ian@0 31 #include <linux/clk.h>
ian@0 32 #include <linux/console.h>
ian@0 33 #include <linux/sysrq.h>
ian@0 34 #include <linux/tty_flip.h>
ian@0 35 #include <linux/platform_device.h>
ian@0 36
ian@0 37 #include <asm/io.h>
ian@0 38
ian@0 39 #include <asm/arch/at91rm9200_usart.h>
ian@0 40 #include <asm/arch/at91rm9200_pdc.h>
ian@0 41 #include <asm/mach/serial_at91.h>
ian@0 42 #include <asm/arch/board.h>
ian@0 43 #include <asm/arch/system.h>
ian@0 44 #include <asm/arch/gpio.h>
ian@0 45
ian@0 46 #if defined(CONFIG_SERIAL_AT91_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
ian@0 47 #define SUPPORT_SYSRQ
ian@0 48 #endif
ian@0 49
ian@0 50 #include <linux/serial_core.h>
ian@0 51
ian@0 52 #ifdef CONFIG_SERIAL_AT91_TTYAT
ian@0 53
ian@0 54 /* Use device name ttyAT, major 204 and minor 154-169. This is necessary if we
ian@0 55 * should coexist with the 8250 driver, such as if we have an external 16C550
ian@0 56 * UART. */
ian@0 57 #define SERIAL_AT91_MAJOR 204
ian@0 58 #define MINOR_START 154
ian@0 59 #define AT91_DEVICENAME "ttyAT"
ian@0 60
ian@0 61 #else
ian@0 62
ian@0 63 /* Use device name ttyS, major 4, minor 64-68. This is the usual serial port
ian@0 64 * name, but it is legally reserved for the 8250 driver. */
ian@0 65 #define SERIAL_AT91_MAJOR TTY_MAJOR
ian@0 66 #define MINOR_START 64
ian@0 67 #define AT91_DEVICENAME "ttyS"
ian@0 68
ian@0 69 #endif
ian@0 70
ian@0 71 #define AT91_ISR_PASS_LIMIT 256
ian@0 72
ian@0 73 #define UART_PUT_CR(port,v) writel(v, (port)->membase + AT91_US_CR)
ian@0 74 #define UART_GET_MR(port) readl((port)->membase + AT91_US_MR)
ian@0 75 #define UART_PUT_MR(port,v) writel(v, (port)->membase + AT91_US_MR)
ian@0 76 #define UART_PUT_IER(port,v) writel(v, (port)->membase + AT91_US_IER)
ian@0 77 #define UART_PUT_IDR(port,v) writel(v, (port)->membase + AT91_US_IDR)
ian@0 78 #define UART_GET_IMR(port) readl((port)->membase + AT91_US_IMR)
ian@0 79 #define UART_GET_CSR(port) readl((port)->membase + AT91_US_CSR)
ian@0 80 #define UART_GET_CHAR(port) readl((port)->membase + AT91_US_RHR)
ian@0 81 #define UART_PUT_CHAR(port,v) writel(v, (port)->membase + AT91_US_THR)
ian@0 82 #define UART_GET_BRGR(port) readl((port)->membase + AT91_US_BRGR)
ian@0 83 #define UART_PUT_BRGR(port,v) writel(v, (port)->membase + AT91_US_BRGR)
ian@0 84 #define UART_PUT_RTOR(port,v) writel(v, (port)->membase + AT91_US_RTOR)
ian@0 85
ian@0 86 // #define UART_GET_CR(port) readl((port)->membase + AT91_US_CR) // is write-only
ian@0 87
ian@0 88 /* PDC registers */
ian@0 89 #define UART_PUT_PTCR(port,v) writel(v, (port)->membase + AT91_PDC_PTCR)
ian@0 90 #define UART_GET_PTSR(port) readl((port)->membase + AT91_PDC_PTSR)
ian@0 91
ian@0 92 #define UART_PUT_RPR(port,v) writel(v, (port)->membase + AT91_PDC_RPR)
ian@0 93 #define UART_GET_RPR(port) readl((port)->membase + AT91_PDC_RPR)
ian@0 94 #define UART_PUT_RCR(port,v) writel(v, (port)->membase + AT91_PDC_RCR)
ian@0 95 #define UART_PUT_RNPR(port,v) writel(v, (port)->membase + AT91_PDC_RNPR)
ian@0 96 #define UART_PUT_RNCR(port,v) writel(v, (port)->membase + AT91_PDC_RNCR)
ian@0 97
ian@0 98 #define UART_PUT_TPR(port,v) writel(v, (port)->membase + AT91_PDC_TPR)
ian@0 99 #define UART_PUT_TCR(port,v) writel(v, (port)->membase + AT91_PDC_TCR)
ian@0 100 //#define UART_PUT_TNPR(port,v) writel(v, (port)->membase + AT91_PDC_TNPR)
ian@0 101 //#define UART_PUT_TNCR(port,v) writel(v, (port)->membase + AT91_PDC_TNCR)
ian@0 102
ian@0 103 static int (*at91_open)(struct uart_port *);
ian@0 104 static void (*at91_close)(struct uart_port *);
ian@0 105
ian@0 106 /*
ian@0 107 * We wrap our port structure around the generic uart_port.
ian@0 108 */
ian@0 109 struct at91_uart_port {
ian@0 110 struct uart_port uart; /* uart */
ian@0 111 struct clk *clk; /* uart clock */
ian@0 112 unsigned short suspended; /* is port suspended? */
ian@0 113 };
ian@0 114
ian@0 115 static struct at91_uart_port at91_ports[AT91_NR_UART];
ian@0 116
ian@0 117 #ifdef SUPPORT_SYSRQ
ian@0 118 static struct console at91_console;
ian@0 119 #endif
ian@0 120
ian@0 121 /*
ian@0 122 * Return TIOCSER_TEMT when transmitter FIFO and Shift register is empty.
ian@0 123 */
ian@0 124 static u_int at91_tx_empty(struct uart_port *port)
ian@0 125 {
ian@0 126 return (UART_GET_CSR(port) & AT91_US_TXEMPTY) ? TIOCSER_TEMT : 0;
ian@0 127 }
ian@0 128
ian@0 129 /*
ian@0 130 * Set state of the modem control output lines
ian@0 131 */
ian@0 132 static void at91_set_mctrl(struct uart_port *port, u_int mctrl)
ian@0 133 {
ian@0 134 unsigned int control = 0;
ian@0 135 unsigned int mode;
ian@0 136
ian@0 137 if (arch_identify() == ARCH_ID_AT91RM9200) {
ian@0 138 /*
ian@0 139 * AT91RM9200 Errata #39: RTS0 is not internally connected to PA21.
ian@0 140 * We need to drive the pin manually.
ian@0 141 */
ian@0 142 if (port->mapbase == AT91_BASE_US0) {
ian@0 143 if (mctrl & TIOCM_RTS)
ian@0 144 at91_set_gpio_value(AT91_PIN_PA21, 0);
ian@0 145 else
ian@0 146 at91_set_gpio_value(AT91_PIN_PA21, 1);
ian@0 147 }
ian@0 148 }
ian@0 149
ian@0 150 if (mctrl & TIOCM_RTS)
ian@0 151 control |= AT91_US_RTSEN;
ian@0 152 else
ian@0 153 control |= AT91_US_RTSDIS;
ian@0 154
ian@0 155 if (mctrl & TIOCM_DTR)
ian@0 156 control |= AT91_US_DTREN;
ian@0 157 else
ian@0 158 control |= AT91_US_DTRDIS;
ian@0 159
ian@0 160 UART_PUT_CR(port, control);
ian@0 161
ian@0 162 /* Local loopback mode? */
ian@0 163 mode = UART_GET_MR(port) & ~AT91_US_CHMODE;
ian@0 164 if (mctrl & TIOCM_LOOP)
ian@0 165 mode |= AT91_US_CHMODE_LOC_LOOP;
ian@0 166 else
ian@0 167 mode |= AT91_US_CHMODE_NORMAL;
ian@0 168 UART_PUT_MR(port, mode);
ian@0 169 }
ian@0 170
ian@0 171 /*
ian@0 172 * Get state of the modem control input lines
ian@0 173 */
ian@0 174 static u_int at91_get_mctrl(struct uart_port *port)
ian@0 175 {
ian@0 176 unsigned int status, ret = 0;
ian@0 177
ian@0 178 status = UART_GET_CSR(port);
ian@0 179
ian@0 180 /*
ian@0 181 * The control signals are active low.
ian@0 182 */
ian@0 183 if (!(status & AT91_US_DCD))
ian@0 184 ret |= TIOCM_CD;
ian@0 185 if (!(status & AT91_US_CTS))
ian@0 186 ret |= TIOCM_CTS;
ian@0 187 if (!(status & AT91_US_DSR))
ian@0 188 ret |= TIOCM_DSR;
ian@0 189 if (!(status & AT91_US_RI))
ian@0 190 ret |= TIOCM_RI;
ian@0 191
ian@0 192 return ret;
ian@0 193 }
ian@0 194
ian@0 195 /*
ian@0 196 * Stop transmitting.
ian@0 197 */
ian@0 198 static void at91_stop_tx(struct uart_port *port)
ian@0 199 {
ian@0 200 struct at91_uart_port *at91_port = (struct at91_uart_port *) port;
ian@0 201
ian@0 202 UART_PUT_IDR(port, AT91_US_TXRDY);
ian@0 203 }
ian@0 204
ian@0 205 /*
ian@0 206 * Start transmitting.
ian@0 207 */
ian@0 208 static void at91_start_tx(struct uart_port *port)
ian@0 209 {
ian@0 210 struct at91_uart_port *at91_port = (struct at91_uart_port *) port;
ian@0 211
ian@0 212 UART_PUT_IER(port, AT91_US_TXRDY);
ian@0 213 }
ian@0 214
ian@0 215 /*
ian@0 216 * Stop receiving - port is in process of being closed.
ian@0 217 */
ian@0 218 static void at91_stop_rx(struct uart_port *port)
ian@0 219 {
ian@0 220 struct at91_uart_port *at91_port = (struct at91_uart_port *) port;
ian@0 221
ian@0 222 UART_PUT_IDR(port, AT91_US_RXRDY);
ian@0 223 }
ian@0 224
ian@0 225 /*
ian@0 226 * Enable modem status interrupts
ian@0 227 */
ian@0 228 static void at91_enable_ms(struct uart_port *port)
ian@0 229 {
ian@0 230 UART_PUT_IER(port, AT91_US_RIIC | AT91_US_DSRIC | AT91_US_DCDIC | AT91_US_CTSIC);
ian@0 231 }
ian@0 232
ian@0 233 /*
ian@0 234 * Control the transmission of a break signal
ian@0 235 */
ian@0 236 static void at91_break_ctl(struct uart_port *port, int break_state)
ian@0 237 {
ian@0 238 if (break_state != 0)
ian@0 239 UART_PUT_CR(port, AT91_US_STTBRK); /* start break */
ian@0 240 else
ian@0 241 UART_PUT_CR(port, AT91_US_STPBRK); /* stop break */
ian@0 242 }
ian@0 243
ian@0 244 /*
ian@0 245 * Characters received (called from interrupt handler)
ian@0 246 */
ian@0 247 static void at91_rx_chars(struct uart_port *port, struct pt_regs *regs)
ian@0 248 {
ian@0 249 struct tty_struct *tty = port->info->tty;
ian@0 250 unsigned int status, ch, flg;
ian@0 251
ian@0 252 status = UART_GET_CSR(port);
ian@0 253 while (status & AT91_US_RXRDY) {
ian@0 254 ch = UART_GET_CHAR(port);
ian@0 255
ian@0 256 port->icount.rx++;
ian@0 257
ian@0 258 flg = TTY_NORMAL;
ian@0 259
ian@0 260 /*
ian@0 261 * note that the error handling code is
ian@0 262 * out of the main execution path
ian@0 263 */
ian@0 264 if (unlikely(status & (AT91_US_PARE | AT91_US_FRAME | AT91_US_OVRE | AT91_US_RXBRK))) {
ian@0 265 UART_PUT_CR(port, AT91_US_RSTSTA); /* clear error */
ian@0 266 if (status & AT91_US_RXBRK) {
ian@0 267 status &= ~(AT91_US_PARE | AT91_US_FRAME); /* ignore side-effect */
ian@0 268 port->icount.brk++;
ian@0 269 if (uart_handle_break(port))
ian@0 270 goto ignore_char;
ian@0 271 }
ian@0 272 if (status & AT91_US_PARE)
ian@0 273 port->icount.parity++;
ian@0 274 if (status & AT91_US_FRAME)
ian@0 275 port->icount.frame++;
ian@0 276 if (status & AT91_US_OVRE)
ian@0 277 port->icount.overrun++;
ian@0 278
ian@0 279 status &= port->read_status_mask;
ian@0 280
ian@0 281 if (status & AT91_US_RXBRK)
ian@0 282 flg = TTY_BREAK;
ian@0 283 else if (status & AT91_US_PARE)
ian@0 284 flg = TTY_PARITY;
ian@0 285 else if (status & AT91_US_FRAME)
ian@0 286 flg = TTY_FRAME;
ian@0 287 }
ian@0 288
ian@0 289 if (uart_handle_sysrq_char(port, ch, regs))
ian@0 290 goto ignore_char;
ian@0 291
ian@0 292 uart_insert_char(port, status, AT91_US_OVRE, ch, flg);
ian@0 293
ian@0 294 ignore_char:
ian@0 295 status = UART_GET_CSR(port);
ian@0 296 }
ian@0 297
ian@0 298 tty_flip_buffer_push(tty);
ian@0 299 }
ian@0 300
ian@0 301 /*
ian@0 302 * Transmit characters (called from interrupt handler)
ian@0 303 */
ian@0 304 static void at91_tx_chars(struct uart_port *port)
ian@0 305 {
ian@0 306 struct circ_buf *xmit = &port->info->xmit;
ian@0 307
ian@0 308 if (port->x_char) {
ian@0 309 UART_PUT_CHAR(port, port->x_char);
ian@0 310 port->icount.tx++;
ian@0 311 port->x_char = 0;
ian@0 312 return;
ian@0 313 }
ian@0 314 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
ian@0 315 at91_stop_tx(port);
ian@0 316 return;
ian@0 317 }
ian@0 318
ian@0 319 while (UART_GET_CSR(port) & AT91_US_TXRDY) {
ian@0 320 UART_PUT_CHAR(port, xmit->buf[xmit->tail]);
ian@0 321 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
ian@0 322 port->icount.tx++;
ian@0 323 if (uart_circ_empty(xmit))
ian@0 324 break;
ian@0 325 }
ian@0 326
ian@0 327 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
ian@0 328 uart_write_wakeup(port);
ian@0 329
ian@0 330 if (uart_circ_empty(xmit))
ian@0 331 at91_stop_tx(port);
ian@0 332 }
ian@0 333
ian@0 334 /*
ian@0 335 * Interrupt handler
ian@0 336 */
ian@0 337 static irqreturn_t at91_interrupt(int irq, void *dev_id, struct pt_regs *regs)
ian@0 338 {
ian@0 339 struct uart_port *port = dev_id;
ian@0 340 struct at91_uart_port *at91_port = (struct at91_uart_port *) port;
ian@0 341 unsigned int status, pending, pass_counter = 0;
ian@0 342
ian@0 343 status = UART_GET_CSR(port);
ian@0 344 pending = status & UART_GET_IMR(port);
ian@0 345 while (pending) {
ian@0 346 /* Interrupt receive */
ian@0 347 if (pending & AT91_US_RXRDY)
ian@0 348 at91_rx_chars(port, regs);
ian@0 349
ian@0 350 // TODO: All reads to CSR will clear these interrupts!
ian@0 351 if (pending & AT91_US_RIIC) port->icount.rng++;
ian@0 352 if (pending & AT91_US_DSRIC) port->icount.dsr++;
ian@0 353 if (pending & AT91_US_DCDIC)
ian@0 354 uart_handle_dcd_change(port, !(status & AT91_US_DCD));
ian@0 355 if (pending & AT91_US_CTSIC)
ian@0 356 uart_handle_cts_change(port, !(status & AT91_US_CTS));
ian@0 357 if (pending & (AT91_US_RIIC | AT91_US_DSRIC | AT91_US_DCDIC | AT91_US_CTSIC))
ian@0 358 wake_up_interruptible(&port->info->delta_msr_wait);
ian@0 359
ian@0 360 /* Interrupt transmit */
ian@0 361 if (pending & AT91_US_TXRDY)
ian@0 362 at91_tx_chars(port);
ian@0 363
ian@0 364 if (pass_counter++ > AT91_ISR_PASS_LIMIT)
ian@0 365 break;
ian@0 366
ian@0 367 status = UART_GET_CSR(port);
ian@0 368 pending = status & UART_GET_IMR(port);
ian@0 369 }
ian@0 370 return IRQ_HANDLED;
ian@0 371 }
ian@0 372
ian@0 373 /*
ian@0 374 * Perform initialization and enable port for reception
ian@0 375 */
ian@0 376 static int at91_startup(struct uart_port *port)
ian@0 377 {
ian@0 378 struct at91_uart_port *at91_port = (struct at91_uart_port *) port;
ian@0 379 int retval;
ian@0 380
ian@0 381 /*
ian@0 382 * Ensure that no interrupts are enabled otherwise when
ian@0 383 * request_irq() is called we could get stuck trying to
ian@0 384 * handle an unexpected interrupt
ian@0 385 */
ian@0 386 UART_PUT_IDR(port, -1);
ian@0 387
ian@0 388 /*
ian@0 389 * Allocate the IRQ
ian@0 390 */
ian@0 391 retval = request_irq(port->irq, at91_interrupt, IRQF_SHARED, "at91_serial", port);
ian@0 392 if (retval) {
ian@0 393 printk("at91_serial: at91_startup - Can't get irq\n");
ian@0 394 return retval;
ian@0 395 }
ian@0 396
ian@0 397 /*
ian@0 398 * If there is a specific "open" function (to register
ian@0 399 * control line interrupts)
ian@0 400 */
ian@0 401 if (at91_open) {
ian@0 402 retval = at91_open(port);
ian@0 403 if (retval) {
ian@0 404 free_irq(port->irq, port);
ian@0 405 return retval;
ian@0 406 }
ian@0 407 }
ian@0 408
ian@0 409 /*
ian@0 410 * Finally, enable the serial port
ian@0 411 */
ian@0 412 UART_PUT_CR(port, AT91_US_RSTSTA | AT91_US_RSTRX);
ian@0 413 UART_PUT_CR(port, AT91_US_TXEN | AT91_US_RXEN); /* enable xmit & rcvr */
ian@0 414
ian@0 415 UART_PUT_IER(port, AT91_US_RXRDY); /* enable receive only */
ian@0 416
ian@0 417 return 0;
ian@0 418 }
ian@0 419
ian@0 420 /*
ian@0 421 * Disable the port
ian@0 422 */
ian@0 423 static void at91_shutdown(struct uart_port *port)
ian@0 424 {
ian@0 425 struct at91_uart_port *at91_port = (struct at91_uart_port *) port;
ian@0 426
ian@0 427 /*
ian@0 428 * Disable all interrupts, port and break condition.
ian@0 429 */
ian@0 430 UART_PUT_CR(port, AT91_US_RSTSTA);
ian@0 431 UART_PUT_IDR(port, -1);
ian@0 432
ian@0 433 /*
ian@0 434 * Free the interrupt
ian@0 435 */
ian@0 436 free_irq(port->irq, port);
ian@0 437
ian@0 438 /*
ian@0 439 * If there is a specific "close" function (to unregister
ian@0 440 * control line interrupts)
ian@0 441 */
ian@0 442 if (at91_close)
ian@0 443 at91_close(port);
ian@0 444 }
ian@0 445
ian@0 446 /*
ian@0 447 * Power / Clock management.
ian@0 448 */
ian@0 449 static void at91_serial_pm(struct uart_port *port, unsigned int state, unsigned int oldstate)
ian@0 450 {
ian@0 451 struct at91_uart_port *at91_port = (struct at91_uart_port *) port;
ian@0 452
ian@0 453 switch (state) {
ian@0 454 case 0:
ian@0 455 /*
ian@0 456 * Enable the peripheral clock for this serial port.
ian@0 457 * This is called on uart_open() or a resume event.
ian@0 458 */
ian@0 459 clk_enable(at91_port->clk);
ian@0 460 break;
ian@0 461 case 3:
ian@0 462 /*
ian@0 463 * Disable the peripheral clock for this serial port.
ian@0 464 * This is called on uart_close() or a suspend event.
ian@0 465 */
ian@0 466 clk_disable(at91_port->clk);
ian@0 467 break;
ian@0 468 default:
ian@0 469 printk(KERN_ERR "at91_serial: unknown pm %d\n", state);
ian@0 470 }
ian@0 471 }
ian@0 472
ian@0 473 /*
ian@0 474 * Change the port parameters
ian@0 475 */
ian@0 476 static void at91_set_termios(struct uart_port *port, struct termios * termios, struct termios * old)
ian@0 477 {
ian@0 478 unsigned long flags;
ian@0 479 unsigned int mode, imr, quot, baud;
ian@0 480
ian@0 481 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
ian@0 482 quot = uart_get_divisor(port, baud);
ian@0 483
ian@0 484 /* Get current mode register */
ian@0 485 mode = UART_GET_MR(port) & ~(AT91_US_CHRL | AT91_US_NBSTOP | AT91_US_PAR);
ian@0 486
ian@0 487 /* byte size */
ian@0 488 switch (termios->c_cflag & CSIZE) {
ian@0 489 case CS5:
ian@0 490 mode |= AT91_US_CHRL_5;
ian@0 491 break;
ian@0 492 case CS6:
ian@0 493 mode |= AT91_US_CHRL_6;
ian@0 494 break;
ian@0 495 case CS7:
ian@0 496 mode |= AT91_US_CHRL_7;
ian@0 497 break;
ian@0 498 default:
ian@0 499 mode |= AT91_US_CHRL_8;
ian@0 500 break;
ian@0 501 }
ian@0 502
ian@0 503 /* stop bits */
ian@0 504 if (termios->c_cflag & CSTOPB)
ian@0 505 mode |= AT91_US_NBSTOP_2;
ian@0 506
ian@0 507 /* parity */
ian@0 508 if (termios->c_cflag & PARENB) {
ian@0 509 if (termios->c_cflag & CMSPAR) { /* Mark or Space parity */
ian@0 510 if (termios->c_cflag & PARODD)
ian@0 511 mode |= AT91_US_PAR_MARK;
ian@0 512 else
ian@0 513 mode |= AT91_US_PAR_SPACE;
ian@0 514 }
ian@0 515 else if (termios->c_cflag & PARODD)
ian@0 516 mode |= AT91_US_PAR_ODD;
ian@0 517 else
ian@0 518 mode |= AT91_US_PAR_EVEN;
ian@0 519 }
ian@0 520 else
ian@0 521 mode |= AT91_US_PAR_NONE;
ian@0 522
ian@0 523 spin_lock_irqsave(&port->lock, flags);
ian@0 524
ian@0 525 port->read_status_mask = AT91_US_OVRE;
ian@0 526 if (termios->c_iflag & INPCK)
ian@0 527 port->read_status_mask |= (AT91_US_FRAME | AT91_US_PARE);
ian@0 528 if (termios->c_iflag & (BRKINT | PARMRK))
ian@0 529 port->read_status_mask |= AT91_US_RXBRK;
ian@0 530
ian@0 531 /*
ian@0 532 * Characters to ignore
ian@0 533 */
ian@0 534 port->ignore_status_mask = 0;
ian@0 535 if (termios->c_iflag & IGNPAR)
ian@0 536 port->ignore_status_mask |= (AT91_US_FRAME | AT91_US_PARE);
ian@0 537 if (termios->c_iflag & IGNBRK) {
ian@0 538 port->ignore_status_mask |= AT91_US_RXBRK;
ian@0 539 /*
ian@0 540 * If we're ignoring parity and break indicators,
ian@0 541 * ignore overruns too (for real raw support).
ian@0 542 */
ian@0 543 if (termios->c_iflag & IGNPAR)
ian@0 544 port->ignore_status_mask |= AT91_US_OVRE;
ian@0 545 }
ian@0 546
ian@0 547 // TODO: Ignore all characters if CREAD is set.
ian@0 548
ian@0 549 /* update the per-port timeout */
ian@0 550 uart_update_timeout(port, termios->c_cflag, baud);
ian@0 551
ian@0 552 /* disable interrupts and drain transmitter */
ian@0 553 imr = UART_GET_IMR(port); /* get interrupt mask */
ian@0 554 UART_PUT_IDR(port, -1); /* disable all interrupts */
ian@0 555 while (!(UART_GET_CSR(port) & AT91_US_TXEMPTY)) { barrier(); }
ian@0 556
ian@0 557 /* disable receiver and transmitter */
ian@0 558 UART_PUT_CR(port, AT91_US_TXDIS | AT91_US_RXDIS);
ian@0 559
ian@0 560 /* set the parity, stop bits and data size */
ian@0 561 UART_PUT_MR(port, mode);
ian@0 562
ian@0 563 /* set the baud rate */
ian@0 564 UART_PUT_BRGR(port, quot);
ian@0 565 UART_PUT_CR(port, AT91_US_RSTSTA | AT91_US_RSTRX);
ian@0 566 UART_PUT_CR(port, AT91_US_TXEN | AT91_US_RXEN);
ian@0 567
ian@0 568 /* restore interrupts */
ian@0 569 UART_PUT_IER(port, imr);
ian@0 570
ian@0 571 /* CTS flow-control and modem-status interrupts */
ian@0 572 if (UART_ENABLE_MS(port, termios->c_cflag))
ian@0 573 port->ops->enable_ms(port);
ian@0 574
ian@0 575 spin_unlock_irqrestore(&port->lock, flags);
ian@0 576 }
ian@0 577
ian@0 578 /*
ian@0 579 * Return string describing the specified port
ian@0 580 */
ian@0 581 static const char *at91_type(struct uart_port *port)
ian@0 582 {
ian@0 583 return (port->type == PORT_AT91) ? "AT91_SERIAL" : NULL;
ian@0 584 }
ian@0 585
ian@0 586 /*
ian@0 587 * Release the memory region(s) being used by 'port'.
ian@0 588 */
ian@0 589 static void at91_release_port(struct uart_port *port)
ian@0 590 {
ian@0 591 struct platform_device *pdev = to_platform_device(port->dev);
ian@0 592 int size = pdev->resource[0].end - pdev->resource[0].start + 1;
ian@0 593
ian@0 594 release_mem_region(port->mapbase, size);
ian@0 595
ian@0 596 if (port->flags & UPF_IOREMAP) {
ian@0 597 iounmap(port->membase);
ian@0 598 port->membase = NULL;
ian@0 599 }
ian@0 600 }
ian@0 601
ian@0 602 /*
ian@0 603 * Request the memory region(s) being used by 'port'.
ian@0 604 */
ian@0 605 static int at91_request_port(struct uart_port *port)
ian@0 606 {
ian@0 607 struct platform_device *pdev = to_platform_device(port->dev);
ian@0 608 int size = pdev->resource[0].end - pdev->resource[0].start + 1;
ian@0 609
ian@0 610 if (!request_mem_region(port->mapbase, size, "at91_serial"))
ian@0 611 return -EBUSY;
ian@0 612
ian@0 613 if (port->flags & UPF_IOREMAP) {
ian@0 614 port->membase = ioremap(port->mapbase, size);
ian@0 615 if (port->membase == NULL) {
ian@0 616 release_mem_region(port->mapbase, size);
ian@0 617 return -ENOMEM;
ian@0 618 }
ian@0 619 }
ian@0 620
ian@0 621 return 0;
ian@0 622 }
ian@0 623
ian@0 624 /*
ian@0 625 * Configure/autoconfigure the port.
ian@0 626 */
ian@0 627 static void at91_config_port(struct uart_port *port, int flags)
ian@0 628 {
ian@0 629 if (flags & UART_CONFIG_TYPE) {
ian@0 630 port->type = PORT_AT91;
ian@0 631 at91_request_port(port);
ian@0 632 }
ian@0 633 }
ian@0 634
ian@0 635 /*
ian@0 636 * Verify the new serial_struct (for TIOCSSERIAL).
ian@0 637 */
ian@0 638 static int at91_verify_port(struct uart_port *port, struct serial_struct *ser)
ian@0 639 {
ian@0 640 int ret = 0;
ian@0 641 if (ser->type != PORT_UNKNOWN && ser->type != PORT_AT91)
ian@0 642 ret = -EINVAL;
ian@0 643 if (port->irq != ser->irq)
ian@0 644 ret = -EINVAL;
ian@0 645 if (ser->io_type != SERIAL_IO_MEM)
ian@0 646 ret = -EINVAL;
ian@0 647 if (port->uartclk / 16 != ser->baud_base)
ian@0 648 ret = -EINVAL;
ian@0 649 if ((void *)port->mapbase != ser->iomem_base)
ian@0 650 ret = -EINVAL;
ian@0 651 if (port->iobase != ser->port)
ian@0 652 ret = -EINVAL;
ian@0 653 if (ser->hub6 != 0)
ian@0 654 ret = -EINVAL;
ian@0 655 return ret;
ian@0 656 }
ian@0 657
ian@0 658 static struct uart_ops at91_pops = {
ian@0 659 .tx_empty = at91_tx_empty,
ian@0 660 .set_mctrl = at91_set_mctrl,
ian@0 661 .get_mctrl = at91_get_mctrl,
ian@0 662 .stop_tx = at91_stop_tx,
ian@0 663 .start_tx = at91_start_tx,
ian@0 664 .stop_rx = at91_stop_rx,
ian@0 665 .enable_ms = at91_enable_ms,
ian@0 666 .break_ctl = at91_break_ctl,
ian@0 667 .startup = at91_startup,
ian@0 668 .shutdown = at91_shutdown,
ian@0 669 .set_termios = at91_set_termios,
ian@0 670 .type = at91_type,
ian@0 671 .release_port = at91_release_port,
ian@0 672 .request_port = at91_request_port,
ian@0 673 .config_port = at91_config_port,
ian@0 674 .verify_port = at91_verify_port,
ian@0 675 .pm = at91_serial_pm,
ian@0 676 };
ian@0 677
ian@0 678 /*
ian@0 679 * Configure the port from the platform device resource info.
ian@0 680 */
ian@0 681 static void __devinit at91_init_port(struct at91_uart_port *at91_port, struct platform_device *pdev)
ian@0 682 {
ian@0 683 struct uart_port *port = &at91_port->uart;
ian@0 684 struct at91_uart_data *data = pdev->dev.platform_data;
ian@0 685
ian@0 686 port->iotype = UPIO_MEM;
ian@0 687 port->flags = UPF_BOOT_AUTOCONF;
ian@0 688 port->ops = &at91_pops;
ian@0 689 port->fifosize = 1;
ian@0 690 port->line = pdev->id;
ian@0 691 port->dev = &pdev->dev;
ian@0 692
ian@0 693 port->mapbase = pdev->resource[0].start;
ian@0 694 port->irq = pdev->resource[1].start;
ian@0 695
ian@0 696 if (port->mapbase == AT91_VA_BASE_SYS + AT91_DBGU) /* Part of system perpherals - already mapped */
ian@0 697 port->membase = (void __iomem *) port->mapbase;
ian@0 698 else {
ian@0 699 port->flags |= UPF_IOREMAP;
ian@0 700 port->membase = NULL;
ian@0 701 }
ian@0 702
ian@0 703 if (!at91_port->clk) { /* for console, the clock could already be configured */
ian@0 704 at91_port->clk = clk_get(&pdev->dev, "usart");
ian@0 705 clk_enable(at91_port->clk);
ian@0 706 port->uartclk = clk_get_rate(at91_port->clk);
ian@0 707 }
ian@0 708 }
ian@0 709
ian@0 710 /*
ian@0 711 * Register board-specific modem-control line handlers.
ian@0 712 */
ian@0 713 void __init at91_register_uart_fns(struct at91_port_fns *fns)
ian@0 714 {
ian@0 715 if (fns->enable_ms)
ian@0 716 at91_pops.enable_ms = fns->enable_ms;
ian@0 717 if (fns->get_mctrl)
ian@0 718 at91_pops.get_mctrl = fns->get_mctrl;
ian@0 719 if (fns->set_mctrl)
ian@0 720 at91_pops.set_mctrl = fns->set_mctrl;
ian@0 721 at91_open = fns->open;
ian@0 722 at91_close = fns->close;
ian@0 723 at91_pops.pm = fns->pm;
ian@0 724 at91_pops.set_wake = fns->set_wake;
ian@0 725 }
ian@0 726
ian@0 727
ian@0 728 #ifdef CONFIG_SERIAL_AT91_CONSOLE
ian@0 729 static void at91_console_putchar(struct uart_port *port, int ch)
ian@0 730 {
ian@0 731 while (!(UART_GET_CSR(port) & AT91_US_TXRDY))
ian@0 732 barrier();
ian@0 733 UART_PUT_CHAR(port, ch);
ian@0 734 }
ian@0 735
ian@0 736 /*
ian@0 737 * Interrupts are disabled on entering
ian@0 738 */
ian@0 739 static void at91_console_write(struct console *co, const char *s, u_int count)
ian@0 740 {
ian@0 741 struct uart_port *port = &at91_ports[co->index].uart;
ian@0 742 unsigned int status, imr;
ian@0 743
ian@0 744 /*
ian@0 745 * First, save IMR and then disable interrupts
ian@0 746 */
ian@0 747 imr = UART_GET_IMR(port); /* get interrupt mask */
ian@0 748 UART_PUT_IDR(port, AT91_US_RXRDY | AT91_US_TXRDY);
ian@0 749
ian@0 750 uart_console_write(port, s, count, at91_console_putchar);
ian@0 751
ian@0 752 /*
ian@0 753 * Finally, wait for transmitter to become empty
ian@0 754 * and restore IMR
ian@0 755 */
ian@0 756 do {
ian@0 757 status = UART_GET_CSR(port);
ian@0 758 } while (!(status & AT91_US_TXRDY));
ian@0 759 UART_PUT_IER(port, imr); /* set interrupts back the way they were */
ian@0 760 }
ian@0 761
ian@0 762 /*
ian@0 763 * If the port was already initialised (eg, by a boot loader), try to determine
ian@0 764 * the current setup.
ian@0 765 */
ian@0 766 static void __init at91_console_get_options(struct uart_port *port, int *baud, int *parity, int *bits)
ian@0 767 {
ian@0 768 unsigned int mr, quot;
ian@0 769
ian@0 770 // TODO: CR is a write-only register
ian@0 771 // unsigned int cr;
ian@0 772 //
ian@0 773 // cr = UART_GET_CR(port) & (AT91_US_RXEN | AT91_US_TXEN);
ian@0 774 // if (cr == (AT91_US_RXEN | AT91_US_TXEN)) {
ian@0 775 // /* ok, the port was enabled */
ian@0 776 // }
ian@0 777
ian@0 778 mr = UART_GET_MR(port) & AT91_US_CHRL;
ian@0 779 if (mr == AT91_US_CHRL_8)
ian@0 780 *bits = 8;
ian@0 781 else
ian@0 782 *bits = 7;
ian@0 783
ian@0 784 mr = UART_GET_MR(port) & AT91_US_PAR;
ian@0 785 if (mr == AT91_US_PAR_EVEN)
ian@0 786 *parity = 'e';
ian@0 787 else if (mr == AT91_US_PAR_ODD)
ian@0 788 *parity = 'o';
ian@0 789
ian@0 790 quot = UART_GET_BRGR(port);
ian@0 791 *baud = port->uartclk / (16 * (quot));
ian@0 792 }
ian@0 793
ian@0 794 static int __init at91_console_setup(struct console *co, char *options)
ian@0 795 {
ian@0 796 struct uart_port *port = &at91_ports[co->index].uart;
ian@0 797 int baud = 115200;
ian@0 798 int bits = 8;
ian@0 799 int parity = 'n';
ian@0 800 int flow = 'n';
ian@0 801
ian@0 802 if (port->membase == 0) /* Port not initialized yet - delay setup */
ian@0 803 return -ENODEV;
ian@0 804
ian@0 805 UART_PUT_IDR(port, -1); /* disable interrupts */
ian@0 806 UART_PUT_CR(port, AT91_US_RSTSTA | AT91_US_RSTRX);
ian@0 807 UART_PUT_CR(port, AT91_US_TXEN | AT91_US_RXEN);
ian@0 808
ian@0 809 if (options)
ian@0 810 uart_parse_options(options, &baud, &parity, &bits, &flow);
ian@0 811 else
ian@0 812 at91_console_get_options(port, &baud, &parity, &bits);
ian@0 813
ian@0 814 return uart_set_options(port, co, baud, parity, bits, flow);
ian@0 815 }
ian@0 816
ian@0 817 static struct uart_driver at91_uart;
ian@0 818
ian@0 819 static struct console at91_console = {
ian@0 820 .name = AT91_DEVICENAME,
ian@0 821 .write = at91_console_write,
ian@0 822 .device = uart_console_device,
ian@0 823 .setup = at91_console_setup,
ian@0 824 .flags = CON_PRINTBUFFER,
ian@0 825 .index = -1,
ian@0 826 .data = &at91_uart,
ian@0 827 };
ian@0 828
ian@0 829 #define AT91_CONSOLE_DEVICE &at91_console
ian@0 830
ian@0 831 /*
ian@0 832 * Early console initialization (before VM subsystem initialized).
ian@0 833 */
ian@0 834 static int __init at91_console_init(void)
ian@0 835 {
ian@0 836 if (at91_default_console_device) {
ian@0 837 add_preferred_console(AT91_DEVICENAME, at91_default_console_device->id, NULL);
ian@0 838 at91_init_port(&(at91_ports[at91_default_console_device->id]), at91_default_console_device);
ian@0 839 register_console(&at91_console);
ian@0 840 }
ian@0 841
ian@0 842 return 0;
ian@0 843 }
ian@0 844 console_initcall(at91_console_init);
ian@0 845
ian@0 846 /*
ian@0 847 * Late console initialization.
ian@0 848 */
ian@0 849 static int __init at91_late_console_init(void)
ian@0 850 {
ian@0 851 if (at91_default_console_device && !(at91_console.flags & CON_ENABLED))
ian@0 852 register_console(&at91_console);
ian@0 853
ian@0 854 return 0;
ian@0 855 }
ian@0 856 core_initcall(at91_late_console_init);
ian@0 857
ian@0 858 #else
ian@0 859 #define AT91_CONSOLE_DEVICE NULL
ian@0 860 #endif
ian@0 861
ian@0 862 static struct uart_driver at91_uart = {
ian@0 863 .owner = THIS_MODULE,
ian@0 864 .driver_name = "at91_serial",
ian@0 865 .dev_name = AT91_DEVICENAME,
ian@0 866 .major = SERIAL_AT91_MAJOR,
ian@0 867 .minor = MINOR_START,
ian@0 868 .nr = AT91_NR_UART,
ian@0 869 .cons = AT91_CONSOLE_DEVICE,
ian@0 870 };
ian@0 871
ian@0 872 #ifdef CONFIG_PM
ian@0 873 static int at91_serial_suspend(struct platform_device *pdev, pm_message_t state)
ian@0 874 {
ian@0 875 struct uart_port *port = platform_get_drvdata(pdev);
ian@0 876 struct at91_uart_port *at91_port = (struct at91_uart_port *) port;
ian@0 877
ian@0 878 if (device_may_wakeup(&pdev->dev) && !at91_suspend_entering_slow_clock())
ian@0 879 enable_irq_wake(port->irq);
ian@0 880 else {
ian@0 881 disable_irq_wake(port->irq);
ian@0 882 uart_suspend_port(&at91_uart, port);
ian@0 883 at91_port->suspended = 1;
ian@0 884 }
ian@0 885
ian@0 886 return 0;
ian@0 887 }
ian@0 888
ian@0 889 static int at91_serial_resume(struct platform_device *pdev)
ian@0 890 {
ian@0 891 struct uart_port *port = platform_get_drvdata(pdev);
ian@0 892 struct at91_uart_port *at91_port = (struct at91_uart_port *) port;
ian@0 893
ian@0 894 if (at91_port->suspended) {
ian@0 895 uart_resume_port(&at91_uart, port);
ian@0 896 at91_port->suspended = 0;
ian@0 897 }
ian@0 898
ian@0 899 return 0;
ian@0 900 }
ian@0 901 #else
ian@0 902 #define at91_serial_suspend NULL
ian@0 903 #define at91_serial_resume NULL
ian@0 904 #endif
ian@0 905
ian@0 906 static int __devinit at91_serial_probe(struct platform_device *pdev)
ian@0 907 {
ian@0 908 struct at91_uart_port *port;
ian@0 909 int ret;
ian@0 910
ian@0 911 port = &at91_ports[pdev->id];
ian@0 912 at91_init_port(port, pdev);
ian@0 913
ian@0 914 ret = uart_add_one_port(&at91_uart, &port->uart);
ian@0 915 if (!ret) {
ian@0 916 device_init_wakeup(&pdev->dev, 1);
ian@0 917 platform_set_drvdata(pdev, port);
ian@0 918 }
ian@0 919
ian@0 920 return ret;
ian@0 921 }
ian@0 922
ian@0 923 static int __devexit at91_serial_remove(struct platform_device *pdev)
ian@0 924 {
ian@0 925 struct uart_port *port = platform_get_drvdata(pdev);
ian@0 926 struct at91_uart_port *at91_port = (struct at91_uart_port *) port;
ian@0 927 int ret = 0;
ian@0 928
ian@0 929 clk_disable(at91_port->clk);
ian@0 930 clk_put(at91_port->clk);
ian@0 931
ian@0 932 device_init_wakeup(&pdev->dev, 0);
ian@0 933 platform_set_drvdata(pdev, NULL);
ian@0 934
ian@0 935 if (port) {
ian@0 936 ret = uart_remove_one_port(&at91_uart, port);
ian@0 937 kfree(port);
ian@0 938 }
ian@0 939
ian@0 940 return ret;
ian@0 941 }
ian@0 942
ian@0 943 static struct platform_driver at91_serial_driver = {
ian@0 944 .probe = at91_serial_probe,
ian@0 945 .remove = __devexit_p(at91_serial_remove),
ian@0 946 .suspend = at91_serial_suspend,
ian@0 947 .resume = at91_serial_resume,
ian@0 948 .driver = {
ian@0 949 .name = "at91_usart",
ian@0 950 .owner = THIS_MODULE,
ian@0 951 },
ian@0 952 };
ian@0 953
ian@0 954 static int __init at91_serial_init(void)
ian@0 955 {
ian@0 956 int ret;
ian@0 957
ian@0 958 ret = uart_register_driver(&at91_uart);
ian@0 959 if (ret)
ian@0 960 return ret;
ian@0 961
ian@0 962 ret = platform_driver_register(&at91_serial_driver);
ian@0 963 if (ret)
ian@0 964 uart_unregister_driver(&at91_uart);
ian@0 965
ian@0 966 return ret;
ian@0 967 }
ian@0 968
ian@0 969 static void __exit at91_serial_exit(void)
ian@0 970 {
ian@0 971 platform_driver_unregister(&at91_serial_driver);
ian@0 972 uart_unregister_driver(&at91_uart);
ian@0 973 }
ian@0 974
ian@0 975 module_init(at91_serial_init);
ian@0 976 module_exit(at91_serial_exit);
ian@0 977
ian@0 978 MODULE_AUTHOR("Rick Bronson");
ian@0 979 MODULE_DESCRIPTION("AT91 generic serial port driver");
ian@0 980 MODULE_LICENSE("GPL");