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 | } |