cachepc-linux

Fork of AMDESE/linux with modifications for CachePC side-channel attack
git clone https://git.sinitax.com/sinitax/cachepc-linux
Log | Files | Refs | README | LICENSE | sfeed.txt

amba-pl010.c (19161B)


      1// SPDX-License-Identifier: GPL-2.0+
      2/*
      3 *  Driver for AMBA serial ports
      4 *
      5 *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
      6 *
      7 *  Copyright 1999 ARM Limited
      8 *  Copyright (C) 2000 Deep Blue Solutions Ltd.
      9 *
     10 * This is a generic driver for ARM AMBA-type serial ports.  They
     11 * have a lot of 16550-like features, but are not register compatible.
     12 * Note that although they do have CTS, DCD and DSR inputs, they do
     13 * not have an RI input, nor do they have DTR or RTS outputs.  If
     14 * required, these have to be supplied via some other means (eg, GPIO)
     15 * and hooked into this driver.
     16 */
     17
     18#include <linux/module.h>
     19#include <linux/ioport.h>
     20#include <linux/init.h>
     21#include <linux/console.h>
     22#include <linux/sysrq.h>
     23#include <linux/device.h>
     24#include <linux/tty.h>
     25#include <linux/tty_flip.h>
     26#include <linux/serial_core.h>
     27#include <linux/serial.h>
     28#include <linux/amba/bus.h>
     29#include <linux/amba/serial.h>
     30#include <linux/clk.h>
     31#include <linux/slab.h>
     32#include <linux/io.h>
     33
     34#define UART_NR		8
     35
     36#define SERIAL_AMBA_MAJOR	204
     37#define SERIAL_AMBA_MINOR	16
     38#define SERIAL_AMBA_NR		UART_NR
     39
     40#define AMBA_ISR_PASS_LIMIT	256
     41
     42#define UART_RX_DATA(s)		(((s) & UART01x_FR_RXFE) == 0)
     43#define UART_TX_READY(s)	(((s) & UART01x_FR_TXFF) == 0)
     44
     45#define UART_DUMMY_RSR_RX	256
     46#define UART_PORT_SIZE		64
     47
     48/*
     49 * We wrap our port structure around the generic uart_port.
     50 */
     51struct uart_amba_port {
     52	struct uart_port	port;
     53	struct clk		*clk;
     54	struct amba_device	*dev;
     55	struct amba_pl010_data	*data;
     56	unsigned int		old_status;
     57};
     58
     59static void pl010_stop_tx(struct uart_port *port)
     60{
     61	struct uart_amba_port *uap =
     62		container_of(port, struct uart_amba_port, port);
     63	unsigned int cr;
     64
     65	cr = readb(uap->port.membase + UART010_CR);
     66	cr &= ~UART010_CR_TIE;
     67	writel(cr, uap->port.membase + UART010_CR);
     68}
     69
     70static void pl010_start_tx(struct uart_port *port)
     71{
     72	struct uart_amba_port *uap =
     73		container_of(port, struct uart_amba_port, port);
     74	unsigned int cr;
     75
     76	cr = readb(uap->port.membase + UART010_CR);
     77	cr |= UART010_CR_TIE;
     78	writel(cr, uap->port.membase + UART010_CR);
     79}
     80
     81static void pl010_stop_rx(struct uart_port *port)
     82{
     83	struct uart_amba_port *uap =
     84		container_of(port, struct uart_amba_port, port);
     85	unsigned int cr;
     86
     87	cr = readb(uap->port.membase + UART010_CR);
     88	cr &= ~(UART010_CR_RIE | UART010_CR_RTIE);
     89	writel(cr, uap->port.membase + UART010_CR);
     90}
     91
     92static void pl010_disable_ms(struct uart_port *port)
     93{
     94	struct uart_amba_port *uap = (struct uart_amba_port *)port;
     95	unsigned int cr;
     96
     97	cr = readb(uap->port.membase + UART010_CR);
     98	cr &= ~UART010_CR_MSIE;
     99	writel(cr, uap->port.membase + UART010_CR);
    100}
    101
    102static void pl010_enable_ms(struct uart_port *port)
    103{
    104	struct uart_amba_port *uap =
    105		container_of(port, struct uart_amba_port, port);
    106	unsigned int cr;
    107
    108	cr = readb(uap->port.membase + UART010_CR);
    109	cr |= UART010_CR_MSIE;
    110	writel(cr, uap->port.membase + UART010_CR);
    111}
    112
    113static void pl010_rx_chars(struct uart_port *port)
    114{
    115	unsigned int status, ch, flag, rsr, max_count = 256;
    116
    117	status = readb(port->membase + UART01x_FR);
    118	while (UART_RX_DATA(status) && max_count--) {
    119		ch = readb(port->membase + UART01x_DR);
    120		flag = TTY_NORMAL;
    121
    122		port->icount.rx++;
    123
    124		/*
    125		 * Note that the error handling code is
    126		 * out of the main execution path
    127		 */
    128		rsr = readb(port->membase + UART01x_RSR) | UART_DUMMY_RSR_RX;
    129		if (unlikely(rsr & UART01x_RSR_ANY)) {
    130			writel(0, port->membase + UART01x_ECR);
    131
    132			if (rsr & UART01x_RSR_BE) {
    133				rsr &= ~(UART01x_RSR_FE | UART01x_RSR_PE);
    134				port->icount.brk++;
    135				if (uart_handle_break(port))
    136					goto ignore_char;
    137			} else if (rsr & UART01x_RSR_PE)
    138				port->icount.parity++;
    139			else if (rsr & UART01x_RSR_FE)
    140				port->icount.frame++;
    141			if (rsr & UART01x_RSR_OE)
    142				port->icount.overrun++;
    143
    144			rsr &= port->read_status_mask;
    145
    146			if (rsr & UART01x_RSR_BE)
    147				flag = TTY_BREAK;
    148			else if (rsr & UART01x_RSR_PE)
    149				flag = TTY_PARITY;
    150			else if (rsr & UART01x_RSR_FE)
    151				flag = TTY_FRAME;
    152		}
    153
    154		if (uart_handle_sysrq_char(port, ch))
    155			goto ignore_char;
    156
    157		uart_insert_char(port, rsr, UART01x_RSR_OE, ch, flag);
    158
    159	ignore_char:
    160		status = readb(port->membase + UART01x_FR);
    161	}
    162	tty_flip_buffer_push(&port->state->port);
    163}
    164
    165static void pl010_tx_chars(struct uart_port *port)
    166{
    167	struct circ_buf *xmit = &port->state->xmit;
    168	int count;
    169
    170	if (port->x_char) {
    171		writel(port->x_char, port->membase + UART01x_DR);
    172		port->icount.tx++;
    173		port->x_char = 0;
    174		return;
    175	}
    176	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
    177		pl010_stop_tx(port);
    178		return;
    179	}
    180
    181	count = port->fifosize >> 1;
    182	do {
    183		writel(xmit->buf[xmit->tail], port->membase + UART01x_DR);
    184		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
    185		port->icount.tx++;
    186		if (uart_circ_empty(xmit))
    187			break;
    188	} while (--count > 0);
    189
    190	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
    191		uart_write_wakeup(port);
    192
    193	if (uart_circ_empty(xmit))
    194		pl010_stop_tx(port);
    195}
    196
    197static void pl010_modem_status(struct uart_amba_port *uap)
    198{
    199	struct uart_port *port = &uap->port;
    200	unsigned int status, delta;
    201
    202	writel(0, port->membase + UART010_ICR);
    203
    204	status = readb(port->membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
    205
    206	delta = status ^ uap->old_status;
    207	uap->old_status = status;
    208
    209	if (!delta)
    210		return;
    211
    212	if (delta & UART01x_FR_DCD)
    213		uart_handle_dcd_change(port, status & UART01x_FR_DCD);
    214
    215	if (delta & UART01x_FR_DSR)
    216		port->icount.dsr++;
    217
    218	if (delta & UART01x_FR_CTS)
    219		uart_handle_cts_change(port, status & UART01x_FR_CTS);
    220
    221	wake_up_interruptible(&port->state->port.delta_msr_wait);
    222}
    223
    224static irqreturn_t pl010_int(int irq, void *dev_id)
    225{
    226	struct uart_amba_port *uap = dev_id;
    227	struct uart_port *port = &uap->port;
    228	unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
    229	int handled = 0;
    230
    231	spin_lock(&port->lock);
    232
    233	status = readb(port->membase + UART010_IIR);
    234	if (status) {
    235		do {
    236			if (status & (UART010_IIR_RTIS | UART010_IIR_RIS))
    237				pl010_rx_chars(port);
    238			if (status & UART010_IIR_MIS)
    239				pl010_modem_status(uap);
    240			if (status & UART010_IIR_TIS)
    241				pl010_tx_chars(port);
    242
    243			if (pass_counter-- == 0)
    244				break;
    245
    246			status = readb(port->membase + UART010_IIR);
    247		} while (status & (UART010_IIR_RTIS | UART010_IIR_RIS |
    248				   UART010_IIR_TIS));
    249		handled = 1;
    250	}
    251
    252	spin_unlock(&port->lock);
    253
    254	return IRQ_RETVAL(handled);
    255}
    256
    257static unsigned int pl010_tx_empty(struct uart_port *port)
    258{
    259	unsigned int status = readb(port->membase + UART01x_FR);
    260
    261	return status & UART01x_FR_BUSY ? 0 : TIOCSER_TEMT;
    262}
    263
    264static unsigned int pl010_get_mctrl(struct uart_port *port)
    265{
    266	unsigned int result = 0;
    267	unsigned int status;
    268
    269	status = readb(port->membase + UART01x_FR);
    270	if (status & UART01x_FR_DCD)
    271		result |= TIOCM_CAR;
    272	if (status & UART01x_FR_DSR)
    273		result |= TIOCM_DSR;
    274	if (status & UART01x_FR_CTS)
    275		result |= TIOCM_CTS;
    276
    277	return result;
    278}
    279
    280static void pl010_set_mctrl(struct uart_port *port, unsigned int mctrl)
    281{
    282	struct uart_amba_port *uap =
    283		container_of(port, struct uart_amba_port, port);
    284
    285	if (uap->data)
    286		uap->data->set_mctrl(uap->dev, port->membase, mctrl);
    287}
    288
    289static void pl010_break_ctl(struct uart_port *port, int break_state)
    290{
    291	unsigned long flags;
    292	unsigned int lcr_h;
    293
    294	spin_lock_irqsave(&port->lock, flags);
    295	lcr_h = readb(port->membase + UART010_LCRH);
    296	if (break_state == -1)
    297		lcr_h |= UART01x_LCRH_BRK;
    298	else
    299		lcr_h &= ~UART01x_LCRH_BRK;
    300	writel(lcr_h, port->membase + UART010_LCRH);
    301	spin_unlock_irqrestore(&port->lock, flags);
    302}
    303
    304static int pl010_startup(struct uart_port *port)
    305{
    306	struct uart_amba_port *uap =
    307		container_of(port, struct uart_amba_port, port);
    308	int retval;
    309
    310	/*
    311	 * Try to enable the clock producer.
    312	 */
    313	retval = clk_prepare_enable(uap->clk);
    314	if (retval)
    315		goto out;
    316
    317	port->uartclk = clk_get_rate(uap->clk);
    318
    319	/*
    320	 * Allocate the IRQ
    321	 */
    322	retval = request_irq(port->irq, pl010_int, 0, "uart-pl010", uap);
    323	if (retval)
    324		goto clk_dis;
    325
    326	/*
    327	 * initialise the old status of the modem signals
    328	 */
    329	uap->old_status = readb(port->membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
    330
    331	/*
    332	 * Finally, enable interrupts
    333	 */
    334	writel(UART01x_CR_UARTEN | UART010_CR_RIE | UART010_CR_RTIE,
    335	       port->membase + UART010_CR);
    336
    337	return 0;
    338
    339 clk_dis:
    340	clk_disable_unprepare(uap->clk);
    341 out:
    342	return retval;
    343}
    344
    345static void pl010_shutdown(struct uart_port *port)
    346{
    347	struct uart_amba_port *uap =
    348		container_of(port, struct uart_amba_port, port);
    349
    350	/*
    351	 * Free the interrupt
    352	 */
    353	free_irq(port->irq, uap);
    354
    355	/*
    356	 * disable all interrupts, disable the port
    357	 */
    358	writel(0, port->membase + UART010_CR);
    359
    360	/* disable break condition and fifos */
    361	writel(readb(port->membase + UART010_LCRH) &
    362		~(UART01x_LCRH_BRK | UART01x_LCRH_FEN),
    363	       port->membase + UART010_LCRH);
    364
    365	/*
    366	 * Shut down the clock producer
    367	 */
    368	clk_disable_unprepare(uap->clk);
    369}
    370
    371static void
    372pl010_set_termios(struct uart_port *port, struct ktermios *termios,
    373		     struct ktermios *old)
    374{
    375	unsigned int lcr_h, old_cr;
    376	unsigned long flags;
    377	unsigned int baud, quot;
    378
    379	/*
    380	 * Ask the core to calculate the divisor for us.
    381	 */
    382	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk / 16);
    383	quot = uart_get_divisor(port, baud);
    384
    385	switch (termios->c_cflag & CSIZE) {
    386	case CS5:
    387		lcr_h = UART01x_LCRH_WLEN_5;
    388		break;
    389	case CS6:
    390		lcr_h = UART01x_LCRH_WLEN_6;
    391		break;
    392	case CS7:
    393		lcr_h = UART01x_LCRH_WLEN_7;
    394		break;
    395	default: // CS8
    396		lcr_h = UART01x_LCRH_WLEN_8;
    397		break;
    398	}
    399	if (termios->c_cflag & CSTOPB)
    400		lcr_h |= UART01x_LCRH_STP2;
    401	if (termios->c_cflag & PARENB) {
    402		lcr_h |= UART01x_LCRH_PEN;
    403		if (!(termios->c_cflag & PARODD))
    404			lcr_h |= UART01x_LCRH_EPS;
    405	}
    406	if (port->fifosize > 1)
    407		lcr_h |= UART01x_LCRH_FEN;
    408
    409	spin_lock_irqsave(&port->lock, flags);
    410
    411	/*
    412	 * Update the per-port timeout.
    413	 */
    414	uart_update_timeout(port, termios->c_cflag, baud);
    415
    416	port->read_status_mask = UART01x_RSR_OE;
    417	if (termios->c_iflag & INPCK)
    418		port->read_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
    419	if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
    420		port->read_status_mask |= UART01x_RSR_BE;
    421
    422	/*
    423	 * Characters to ignore
    424	 */
    425	port->ignore_status_mask = 0;
    426	if (termios->c_iflag & IGNPAR)
    427		port->ignore_status_mask |= UART01x_RSR_FE | UART01x_RSR_PE;
    428	if (termios->c_iflag & IGNBRK) {
    429		port->ignore_status_mask |= UART01x_RSR_BE;
    430		/*
    431		 * If we're ignoring parity and break indicators,
    432		 * ignore overruns too (for real raw support).
    433		 */
    434		if (termios->c_iflag & IGNPAR)
    435			port->ignore_status_mask |= UART01x_RSR_OE;
    436	}
    437
    438	/*
    439	 * Ignore all characters if CREAD is not set.
    440	 */
    441	if ((termios->c_cflag & CREAD) == 0)
    442		port->ignore_status_mask |= UART_DUMMY_RSR_RX;
    443
    444	old_cr = readb(port->membase + UART010_CR) & ~UART010_CR_MSIE;
    445
    446	if (UART_ENABLE_MS(port, termios->c_cflag))
    447		old_cr |= UART010_CR_MSIE;
    448
    449	/* Set baud rate */
    450	quot -= 1;
    451	writel((quot & 0xf00) >> 8, port->membase + UART010_LCRM);
    452	writel(quot & 0xff, port->membase + UART010_LCRL);
    453
    454	/*
    455	 * ----------v----------v----------v----------v-----
    456	 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
    457	 * ----------^----------^----------^----------^-----
    458	 */
    459	writel(lcr_h, port->membase + UART010_LCRH);
    460	writel(old_cr, port->membase + UART010_CR);
    461
    462	spin_unlock_irqrestore(&port->lock, flags);
    463}
    464
    465static void pl010_set_ldisc(struct uart_port *port, struct ktermios *termios)
    466{
    467	if (termios->c_line == N_PPS) {
    468		port->flags |= UPF_HARDPPS_CD;
    469		spin_lock_irq(&port->lock);
    470		pl010_enable_ms(port);
    471		spin_unlock_irq(&port->lock);
    472	} else {
    473		port->flags &= ~UPF_HARDPPS_CD;
    474		if (!UART_ENABLE_MS(port, termios->c_cflag)) {
    475			spin_lock_irq(&port->lock);
    476			pl010_disable_ms(port);
    477			spin_unlock_irq(&port->lock);
    478		}
    479	}
    480}
    481
    482static const char *pl010_type(struct uart_port *port)
    483{
    484	return port->type == PORT_AMBA ? "AMBA" : NULL;
    485}
    486
    487/*
    488 * Release the memory region(s) being used by 'port'
    489 */
    490static void pl010_release_port(struct uart_port *port)
    491{
    492	release_mem_region(port->mapbase, UART_PORT_SIZE);
    493}
    494
    495/*
    496 * Request the memory region(s) being used by 'port'
    497 */
    498static int pl010_request_port(struct uart_port *port)
    499{
    500	return request_mem_region(port->mapbase, UART_PORT_SIZE, "uart-pl010")
    501			!= NULL ? 0 : -EBUSY;
    502}
    503
    504/*
    505 * Configure/autoconfigure the port.
    506 */
    507static void pl010_config_port(struct uart_port *port, int flags)
    508{
    509	if (flags & UART_CONFIG_TYPE) {
    510		port->type = PORT_AMBA;
    511		pl010_request_port(port);
    512	}
    513}
    514
    515/*
    516 * verify the new serial_struct (for TIOCSSERIAL).
    517 */
    518static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser)
    519{
    520	int ret = 0;
    521	if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)
    522		ret = -EINVAL;
    523	if (ser->irq < 0 || ser->irq >= nr_irqs)
    524		ret = -EINVAL;
    525	if (ser->baud_base < 9600)
    526		ret = -EINVAL;
    527	return ret;
    528}
    529
    530static const struct uart_ops amba_pl010_pops = {
    531	.tx_empty	= pl010_tx_empty,
    532	.set_mctrl	= pl010_set_mctrl,
    533	.get_mctrl	= pl010_get_mctrl,
    534	.stop_tx	= pl010_stop_tx,
    535	.start_tx	= pl010_start_tx,
    536	.stop_rx	= pl010_stop_rx,
    537	.enable_ms	= pl010_enable_ms,
    538	.break_ctl	= pl010_break_ctl,
    539	.startup	= pl010_startup,
    540	.shutdown	= pl010_shutdown,
    541	.set_termios	= pl010_set_termios,
    542	.set_ldisc	= pl010_set_ldisc,
    543	.type		= pl010_type,
    544	.release_port	= pl010_release_port,
    545	.request_port	= pl010_request_port,
    546	.config_port	= pl010_config_port,
    547	.verify_port	= pl010_verify_port,
    548};
    549
    550static struct uart_amba_port *amba_ports[UART_NR];
    551
    552#ifdef CONFIG_SERIAL_AMBA_PL010_CONSOLE
    553
    554static void pl010_console_putchar(struct uart_port *port, unsigned char ch)
    555{
    556	unsigned int status;
    557
    558	do {
    559		status = readb(port->membase + UART01x_FR);
    560		barrier();
    561	} while (!UART_TX_READY(status));
    562	writel(ch, port->membase + UART01x_DR);
    563}
    564
    565static void
    566pl010_console_write(struct console *co, const char *s, unsigned int count)
    567{
    568	struct uart_amba_port *uap = amba_ports[co->index];
    569	struct uart_port *port = &uap->port;
    570	unsigned int status, old_cr;
    571
    572	clk_enable(uap->clk);
    573
    574	/*
    575	 *	First save the CR then disable the interrupts
    576	 */
    577	old_cr = readb(port->membase + UART010_CR);
    578	writel(UART01x_CR_UARTEN, port->membase + UART010_CR);
    579
    580	uart_console_write(port, s, count, pl010_console_putchar);
    581
    582	/*
    583	 *	Finally, wait for transmitter to become empty
    584	 *	and restore the TCR
    585	 */
    586	do {
    587		status = readb(port->membase + UART01x_FR);
    588		barrier();
    589	} while (status & UART01x_FR_BUSY);
    590	writel(old_cr, port->membase + UART010_CR);
    591
    592	clk_disable(uap->clk);
    593}
    594
    595static void __init
    596pl010_console_get_options(struct uart_amba_port *uap, int *baud,
    597			     int *parity, int *bits)
    598{
    599	if (readb(uap->port.membase + UART010_CR) & UART01x_CR_UARTEN) {
    600		unsigned int lcr_h, quot;
    601		lcr_h = readb(uap->port.membase + UART010_LCRH);
    602
    603		*parity = 'n';
    604		if (lcr_h & UART01x_LCRH_PEN) {
    605			if (lcr_h & UART01x_LCRH_EPS)
    606				*parity = 'e';
    607			else
    608				*parity = 'o';
    609		}
    610
    611		if ((lcr_h & 0x60) == UART01x_LCRH_WLEN_7)
    612			*bits = 7;
    613		else
    614			*bits = 8;
    615
    616		quot = readb(uap->port.membase + UART010_LCRL) |
    617		       readb(uap->port.membase + UART010_LCRM) << 8;
    618		*baud = uap->port.uartclk / (16 * (quot + 1));
    619	}
    620}
    621
    622static int __init pl010_console_setup(struct console *co, char *options)
    623{
    624	struct uart_amba_port *uap;
    625	int baud = 38400;
    626	int bits = 8;
    627	int parity = 'n';
    628	int flow = 'n';
    629	int ret;
    630
    631	/*
    632	 * Check whether an invalid uart number has been specified, and
    633	 * if so, search for the first available port that does have
    634	 * console support.
    635	 */
    636	if (co->index >= UART_NR)
    637		co->index = 0;
    638	uap = amba_ports[co->index];
    639	if (!uap)
    640		return -ENODEV;
    641
    642	ret = clk_prepare(uap->clk);
    643	if (ret)
    644		return ret;
    645
    646	uap->port.uartclk = clk_get_rate(uap->clk);
    647
    648	if (options)
    649		uart_parse_options(options, &baud, &parity, &bits, &flow);
    650	else
    651		pl010_console_get_options(uap, &baud, &parity, &bits);
    652
    653	return uart_set_options(&uap->port, co, baud, parity, bits, flow);
    654}
    655
    656static struct uart_driver amba_reg;
    657static struct console amba_console = {
    658	.name		= "ttyAM",
    659	.write		= pl010_console_write,
    660	.device		= uart_console_device,
    661	.setup		= pl010_console_setup,
    662	.flags		= CON_PRINTBUFFER,
    663	.index		= -1,
    664	.data		= &amba_reg,
    665};
    666
    667#define AMBA_CONSOLE	&amba_console
    668#else
    669#define AMBA_CONSOLE	NULL
    670#endif
    671
    672static DEFINE_MUTEX(amba_reg_lock);
    673static struct uart_driver amba_reg = {
    674	.owner			= THIS_MODULE,
    675	.driver_name		= "ttyAM",
    676	.dev_name		= "ttyAM",
    677	.major			= SERIAL_AMBA_MAJOR,
    678	.minor			= SERIAL_AMBA_MINOR,
    679	.nr			= UART_NR,
    680	.cons			= AMBA_CONSOLE,
    681};
    682
    683static int pl010_probe(struct amba_device *dev, const struct amba_id *id)
    684{
    685	struct uart_amba_port *uap;
    686	void __iomem *base;
    687	int i, ret;
    688
    689	for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
    690		if (amba_ports[i] == NULL)
    691			break;
    692
    693	if (i == ARRAY_SIZE(amba_ports))
    694		return -EBUSY;
    695
    696	uap = devm_kzalloc(&dev->dev, sizeof(struct uart_amba_port),
    697			   GFP_KERNEL);
    698	if (!uap)
    699		return -ENOMEM;
    700
    701	base = devm_ioremap(&dev->dev, dev->res.start,
    702			    resource_size(&dev->res));
    703	if (!base)
    704		return -ENOMEM;
    705
    706	uap->clk = devm_clk_get(&dev->dev, NULL);
    707	if (IS_ERR(uap->clk))
    708		return PTR_ERR(uap->clk);
    709
    710	uap->port.dev = &dev->dev;
    711	uap->port.mapbase = dev->res.start;
    712	uap->port.membase = base;
    713	uap->port.iotype = UPIO_MEM;
    714	uap->port.irq = dev->irq[0];
    715	uap->port.fifosize = 16;
    716	uap->port.has_sysrq = IS_ENABLED(CONFIG_SERIAL_AMBA_PL010_CONSOLE);
    717	uap->port.ops = &amba_pl010_pops;
    718	uap->port.flags = UPF_BOOT_AUTOCONF;
    719	uap->port.line = i;
    720	uap->dev = dev;
    721	uap->data = dev_get_platdata(&dev->dev);
    722
    723	amba_ports[i] = uap;
    724
    725	amba_set_drvdata(dev, uap);
    726
    727	mutex_lock(&amba_reg_lock);
    728	if (!amba_reg.state) {
    729		ret = uart_register_driver(&amba_reg);
    730		if (ret < 0) {
    731			mutex_unlock(&amba_reg_lock);
    732			dev_err(uap->port.dev,
    733				"Failed to register AMBA-PL010 driver\n");
    734			return ret;
    735		}
    736	}
    737	mutex_unlock(&amba_reg_lock);
    738
    739	ret = uart_add_one_port(&amba_reg, &uap->port);
    740	if (ret)
    741		amba_ports[i] = NULL;
    742
    743	return ret;
    744}
    745
    746static void pl010_remove(struct amba_device *dev)
    747{
    748	struct uart_amba_port *uap = amba_get_drvdata(dev);
    749	int i;
    750	bool busy = false;
    751
    752	uart_remove_one_port(&amba_reg, &uap->port);
    753
    754	for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
    755		if (amba_ports[i] == uap)
    756			amba_ports[i] = NULL;
    757		else if (amba_ports[i])
    758			busy = true;
    759
    760	if (!busy)
    761		uart_unregister_driver(&amba_reg);
    762}
    763
    764#ifdef CONFIG_PM_SLEEP
    765static int pl010_suspend(struct device *dev)
    766{
    767	struct uart_amba_port *uap = dev_get_drvdata(dev);
    768
    769	if (uap)
    770		uart_suspend_port(&amba_reg, &uap->port);
    771
    772	return 0;
    773}
    774
    775static int pl010_resume(struct device *dev)
    776{
    777	struct uart_amba_port *uap = dev_get_drvdata(dev);
    778
    779	if (uap)
    780		uart_resume_port(&amba_reg, &uap->port);
    781
    782	return 0;
    783}
    784#endif
    785
    786static SIMPLE_DEV_PM_OPS(pl010_dev_pm_ops, pl010_suspend, pl010_resume);
    787
    788static const struct amba_id pl010_ids[] = {
    789	{
    790		.id	= 0x00041010,
    791		.mask	= 0x000fffff,
    792	},
    793	{ 0, 0 },
    794};
    795
    796MODULE_DEVICE_TABLE(amba, pl010_ids);
    797
    798static struct amba_driver pl010_driver = {
    799	.drv = {
    800		.name	= "uart-pl010",
    801		.pm	= &pl010_dev_pm_ops,
    802	},
    803	.id_table	= pl010_ids,
    804	.probe		= pl010_probe,
    805	.remove		= pl010_remove,
    806};
    807
    808static int __init pl010_init(void)
    809{
    810	printk(KERN_INFO "Serial: AMBA driver\n");
    811
    812	return  amba_driver_register(&pl010_driver);
    813}
    814
    815static void __exit pl010_exit(void)
    816{
    817	amba_driver_unregister(&pl010_driver);
    818}
    819
    820module_init(pl010_init);
    821module_exit(pl010_exit);
    822
    823MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd");
    824MODULE_DESCRIPTION("ARM AMBA serial port driver");
    825MODULE_LICENSE("GPL");