diff options
| -rw-r--r-- | drivers/serial/amba-pl010.c | 110 |
1 files changed, 49 insertions, 61 deletions
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c index e04d5e82d9ae..127d6cd5de7f 100644 --- a/drivers/serial/amba-pl010.c +++ b/drivers/serial/amba-pl010.c | |||
| @@ -62,26 +62,8 @@ | |||
| 62 | 62 | ||
| 63 | #define AMBA_ISR_PASS_LIMIT 256 | 63 | #define AMBA_ISR_PASS_LIMIT 256 |
| 64 | 64 | ||
| 65 | /* | ||
| 66 | * Access macros for the AMBA UARTs | ||
| 67 | */ | ||
| 68 | #define UART_GET_INT_STATUS(p) readb((p)->membase + UART010_IIR) | ||
| 69 | #define UART_PUT_ICR(p, c) writel((c), (p)->membase + UART010_ICR) | ||
| 70 | #define UART_GET_FR(p) readb((p)->membase + UART01x_FR) | ||
| 71 | #define UART_GET_CHAR(p) readb((p)->membase + UART01x_DR) | ||
| 72 | #define UART_PUT_CHAR(p, c) writel((c), (p)->membase + UART01x_DR) | ||
| 73 | #define UART_GET_RSR(p) readb((p)->membase + UART01x_RSR) | ||
| 74 | #define UART_GET_CR(p) readb((p)->membase + UART010_CR) | ||
| 75 | #define UART_PUT_CR(p,c) writel((c), (p)->membase + UART010_CR) | ||
| 76 | #define UART_GET_LCRL(p) readb((p)->membase + UART010_LCRL) | ||
| 77 | #define UART_PUT_LCRL(p,c) writel((c), (p)->membase + UART010_LCRL) | ||
| 78 | #define UART_GET_LCRM(p) readb((p)->membase + UART010_LCRM) | ||
| 79 | #define UART_PUT_LCRM(p,c) writel((c), (p)->membase + UART010_LCRM) | ||
| 80 | #define UART_GET_LCRH(p) readb((p)->membase + UART010_LCRH) | ||
| 81 | #define UART_PUT_LCRH(p,c) writel((c), (p)->membase + UART010_LCRH) | ||
| 82 | #define UART_RX_DATA(s) (((s) & UART01x_FR_RXFE) == 0) | 65 | #define UART_RX_DATA(s) (((s) & UART01x_FR_RXFE) == 0) |
| 83 | #define UART_TX_READY(s) (((s) & UART01x_FR_TXFF) == 0) | 66 | #define UART_TX_READY(s) (((s) & UART01x_FR_TXFF) == 0) |
| 84 | #define UART_TX_EMPTY(p) ((UART_GET_FR(p) & UART01x_FR_TMSK) == 0) | ||
| 85 | 67 | ||
| 86 | #define UART_DUMMY_RSR_RX /*256*/0 | 68 | #define UART_DUMMY_RSR_RX /*256*/0 |
| 87 | #define UART_PORT_SIZE 64 | 69 | #define UART_PORT_SIZE 64 |
| @@ -110,36 +92,36 @@ static void pl010_stop_tx(struct uart_port *port) | |||
| 110 | { | 92 | { |
| 111 | unsigned int cr; | 93 | unsigned int cr; |
| 112 | 94 | ||
| 113 | cr = UART_GET_CR(port); | 95 | cr = readb(port->membase + UART010_CR); |
| 114 | cr &= ~UART010_CR_TIE; | 96 | cr &= ~UART010_CR_TIE; |
| 115 | UART_PUT_CR(port, cr); | 97 | writel(cr, port->membase + UART010_CR); |
| 116 | } | 98 | } |
| 117 | 99 | ||
| 118 | static void pl010_start_tx(struct uart_port *port) | 100 | static void pl010_start_tx(struct uart_port *port) |
| 119 | { | 101 | { |
| 120 | unsigned int cr; | 102 | unsigned int cr; |
| 121 | 103 | ||
| 122 | cr = UART_GET_CR(port); | 104 | cr = readb(port->membase + UART010_CR); |
| 123 | cr |= UART010_CR_TIE; | 105 | cr |= UART010_CR_TIE; |
| 124 | UART_PUT_CR(port, cr); | 106 | writel(cr, port->membase + UART010_CR); |
| 125 | } | 107 | } |
| 126 | 108 | ||
| 127 | static void pl010_stop_rx(struct uart_port *port) | 109 | static void pl010_stop_rx(struct uart_port *port) |
| 128 | { | 110 | { |
| 129 | unsigned int cr; | 111 | unsigned int cr; |
| 130 | 112 | ||
| 131 | cr = UART_GET_CR(port); | 113 | cr = readb(port->membase + UART010_CR); |
| 132 | cr &= ~(UART010_CR_RIE | UART010_CR_RTIE); | 114 | cr &= ~(UART010_CR_RIE | UART010_CR_RTIE); |
| 133 | UART_PUT_CR(port, cr); | 115 | writel(cr, port->membase + UART010_CR); |
| 134 | } | 116 | } |
| 135 | 117 | ||
| 136 | static void pl010_enable_ms(struct uart_port *port) | 118 | static void pl010_enable_ms(struct uart_port *port) |
| 137 | { | 119 | { |
| 138 | unsigned int cr; | 120 | unsigned int cr; |
| 139 | 121 | ||
| 140 | cr = UART_GET_CR(port); | 122 | cr = readb(port->membase + UART010_CR); |
| 141 | cr |= UART010_CR_MSIE; | 123 | cr |= UART010_CR_MSIE; |
| 142 | UART_PUT_CR(port, cr); | 124 | writel(cr, port->membase + UART010_CR); |
| 143 | } | 125 | } |
| 144 | 126 | ||
| 145 | static void | 127 | static void |
| @@ -152,9 +134,9 @@ pl010_rx_chars(struct uart_port *port) | |||
| 152 | struct tty_struct *tty = port->info->tty; | 134 | struct tty_struct *tty = port->info->tty; |
| 153 | unsigned int status, ch, flag, rsr, max_count = 256; | 135 | unsigned int status, ch, flag, rsr, max_count = 256; |
| 154 | 136 | ||
| 155 | status = UART_GET_FR(port); | 137 | status = readb(port->membase + UART01x_FR); |
| 156 | while (UART_RX_DATA(status) && max_count--) { | 138 | while (UART_RX_DATA(status) && max_count--) { |
| 157 | ch = UART_GET_CHAR(port); | 139 | ch = readb(port->membase + UART01x_DR); |
| 158 | flag = TTY_NORMAL; | 140 | flag = TTY_NORMAL; |
| 159 | 141 | ||
| 160 | port->icount.rx++; | 142 | port->icount.rx++; |
| @@ -163,7 +145,7 @@ pl010_rx_chars(struct uart_port *port) | |||
| 163 | * Note that the error handling code is | 145 | * Note that the error handling code is |
| 164 | * out of the main execution path | 146 | * out of the main execution path |
| 165 | */ | 147 | */ |
| 166 | rsr = UART_GET_RSR(port) | UART_DUMMY_RSR_RX; | 148 | rsr = readb(port->membase + UART01x_RSR) | UART_DUMMY_RSR_RX; |
| 167 | if (unlikely(rsr & UART01x_RSR_ANY)) { | 149 | if (unlikely(rsr & UART01x_RSR_ANY)) { |
| 168 | if (rsr & UART01x_RSR_BE) { | 150 | if (rsr & UART01x_RSR_BE) { |
| 169 | rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE); | 151 | rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE); |
| @@ -193,7 +175,7 @@ pl010_rx_chars(struct uart_port *port) | |||
| 193 | uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag); | 175 | uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag); |
| 194 | 176 | ||
| 195 | ignore_char: | 177 | ignore_char: |
| 196 | status = UART_GET_FR(port); | 178 | status = readb(port->membase + UART01x_FR); |
| 197 | } | 179 | } |
| 198 | tty_flip_buffer_push(tty); | 180 | tty_flip_buffer_push(tty); |
| 199 | return; | 181 | return; |
| @@ -205,7 +187,7 @@ static void pl010_tx_chars(struct uart_port *port) | |||
| 205 | int count; | 187 | int count; |
| 206 | 188 | ||
| 207 | if (port->x_char) { | 189 | if (port->x_char) { |
| 208 | UART_PUT_CHAR(port, port->x_char); | 190 | writel(port->x_char, port->membase + UART01x_DR); |
| 209 | port->icount.tx++; | 191 | port->icount.tx++; |
| 210 | port->x_char = 0; | 192 | port->x_char = 0; |
| 211 | return; | 193 | return; |
| @@ -217,7 +199,7 @@ static void pl010_tx_chars(struct uart_port *port) | |||
| 217 | 199 | ||
| 218 | count = port->fifosize >> 1; | 200 | count = port->fifosize >> 1; |
| 219 | do { | 201 | do { |
| 220 | UART_PUT_CHAR(port, xmit->buf[xmit->tail]); | 202 | writel(xmit->buf[xmit->tail], port->membase + UART01x_DR); |
| 221 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); | 203 | xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); |
| 222 | port->icount.tx++; | 204 | port->icount.tx++; |
| 223 | if (uart_circ_empty(xmit)) | 205 | if (uart_circ_empty(xmit)) |
| @@ -236,9 +218,9 @@ static void pl010_modem_status(struct uart_port *port) | |||
| 236 | struct uart_amba_port *uap = (struct uart_amba_port *)port; | 218 | struct uart_amba_port *uap = (struct uart_amba_port *)port; |
| 237 | unsigned int status, delta; | 219 | unsigned int status, delta; |
| 238 | 220 | ||
| 239 | UART_PUT_ICR(&uap->port, 0); | 221 | writel(0, uap->port.membase + UART010_ICR); |
| 240 | 222 | ||
| 241 | status = UART_GET_FR(&uap->port) & UART01x_FR_MODEM_ANY; | 223 | status = readb(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY; |
| 242 | 224 | ||
| 243 | delta = status ^ uap->old_status; | 225 | delta = status ^ uap->old_status; |
| 244 | uap->old_status = status; | 226 | uap->old_status = status; |
| @@ -266,7 +248,7 @@ static irqreturn_t pl010_int(int irq, void *dev_id, struct pt_regs *regs) | |||
| 266 | 248 | ||
| 267 | spin_lock(&port->lock); | 249 | spin_lock(&port->lock); |
| 268 | 250 | ||
| 269 | status = UART_GET_INT_STATUS(port); | 251 | status = readb(port->membase + UART010_IIR); |
| 270 | if (status) { | 252 | if (status) { |
| 271 | do { | 253 | do { |
| 272 | if (status & (UART010_IIR_RTIS | UART010_IIR_RIS)) | 254 | if (status & (UART010_IIR_RTIS | UART010_IIR_RIS)) |
| @@ -283,7 +265,7 @@ static irqreturn_t pl010_int(int irq, void *dev_id, struct pt_regs *regs) | |||
| 283 | if (pass_counter-- == 0) | 265 | if (pass_counter-- == 0) |
| 284 | break; | 266 | break; |
| 285 | 267 | ||
| 286 | status = UART_GET_INT_STATUS(port); | 268 | status = readb(port->membase + UART010_IIR); |
| 287 | } while (status & (UART010_IIR_RTIS | UART010_IIR_RIS | | 269 | } while (status & (UART010_IIR_RTIS | UART010_IIR_RIS | |
| 288 | UART010_IIR_TIS)); | 270 | UART010_IIR_TIS)); |
| 289 | handled = 1; | 271 | handled = 1; |
| @@ -296,7 +278,7 @@ static irqreturn_t pl010_int(int irq, void *dev_id, struct pt_regs *regs) | |||
| 296 | 278 | ||
| 297 | static unsigned int pl010_tx_empty(struct uart_port *port) | 279 | static unsigned int pl010_tx_empty(struct uart_port *port) |
| 298 | { | 280 | { |
| 299 | return UART_GET_FR(port) & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT; | 281 | return readb(port->membase + UART01x_FR) & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT; |
| 300 | } | 282 | } |
| 301 | 283 | ||
| 302 | static unsigned int pl010_get_mctrl(struct uart_port *port) | 284 | static unsigned int pl010_get_mctrl(struct uart_port *port) |
| @@ -304,7 +286,7 @@ static unsigned int pl010_get_mctrl(struct uart_port *port) | |||
| 304 | unsigned int result = 0; | 286 | unsigned int result = 0; |
| 305 | unsigned int status; | 287 | unsigned int status; |
| 306 | 288 | ||
| 307 | status = UART_GET_FR(port); | 289 | status = readb(port->membase + UART01x_FR); |
| 308 | if (status & UART01x_FR_DCD) | 290 | if (status & UART01x_FR_DCD) |
| 309 | result |= TIOCM_CAR; | 291 | result |= TIOCM_CAR; |
| 310 | if (status & UART01x_FR_DSR) | 292 | if (status & UART01x_FR_DSR) |
| @@ -340,12 +322,12 @@ static void pl010_break_ctl(struct uart_port *port, int break_state) | |||
| 340 | unsigned int lcr_h; | 322 | unsigned int lcr_h; |
| 341 | 323 | ||
| 342 | spin_lock_irqsave(&port->lock, flags); | 324 | spin_lock_irqsave(&port->lock, flags); |
| 343 | lcr_h = UART_GET_LCRH(port); | 325 | lcr_h = readb(port->membase + UART010_LCRH); |
| 344 | if (break_state == -1) | 326 | if (break_state == -1) |
| 345 | lcr_h |= UART01x_LCRH_BRK; | 327 | lcr_h |= UART01x_LCRH_BRK; |
| 346 | else | 328 | else |
| 347 | lcr_h &= ~UART01x_LCRH_BRK; | 329 | lcr_h &= ~UART01x_LCRH_BRK; |
| 348 | UART_PUT_LCRH(port, lcr_h); | 330 | writel(lcr_h, port->membase + UART010_LCRH); |
| 349 | spin_unlock_irqrestore(&port->lock, flags); | 331 | spin_unlock_irqrestore(&port->lock, flags); |
| 350 | } | 332 | } |
| 351 | 333 | ||
| @@ -364,13 +346,13 @@ static int pl010_startup(struct uart_port *port) | |||
| 364 | /* | 346 | /* |
| 365 | * initialise the old status of the modem signals | 347 | * initialise the old status of the modem signals |
| 366 | */ | 348 | */ |
| 367 | uap->old_status = UART_GET_FR(port) & UART01x_FR_MODEM_ANY; | 349 | uap->old_status = readb(port->membase + UART01x_FR) & UART01x_FR_MODEM_ANY; |
| 368 | 350 | ||
| 369 | /* | 351 | /* |
| 370 | * Finally, enable interrupts | 352 | * Finally, enable interrupts |
| 371 | */ | 353 | */ |
| 372 | UART_PUT_CR(port, UART01x_CR_UARTEN | UART010_CR_RIE | | 354 | writel(UART01x_CR_UARTEN | UART010_CR_RIE | UART010_CR_RTIE, |
| 373 | UART010_CR_RTIE); | 355 | port->membase + UART010_CR); |
| 374 | 356 | ||
| 375 | return 0; | 357 | return 0; |
| 376 | } | 358 | } |
| @@ -385,11 +367,12 @@ static void pl010_shutdown(struct uart_port *port) | |||
| 385 | /* | 367 | /* |
| 386 | * disable all interrupts, disable the port | 368 | * disable all interrupts, disable the port |
| 387 | */ | 369 | */ |
| 388 | UART_PUT_CR(port, 0); | 370 | writel(0, port->membase + UART010_CR); |
| 389 | 371 | ||
| 390 | /* disable break condition and fifos */ | 372 | /* disable break condition and fifos */ |
| 391 | UART_PUT_LCRH(port, UART_GET_LCRH(port) & | 373 | writel(readb(port->membase + UART010_LCRH) & |
| 392 | ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN)); | 374 | ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN), |
| 375 | port->membase + UART010_LCRH); | ||
| 393 | } | 376 | } |
| 394 | 377 | ||
| 395 | static void | 378 | static void |
| @@ -466,25 +449,25 @@ pl010_set_termios(struct uart_port *port, struct termios *termios, | |||
| 466 | port->ignore_status_mask |= UART_DUMMY_RSR_RX; | 449 | port->ignore_status_mask |= UART_DUMMY_RSR_RX; |
| 467 | 450 | ||
| 468 | /* first, disable everything */ | 451 | /* first, disable everything */ |
| 469 | old_cr = UART_GET_CR(port) & ~UART010_CR_MSIE; | 452 | old_cr = readb(port->membase + UART010_CR) & ~UART010_CR_MSIE; |
| 470 | 453 | ||
| 471 | if (UART_ENABLE_MS(port, termios->c_cflag)) | 454 | if (UART_ENABLE_MS(port, termios->c_cflag)) |
| 472 | old_cr |= UART010_CR_MSIE; | 455 | old_cr |= UART010_CR_MSIE; |
| 473 | 456 | ||
| 474 | UART_PUT_CR(port, 0); | 457 | writel(0, port->membase + UART010_CR); |
| 475 | 458 | ||
| 476 | /* Set baud rate */ | 459 | /* Set baud rate */ |
| 477 | quot -= 1; | 460 | quot -= 1; |
| 478 | UART_PUT_LCRM(port, ((quot & 0xf00) >> 8)); | 461 | writel((quot & 0xf00) >> 8, port->membase + UART010_LCRM); |
| 479 | UART_PUT_LCRL(port, (quot & 0xff)); | 462 | writel(quot & 0xff, port->membase + UART010_LCRL); |
| 480 | 463 | ||
| 481 | /* | 464 | /* |
| 482 | * ----------v----------v----------v----------v----- | 465 | * ----------v----------v----------v----------v----- |
| 483 | * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L | 466 | * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L |
| 484 | * ----------^----------^----------^----------^----- | 467 | * ----------^----------^----------^----------^----- |
| 485 | */ | 468 | */ |
| 486 | UART_PUT_LCRH(port, lcr_h); | 469 | writel(lcr_h, port->membase + UART010_LCRH); |
| 487 | UART_PUT_CR(port, old_cr); | 470 | writel(old_cr, port->membase + UART010_CR); |
| 488 | 471 | ||
| 489 | spin_unlock_irqrestore(&port->lock, flags); | 472 | spin_unlock_irqrestore(&port->lock, flags); |
| 490 | } | 473 | } |
| @@ -593,9 +576,13 @@ static struct uart_amba_port amba_ports[UART_NR] = { | |||
| 593 | 576 | ||
| 594 | static void pl010_console_putchar(struct uart_port *port, int ch) | 577 | static void pl010_console_putchar(struct uart_port *port, int ch) |
| 595 | { | 578 | { |
| 596 | while (!UART_TX_READY(UART_GET_FR(port))) | 579 | unsigned int status; |
| 580 | |||
| 581 | do { | ||
| 582 | status = readb(port->membase + UART01x_FR); | ||
| 597 | barrier(); | 583 | barrier(); |
| 598 | UART_PUT_CHAR(port, ch); | 584 | } while (!UART_TX_READY(status)); |
| 585 | writel(ch, port->membase + UART01x_DR); | ||
| 599 | } | 586 | } |
| 600 | 587 | ||
| 601 | static void | 588 | static void |
| @@ -607,8 +594,8 @@ pl010_console_write(struct console *co, const char *s, unsigned int count) | |||
| 607 | /* | 594 | /* |
| 608 | * First save the CR then disable the interrupts | 595 | * First save the CR then disable the interrupts |
| 609 | */ | 596 | */ |
| 610 | old_cr = UART_GET_CR(port); | 597 | old_cr = readb(port->membase + UART010_CR); |
| 611 | UART_PUT_CR(port, UART01x_CR_UARTEN); | 598 | writel(UART01x_CR_UARTEN, port->membase + UART010_CR); |
| 612 | 599 | ||
| 613 | uart_console_write(port, s, count, pl010_console_putchar); | 600 | uart_console_write(port, s, count, pl010_console_putchar); |
| 614 | 601 | ||
| @@ -617,18 +604,19 @@ pl010_console_write(struct console *co, const char *s, unsigned int count) | |||
| 617 | * and restore the TCR | 604 | * and restore the TCR |
| 618 | */ | 605 | */ |
| 619 | do { | 606 | do { |
| 620 | status = UART_GET_FR(port); | 607 | status = readb(port->membase + UART01x_FR); |
| 608 | barrier(); | ||
| 621 | } while (status & UART01x_FR_BUSY); | 609 | } while (status & UART01x_FR_BUSY); |
| 622 | UART_PUT_CR(port, old_cr); | 610 | writel(old_cr, port->membase + UART010_CR); |
| 623 | } | 611 | } |
| 624 | 612 | ||
| 625 | static void __init | 613 | static void __init |
| 626 | pl010_console_get_options(struct uart_port *port, int *baud, | 614 | pl010_console_get_options(struct uart_port *port, int *baud, |
| 627 | int *parity, int *bits) | 615 | int *parity, int *bits) |
| 628 | { | 616 | { |
| 629 | if (UART_GET_CR(port) & UART01x_CR_UARTEN) { | 617 | if (readb(port->membase + UART010_CR) & UART01x_CR_UARTEN) { |
| 630 | unsigned int lcr_h, quot; | 618 | unsigned int lcr_h, quot; |
| 631 | lcr_h = UART_GET_LCRH(port); | 619 | lcr_h = readb(port->membase + UART010_LCRH); |
| 632 | 620 | ||
| 633 | *parity = 'n'; | 621 | *parity = 'n'; |
| 634 | if (lcr_h & UART01x_LCRH_PEN) { | 622 | if (lcr_h & UART01x_LCRH_PEN) { |
| @@ -643,7 +631,7 @@ pl010_console_get_options(struct uart_port *port, int *baud, | |||
| 643 | else | 631 | else |
| 644 | *bits = 8; | 632 | *bits = 8; |
| 645 | 633 | ||
| 646 | quot = UART_GET_LCRL(port) | UART_GET_LCRM(port) << 8; | 634 | quot = readb(port->membase + UART010_LCRL) | readb(port->membase + UART010_LCRM) << 8; |
| 647 | *baud = port->uartclk / (16 * (quot + 1)); | 635 | *baud = port->uartclk / (16 * (quot + 1)); |
| 648 | } | 636 | } |
| 649 | } | 637 | } |
