aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--drivers/serial/amba-pl010.c110
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
118static void pl010_start_tx(struct uart_port *port) 100static 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
127static void pl010_stop_rx(struct uart_port *port) 109static 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
136static void pl010_enable_ms(struct uart_port *port) 118static 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
145static void 127static 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
297static unsigned int pl010_tx_empty(struct uart_port *port) 279static 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
302static unsigned int pl010_get_mctrl(struct uart_port *port) 284static 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
395static void 378static 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
594static void pl010_console_putchar(struct uart_port *port, int ch) 577static 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
601static void 588static 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
625static void __init 613static void __init
626pl010_console_get_options(struct uart_port *port, int *baud, 614pl010_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}