aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/serial/amba-pl010.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/serial/amba-pl010.c')
-rw-r--r--drivers/serial/amba-pl010.c270
1 files changed, 116 insertions, 154 deletions
diff --git a/drivers/serial/amba-pl010.c b/drivers/serial/amba-pl010.c
index e04d5e82d9ae..1631414000a2 100644
--- a/drivers/serial/amba-pl010.c
+++ b/drivers/serial/amba-pl010.c
@@ -51,8 +51,6 @@
51#include <linux/amba/serial.h> 51#include <linux/amba/serial.h>
52 52
53#include <asm/io.h> 53#include <asm/io.h>
54#include <asm/irq.h>
55#include <asm/hardware.h>
56 54
57#define UART_NR 2 55#define UART_NR 2
58 56
@@ -62,47 +60,19 @@
62 60
63#define AMBA_ISR_PASS_LIMIT 256 61#define AMBA_ISR_PASS_LIMIT 256
64 62
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) 63#define UART_RX_DATA(s) (((s) & UART01x_FR_RXFE) == 0)
83#define UART_TX_READY(s) (((s) & UART01x_FR_TXFF) == 0) 64#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 65
86#define UART_DUMMY_RSR_RX /*256*/0 66#define UART_DUMMY_RSR_RX 256
87#define UART_PORT_SIZE 64 67#define UART_PORT_SIZE 64
88 68
89/* 69/*
90 * On the Integrator platform, the port RTS and DTR are provided by
91 * bits in the following SC_CTRLS register bits:
92 * RTS DTR
93 * UART0 7 6
94 * UART1 5 4
95 */
96#define SC_CTRLC (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLC_OFFSET)
97#define SC_CTRLS (IO_ADDRESS(INTEGRATOR_SC_BASE) + INTEGRATOR_SC_CTRLS_OFFSET)
98
99/*
100 * We wrap our port structure around the generic uart_port. 70 * We wrap our port structure around the generic uart_port.
101 */ 71 */
102struct uart_amba_port { 72struct uart_amba_port {
103 struct uart_port port; 73 struct uart_port port;
104 unsigned int dtr_mask; 74 struct amba_device *dev;
105 unsigned int rts_mask; 75 struct amba_pl010_data *data;
106 unsigned int old_status; 76 unsigned int old_status;
107}; 77};
108 78
@@ -110,36 +80,36 @@ static void pl010_stop_tx(struct uart_port *port)
110{ 80{
111 unsigned int cr; 81 unsigned int cr;
112 82
113 cr = UART_GET_CR(port); 83 cr = readb(port->membase + UART010_CR);
114 cr &= ~UART010_CR_TIE; 84 cr &= ~UART010_CR_TIE;
115 UART_PUT_CR(port, cr); 85 writel(cr, port->membase + UART010_CR);
116} 86}
117 87
118static void pl010_start_tx(struct uart_port *port) 88static void pl010_start_tx(struct uart_port *port)
119{ 89{
120 unsigned int cr; 90 unsigned int cr;
121 91
122 cr = UART_GET_CR(port); 92 cr = readb(port->membase + UART010_CR);
123 cr |= UART010_CR_TIE; 93 cr |= UART010_CR_TIE;
124 UART_PUT_CR(port, cr); 94 writel(cr, port->membase + UART010_CR);
125} 95}
126 96
127static void pl010_stop_rx(struct uart_port *port) 97static void pl010_stop_rx(struct uart_port *port)
128{ 98{
129 unsigned int cr; 99 unsigned int cr;
130 100
131 cr = UART_GET_CR(port); 101 cr = readb(port->membase + UART010_CR);
132 cr &= ~(UART010_CR_RIE | UART010_CR_RTIE); 102 cr &= ~(UART010_CR_RIE | UART010_CR_RTIE);
133 UART_PUT_CR(port, cr); 103 writel(cr, port->membase + UART010_CR);
134} 104}
135 105
136static void pl010_enable_ms(struct uart_port *port) 106static void pl010_enable_ms(struct uart_port *port)
137{ 107{
138 unsigned int cr; 108 unsigned int cr;
139 109
140 cr = UART_GET_CR(port); 110 cr = readb(port->membase + UART010_CR);
141 cr |= UART010_CR_MSIE; 111 cr |= UART010_CR_MSIE;
142 UART_PUT_CR(port, cr); 112 writel(cr, port->membase + UART010_CR);
143} 113}
144 114
145static void 115static void
@@ -152,9 +122,9 @@ pl010_rx_chars(struct uart_port *port)
152 struct tty_struct *tty = port->info->tty; 122 struct tty_struct *tty = port->info->tty;
153 unsigned int status, ch, flag, rsr, max_count = 256; 123 unsigned int status, ch, flag, rsr, max_count = 256;
154 124
155 status = UART_GET_FR(port); 125 status = readb(port->membase + UART01x_FR);
156 while (UART_RX_DATA(status) && max_count--) { 126 while (UART_RX_DATA(status) && max_count--) {
157 ch = UART_GET_CHAR(port); 127 ch = readb(port->membase + UART01x_DR);
158 flag = TTY_NORMAL; 128 flag = TTY_NORMAL;
159 129
160 port->icount.rx++; 130 port->icount.rx++;
@@ -163,7 +133,7 @@ pl010_rx_chars(struct uart_port *port)
163 * Note that the error handling code is 133 * Note that the error handling code is
164 * out of the main execution path 134 * out of the main execution path
165 */ 135 */
166 rsr = UART_GET_RSR(port) | UART_DUMMY_RSR_RX; 136 rsr = readb(port->membase + UART01x_RSR) | UART_DUMMY_RSR_RX;
167 if (unlikely(rsr & UART01x_RSR_ANY)) { 137 if (unlikely(rsr & UART01x_RSR_ANY)) {
168 if (rsr & UART01x_RSR_BE) { 138 if (rsr & UART01x_RSR_BE) {
169 rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE); 139 rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE);
@@ -193,7 +163,7 @@ pl010_rx_chars(struct uart_port *port)
193 uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag); 163 uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag);
194 164
195 ignore_char: 165 ignore_char:
196 status = UART_GET_FR(port); 166 status = readb(port->membase + UART01x_FR);
197 } 167 }
198 tty_flip_buffer_push(tty); 168 tty_flip_buffer_push(tty);
199 return; 169 return;
@@ -205,7 +175,7 @@ static void pl010_tx_chars(struct uart_port *port)
205 int count; 175 int count;
206 176
207 if (port->x_char) { 177 if (port->x_char) {
208 UART_PUT_CHAR(port, port->x_char); 178 writel(port->x_char, port->membase + UART01x_DR);
209 port->icount.tx++; 179 port->icount.tx++;
210 port->x_char = 0; 180 port->x_char = 0;
211 return; 181 return;
@@ -217,7 +187,7 @@ static void pl010_tx_chars(struct uart_port *port)
217 187
218 count = port->fifosize >> 1; 188 count = port->fifosize >> 1;
219 do { 189 do {
220 UART_PUT_CHAR(port, xmit->buf[xmit->tail]); 190 writel(xmit->buf[xmit->tail], port->membase + UART01x_DR);
221 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1); 191 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
222 port->icount.tx++; 192 port->icount.tx++;
223 if (uart_circ_empty(xmit)) 193 if (uart_circ_empty(xmit))
@@ -236,9 +206,9 @@ static void pl010_modem_status(struct uart_port *port)
236 struct uart_amba_port *uap = (struct uart_amba_port *)port; 206 struct uart_amba_port *uap = (struct uart_amba_port *)port;
237 unsigned int status, delta; 207 unsigned int status, delta;
238 208
239 UART_PUT_ICR(&uap->port, 0); 209 writel(0, uap->port.membase + UART010_ICR);
240 210
241 status = UART_GET_FR(&uap->port) & UART01x_FR_MODEM_ANY; 211 status = readb(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
242 212
243 delta = status ^ uap->old_status; 213 delta = status ^ uap->old_status;
244 uap->old_status = status; 214 uap->old_status = status;
@@ -266,7 +236,7 @@ static irqreturn_t pl010_int(int irq, void *dev_id, struct pt_regs *regs)
266 236
267 spin_lock(&port->lock); 237 spin_lock(&port->lock);
268 238
269 status = UART_GET_INT_STATUS(port); 239 status = readb(port->membase + UART010_IIR);
270 if (status) { 240 if (status) {
271 do { 241 do {
272 if (status & (UART010_IIR_RTIS | UART010_IIR_RIS)) 242 if (status & (UART010_IIR_RTIS | UART010_IIR_RIS))
@@ -283,7 +253,7 @@ static irqreturn_t pl010_int(int irq, void *dev_id, struct pt_regs *regs)
283 if (pass_counter-- == 0) 253 if (pass_counter-- == 0)
284 break; 254 break;
285 255
286 status = UART_GET_INT_STATUS(port); 256 status = readb(port->membase + UART010_IIR);
287 } while (status & (UART010_IIR_RTIS | UART010_IIR_RIS | 257 } while (status & (UART010_IIR_RTIS | UART010_IIR_RIS |
288 UART010_IIR_TIS)); 258 UART010_IIR_TIS));
289 handled = 1; 259 handled = 1;
@@ -296,7 +266,7 @@ static irqreturn_t pl010_int(int irq, void *dev_id, struct pt_regs *regs)
296 266
297static unsigned int pl010_tx_empty(struct uart_port *port) 267static unsigned int pl010_tx_empty(struct uart_port *port)
298{ 268{
299 return UART_GET_FR(port) & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT; 269 return readb(port->membase + UART01x_FR) & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT;
300} 270}
301 271
302static unsigned int pl010_get_mctrl(struct uart_port *port) 272static unsigned int pl010_get_mctrl(struct uart_port *port)
@@ -304,7 +274,7 @@ static unsigned int pl010_get_mctrl(struct uart_port *port)
304 unsigned int result = 0; 274 unsigned int result = 0;
305 unsigned int status; 275 unsigned int status;
306 276
307 status = UART_GET_FR(port); 277 status = readb(port->membase + UART01x_FR);
308 if (status & UART01x_FR_DCD) 278 if (status & UART01x_FR_DCD)
309 result |= TIOCM_CAR; 279 result |= TIOCM_CAR;
310 if (status & UART01x_FR_DSR) 280 if (status & UART01x_FR_DSR)
@@ -318,20 +288,9 @@ static unsigned int pl010_get_mctrl(struct uart_port *port)
318static void pl010_set_mctrl(struct uart_port *port, unsigned int mctrl) 288static void pl010_set_mctrl(struct uart_port *port, unsigned int mctrl)
319{ 289{
320 struct uart_amba_port *uap = (struct uart_amba_port *)port; 290 struct uart_amba_port *uap = (struct uart_amba_port *)port;
321 unsigned int ctrls = 0, ctrlc = 0;
322
323 if (mctrl & TIOCM_RTS)
324 ctrlc |= uap->rts_mask;
325 else
326 ctrls |= uap->rts_mask;
327
328 if (mctrl & TIOCM_DTR)
329 ctrlc |= uap->dtr_mask;
330 else
331 ctrls |= uap->dtr_mask;
332 291
333 __raw_writel(ctrls, SC_CTRLS); 292 if (uap->data)
334 __raw_writel(ctrlc, SC_CTRLC); 293 uap->data->set_mctrl(uap->dev, uap->port.membase, mctrl);
335} 294}
336 295
337static void pl010_break_ctl(struct uart_port *port, int break_state) 296static void pl010_break_ctl(struct uart_port *port, int break_state)
@@ -340,12 +299,12 @@ static void pl010_break_ctl(struct uart_port *port, int break_state)
340 unsigned int lcr_h; 299 unsigned int lcr_h;
341 300
342 spin_lock_irqsave(&port->lock, flags); 301 spin_lock_irqsave(&port->lock, flags);
343 lcr_h = UART_GET_LCRH(port); 302 lcr_h = readb(port->membase + UART010_LCRH);
344 if (break_state == -1) 303 if (break_state == -1)
345 lcr_h |= UART01x_LCRH_BRK; 304 lcr_h |= UART01x_LCRH_BRK;
346 else 305 else
347 lcr_h &= ~UART01x_LCRH_BRK; 306 lcr_h &= ~UART01x_LCRH_BRK;
348 UART_PUT_LCRH(port, lcr_h); 307 writel(lcr_h, port->membase + UART010_LCRH);
349 spin_unlock_irqrestore(&port->lock, flags); 308 spin_unlock_irqrestore(&port->lock, flags);
350} 309}
351 310
@@ -364,13 +323,13 @@ static int pl010_startup(struct uart_port *port)
364 /* 323 /*
365 * initialise the old status of the modem signals 324 * initialise the old status of the modem signals
366 */ 325 */
367 uap->old_status = UART_GET_FR(port) & UART01x_FR_MODEM_ANY; 326 uap->old_status = readb(port->membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
368 327
369 /* 328 /*
370 * Finally, enable interrupts 329 * Finally, enable interrupts
371 */ 330 */
372 UART_PUT_CR(port, UART01x_CR_UARTEN | UART010_CR_RIE | 331 writel(UART01x_CR_UARTEN | UART010_CR_RIE | UART010_CR_RTIE,
373 UART010_CR_RTIE); 332 port->membase + UART010_CR);
374 333
375 return 0; 334 return 0;
376} 335}
@@ -385,11 +344,12 @@ static void pl010_shutdown(struct uart_port *port)
385 /* 344 /*
386 * disable all interrupts, disable the port 345 * disable all interrupts, disable the port
387 */ 346 */
388 UART_PUT_CR(port, 0); 347 writel(0, port->membase + UART010_CR);
389 348
390 /* disable break condition and fifos */ 349 /* disable break condition and fifos */
391 UART_PUT_LCRH(port, UART_GET_LCRH(port) & 350 writel(readb(port->membase + UART010_LCRH) &
392 ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN)); 351 ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN),
352 port->membase + UART010_LCRH);
393} 353}
394 354
395static void 355static void
@@ -466,25 +426,25 @@ pl010_set_termios(struct uart_port *port, struct termios *termios,
466 port->ignore_status_mask |= UART_DUMMY_RSR_RX; 426 port->ignore_status_mask |= UART_DUMMY_RSR_RX;
467 427
468 /* first, disable everything */ 428 /* first, disable everything */
469 old_cr = UART_GET_CR(port) & ~UART010_CR_MSIE; 429 old_cr = readb(port->membase + UART010_CR) & ~UART010_CR_MSIE;
470 430
471 if (UART_ENABLE_MS(port, termios->c_cflag)) 431 if (UART_ENABLE_MS(port, termios->c_cflag))
472 old_cr |= UART010_CR_MSIE; 432 old_cr |= UART010_CR_MSIE;
473 433
474 UART_PUT_CR(port, 0); 434 writel(0, port->membase + UART010_CR);
475 435
476 /* Set baud rate */ 436 /* Set baud rate */
477 quot -= 1; 437 quot -= 1;
478 UART_PUT_LCRM(port, ((quot & 0xf00) >> 8)); 438 writel((quot & 0xf00) >> 8, port->membase + UART010_LCRM);
479 UART_PUT_LCRL(port, (quot & 0xff)); 439 writel(quot & 0xff, port->membase + UART010_LCRL);
480 440
481 /* 441 /*
482 * ----------v----------v----------v----------v----- 442 * ----------v----------v----------v----------v-----
483 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L 443 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
484 * ----------^----------^----------^----------^----- 444 * ----------^----------^----------^----------^-----
485 */ 445 */
486 UART_PUT_LCRH(port, lcr_h); 446 writel(lcr_h, port->membase + UART010_LCRH);
487 UART_PUT_CR(port, old_cr); 447 writel(old_cr, port->membase + UART010_CR);
488 448
489 spin_unlock_irqrestore(&port->lock, flags); 449 spin_unlock_irqrestore(&port->lock, flags);
490} 450}
@@ -556,59 +516,32 @@ static struct uart_ops amba_pl010_pops = {
556 .verify_port = pl010_verify_port, 516 .verify_port = pl010_verify_port,
557}; 517};
558 518
559static struct uart_amba_port amba_ports[UART_NR] = { 519static struct uart_amba_port *amba_ports[UART_NR];
560 {
561 .port = {
562 .membase = (void *)IO_ADDRESS(INTEGRATOR_UART0_BASE),
563 .mapbase = INTEGRATOR_UART0_BASE,
564 .iotype = UPIO_MEM,
565 .irq = IRQ_UARTINT0,
566 .uartclk = 14745600,
567 .fifosize = 16,
568 .ops = &amba_pl010_pops,
569 .flags = UPF_BOOT_AUTOCONF,
570 .line = 0,
571 },
572 .dtr_mask = 1 << 5,
573 .rts_mask = 1 << 4,
574 },
575 {
576 .port = {
577 .membase = (void *)IO_ADDRESS(INTEGRATOR_UART1_BASE),
578 .mapbase = INTEGRATOR_UART1_BASE,
579 .iotype = UPIO_MEM,
580 .irq = IRQ_UARTINT1,
581 .uartclk = 14745600,
582 .fifosize = 16,
583 .ops = &amba_pl010_pops,
584 .flags = UPF_BOOT_AUTOCONF,
585 .line = 1,
586 },
587 .dtr_mask = 1 << 7,
588 .rts_mask = 1 << 6,
589 }
590};
591 520
592#ifdef CONFIG_SERIAL_AMBA_PL010_CONSOLE 521#ifdef CONFIG_SERIAL_AMBA_PL010_CONSOLE
593 522
594static void pl010_console_putchar(struct uart_port *port, int ch) 523static void pl010_console_putchar(struct uart_port *port, int ch)
595{ 524{
596 while (!UART_TX_READY(UART_GET_FR(port))) 525 unsigned int status;
526
527 do {
528 status = readb(port->membase + UART01x_FR);
597 barrier(); 529 barrier();
598 UART_PUT_CHAR(port, ch); 530 } while (!UART_TX_READY(status));
531 writel(ch, port->membase + UART01x_DR);
599} 532}
600 533
601static void 534static void
602pl010_console_write(struct console *co, const char *s, unsigned int count) 535pl010_console_write(struct console *co, const char *s, unsigned int count)
603{ 536{
604 struct uart_port *port = &amba_ports[co->index].port; 537 struct uart_port *port = &amba_ports[co->index]->port;
605 unsigned int status, old_cr; 538 unsigned int status, old_cr;
606 539
607 /* 540 /*
608 * First save the CR then disable the interrupts 541 * First save the CR then disable the interrupts
609 */ 542 */
610 old_cr = UART_GET_CR(port); 543 old_cr = readb(port->membase + UART010_CR);
611 UART_PUT_CR(port, UART01x_CR_UARTEN); 544 writel(UART01x_CR_UARTEN, port->membase + UART010_CR);
612 545
613 uart_console_write(port, s, count, pl010_console_putchar); 546 uart_console_write(port, s, count, pl010_console_putchar);
614 547
@@ -617,18 +550,19 @@ pl010_console_write(struct console *co, const char *s, unsigned int count)
617 * and restore the TCR 550 * and restore the TCR
618 */ 551 */
619 do { 552 do {
620 status = UART_GET_FR(port); 553 status = readb(port->membase + UART01x_FR);
554 barrier();
621 } while (status & UART01x_FR_BUSY); 555 } while (status & UART01x_FR_BUSY);
622 UART_PUT_CR(port, old_cr); 556 writel(old_cr, port->membase + UART010_CR);
623} 557}
624 558
625static void __init 559static void __init
626pl010_console_get_options(struct uart_port *port, int *baud, 560pl010_console_get_options(struct uart_port *port, int *baud,
627 int *parity, int *bits) 561 int *parity, int *bits)
628{ 562{
629 if (UART_GET_CR(port) & UART01x_CR_UARTEN) { 563 if (readb(port->membase + UART010_CR) & UART01x_CR_UARTEN) {
630 unsigned int lcr_h, quot; 564 unsigned int lcr_h, quot;
631 lcr_h = UART_GET_LCRH(port); 565 lcr_h = readb(port->membase + UART010_LCRH);
632 566
633 *parity = 'n'; 567 *parity = 'n';
634 if (lcr_h & UART01x_LCRH_PEN) { 568 if (lcr_h & UART01x_LCRH_PEN) {
@@ -643,7 +577,7 @@ pl010_console_get_options(struct uart_port *port, int *baud,
643 else 577 else
644 *bits = 8; 578 *bits = 8;
645 579
646 quot = UART_GET_LCRL(port) | UART_GET_LCRM(port) << 8; 580 quot = readb(port->membase + UART010_LCRL) | readb(port->membase + UART010_LCRM) << 8;
647 *baud = port->uartclk / (16 * (quot + 1)); 581 *baud = port->uartclk / (16 * (quot + 1));
648 } 582 }
649} 583}
@@ -663,7 +597,7 @@ static int __init pl010_console_setup(struct console *co, char *options)
663 */ 597 */
664 if (co->index >= UART_NR) 598 if (co->index >= UART_NR)
665 co->index = 0; 599 co->index = 0;
666 port = &amba_ports[co->index].port; 600 port = &amba_ports[co->index]->port;
667 601
668 if (options) 602 if (options)
669 uart_parse_options(options, &baud, &parity, &bits, &flow); 603 uart_parse_options(options, &baud, &parity, &bits, &flow);
@@ -684,24 +618,6 @@ static struct console amba_console = {
684 .data = &amba_reg, 618 .data = &amba_reg,
685}; 619};
686 620
687static int __init amba_console_init(void)
688{
689 /*
690 * All port initializations are done statically
691 */
692 register_console(&amba_console);
693 return 0;
694}
695console_initcall(amba_console_init);
696
697static int __init amba_late_console_init(void)
698{
699 if (!(amba_console.flags & CON_ENABLED))
700 register_console(&amba_console);
701 return 0;
702}
703late_initcall(amba_late_console_init);
704
705#define AMBA_CONSOLE &amba_console 621#define AMBA_CONSOLE &amba_console
706#else 622#else
707#define AMBA_CONSOLE NULL 623#define AMBA_CONSOLE NULL
@@ -719,30 +635,76 @@ static struct uart_driver amba_reg = {
719 635
720static int pl010_probe(struct amba_device *dev, void *id) 636static int pl010_probe(struct amba_device *dev, void *id)
721{ 637{
722 int i; 638 struct uart_amba_port *port;
639 void __iomem *base;
640 int i, ret;
723 641
724 for (i = 0; i < UART_NR; i++) { 642 for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
725 if (amba_ports[i].port.mapbase != dev->res.start) 643 if (amba_ports[i] == NULL)
726 continue; 644 break;
727 645
728 amba_ports[i].port.dev = &dev->dev; 646 if (i == ARRAY_SIZE(amba_ports)) {
729 uart_add_one_port(&amba_reg, &amba_ports[i].port); 647 ret = -EBUSY;
730 amba_set_drvdata(dev, &amba_ports[i]); 648 goto out;
731 break;
732 } 649 }
733 650
734 return 0; 651 port = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL);
652 if (!port) {
653 ret = -ENOMEM;
654 goto out;
655 }
656
657 base = ioremap(dev->res.start, PAGE_SIZE);
658 if (!base) {
659 ret = -ENOMEM;
660 goto free;
661 }
662
663 port->port.dev = &dev->dev;
664 port->port.mapbase = dev->res.start;
665 port->port.membase = base;
666 port->port.iotype = UPIO_MEM;
667 port->port.irq = dev->irq[0];
668 port->port.uartclk = 14745600;
669 port->port.fifosize = 16;
670 port->port.ops = &amba_pl010_pops;
671 port->port.flags = UPF_BOOT_AUTOCONF;
672 port->port.line = i;
673 port->dev = dev;
674 port->data = dev->dev.platform_data;
675
676 amba_ports[i] = port;
677
678 amba_set_drvdata(dev, port);
679 ret = uart_add_one_port(&amba_reg, &port->port);
680 if (ret) {
681 amba_set_drvdata(dev, NULL);
682 amba_ports[i] = NULL;
683 iounmap(base);
684 free:
685 kfree(port);
686 }
687
688 out:
689 return ret;
735} 690}
736 691
737static int pl010_remove(struct amba_device *dev) 692static int pl010_remove(struct amba_device *dev)
738{ 693{
739 struct uart_amba_port *uap = amba_get_drvdata(dev); 694 struct uart_amba_port *port = amba_get_drvdata(dev);
740 695 int i;
741 if (uap)
742 uart_remove_one_port(&amba_reg, &uap->port);
743 696
744 amba_set_drvdata(dev, NULL); 697 amba_set_drvdata(dev, NULL);
745 698
699 uart_remove_one_port(&amba_reg, &port->port);
700
701 for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
702 if (amba_ports[i] == port)
703 amba_ports[i] = NULL;
704
705 iounmap(port->port.membase);
706 kfree(port);
707
746 return 0; 708 return 0;
747} 709}
748 710