Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

at v2.6.36-rc6 989 lines 24 kB view raw
1/* 2 * linux/drivers/char/amba.c 3 * 4 * Driver for AMBA serial ports 5 * 6 * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o. 7 * 8 * Copyright 1999 ARM Limited 9 * Copyright (C) 2000 Deep Blue Solutions Ltd. 10 * 11 * This program is free software; you can redistribute it and/or modify 12 * it under the terms of the GNU General Public License as published by 13 * the Free Software Foundation; either version 2 of the License, or 14 * (at your option) any later version. 15 * 16 * This program is distributed in the hope that it will be useful, 17 * but WITHOUT ANY WARRANTY; without even the implied warranty of 18 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 19 * GNU General Public License for more details. 20 * 21 * You should have received a copy of the GNU General Public License 22 * along with this program; if not, write to the Free Software 23 * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA 24 * 25 * This is a generic driver for ARM AMBA-type serial ports. They 26 * have a lot of 16550-like features, but are not register compatible. 27 * Note that although they do have CTS, DCD and DSR inputs, they do 28 * not have an RI input, nor do they have DTR or RTS outputs. If 29 * required, these have to be supplied via some other means (eg, GPIO) 30 * and hooked into this driver. 31 */ 32 33#if defined(CONFIG_SERIAL_AMBA_PL011_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ) 34#define SUPPORT_SYSRQ 35#endif 36 37#include <linux/module.h> 38#include <linux/ioport.h> 39#include <linux/init.h> 40#include <linux/console.h> 41#include <linux/sysrq.h> 42#include <linux/device.h> 43#include <linux/tty.h> 44#include <linux/tty_flip.h> 45#include <linux/serial_core.h> 46#include <linux/serial.h> 47#include <linux/amba/bus.h> 48#include <linux/amba/serial.h> 49#include <linux/clk.h> 50#include <linux/slab.h> 51 52#include <asm/io.h> 53#include <asm/sizes.h> 54 55#define UART_NR 14 56 57#define SERIAL_AMBA_MAJOR 204 58#define SERIAL_AMBA_MINOR 64 59#define SERIAL_AMBA_NR UART_NR 60 61#define AMBA_ISR_PASS_LIMIT 256 62 63#define UART_DR_ERROR (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE) 64#define UART_DUMMY_DR_RX (1 << 16) 65 66/* 67 * We wrap our port structure around the generic uart_port. 68 */ 69struct uart_amba_port { 70 struct uart_port port; 71 struct clk *clk; 72 unsigned int im; /* interrupt mask */ 73 unsigned int old_status; 74 unsigned int ifls; /* vendor-specific */ 75 unsigned int lcrh_tx; /* vendor-specific */ 76 unsigned int lcrh_rx; /* vendor-specific */ 77 bool oversampling; /* vendor-specific */ 78 bool autorts; 79}; 80 81/* There is by now at least one vendor with differing details, so handle it */ 82struct vendor_data { 83 unsigned int ifls; 84 unsigned int fifosize; 85 unsigned int lcrh_tx; 86 unsigned int lcrh_rx; 87 bool oversampling; 88}; 89 90static struct vendor_data vendor_arm = { 91 .ifls = UART011_IFLS_RX4_8|UART011_IFLS_TX4_8, 92 .fifosize = 16, 93 .lcrh_tx = UART011_LCRH, 94 .lcrh_rx = UART011_LCRH, 95 .oversampling = false, 96}; 97 98static struct vendor_data vendor_st = { 99 .ifls = UART011_IFLS_RX_HALF|UART011_IFLS_TX_HALF, 100 .fifosize = 64, 101 .lcrh_tx = ST_UART011_LCRH_TX, 102 .lcrh_rx = ST_UART011_LCRH_RX, 103 .oversampling = true, 104}; 105 106static void pl011_stop_tx(struct uart_port *port) 107{ 108 struct uart_amba_port *uap = (struct uart_amba_port *)port; 109 110 uap->im &= ~UART011_TXIM; 111 writew(uap->im, uap->port.membase + UART011_IMSC); 112} 113 114static void pl011_start_tx(struct uart_port *port) 115{ 116 struct uart_amba_port *uap = (struct uart_amba_port *)port; 117 118 uap->im |= UART011_TXIM; 119 writew(uap->im, uap->port.membase + UART011_IMSC); 120} 121 122static void pl011_stop_rx(struct uart_port *port) 123{ 124 struct uart_amba_port *uap = (struct uart_amba_port *)port; 125 126 uap->im &= ~(UART011_RXIM|UART011_RTIM|UART011_FEIM| 127 UART011_PEIM|UART011_BEIM|UART011_OEIM); 128 writew(uap->im, uap->port.membase + UART011_IMSC); 129} 130 131static void pl011_enable_ms(struct uart_port *port) 132{ 133 struct uart_amba_port *uap = (struct uart_amba_port *)port; 134 135 uap->im |= UART011_RIMIM|UART011_CTSMIM|UART011_DCDMIM|UART011_DSRMIM; 136 writew(uap->im, uap->port.membase + UART011_IMSC); 137} 138 139static void pl011_rx_chars(struct uart_amba_port *uap) 140{ 141 struct tty_struct *tty = uap->port.state->port.tty; 142 unsigned int status, ch, flag, max_count = 256; 143 144 status = readw(uap->port.membase + UART01x_FR); 145 while ((status & UART01x_FR_RXFE) == 0 && max_count--) { 146 ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX; 147 flag = TTY_NORMAL; 148 uap->port.icount.rx++; 149 150 /* 151 * Note that the error handling code is 152 * out of the main execution path 153 */ 154 if (unlikely(ch & UART_DR_ERROR)) { 155 if (ch & UART011_DR_BE) { 156 ch &= ~(UART011_DR_FE | UART011_DR_PE); 157 uap->port.icount.brk++; 158 if (uart_handle_break(&uap->port)) 159 goto ignore_char; 160 } else if (ch & UART011_DR_PE) 161 uap->port.icount.parity++; 162 else if (ch & UART011_DR_FE) 163 uap->port.icount.frame++; 164 if (ch & UART011_DR_OE) 165 uap->port.icount.overrun++; 166 167 ch &= uap->port.read_status_mask; 168 169 if (ch & UART011_DR_BE) 170 flag = TTY_BREAK; 171 else if (ch & UART011_DR_PE) 172 flag = TTY_PARITY; 173 else if (ch & UART011_DR_FE) 174 flag = TTY_FRAME; 175 } 176 177 if (uart_handle_sysrq_char(&uap->port, ch & 255)) 178 goto ignore_char; 179 180 uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag); 181 182 ignore_char: 183 status = readw(uap->port.membase + UART01x_FR); 184 } 185 spin_unlock(&uap->port.lock); 186 tty_flip_buffer_push(tty); 187 spin_lock(&uap->port.lock); 188} 189 190static void pl011_tx_chars(struct uart_amba_port *uap) 191{ 192 struct circ_buf *xmit = &uap->port.state->xmit; 193 int count; 194 195 if (uap->port.x_char) { 196 writew(uap->port.x_char, uap->port.membase + UART01x_DR); 197 uap->port.icount.tx++; 198 uap->port.x_char = 0; 199 return; 200 } 201 if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) { 202 pl011_stop_tx(&uap->port); 203 return; 204 } 205 206 count = uap->port.fifosize >> 1; 207 do { 208 writew(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR); 209 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 210 uap->port.icount.tx++; 211 if (uart_circ_empty(xmit)) 212 break; 213 } while (--count > 0); 214 215 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS) 216 uart_write_wakeup(&uap->port); 217 218 if (uart_circ_empty(xmit)) 219 pl011_stop_tx(&uap->port); 220} 221 222static void pl011_modem_status(struct uart_amba_port *uap) 223{ 224 unsigned int status, delta; 225 226 status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; 227 228 delta = status ^ uap->old_status; 229 uap->old_status = status; 230 231 if (!delta) 232 return; 233 234 if (delta & UART01x_FR_DCD) 235 uart_handle_dcd_change(&uap->port, status & UART01x_FR_DCD); 236 237 if (delta & UART01x_FR_DSR) 238 uap->port.icount.dsr++; 239 240 if (delta & UART01x_FR_CTS) 241 uart_handle_cts_change(&uap->port, status & UART01x_FR_CTS); 242 243 wake_up_interruptible(&uap->port.state->port.delta_msr_wait); 244} 245 246static irqreturn_t pl011_int(int irq, void *dev_id) 247{ 248 struct uart_amba_port *uap = dev_id; 249 unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT; 250 int handled = 0; 251 252 spin_lock(&uap->port.lock); 253 254 status = readw(uap->port.membase + UART011_MIS); 255 if (status) { 256 do { 257 writew(status & ~(UART011_TXIS|UART011_RTIS| 258 UART011_RXIS), 259 uap->port.membase + UART011_ICR); 260 261 if (status & (UART011_RTIS|UART011_RXIS)) 262 pl011_rx_chars(uap); 263 if (status & (UART011_DSRMIS|UART011_DCDMIS| 264 UART011_CTSMIS|UART011_RIMIS)) 265 pl011_modem_status(uap); 266 if (status & UART011_TXIS) 267 pl011_tx_chars(uap); 268 269 if (pass_counter-- == 0) 270 break; 271 272 status = readw(uap->port.membase + UART011_MIS); 273 } while (status != 0); 274 handled = 1; 275 } 276 277 spin_unlock(&uap->port.lock); 278 279 return IRQ_RETVAL(handled); 280} 281 282static unsigned int pl01x_tx_empty(struct uart_port *port) 283{ 284 struct uart_amba_port *uap = (struct uart_amba_port *)port; 285 unsigned int status = readw(uap->port.membase + UART01x_FR); 286 return status & (UART01x_FR_BUSY|UART01x_FR_TXFF) ? 0 : TIOCSER_TEMT; 287} 288 289static unsigned int pl01x_get_mctrl(struct uart_port *port) 290{ 291 struct uart_amba_port *uap = (struct uart_amba_port *)port; 292 unsigned int result = 0; 293 unsigned int status = readw(uap->port.membase + UART01x_FR); 294 295#define TIOCMBIT(uartbit, tiocmbit) \ 296 if (status & uartbit) \ 297 result |= tiocmbit 298 299 TIOCMBIT(UART01x_FR_DCD, TIOCM_CAR); 300 TIOCMBIT(UART01x_FR_DSR, TIOCM_DSR); 301 TIOCMBIT(UART01x_FR_CTS, TIOCM_CTS); 302 TIOCMBIT(UART011_FR_RI, TIOCM_RNG); 303#undef TIOCMBIT 304 return result; 305} 306 307static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl) 308{ 309 struct uart_amba_port *uap = (struct uart_amba_port *)port; 310 unsigned int cr; 311 312 cr = readw(uap->port.membase + UART011_CR); 313 314#define TIOCMBIT(tiocmbit, uartbit) \ 315 if (mctrl & tiocmbit) \ 316 cr |= uartbit; \ 317 else \ 318 cr &= ~uartbit 319 320 TIOCMBIT(TIOCM_RTS, UART011_CR_RTS); 321 TIOCMBIT(TIOCM_DTR, UART011_CR_DTR); 322 TIOCMBIT(TIOCM_OUT1, UART011_CR_OUT1); 323 TIOCMBIT(TIOCM_OUT2, UART011_CR_OUT2); 324 TIOCMBIT(TIOCM_LOOP, UART011_CR_LBE); 325 326 if (uap->autorts) { 327 /* We need to disable auto-RTS if we want to turn RTS off */ 328 TIOCMBIT(TIOCM_RTS, UART011_CR_RTSEN); 329 } 330#undef TIOCMBIT 331 332 writew(cr, uap->port.membase + UART011_CR); 333} 334 335static void pl011_break_ctl(struct uart_port *port, int break_state) 336{ 337 struct uart_amba_port *uap = (struct uart_amba_port *)port; 338 unsigned long flags; 339 unsigned int lcr_h; 340 341 spin_lock_irqsave(&uap->port.lock, flags); 342 lcr_h = readw(uap->port.membase + uap->lcrh_tx); 343 if (break_state == -1) 344 lcr_h |= UART01x_LCRH_BRK; 345 else 346 lcr_h &= ~UART01x_LCRH_BRK; 347 writew(lcr_h, uap->port.membase + uap->lcrh_tx); 348 spin_unlock_irqrestore(&uap->port.lock, flags); 349} 350 351#ifdef CONFIG_CONSOLE_POLL 352static int pl010_get_poll_char(struct uart_port *port) 353{ 354 struct uart_amba_port *uap = (struct uart_amba_port *)port; 355 unsigned int status; 356 357 status = readw(uap->port.membase + UART01x_FR); 358 if (status & UART01x_FR_RXFE) 359 return NO_POLL_CHAR; 360 361 return readw(uap->port.membase + UART01x_DR); 362} 363 364static void pl010_put_poll_char(struct uart_port *port, 365 unsigned char ch) 366{ 367 struct uart_amba_port *uap = (struct uart_amba_port *)port; 368 369 while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) 370 barrier(); 371 372 writew(ch, uap->port.membase + UART01x_DR); 373} 374 375#endif /* CONFIG_CONSOLE_POLL */ 376 377static int pl011_startup(struct uart_port *port) 378{ 379 struct uart_amba_port *uap = (struct uart_amba_port *)port; 380 unsigned int cr; 381 int retval; 382 383 /* 384 * Try to enable the clock producer. 385 */ 386 retval = clk_enable(uap->clk); 387 if (retval) 388 goto out; 389 390 uap->port.uartclk = clk_get_rate(uap->clk); 391 392 /* 393 * Allocate the IRQ 394 */ 395 retval = request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap); 396 if (retval) 397 goto clk_dis; 398 399 writew(uap->ifls, uap->port.membase + UART011_IFLS); 400 401 /* 402 * Provoke TX FIFO interrupt into asserting. 403 */ 404 cr = UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_LBE; 405 writew(cr, uap->port.membase + UART011_CR); 406 writew(0, uap->port.membase + UART011_FBRD); 407 writew(1, uap->port.membase + UART011_IBRD); 408 writew(0, uap->port.membase + uap->lcrh_rx); 409 if (uap->lcrh_tx != uap->lcrh_rx) { 410 int i; 411 /* 412 * Wait 10 PCLKs before writing LCRH_TX register, 413 * to get this delay write read only register 10 times 414 */ 415 for (i = 0; i < 10; ++i) 416 writew(0xff, uap->port.membase + UART011_MIS); 417 writew(0, uap->port.membase + uap->lcrh_tx); 418 } 419 writew(0, uap->port.membase + UART01x_DR); 420 while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY) 421 barrier(); 422 423 cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE; 424 writew(cr, uap->port.membase + UART011_CR); 425 426 /* 427 * initialise the old status of the modem signals 428 */ 429 uap->old_status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; 430 431 /* 432 * Finally, enable interrupts 433 */ 434 spin_lock_irq(&uap->port.lock); 435 uap->im = UART011_RXIM | UART011_RTIM; 436 writew(uap->im, uap->port.membase + UART011_IMSC); 437 spin_unlock_irq(&uap->port.lock); 438 439 return 0; 440 441 clk_dis: 442 clk_disable(uap->clk); 443 out: 444 return retval; 445} 446 447static void pl011_shutdown_channel(struct uart_amba_port *uap, 448 unsigned int lcrh) 449{ 450 unsigned long val; 451 452 val = readw(uap->port.membase + lcrh); 453 val &= ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN); 454 writew(val, uap->port.membase + lcrh); 455} 456 457static void pl011_shutdown(struct uart_port *port) 458{ 459 struct uart_amba_port *uap = (struct uart_amba_port *)port; 460 461 /* 462 * disable all interrupts 463 */ 464 spin_lock_irq(&uap->port.lock); 465 uap->im = 0; 466 writew(uap->im, uap->port.membase + UART011_IMSC); 467 writew(0xffff, uap->port.membase + UART011_ICR); 468 spin_unlock_irq(&uap->port.lock); 469 470 /* 471 * Free the interrupt 472 */ 473 free_irq(uap->port.irq, uap); 474 475 /* 476 * disable the port 477 */ 478 uap->autorts = false; 479 writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR); 480 481 /* 482 * disable break condition and fifos 483 */ 484 pl011_shutdown_channel(uap, uap->lcrh_rx); 485 if (uap->lcrh_rx != uap->lcrh_tx) 486 pl011_shutdown_channel(uap, uap->lcrh_tx); 487 488 /* 489 * Shut down the clock producer 490 */ 491 clk_disable(uap->clk); 492} 493 494static void 495pl011_set_termios(struct uart_port *port, struct ktermios *termios, 496 struct ktermios *old) 497{ 498 struct uart_amba_port *uap = (struct uart_amba_port *)port; 499 unsigned int lcr_h, old_cr; 500 unsigned long flags; 501 unsigned int baud, quot; 502 503 /* 504 * Ask the core to calculate the divisor for us. 505 */ 506 baud = uart_get_baud_rate(port, termios, old, 0, 507 port->uartclk/(uap->oversampling ? 8 : 16)); 508 509 if (baud > port->uartclk/16) 510 quot = DIV_ROUND_CLOSEST(port->uartclk * 8, baud); 511 else 512 quot = DIV_ROUND_CLOSEST(port->uartclk * 4, baud); 513 514 switch (termios->c_cflag & CSIZE) { 515 case CS5: 516 lcr_h = UART01x_LCRH_WLEN_5; 517 break; 518 case CS6: 519 lcr_h = UART01x_LCRH_WLEN_6; 520 break; 521 case CS7: 522 lcr_h = UART01x_LCRH_WLEN_7; 523 break; 524 default: // CS8 525 lcr_h = UART01x_LCRH_WLEN_8; 526 break; 527 } 528 if (termios->c_cflag & CSTOPB) 529 lcr_h |= UART01x_LCRH_STP2; 530 if (termios->c_cflag & PARENB) { 531 lcr_h |= UART01x_LCRH_PEN; 532 if (!(termios->c_cflag & PARODD)) 533 lcr_h |= UART01x_LCRH_EPS; 534 } 535 if (port->fifosize > 1) 536 lcr_h |= UART01x_LCRH_FEN; 537 538 spin_lock_irqsave(&port->lock, flags); 539 540 /* 541 * Update the per-port timeout. 542 */ 543 uart_update_timeout(port, termios->c_cflag, baud); 544 545 port->read_status_mask = UART011_DR_OE | 255; 546 if (termios->c_iflag & INPCK) 547 port->read_status_mask |= UART011_DR_FE | UART011_DR_PE; 548 if (termios->c_iflag & (BRKINT | PARMRK)) 549 port->read_status_mask |= UART011_DR_BE; 550 551 /* 552 * Characters to ignore 553 */ 554 port->ignore_status_mask = 0; 555 if (termios->c_iflag & IGNPAR) 556 port->ignore_status_mask |= UART011_DR_FE | UART011_DR_PE; 557 if (termios->c_iflag & IGNBRK) { 558 port->ignore_status_mask |= UART011_DR_BE; 559 /* 560 * If we're ignoring parity and break indicators, 561 * ignore overruns too (for real raw support). 562 */ 563 if (termios->c_iflag & IGNPAR) 564 port->ignore_status_mask |= UART011_DR_OE; 565 } 566 567 /* 568 * Ignore all characters if CREAD is not set. 569 */ 570 if ((termios->c_cflag & CREAD) == 0) 571 port->ignore_status_mask |= UART_DUMMY_DR_RX; 572 573 if (UART_ENABLE_MS(port, termios->c_cflag)) 574 pl011_enable_ms(port); 575 576 /* first, disable everything */ 577 old_cr = readw(port->membase + UART011_CR); 578 writew(0, port->membase + UART011_CR); 579 580 if (termios->c_cflag & CRTSCTS) { 581 if (old_cr & UART011_CR_RTS) 582 old_cr |= UART011_CR_RTSEN; 583 584 old_cr |= UART011_CR_CTSEN; 585 uap->autorts = true; 586 } else { 587 old_cr &= ~(UART011_CR_CTSEN | UART011_CR_RTSEN); 588 uap->autorts = false; 589 } 590 591 if (uap->oversampling) { 592 if (baud > port->uartclk/16) 593 old_cr |= ST_UART011_CR_OVSFACT; 594 else 595 old_cr &= ~ST_UART011_CR_OVSFACT; 596 } 597 598 /* Set baud rate */ 599 writew(quot & 0x3f, port->membase + UART011_FBRD); 600 writew(quot >> 6, port->membase + UART011_IBRD); 601 602 /* 603 * ----------v----------v----------v----------v----- 604 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L 605 * ----------^----------^----------^----------^----- 606 */ 607 writew(lcr_h, port->membase + uap->lcrh_rx); 608 if (uap->lcrh_rx != uap->lcrh_tx) { 609 int i; 610 /* 611 * Wait 10 PCLKs before writing LCRH_TX register, 612 * to get this delay write read only register 10 times 613 */ 614 for (i = 0; i < 10; ++i) 615 writew(0xff, uap->port.membase + UART011_MIS); 616 writew(lcr_h, port->membase + uap->lcrh_tx); 617 } 618 writew(old_cr, port->membase + UART011_CR); 619 620 spin_unlock_irqrestore(&port->lock, flags); 621} 622 623static const char *pl011_type(struct uart_port *port) 624{ 625 return port->type == PORT_AMBA ? "AMBA/PL011" : NULL; 626} 627 628/* 629 * Release the memory region(s) being used by 'port' 630 */ 631static void pl010_release_port(struct uart_port *port) 632{ 633 release_mem_region(port->mapbase, SZ_4K); 634} 635 636/* 637 * Request the memory region(s) being used by 'port' 638 */ 639static int pl010_request_port(struct uart_port *port) 640{ 641 return request_mem_region(port->mapbase, SZ_4K, "uart-pl011") 642 != NULL ? 0 : -EBUSY; 643} 644 645/* 646 * Configure/autoconfigure the port. 647 */ 648static void pl010_config_port(struct uart_port *port, int flags) 649{ 650 if (flags & UART_CONFIG_TYPE) { 651 port->type = PORT_AMBA; 652 pl010_request_port(port); 653 } 654} 655 656/* 657 * verify the new serial_struct (for TIOCSSERIAL). 658 */ 659static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser) 660{ 661 int ret = 0; 662 if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA) 663 ret = -EINVAL; 664 if (ser->irq < 0 || ser->irq >= nr_irqs) 665 ret = -EINVAL; 666 if (ser->baud_base < 9600) 667 ret = -EINVAL; 668 return ret; 669} 670 671static struct uart_ops amba_pl011_pops = { 672 .tx_empty = pl01x_tx_empty, 673 .set_mctrl = pl011_set_mctrl, 674 .get_mctrl = pl01x_get_mctrl, 675 .stop_tx = pl011_stop_tx, 676 .start_tx = pl011_start_tx, 677 .stop_rx = pl011_stop_rx, 678 .enable_ms = pl011_enable_ms, 679 .break_ctl = pl011_break_ctl, 680 .startup = pl011_startup, 681 .shutdown = pl011_shutdown, 682 .set_termios = pl011_set_termios, 683 .type = pl011_type, 684 .release_port = pl010_release_port, 685 .request_port = pl010_request_port, 686 .config_port = pl010_config_port, 687 .verify_port = pl010_verify_port, 688#ifdef CONFIG_CONSOLE_POLL 689 .poll_get_char = pl010_get_poll_char, 690 .poll_put_char = pl010_put_poll_char, 691#endif 692}; 693 694static struct uart_amba_port *amba_ports[UART_NR]; 695 696#ifdef CONFIG_SERIAL_AMBA_PL011_CONSOLE 697 698static void pl011_console_putchar(struct uart_port *port, int ch) 699{ 700 struct uart_amba_port *uap = (struct uart_amba_port *)port; 701 702 while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF) 703 barrier(); 704 writew(ch, uap->port.membase + UART01x_DR); 705} 706 707static void 708pl011_console_write(struct console *co, const char *s, unsigned int count) 709{ 710 struct uart_amba_port *uap = amba_ports[co->index]; 711 unsigned int status, old_cr, new_cr; 712 713 clk_enable(uap->clk); 714 715 /* 716 * First save the CR then disable the interrupts 717 */ 718 old_cr = readw(uap->port.membase + UART011_CR); 719 new_cr = old_cr & ~UART011_CR_CTSEN; 720 new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE; 721 writew(new_cr, uap->port.membase + UART011_CR); 722 723 uart_console_write(&uap->port, s, count, pl011_console_putchar); 724 725 /* 726 * Finally, wait for transmitter to become empty 727 * and restore the TCR 728 */ 729 do { 730 status = readw(uap->port.membase + UART01x_FR); 731 } while (status & UART01x_FR_BUSY); 732 writew(old_cr, uap->port.membase + UART011_CR); 733 734 clk_disable(uap->clk); 735} 736 737static void __init 738pl011_console_get_options(struct uart_amba_port *uap, int *baud, 739 int *parity, int *bits) 740{ 741 if (readw(uap->port.membase + UART011_CR) & UART01x_CR_UARTEN) { 742 unsigned int lcr_h, ibrd, fbrd; 743 744 lcr_h = readw(uap->port.membase + uap->lcrh_tx); 745 746 *parity = 'n'; 747 if (lcr_h & UART01x_LCRH_PEN) { 748 if (lcr_h & UART01x_LCRH_EPS) 749 *parity = 'e'; 750 else 751 *parity = 'o'; 752 } 753 754 if ((lcr_h & 0x60) == UART01x_LCRH_WLEN_7) 755 *bits = 7; 756 else 757 *bits = 8; 758 759 ibrd = readw(uap->port.membase + UART011_IBRD); 760 fbrd = readw(uap->port.membase + UART011_FBRD); 761 762 *baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd); 763 764 if (uap->oversampling) { 765 if (readw(uap->port.membase + UART011_CR) 766 & ST_UART011_CR_OVSFACT) 767 *baud *= 2; 768 } 769 } 770} 771 772static int __init pl011_console_setup(struct console *co, char *options) 773{ 774 struct uart_amba_port *uap; 775 int baud = 38400; 776 int bits = 8; 777 int parity = 'n'; 778 int flow = 'n'; 779 780 /* 781 * Check whether an invalid uart number has been specified, and 782 * if so, search for the first available port that does have 783 * console support. 784 */ 785 if (co->index >= UART_NR) 786 co->index = 0; 787 uap = amba_ports[co->index]; 788 if (!uap) 789 return -ENODEV; 790 791 uap->port.uartclk = clk_get_rate(uap->clk); 792 793 if (options) 794 uart_parse_options(options, &baud, &parity, &bits, &flow); 795 else 796 pl011_console_get_options(uap, &baud, &parity, &bits); 797 798 return uart_set_options(&uap->port, co, baud, parity, bits, flow); 799} 800 801static struct uart_driver amba_reg; 802static struct console amba_console = { 803 .name = "ttyAMA", 804 .write = pl011_console_write, 805 .device = uart_console_device, 806 .setup = pl011_console_setup, 807 .flags = CON_PRINTBUFFER, 808 .index = -1, 809 .data = &amba_reg, 810}; 811 812#define AMBA_CONSOLE (&amba_console) 813#else 814#define AMBA_CONSOLE NULL 815#endif 816 817static struct uart_driver amba_reg = { 818 .owner = THIS_MODULE, 819 .driver_name = "ttyAMA", 820 .dev_name = "ttyAMA", 821 .major = SERIAL_AMBA_MAJOR, 822 .minor = SERIAL_AMBA_MINOR, 823 .nr = UART_NR, 824 .cons = AMBA_CONSOLE, 825}; 826 827static int pl011_probe(struct amba_device *dev, struct amba_id *id) 828{ 829 struct uart_amba_port *uap; 830 struct vendor_data *vendor = id->data; 831 void __iomem *base; 832 int i, ret; 833 834 for (i = 0; i < ARRAY_SIZE(amba_ports); i++) 835 if (amba_ports[i] == NULL) 836 break; 837 838 if (i == ARRAY_SIZE(amba_ports)) { 839 ret = -EBUSY; 840 goto out; 841 } 842 843 uap = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL); 844 if (uap == NULL) { 845 ret = -ENOMEM; 846 goto out; 847 } 848 849 base = ioremap(dev->res.start, resource_size(&dev->res)); 850 if (!base) { 851 ret = -ENOMEM; 852 goto free; 853 } 854 855 uap->clk = clk_get(&dev->dev, NULL); 856 if (IS_ERR(uap->clk)) { 857 ret = PTR_ERR(uap->clk); 858 goto unmap; 859 } 860 861 uap->ifls = vendor->ifls; 862 uap->lcrh_rx = vendor->lcrh_rx; 863 uap->lcrh_tx = vendor->lcrh_tx; 864 uap->oversampling = vendor->oversampling; 865 uap->port.dev = &dev->dev; 866 uap->port.mapbase = dev->res.start; 867 uap->port.membase = base; 868 uap->port.iotype = UPIO_MEM; 869 uap->port.irq = dev->irq[0]; 870 uap->port.fifosize = vendor->fifosize; 871 uap->port.ops = &amba_pl011_pops; 872 uap->port.flags = UPF_BOOT_AUTOCONF; 873 uap->port.line = i; 874 875 amba_ports[i] = uap; 876 877 amba_set_drvdata(dev, uap); 878 ret = uart_add_one_port(&amba_reg, &uap->port); 879 if (ret) { 880 amba_set_drvdata(dev, NULL); 881 amba_ports[i] = NULL; 882 clk_put(uap->clk); 883 unmap: 884 iounmap(base); 885 free: 886 kfree(uap); 887 } 888 out: 889 return ret; 890} 891 892static int pl011_remove(struct amba_device *dev) 893{ 894 struct uart_amba_port *uap = amba_get_drvdata(dev); 895 int i; 896 897 amba_set_drvdata(dev, NULL); 898 899 uart_remove_one_port(&amba_reg, &uap->port); 900 901 for (i = 0; i < ARRAY_SIZE(amba_ports); i++) 902 if (amba_ports[i] == uap) 903 amba_ports[i] = NULL; 904 905 iounmap(uap->port.membase); 906 clk_put(uap->clk); 907 kfree(uap); 908 return 0; 909} 910 911#ifdef CONFIG_PM 912static int pl011_suspend(struct amba_device *dev, pm_message_t state) 913{ 914 struct uart_amba_port *uap = amba_get_drvdata(dev); 915 916 if (!uap) 917 return -EINVAL; 918 919 return uart_suspend_port(&amba_reg, &uap->port); 920} 921 922static int pl011_resume(struct amba_device *dev) 923{ 924 struct uart_amba_port *uap = amba_get_drvdata(dev); 925 926 if (!uap) 927 return -EINVAL; 928 929 return uart_resume_port(&amba_reg, &uap->port); 930} 931#endif 932 933static struct amba_id pl011_ids[] = { 934 { 935 .id = 0x00041011, 936 .mask = 0x000fffff, 937 .data = &vendor_arm, 938 }, 939 { 940 .id = 0x00380802, 941 .mask = 0x00ffffff, 942 .data = &vendor_st, 943 }, 944 { 0, 0 }, 945}; 946 947static struct amba_driver pl011_driver = { 948 .drv = { 949 .name = "uart-pl011", 950 }, 951 .id_table = pl011_ids, 952 .probe = pl011_probe, 953 .remove = pl011_remove, 954#ifdef CONFIG_PM 955 .suspend = pl011_suspend, 956 .resume = pl011_resume, 957#endif 958}; 959 960static int __init pl011_init(void) 961{ 962 int ret; 963 printk(KERN_INFO "Serial: AMBA PL011 UART driver\n"); 964 965 ret = uart_register_driver(&amba_reg); 966 if (ret == 0) { 967 ret = amba_driver_register(&pl011_driver); 968 if (ret) 969 uart_unregister_driver(&amba_reg); 970 } 971 return ret; 972} 973 974static void __exit pl011_exit(void) 975{ 976 amba_driver_unregister(&pl011_driver); 977 uart_unregister_driver(&amba_reg); 978} 979 980/* 981 * While this can be a module, if builtin it's most likely the console 982 * So let's leave module_exit but move module_init to an earlier place 983 */ 984arch_initcall(pl011_init); 985module_exit(pl011_exit); 986 987MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd"); 988MODULE_DESCRIPTION("ARM AMBA serial port driver"); 989MODULE_LICENSE("GPL");