ia64/linux-2.6.18-xen.hg

view drivers/serial/amba-pl011.c @ 897:329ea0ccb344

balloon: try harder to balloon up under memory pressure.

Currently if the balloon driver is unable to increase the guest's
reservation it assumes the failure was due to reaching its full
allocation, gives up on the ballooning operation and records the limit
it reached as the "hard limit". The driver will not try again until
the target is set again (even to the same value).

However it is possible that ballooning has in fact failed due to
memory pressure in the host and therefore it is desirable to keep
attempting to reach the target in case memory becomes available. The
most likely scenario is that some guests are ballooning down while
others are ballooning up and therefore there is temporary memory
pressure while things stabilise. You would not expect a well behaved
toolstack to ask a domain to balloon to more than its allocation nor
would you expect it to deliberately over-commit memory by setting
balloon targets which exceed the total host memory.

This patch drops the concept of a hard limit and causes the balloon
driver to retry increasing the reservation on a timer in the same
manner as when decreasing the reservation.

Also if we partially succeed in increasing the reservation
(i.e. receive less pages than we asked for) then we may as well keep
those pages rather than returning them to Xen.

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