ia64/linux-2.6.18-xen.hg

view drivers/serial/amba-pl010.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_PL010_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>
52 #include <asm/io.h>
54 #define UART_NR 8
56 #define SERIAL_AMBA_MAJOR 204
57 #define SERIAL_AMBA_MINOR 16
58 #define SERIAL_AMBA_NR UART_NR
60 #define AMBA_ISR_PASS_LIMIT 256
62 #define UART_RX_DATA(s) (((s) & UART01x_FR_RXFE) == 0)
63 #define UART_TX_READY(s) (((s) & UART01x_FR_TXFF) == 0)
65 #define UART_DUMMY_RSR_RX 256
66 #define UART_PORT_SIZE 64
68 /*
69 * We wrap our port structure around the generic uart_port.
70 */
71 struct uart_amba_port {
72 struct uart_port port;
73 struct amba_device *dev;
74 struct amba_pl010_data *data;
75 unsigned int old_status;
76 };
78 static void pl010_stop_tx(struct uart_port *port)
79 {
80 unsigned int cr;
82 cr = readb(port->membase + UART010_CR);
83 cr &= ~UART010_CR_TIE;
84 writel(cr, port->membase + UART010_CR);
85 }
87 static void pl010_start_tx(struct uart_port *port)
88 {
89 unsigned int cr;
91 cr = readb(port->membase + UART010_CR);
92 cr |= UART010_CR_TIE;
93 writel(cr, port->membase + UART010_CR);
94 }
96 static void pl010_stop_rx(struct uart_port *port)
97 {
98 unsigned int cr;
100 cr = readb(port->membase + UART010_CR);
101 cr &= ~(UART010_CR_RIE | UART010_CR_RTIE);
102 writel(cr, port->membase + UART010_CR);
103 }
105 static void pl010_enable_ms(struct uart_port *port)
106 {
107 unsigned int cr;
109 cr = readb(port->membase + UART010_CR);
110 cr |= UART010_CR_MSIE;
111 writel(cr, port->membase + UART010_CR);
112 }
114 static void
115 #ifdef SUPPORT_SYSRQ
116 pl010_rx_chars(struct uart_port *port, struct pt_regs *regs)
117 #else
118 pl010_rx_chars(struct uart_port *port)
119 #endif
120 {
121 struct tty_struct *tty = port->info->tty;
122 unsigned int status, ch, flag, rsr, max_count = 256;
124 status = readb(port->membase + UART01x_FR);
125 while (UART_RX_DATA(status) && max_count--) {
126 ch = readb(port->membase + UART01x_DR);
127 flag = TTY_NORMAL;
129 port->icount.rx++;
131 /*
132 * Note that the error handling code is
133 * out of the main execution path
134 */
135 rsr = readb(port->membase + UART01x_RSR) | UART_DUMMY_RSR_RX;
136 if (unlikely(rsr & UART01x_RSR_ANY)) {
137 if (rsr & UART01x_RSR_BE) {
138 rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE);
139 port->icount.brk++;
140 if (uart_handle_break(port))
141 goto ignore_char;
142 } else if (rsr & UART01x_RSR_PE)
143 port->icount.parity++;
144 else if (rsr & UART01x_RSR_FE)
145 port->icount.frame++;
146 if (rsr & UART01x_RSR_OE)
147 port->icount.overrun++;
149 rsr &= port->read_status_mask;
151 if (rsr & UART01x_RSR_BE)
152 flag = TTY_BREAK;
153 else if (rsr & UART01x_RSR_PE)
154 flag = TTY_PARITY;
155 else if (rsr & UART01x_RSR_FE)
156 flag = TTY_FRAME;
157 }
159 if (uart_handle_sysrq_char(port, ch, regs))
160 goto ignore_char;
162 uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag);
164 ignore_char:
165 status = readb(port->membase + UART01x_FR);
166 }
167 tty_flip_buffer_push(tty);
168 return;
169 }
171 static void pl010_tx_chars(struct uart_port *port)
172 {
173 struct circ_buf *xmit = &port->info->xmit;
174 int count;
176 if (port->x_char) {
177 writel(port->x_char, port->membase + UART01x_DR);
178 port->icount.tx++;
179 port->x_char = 0;
180 return;
181 }
182 if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
183 pl010_stop_tx(port);
184 return;
185 }
187 count = port->fifosize >> 1;
188 do {
189 writel(xmit->buf[xmit->tail], port->membase + UART01x_DR);
190 xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
191 port->icount.tx++;
192 if (uart_circ_empty(xmit))
193 break;
194 } while (--count > 0);
196 if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
197 uart_write_wakeup(port);
199 if (uart_circ_empty(xmit))
200 pl010_stop_tx(port);
201 }
203 static void pl010_modem_status(struct uart_port *port)
204 {
205 struct uart_amba_port *uap = (struct uart_amba_port *)port;
206 unsigned int status, delta;
208 writel(0, uap->port.membase + UART010_ICR);
210 status = readb(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
212 delta = status ^ uap->old_status;
213 uap->old_status = status;
215 if (!delta)
216 return;
218 if (delta & UART01x_FR_DCD)
219 uart_handle_dcd_change(&uap->port, status & UART01x_FR_DCD);
221 if (delta & UART01x_FR_DSR)
222 uap->port.icount.dsr++;
224 if (delta & UART01x_FR_CTS)
225 uart_handle_cts_change(&uap->port, status & UART01x_FR_CTS);
227 wake_up_interruptible(&uap->port.info->delta_msr_wait);
228 }
230 static irqreturn_t pl010_int(int irq, void *dev_id, struct pt_regs *regs)
231 {
232 struct uart_port *port = dev_id;
233 unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
234 int handled = 0;
236 spin_lock(&port->lock);
238 status = readb(port->membase + UART010_IIR);
239 if (status) {
240 do {
241 if (status & (UART010_IIR_RTIS | UART010_IIR_RIS))
242 #ifdef SUPPORT_SYSRQ
243 pl010_rx_chars(port, regs);
244 #else
245 pl010_rx_chars(port);
246 #endif
247 if (status & UART010_IIR_MIS)
248 pl010_modem_status(port);
249 if (status & UART010_IIR_TIS)
250 pl010_tx_chars(port);
252 if (pass_counter-- == 0)
253 break;
255 status = readb(port->membase + UART010_IIR);
256 } while (status & (UART010_IIR_RTIS | UART010_IIR_RIS |
257 UART010_IIR_TIS));
258 handled = 1;
259 }
261 spin_unlock(&port->lock);
263 return IRQ_RETVAL(handled);
264 }
266 static unsigned int pl010_tx_empty(struct uart_port *port)
267 {
268 return readb(port->membase + UART01x_FR) & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT;
269 }
271 static unsigned int pl010_get_mctrl(struct uart_port *port)
272 {
273 unsigned int result = 0;
274 unsigned int status;
276 status = readb(port->membase + UART01x_FR);
277 if (status & UART01x_FR_DCD)
278 result |= TIOCM_CAR;
279 if (status & UART01x_FR_DSR)
280 result |= TIOCM_DSR;
281 if (status & UART01x_FR_CTS)
282 result |= TIOCM_CTS;
284 return result;
285 }
287 static void pl010_set_mctrl(struct uart_port *port, unsigned int mctrl)
288 {
289 struct uart_amba_port *uap = (struct uart_amba_port *)port;
291 if (uap->data)
292 uap->data->set_mctrl(uap->dev, uap->port.membase, mctrl);
293 }
295 static void pl010_break_ctl(struct uart_port *port, int break_state)
296 {
297 unsigned long flags;
298 unsigned int lcr_h;
300 spin_lock_irqsave(&port->lock, flags);
301 lcr_h = readb(port->membase + UART010_LCRH);
302 if (break_state == -1)
303 lcr_h |= UART01x_LCRH_BRK;
304 else
305 lcr_h &= ~UART01x_LCRH_BRK;
306 writel(lcr_h, port->membase + UART010_LCRH);
307 spin_unlock_irqrestore(&port->lock, flags);
308 }
310 static int pl010_startup(struct uart_port *port)
311 {
312 struct uart_amba_port *uap = (struct uart_amba_port *)port;
313 int retval;
315 /*
316 * Allocate the IRQ
317 */
318 retval = request_irq(port->irq, pl010_int, 0, "uart-pl010", port);
319 if (retval)
320 return retval;
322 /*
323 * initialise the old status of the modem signals
324 */
325 uap->old_status = readb(port->membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
327 /*
328 * Finally, enable interrupts
329 */
330 writel(UART01x_CR_UARTEN | UART010_CR_RIE | UART010_CR_RTIE,
331 port->membase + UART010_CR);
333 return 0;
334 }
336 static void pl010_shutdown(struct uart_port *port)
337 {
338 /*
339 * Free the interrupt
340 */
341 free_irq(port->irq, port);
343 /*
344 * disable all interrupts, disable the port
345 */
346 writel(0, port->membase + UART010_CR);
348 /* disable break condition and fifos */
349 writel(readb(port->membase + UART010_LCRH) &
350 ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN),
351 port->membase + UART010_LCRH);
352 }
354 static void
355 pl010_set_termios(struct uart_port *port, struct termios *termios,
356 struct termios *old)
357 {
358 unsigned int lcr_h, old_cr;
359 unsigned long flags;
360 unsigned int baud, quot;
362 /*
363 * Ask the core to calculate the divisor for us.
364 */
365 baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
366 quot = uart_get_divisor(port, baud);
368 switch (termios->c_cflag & CSIZE) {
369 case CS5:
370 lcr_h = UART01x_LCRH_WLEN_5;
371 break;
372 case CS6:
373 lcr_h = UART01x_LCRH_WLEN_6;
374 break;
375 case CS7:
376 lcr_h = UART01x_LCRH_WLEN_7;
377 break;
378 default: // CS8
379 lcr_h = UART01x_LCRH_WLEN_8;
380 break;
381 }
382 if (termios->c_cflag & CSTOPB)
383 lcr_h |= UART01x_LCRH_STP2;
384 if (termios->c_cflag & PARENB) {
385 lcr_h |= UART01x_LCRH_PEN;
386 if (!(termios->c_cflag & PARODD))
387 lcr_h |= UART01x_LCRH_EPS;
388 }
389 if (port->fifosize > 1)
390 lcr_h |= UART01x_LCRH_FEN;
392 spin_lock_irqsave(&port->lock, flags);
394 /*
395 * Update the per-port timeout.
396 */
397 uart_update_timeout(port, termios->c_cflag, baud);
399 port->read_status_mask = UART01x_RSR_OE;
400 if (termios->c_iflag & INPCK)
401 port->read_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
402 if (termios->c_iflag & (BRKINT | PARMRK))
403 port->read_status_mask |= UART01x_RSR_BE;
405 /*
406 * Characters to ignore
407 */
408 port->ignore_status_mask = 0;
409 if (termios->c_iflag & IGNPAR)
410 port->ignore_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
411 if (termios->c_iflag & IGNBRK) {
412 port->ignore_status_mask |= UART01x_RSR_BE;
413 /*
414 * If we're ignoring parity and break indicators,
415 * ignore overruns too (for real raw support).
416 */
417 if (termios->c_iflag & IGNPAR)
418 port->ignore_status_mask |= UART01x_RSR_OE;
419 }
421 /*
422 * Ignore all characters if CREAD is not set.
423 */
424 if ((termios->c_cflag & CREAD) == 0)
425 port->ignore_status_mask |= UART_DUMMY_RSR_RX;
427 /* first, disable everything */
428 old_cr = readb(port->membase + UART010_CR) & ~UART010_CR_MSIE;
430 if (UART_ENABLE_MS(port, termios->c_cflag))
431 old_cr |= UART010_CR_MSIE;
433 writel(0, port->membase + UART010_CR);
435 /* Set baud rate */
436 quot -= 1;
437 writel((quot & 0xf00) >> 8, port->membase + UART010_LCRM);
438 writel(quot & 0xff, port->membase + UART010_LCRL);
440 /*
441 * ----------v----------v----------v----------v-----
442 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
443 * ----------^----------^----------^----------^-----
444 */
445 writel(lcr_h, port->membase + UART010_LCRH);
446 writel(old_cr, port->membase + UART010_CR);
448 spin_unlock_irqrestore(&port->lock, flags);
449 }
451 static const char *pl010_type(struct uart_port *port)
452 {
453 return port->type == PORT_AMBA ? "AMBA" : NULL;
454 }
456 /*
457 * Release the memory region(s) being used by 'port'
458 */
459 static void pl010_release_port(struct uart_port *port)
460 {
461 release_mem_region(port->mapbase, UART_PORT_SIZE);
462 }
464 /*
465 * Request the memory region(s) being used by 'port'
466 */
467 static int pl010_request_port(struct uart_port *port)
468 {
469 return request_mem_region(port->mapbase, UART_PORT_SIZE, "uart-pl010")
470 != NULL ? 0 : -EBUSY;
471 }
473 /*
474 * Configure/autoconfigure the port.
475 */
476 static void pl010_config_port(struct uart_port *port, int flags)
477 {
478 if (flags & UART_CONFIG_TYPE) {
479 port->type = PORT_AMBA;
480 pl010_request_port(port);
481 }
482 }
484 /*
485 * verify the new serial_struct (for TIOCSSERIAL).
486 */
487 static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser)
488 {
489 int ret = 0;
490 if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)
491 ret = -EINVAL;
492 if (ser->irq < 0 || ser->irq >= NR_IRQS)
493 ret = -EINVAL;
494 if (ser->baud_base < 9600)
495 ret = -EINVAL;
496 return ret;
497 }
499 static struct uart_ops amba_pl010_pops = {
500 .tx_empty = pl010_tx_empty,
501 .set_mctrl = pl010_set_mctrl,
502 .get_mctrl = pl010_get_mctrl,
503 .stop_tx = pl010_stop_tx,
504 .start_tx = pl010_start_tx,
505 .stop_rx = pl010_stop_rx,
506 .enable_ms = pl010_enable_ms,
507 .break_ctl = pl010_break_ctl,
508 .startup = pl010_startup,
509 .shutdown = pl010_shutdown,
510 .set_termios = pl010_set_termios,
511 .type = pl010_type,
512 .release_port = pl010_release_port,
513 .request_port = pl010_request_port,
514 .config_port = pl010_config_port,
515 .verify_port = pl010_verify_port,
516 };
518 static struct uart_amba_port *amba_ports[UART_NR];
520 #ifdef CONFIG_SERIAL_AMBA_PL010_CONSOLE
522 static void pl010_console_putchar(struct uart_port *port, int ch)
523 {
524 unsigned int status;
526 do {
527 status = readb(port->membase + UART01x_FR);
528 barrier();
529 } while (!UART_TX_READY(status));
530 writel(ch, port->membase + UART01x_DR);
531 }
533 static void
534 pl010_console_write(struct console *co, const char *s, unsigned int count)
535 {
536 struct uart_port *port = &amba_ports[co->index]->port;
537 unsigned int status, old_cr;
539 /*
540 * First save the CR then disable the interrupts
541 */
542 old_cr = readb(port->membase + UART010_CR);
543 writel(UART01x_CR_UARTEN, port->membase + UART010_CR);
545 uart_console_write(port, s, count, pl010_console_putchar);
547 /*
548 * Finally, wait for transmitter to become empty
549 * and restore the TCR
550 */
551 do {
552 status = readb(port->membase + UART01x_FR);
553 barrier();
554 } while (status & UART01x_FR_BUSY);
555 writel(old_cr, port->membase + UART010_CR);
556 }
558 static void __init
559 pl010_console_get_options(struct uart_port *port, int *baud,
560 int *parity, int *bits)
561 {
562 if (readb(port->membase + UART010_CR) & UART01x_CR_UARTEN) {
563 unsigned int lcr_h, quot;
564 lcr_h = readb(port->membase + UART010_LCRH);
566 *parity = 'n';
567 if (lcr_h & UART01x_LCRH_PEN) {
568 if (lcr_h & UART01x_LCRH_EPS)
569 *parity = 'e';
570 else
571 *parity = 'o';
572 }
574 if ((lcr_h & 0x60) == UART01x_LCRH_WLEN_7)
575 *bits = 7;
576 else
577 *bits = 8;
579 quot = readb(port->membase + UART010_LCRL) | readb(port->membase + UART010_LCRM) << 8;
580 *baud = port->uartclk / (16 * (quot + 1));
581 }
582 }
584 static int __init pl010_console_setup(struct console *co, char *options)
585 {
586 struct uart_port *port;
587 int baud = 38400;
588 int bits = 8;
589 int parity = 'n';
590 int flow = 'n';
592 /*
593 * Check whether an invalid uart number has been specified, and
594 * if so, search for the first available port that does have
595 * console support.
596 */
597 if (co->index >= UART_NR)
598 co->index = 0;
599 port = &amba_ports[co->index]->port;
601 if (options)
602 uart_parse_options(options, &baud, &parity, &bits, &flow);
603 else
604 pl010_console_get_options(port, &baud, &parity, &bits);
606 return uart_set_options(port, co, baud, parity, bits, flow);
607 }
609 static struct uart_driver amba_reg;
610 static struct console amba_console = {
611 .name = "ttyAM",
612 .write = pl010_console_write,
613 .device = uart_console_device,
614 .setup = pl010_console_setup,
615 .flags = CON_PRINTBUFFER,
616 .index = -1,
617 .data = &amba_reg,
618 };
620 #define AMBA_CONSOLE &amba_console
621 #else
622 #define AMBA_CONSOLE NULL
623 #endif
625 static struct uart_driver amba_reg = {
626 .owner = THIS_MODULE,
627 .driver_name = "ttyAM",
628 .dev_name = "ttyAM",
629 .major = SERIAL_AMBA_MAJOR,
630 .minor = SERIAL_AMBA_MINOR,
631 .nr = UART_NR,
632 .cons = AMBA_CONSOLE,
633 };
635 static int pl010_probe(struct amba_device *dev, void *id)
636 {
637 struct uart_amba_port *port;
638 void __iomem *base;
639 int i, ret;
641 for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
642 if (amba_ports[i] == NULL)
643 break;
645 if (i == ARRAY_SIZE(amba_ports)) {
646 ret = -EBUSY;
647 goto out;
648 }
650 port = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL);
651 if (!port) {
652 ret = -ENOMEM;
653 goto out;
654 }
656 base = ioremap(dev->res.start, PAGE_SIZE);
657 if (!base) {
658 ret = -ENOMEM;
659 goto free;
660 }
662 port->port.dev = &dev->dev;
663 port->port.mapbase = dev->res.start;
664 port->port.membase = base;
665 port->port.iotype = UPIO_MEM;
666 port->port.irq = dev->irq[0];
667 port->port.uartclk = 14745600;
668 port->port.fifosize = 16;
669 port->port.ops = &amba_pl010_pops;
670 port->port.flags = UPF_BOOT_AUTOCONF;
671 port->port.line = i;
672 port->dev = dev;
673 port->data = dev->dev.platform_data;
675 amba_ports[i] = port;
677 amba_set_drvdata(dev, port);
678 ret = uart_add_one_port(&amba_reg, &port->port);
679 if (ret) {
680 amba_set_drvdata(dev, NULL);
681 amba_ports[i] = NULL;
682 iounmap(base);
683 free:
684 kfree(port);
685 }
687 out:
688 return ret;
689 }
691 static int pl010_remove(struct amba_device *dev)
692 {
693 struct uart_amba_port *port = amba_get_drvdata(dev);
694 int i;
696 amba_set_drvdata(dev, NULL);
698 uart_remove_one_port(&amba_reg, &port->port);
700 for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
701 if (amba_ports[i] == port)
702 amba_ports[i] = NULL;
704 iounmap(port->port.membase);
705 kfree(port);
707 return 0;
708 }
710 static int pl010_suspend(struct amba_device *dev, pm_message_t state)
711 {
712 struct uart_amba_port *uap = amba_get_drvdata(dev);
714 if (uap)
715 uart_suspend_port(&amba_reg, &uap->port);
717 return 0;
718 }
720 static int pl010_resume(struct amba_device *dev)
721 {
722 struct uart_amba_port *uap = amba_get_drvdata(dev);
724 if (uap)
725 uart_resume_port(&amba_reg, &uap->port);
727 return 0;
728 }
730 static struct amba_id pl010_ids[] __initdata = {
731 {
732 .id = 0x00041010,
733 .mask = 0x000fffff,
734 },
735 { 0, 0 },
736 };
738 static struct amba_driver pl010_driver = {
739 .drv = {
740 .name = "uart-pl010",
741 },
742 .id_table = pl010_ids,
743 .probe = pl010_probe,
744 .remove = pl010_remove,
745 .suspend = pl010_suspend,
746 .resume = pl010_resume,
747 };
749 static int __init pl010_init(void)
750 {
751 int ret;
753 printk(KERN_INFO "Serial: AMBA driver $Revision: 1.41 $\n");
755 ret = uart_register_driver(&amba_reg);
756 if (ret == 0) {
757 ret = amba_driver_register(&pl010_driver);
758 if (ret)
759 uart_unregister_driver(&amba_reg);
760 }
761 return ret;
762 }
764 static void __exit pl010_exit(void)
765 {
766 amba_driver_unregister(&pl010_driver);
767 uart_unregister_driver(&amba_reg);
768 }
770 module_init(pl010_init);
771 module_exit(pl010_exit);
773 MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd");
774 MODULE_DESCRIPTION("ARM AMBA serial port driver $Revision: 1.41 $");
775 MODULE_LICENSE("GPL");