Merge branch 'for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tiwai/sound-2.6
[linux-2.6] / drivers / serial / amba-pl011.c
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
51 #include <asm/io.h>
52 #include <asm/sizes.h>
53
54 #define UART_NR                 14
55
56 #define SERIAL_AMBA_MAJOR       204
57 #define SERIAL_AMBA_MINOR       64
58 #define SERIAL_AMBA_NR          UART_NR
59
60 #define AMBA_ISR_PASS_LIMIT     256
61
62 #define UART_DR_ERROR           (UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE)
63 #define UART_DUMMY_DR_RX        (1 << 16)
64
65 /*
66  * We wrap our port structure around the generic uart_port.
67  */
68 struct uart_amba_port {
69         struct uart_port        port;
70         struct clk              *clk;
71         unsigned int            im;     /* interrupt mask */
72         unsigned int            old_status;
73 };
74
75 static void pl011_stop_tx(struct uart_port *port)
76 {
77         struct uart_amba_port *uap = (struct uart_amba_port *)port;
78
79         uap->im &= ~UART011_TXIM;
80         writew(uap->im, uap->port.membase + UART011_IMSC);
81 }
82
83 static void pl011_start_tx(struct uart_port *port)
84 {
85         struct uart_amba_port *uap = (struct uart_amba_port *)port;
86
87         uap->im |= UART011_TXIM;
88         writew(uap->im, uap->port.membase + UART011_IMSC);
89 }
90
91 static void pl011_stop_rx(struct uart_port *port)
92 {
93         struct uart_amba_port *uap = (struct uart_amba_port *)port;
94
95         uap->im &= ~(UART011_RXIM|UART011_RTIM|UART011_FEIM|
96                      UART011_PEIM|UART011_BEIM|UART011_OEIM);
97         writew(uap->im, uap->port.membase + UART011_IMSC);
98 }
99
100 static void pl011_enable_ms(struct uart_port *port)
101 {
102         struct uart_amba_port *uap = (struct uart_amba_port *)port;
103
104         uap->im |= UART011_RIMIM|UART011_CTSMIM|UART011_DCDMIM|UART011_DSRMIM;
105         writew(uap->im, uap->port.membase + UART011_IMSC);
106 }
107
108 static void pl011_rx_chars(struct uart_amba_port *uap)
109 {
110         struct tty_struct *tty = uap->port.info->port.tty;
111         unsigned int status, ch, flag, max_count = 256;
112
113         status = readw(uap->port.membase + UART01x_FR);
114         while ((status & UART01x_FR_RXFE) == 0 && max_count--) {
115                 ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX;
116                 flag = TTY_NORMAL;
117                 uap->port.icount.rx++;
118
119                 /*
120                  * Note that the error handling code is
121                  * out of the main execution path
122                  */
123                 if (unlikely(ch & UART_DR_ERROR)) {
124                         if (ch & UART011_DR_BE) {
125                                 ch &= ~(UART011_DR_FE | UART011_DR_PE);
126                                 uap->port.icount.brk++;
127                                 if (uart_handle_break(&uap->port))
128                                         goto ignore_char;
129                         } else if (ch & UART011_DR_PE)
130                                 uap->port.icount.parity++;
131                         else if (ch & UART011_DR_FE)
132                                 uap->port.icount.frame++;
133                         if (ch & UART011_DR_OE)
134                                 uap->port.icount.overrun++;
135
136                         ch &= uap->port.read_status_mask;
137
138                         if (ch & UART011_DR_BE)
139                                 flag = TTY_BREAK;
140                         else if (ch & UART011_DR_PE)
141                                 flag = TTY_PARITY;
142                         else if (ch & UART011_DR_FE)
143                                 flag = TTY_FRAME;
144                 }
145
146                 if (uart_handle_sysrq_char(&uap->port, ch & 255))
147                         goto ignore_char;
148
149                 uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag);
150
151         ignore_char:
152                 status = readw(uap->port.membase + UART01x_FR);
153         }
154         spin_unlock(&uap->port.lock);
155         tty_flip_buffer_push(tty);
156         spin_lock(&uap->port.lock);
157 }
158
159 static void pl011_tx_chars(struct uart_amba_port *uap)
160 {
161         struct circ_buf *xmit = &uap->port.info->xmit;
162         int count;
163
164         if (uap->port.x_char) {
165                 writew(uap->port.x_char, uap->port.membase + UART01x_DR);
166                 uap->port.icount.tx++;
167                 uap->port.x_char = 0;
168                 return;
169         }
170         if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) {
171                 pl011_stop_tx(&uap->port);
172                 return;
173         }
174
175         count = uap->port.fifosize >> 1;
176         do {
177                 writew(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR);
178                 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
179                 uap->port.icount.tx++;
180                 if (uart_circ_empty(xmit))
181                         break;
182         } while (--count > 0);
183
184         if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
185                 uart_write_wakeup(&uap->port);
186
187         if (uart_circ_empty(xmit))
188                 pl011_stop_tx(&uap->port);
189 }
190
191 static void pl011_modem_status(struct uart_amba_port *uap)
192 {
193         unsigned int status, delta;
194
195         status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
196
197         delta = status ^ uap->old_status;
198         uap->old_status = status;
199
200         if (!delta)
201                 return;
202
203         if (delta & UART01x_FR_DCD)
204                 uart_handle_dcd_change(&uap->port, status & UART01x_FR_DCD);
205
206         if (delta & UART01x_FR_DSR)
207                 uap->port.icount.dsr++;
208
209         if (delta & UART01x_FR_CTS)
210                 uart_handle_cts_change(&uap->port, status & UART01x_FR_CTS);
211
212         wake_up_interruptible(&uap->port.info->delta_msr_wait);
213 }
214
215 static irqreturn_t pl011_int(int irq, void *dev_id)
216 {
217         struct uart_amba_port *uap = dev_id;
218         unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
219         int handled = 0;
220
221         spin_lock(&uap->port.lock);
222
223         status = readw(uap->port.membase + UART011_MIS);
224         if (status) {
225                 do {
226                         writew(status & ~(UART011_TXIS|UART011_RTIS|
227                                           UART011_RXIS),
228                                uap->port.membase + UART011_ICR);
229
230                         if (status & (UART011_RTIS|UART011_RXIS))
231                                 pl011_rx_chars(uap);
232                         if (status & (UART011_DSRMIS|UART011_DCDMIS|
233                                       UART011_CTSMIS|UART011_RIMIS))
234                                 pl011_modem_status(uap);
235                         if (status & UART011_TXIS)
236                                 pl011_tx_chars(uap);
237
238                         if (pass_counter-- == 0)
239                                 break;
240
241                         status = readw(uap->port.membase + UART011_MIS);
242                 } while (status != 0);
243                 handled = 1;
244         }
245
246         spin_unlock(&uap->port.lock);
247
248         return IRQ_RETVAL(handled);
249 }
250
251 static unsigned int pl01x_tx_empty(struct uart_port *port)
252 {
253         struct uart_amba_port *uap = (struct uart_amba_port *)port;
254         unsigned int status = readw(uap->port.membase + UART01x_FR);
255         return status & (UART01x_FR_BUSY|UART01x_FR_TXFF) ? 0 : TIOCSER_TEMT;
256 }
257
258 static unsigned int pl01x_get_mctrl(struct uart_port *port)
259 {
260         struct uart_amba_port *uap = (struct uart_amba_port *)port;
261         unsigned int result = 0;
262         unsigned int status = readw(uap->port.membase + UART01x_FR);
263
264 #define TIOCMBIT(uartbit, tiocmbit)     \
265         if (status & uartbit)           \
266                 result |= tiocmbit
267
268         TIOCMBIT(UART01x_FR_DCD, TIOCM_CAR);
269         TIOCMBIT(UART01x_FR_DSR, TIOCM_DSR);
270         TIOCMBIT(UART01x_FR_CTS, TIOCM_CTS);
271         TIOCMBIT(UART011_FR_RI, TIOCM_RNG);
272 #undef TIOCMBIT
273         return result;
274 }
275
276 static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl)
277 {
278         struct uart_amba_port *uap = (struct uart_amba_port *)port;
279         unsigned int cr;
280
281         cr = readw(uap->port.membase + UART011_CR);
282
283 #define TIOCMBIT(tiocmbit, uartbit)             \
284         if (mctrl & tiocmbit)           \
285                 cr |= uartbit;          \
286         else                            \
287                 cr &= ~uartbit
288
289         TIOCMBIT(TIOCM_RTS, UART011_CR_RTS);
290         TIOCMBIT(TIOCM_DTR, UART011_CR_DTR);
291         TIOCMBIT(TIOCM_OUT1, UART011_CR_OUT1);
292         TIOCMBIT(TIOCM_OUT2, UART011_CR_OUT2);
293         TIOCMBIT(TIOCM_LOOP, UART011_CR_LBE);
294 #undef TIOCMBIT
295
296         writew(cr, uap->port.membase + UART011_CR);
297 }
298
299 static void pl011_break_ctl(struct uart_port *port, int break_state)
300 {
301         struct uart_amba_port *uap = (struct uart_amba_port *)port;
302         unsigned long flags;
303         unsigned int lcr_h;
304
305         spin_lock_irqsave(&uap->port.lock, flags);
306         lcr_h = readw(uap->port.membase + UART011_LCRH);
307         if (break_state == -1)
308                 lcr_h |= UART01x_LCRH_BRK;
309         else
310                 lcr_h &= ~UART01x_LCRH_BRK;
311         writew(lcr_h, uap->port.membase + UART011_LCRH);
312         spin_unlock_irqrestore(&uap->port.lock, flags);
313 }
314
315 #ifdef CONFIG_CONSOLE_POLL
316 static int pl010_get_poll_char(struct uart_port *port)
317 {
318         struct uart_amba_port *uap = (struct uart_amba_port *)port;
319         unsigned int status;
320
321         do {
322                 status = readw(uap->port.membase + UART01x_FR);
323         } while (status & UART01x_FR_RXFE);
324
325         return readw(uap->port.membase + UART01x_DR);
326 }
327
328 static void pl010_put_poll_char(struct uart_port *port,
329                          unsigned char ch)
330 {
331         struct uart_amba_port *uap = (struct uart_amba_port *)port;
332
333         while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF)
334                 barrier();
335
336         writew(ch, uap->port.membase + UART01x_DR);
337 }
338
339 #endif /* CONFIG_CONSOLE_POLL */
340
341 static int pl011_startup(struct uart_port *port)
342 {
343         struct uart_amba_port *uap = (struct uart_amba_port *)port;
344         unsigned int cr;
345         int retval;
346
347         /*
348          * Try to enable the clock producer.
349          */
350         retval = clk_enable(uap->clk);
351         if (retval)
352                 goto out;
353
354         uap->port.uartclk = clk_get_rate(uap->clk);
355
356         /*
357          * Allocate the IRQ
358          */
359         retval = request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap);
360         if (retval)
361                 goto clk_dis;
362
363         writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
364                uap->port.membase + UART011_IFLS);
365
366         /*
367          * Provoke TX FIFO interrupt into asserting.
368          */
369         cr = UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_LBE;
370         writew(cr, uap->port.membase + UART011_CR);
371         writew(0, uap->port.membase + UART011_FBRD);
372         writew(1, uap->port.membase + UART011_IBRD);
373         writew(0, uap->port.membase + UART011_LCRH);
374         writew(0, uap->port.membase + UART01x_DR);
375         while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY)
376                 barrier();
377
378         cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE;
379         writew(cr, uap->port.membase + UART011_CR);
380
381         /*
382          * initialise the old status of the modem signals
383          */
384         uap->old_status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
385
386         /*
387          * Finally, enable interrupts
388          */
389         spin_lock_irq(&uap->port.lock);
390         uap->im = UART011_RXIM | UART011_RTIM;
391         writew(uap->im, uap->port.membase + UART011_IMSC);
392         spin_unlock_irq(&uap->port.lock);
393
394         return 0;
395
396  clk_dis:
397         clk_disable(uap->clk);
398  out:
399         return retval;
400 }
401
402 static void pl011_shutdown(struct uart_port *port)
403 {
404         struct uart_amba_port *uap = (struct uart_amba_port *)port;
405         unsigned long val;
406
407         /*
408          * disable all interrupts
409          */
410         spin_lock_irq(&uap->port.lock);
411         uap->im = 0;
412         writew(uap->im, uap->port.membase + UART011_IMSC);
413         writew(0xffff, uap->port.membase + UART011_ICR);
414         spin_unlock_irq(&uap->port.lock);
415
416         /*
417          * Free the interrupt
418          */
419         free_irq(uap->port.irq, uap);
420
421         /*
422          * disable the port
423          */
424         writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR);
425
426         /*
427          * disable break condition and fifos
428          */
429         val = readw(uap->port.membase + UART011_LCRH);
430         val &= ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN);
431         writew(val, uap->port.membase + UART011_LCRH);
432
433         /*
434          * Shut down the clock producer
435          */
436         clk_disable(uap->clk);
437 }
438
439 static void
440 pl011_set_termios(struct uart_port *port, struct ktermios *termios,
441                      struct ktermios *old)
442 {
443         unsigned int lcr_h, old_cr;
444         unsigned long flags;
445         unsigned int baud, quot;
446
447         /*
448          * Ask the core to calculate the divisor for us.
449          */
450         baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
451         quot = port->uartclk * 4 / baud;
452
453         switch (termios->c_cflag & CSIZE) {
454         case CS5:
455                 lcr_h = UART01x_LCRH_WLEN_5;
456                 break;
457         case CS6:
458                 lcr_h = UART01x_LCRH_WLEN_6;
459                 break;
460         case CS7:
461                 lcr_h = UART01x_LCRH_WLEN_7;
462                 break;
463         default: // CS8
464                 lcr_h = UART01x_LCRH_WLEN_8;
465                 break;
466         }
467         if (termios->c_cflag & CSTOPB)
468                 lcr_h |= UART01x_LCRH_STP2;
469         if (termios->c_cflag & PARENB) {
470                 lcr_h |= UART01x_LCRH_PEN;
471                 if (!(termios->c_cflag & PARODD))
472                         lcr_h |= UART01x_LCRH_EPS;
473         }
474         if (port->fifosize > 1)
475                 lcr_h |= UART01x_LCRH_FEN;
476
477         spin_lock_irqsave(&port->lock, flags);
478
479         /*
480          * Update the per-port timeout.
481          */
482         uart_update_timeout(port, termios->c_cflag, baud);
483
484         port->read_status_mask = UART011_DR_OE | 255;
485         if (termios->c_iflag & INPCK)
486                 port->read_status_mask |= UART011_DR_FE | UART011_DR_PE;
487         if (termios->c_iflag & (BRKINT | PARMRK))
488                 port->read_status_mask |= UART011_DR_BE;
489
490         /*
491          * Characters to ignore
492          */
493         port->ignore_status_mask = 0;
494         if (termios->c_iflag & IGNPAR)
495                 port->ignore_status_mask |= UART011_DR_FE | UART011_DR_PE;
496         if (termios->c_iflag & IGNBRK) {
497                 port->ignore_status_mask |= UART011_DR_BE;
498                 /*
499                  * If we're ignoring parity and break indicators,
500                  * ignore overruns too (for real raw support).
501                  */
502                 if (termios->c_iflag & IGNPAR)
503                         port->ignore_status_mask |= UART011_DR_OE;
504         }
505
506         /*
507          * Ignore all characters if CREAD is not set.
508          */
509         if ((termios->c_cflag & CREAD) == 0)
510                 port->ignore_status_mask |= UART_DUMMY_DR_RX;
511
512         if (UART_ENABLE_MS(port, termios->c_cflag))
513                 pl011_enable_ms(port);
514
515         /* first, disable everything */
516         old_cr = readw(port->membase + UART011_CR);
517         writew(0, port->membase + UART011_CR);
518
519         /* Set baud rate */
520         writew(quot & 0x3f, port->membase + UART011_FBRD);
521         writew(quot >> 6, port->membase + UART011_IBRD);
522
523         /*
524          * ----------v----------v----------v----------v-----
525          * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
526          * ----------^----------^----------^----------^-----
527          */
528         writew(lcr_h, port->membase + UART011_LCRH);
529         writew(old_cr, port->membase + UART011_CR);
530
531         spin_unlock_irqrestore(&port->lock, flags);
532 }
533
534 static const char *pl011_type(struct uart_port *port)
535 {
536         return port->type == PORT_AMBA ? "AMBA/PL011" : NULL;
537 }
538
539 /*
540  * Release the memory region(s) being used by 'port'
541  */
542 static void pl010_release_port(struct uart_port *port)
543 {
544         release_mem_region(port->mapbase, SZ_4K);
545 }
546
547 /*
548  * Request the memory region(s) being used by 'port'
549  */
550 static int pl010_request_port(struct uart_port *port)
551 {
552         return request_mem_region(port->mapbase, SZ_4K, "uart-pl011")
553                         != NULL ? 0 : -EBUSY;
554 }
555
556 /*
557  * Configure/autoconfigure the port.
558  */
559 static void pl010_config_port(struct uart_port *port, int flags)
560 {
561         if (flags & UART_CONFIG_TYPE) {
562                 port->type = PORT_AMBA;
563                 pl010_request_port(port);
564         }
565 }
566
567 /*
568  * verify the new serial_struct (for TIOCSSERIAL).
569  */
570 static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser)
571 {
572         int ret = 0;
573         if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)
574                 ret = -EINVAL;
575         if (ser->irq < 0 || ser->irq >= NR_IRQS)
576                 ret = -EINVAL;
577         if (ser->baud_base < 9600)
578                 ret = -EINVAL;
579         return ret;
580 }
581
582 static struct uart_ops amba_pl011_pops = {
583         .tx_empty       = pl01x_tx_empty,
584         .set_mctrl      = pl011_set_mctrl,
585         .get_mctrl      = pl01x_get_mctrl,
586         .stop_tx        = pl011_stop_tx,
587         .start_tx       = pl011_start_tx,
588         .stop_rx        = pl011_stop_rx,
589         .enable_ms      = pl011_enable_ms,
590         .break_ctl      = pl011_break_ctl,
591         .startup        = pl011_startup,
592         .shutdown       = pl011_shutdown,
593         .set_termios    = pl011_set_termios,
594         .type           = pl011_type,
595         .release_port   = pl010_release_port,
596         .request_port   = pl010_request_port,
597         .config_port    = pl010_config_port,
598         .verify_port    = pl010_verify_port,
599 #ifdef CONFIG_CONSOLE_POLL
600         .poll_get_char = pl010_get_poll_char,
601         .poll_put_char = pl010_put_poll_char,
602 #endif
603 };
604
605 static struct uart_amba_port *amba_ports[UART_NR];
606
607 #ifdef CONFIG_SERIAL_AMBA_PL011_CONSOLE
608
609 static void pl011_console_putchar(struct uart_port *port, int ch)
610 {
611         struct uart_amba_port *uap = (struct uart_amba_port *)port;
612
613         while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF)
614                 barrier();
615         writew(ch, uap->port.membase + UART01x_DR);
616 }
617
618 static void
619 pl011_console_write(struct console *co, const char *s, unsigned int count)
620 {
621         struct uart_amba_port *uap = amba_ports[co->index];
622         unsigned int status, old_cr, new_cr;
623
624         clk_enable(uap->clk);
625
626         /*
627          *      First save the CR then disable the interrupts
628          */
629         old_cr = readw(uap->port.membase + UART011_CR);
630         new_cr = old_cr & ~UART011_CR_CTSEN;
631         new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE;
632         writew(new_cr, uap->port.membase + UART011_CR);
633
634         uart_console_write(&uap->port, s, count, pl011_console_putchar);
635
636         /*
637          *      Finally, wait for transmitter to become empty
638          *      and restore the TCR
639          */
640         do {
641                 status = readw(uap->port.membase + UART01x_FR);
642         } while (status & UART01x_FR_BUSY);
643         writew(old_cr, uap->port.membase + UART011_CR);
644
645         clk_disable(uap->clk);
646 }
647
648 static void __init
649 pl011_console_get_options(struct uart_amba_port *uap, int *baud,
650                              int *parity, int *bits)
651 {
652         if (readw(uap->port.membase + UART011_CR) & UART01x_CR_UARTEN) {
653                 unsigned int lcr_h, ibrd, fbrd;
654
655                 lcr_h = readw(uap->port.membase + UART011_LCRH);
656
657                 *parity = 'n';
658                 if (lcr_h & UART01x_LCRH_PEN) {
659                         if (lcr_h & UART01x_LCRH_EPS)
660                                 *parity = 'e';
661                         else
662                                 *parity = 'o';
663                 }
664
665                 if ((lcr_h & 0x60) == UART01x_LCRH_WLEN_7)
666                         *bits = 7;
667                 else
668                         *bits = 8;
669
670                 ibrd = readw(uap->port.membase + UART011_IBRD);
671                 fbrd = readw(uap->port.membase + UART011_FBRD);
672
673                 *baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd);
674         }
675 }
676
677 static int __init pl011_console_setup(struct console *co, char *options)
678 {
679         struct uart_amba_port *uap;
680         int baud = 38400;
681         int bits = 8;
682         int parity = 'n';
683         int flow = 'n';
684
685         /*
686          * Check whether an invalid uart number has been specified, and
687          * if so, search for the first available port that does have
688          * console support.
689          */
690         if (co->index >= UART_NR)
691                 co->index = 0;
692         uap = amba_ports[co->index];
693         if (!uap)
694                 return -ENODEV;
695
696         uap->port.uartclk = clk_get_rate(uap->clk);
697
698         if (options)
699                 uart_parse_options(options, &baud, &parity, &bits, &flow);
700         else
701                 pl011_console_get_options(uap, &baud, &parity, &bits);
702
703         return uart_set_options(&uap->port, co, baud, parity, bits, flow);
704 }
705
706 static struct uart_driver amba_reg;
707 static struct console amba_console = {
708         .name           = "ttyAMA",
709         .write          = pl011_console_write,
710         .device         = uart_console_device,
711         .setup          = pl011_console_setup,
712         .flags          = CON_PRINTBUFFER,
713         .index          = -1,
714         .data           = &amba_reg,
715 };
716
717 #define AMBA_CONSOLE    (&amba_console)
718 #else
719 #define AMBA_CONSOLE    NULL
720 #endif
721
722 static struct uart_driver amba_reg = {
723         .owner                  = THIS_MODULE,
724         .driver_name            = "ttyAMA",
725         .dev_name               = "ttyAMA",
726         .major                  = SERIAL_AMBA_MAJOR,
727         .minor                  = SERIAL_AMBA_MINOR,
728         .nr                     = UART_NR,
729         .cons                   = AMBA_CONSOLE,
730 };
731
732 static int pl011_probe(struct amba_device *dev, void *id)
733 {
734         struct uart_amba_port *uap;
735         void __iomem *base;
736         int i, ret;
737
738         for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
739                 if (amba_ports[i] == NULL)
740                         break;
741
742         if (i == ARRAY_SIZE(amba_ports)) {
743                 ret = -EBUSY;
744                 goto out;
745         }
746
747         uap = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL);
748         if (uap == NULL) {
749                 ret = -ENOMEM;
750                 goto out;
751         }
752
753         base = ioremap(dev->res.start, PAGE_SIZE);
754         if (!base) {
755                 ret = -ENOMEM;
756                 goto free;
757         }
758
759         uap->clk = clk_get(&dev->dev, "UARTCLK");
760         if (IS_ERR(uap->clk)) {
761                 ret = PTR_ERR(uap->clk);
762                 goto unmap;
763         }
764
765         uap->port.dev = &dev->dev;
766         uap->port.mapbase = dev->res.start;
767         uap->port.membase = base;
768         uap->port.iotype = UPIO_MEM;
769         uap->port.irq = dev->irq[0];
770         uap->port.fifosize = 16;
771         uap->port.ops = &amba_pl011_pops;
772         uap->port.flags = UPF_BOOT_AUTOCONF;
773         uap->port.line = i;
774
775         amba_ports[i] = uap;
776
777         amba_set_drvdata(dev, uap);
778         ret = uart_add_one_port(&amba_reg, &uap->port);
779         if (ret) {
780                 amba_set_drvdata(dev, NULL);
781                 amba_ports[i] = NULL;
782                 clk_put(uap->clk);
783  unmap:
784                 iounmap(base);
785  free:
786                 kfree(uap);
787         }
788  out:
789         return ret;
790 }
791
792 static int pl011_remove(struct amba_device *dev)
793 {
794         struct uart_amba_port *uap = amba_get_drvdata(dev);
795         int i;
796
797         amba_set_drvdata(dev, NULL);
798
799         uart_remove_one_port(&amba_reg, &uap->port);
800
801         for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
802                 if (amba_ports[i] == uap)
803                         amba_ports[i] = NULL;
804
805         iounmap(uap->port.membase);
806         clk_put(uap->clk);
807         kfree(uap);
808         return 0;
809 }
810
811 static struct amba_id pl011_ids[] __initdata = {
812         {
813                 .id     = 0x00041011,
814                 .mask   = 0x000fffff,
815         },
816         { 0, 0 },
817 };
818
819 static struct amba_driver pl011_driver = {
820         .drv = {
821                 .name   = "uart-pl011",
822         },
823         .id_table       = pl011_ids,
824         .probe          = pl011_probe,
825         .remove         = pl011_remove,
826 };
827
828 static int __init pl011_init(void)
829 {
830         int ret;
831         printk(KERN_INFO "Serial: AMBA PL011 UART driver\n");
832
833         ret = uart_register_driver(&amba_reg);
834         if (ret == 0) {
835                 ret = amba_driver_register(&pl011_driver);
836                 if (ret)
837                         uart_unregister_driver(&amba_reg);
838         }
839         return ret;
840 }
841
842 static void __exit pl011_exit(void)
843 {
844         amba_driver_unregister(&pl011_driver);
845         uart_unregister_driver(&amba_reg);
846 }
847
848 module_init(pl011_init);
849 module_exit(pl011_exit);
850
851 MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd");
852 MODULE_DESCRIPTION("ARM AMBA serial port driver");
853 MODULE_LICENSE("GPL");