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

sunplus-uart.c (18854B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Sunplus SoC UART driver
      4 *
      5 * Author: Hammer Hsieh <hammerh0314@gmail.com>
      6 *
      7 * Note1: This driver is 8250-like uart, but are not register compatible.
      8 *
      9 * Note2: On some buses, for preventing data incoherence, must do a read
     10 * for ensure write made it to hardware. In this driver, function startup
     11 * and shutdown did not do a read but only do a write directly. For what?
     12 * In Sunplus bus communication between memory bus and peripheral bus with
     13 * posted write, it will send a specific command after last write command
     14 * to make sure write done. Then memory bus identify the specific command
     15 * and send done signal back to master device. After master device received
     16 * done signal, then proceed next write command. It is no need to do a read
     17 * before write.
     18 */
     19#include <linux/clk.h>
     20#include <linux/console.h>
     21#include <linux/interrupt.h>
     22#include <linux/io.h>
     23#include <linux/iopoll.h>
     24#include <linux/module.h>
     25#include <linux/of.h>
     26#include <linux/of_platform.h>
     27#include <linux/platform_device.h>
     28#include <linux/reset.h>
     29#include <linux/serial_core.h>
     30#include <linux/serial_reg.h>
     31#include <linux/sysrq.h>
     32#include <linux/tty.h>
     33#include <linux/tty_flip.h>
     34#include <asm/irq.h>
     35
     36/* Register offsets */
     37#define SUP_UART_DATA			0x00
     38#define SUP_UART_LSR			0x04
     39#define SUP_UART_MSR			0x08
     40#define SUP_UART_LCR			0x0C
     41#define SUP_UART_MCR			0x10
     42#define SUP_UART_DIV_L			0x14
     43#define SUP_UART_DIV_H			0x18
     44#define SUP_UART_ISC			0x1C
     45#define SUP_UART_TX_RESIDUE		0x20
     46#define SUP_UART_RX_RESIDUE		0x24
     47
     48/* Line Status Register bits */
     49#define SUP_UART_LSR_BC			BIT(5) /* break condition status */
     50#define SUP_UART_LSR_FE			BIT(4) /* frame error status */
     51#define SUP_UART_LSR_OE			BIT(3) /* overrun error status */
     52#define SUP_UART_LSR_PE			BIT(2) /* parity error status */
     53#define SUP_UART_LSR_RX			BIT(1) /* 1: receive fifo not empty */
     54#define SUP_UART_LSR_TX			BIT(0) /* 1: transmit fifo is not full */
     55#define SUP_UART_LSR_TX_NOT_FULL	1
     56#define SUP_UART_LSR_BRK_ERROR_BITS	GENMASK(5, 2)
     57
     58/* Line Control Register bits */
     59#define SUP_UART_LCR_SBC		BIT(5) /* select break condition */
     60
     61/* Modem Control Register bits */
     62#define SUP_UART_MCR_RI			BIT(3) /* ring indicator */
     63#define SUP_UART_MCR_DCD		BIT(2) /* data carrier detect */
     64
     65/* Interrupt Status/Control Register bits */
     66#define SUP_UART_ISC_RXM		BIT(5) /* RX interrupt enable */
     67#define SUP_UART_ISC_TXM		BIT(4) /* TX interrupt enable */
     68#define SUP_UART_ISC_RX			BIT(1) /* RX interrupt status */
     69#define SUP_UART_ISC_TX			BIT(0) /* TX interrupt status */
     70
     71#define SUP_DUMMY_READ			BIT(16) /* drop bytes received on a !CREAD port */
     72#define SUP_UART_NR			5
     73
     74struct sunplus_uart_port {
     75	struct uart_port port;
     76	struct clk *clk;
     77	struct reset_control *rstc;
     78};
     79
     80static void sp_uart_put_char(struct uart_port *port, unsigned int ch)
     81{
     82	writel(ch, port->membase + SUP_UART_DATA);
     83}
     84
     85static u32 sunplus_tx_buf_not_full(struct uart_port *port)
     86{
     87	unsigned int lsr = readl(port->membase + SUP_UART_LSR);
     88
     89	return (lsr & SUP_UART_LSR_TX) ? SUP_UART_LSR_TX_NOT_FULL : 0;
     90}
     91
     92static unsigned int sunplus_tx_empty(struct uart_port *port)
     93{
     94	unsigned int lsr = readl(port->membase + SUP_UART_LSR);
     95
     96	return (lsr & UART_LSR_TEMT) ? TIOCSER_TEMT : 0;
     97}
     98
     99static void sunplus_set_mctrl(struct uart_port *port, unsigned int mctrl)
    100{
    101	unsigned int mcr = readl(port->membase + SUP_UART_MCR);
    102
    103	if (mctrl & TIOCM_DTR)
    104		mcr |= UART_MCR_DTR;
    105	else
    106		mcr &= ~UART_MCR_DTR;
    107
    108	if (mctrl & TIOCM_RTS)
    109		mcr |= UART_MCR_RTS;
    110	else
    111		mcr &= ~UART_MCR_RTS;
    112
    113	if (mctrl & TIOCM_CAR)
    114		mcr |= SUP_UART_MCR_DCD;
    115	else
    116		mcr &= ~SUP_UART_MCR_DCD;
    117
    118	if (mctrl & TIOCM_RI)
    119		mcr |= SUP_UART_MCR_RI;
    120	else
    121		mcr &= ~SUP_UART_MCR_RI;
    122
    123	if (mctrl & TIOCM_LOOP)
    124		mcr |= UART_MCR_LOOP;
    125	else
    126		mcr &= ~UART_MCR_LOOP;
    127
    128	writel(mcr, port->membase + SUP_UART_MCR);
    129}
    130
    131static unsigned int sunplus_get_mctrl(struct uart_port *port)
    132{
    133	unsigned int mcr, ret = 0;
    134
    135	mcr = readl(port->membase + SUP_UART_MCR);
    136
    137	if (mcr & UART_MCR_DTR)
    138		ret |= TIOCM_DTR;
    139
    140	if (mcr & UART_MCR_RTS)
    141		ret |= TIOCM_RTS;
    142
    143	if (mcr & SUP_UART_MCR_DCD)
    144		ret |= TIOCM_CAR;
    145
    146	if (mcr & SUP_UART_MCR_RI)
    147		ret |= TIOCM_RI;
    148
    149	if (mcr & UART_MCR_LOOP)
    150		ret |= TIOCM_LOOP;
    151
    152	return ret;
    153}
    154
    155static void sunplus_stop_tx(struct uart_port *port)
    156{
    157	unsigned int isc;
    158
    159	isc = readl(port->membase + SUP_UART_ISC);
    160	isc &= ~SUP_UART_ISC_TXM;
    161	writel(isc, port->membase + SUP_UART_ISC);
    162}
    163
    164static void sunplus_start_tx(struct uart_port *port)
    165{
    166	unsigned int isc;
    167
    168	isc = readl(port->membase + SUP_UART_ISC);
    169	isc |= SUP_UART_ISC_TXM;
    170	writel(isc, port->membase + SUP_UART_ISC);
    171}
    172
    173static void sunplus_stop_rx(struct uart_port *port)
    174{
    175	unsigned int isc;
    176
    177	isc = readl(port->membase + SUP_UART_ISC);
    178	isc &= ~SUP_UART_ISC_RXM;
    179	writel(isc, port->membase + SUP_UART_ISC);
    180}
    181
    182static void sunplus_break_ctl(struct uart_port *port, int ctl)
    183{
    184	unsigned long flags;
    185	unsigned int lcr;
    186
    187	spin_lock_irqsave(&port->lock, flags);
    188
    189	lcr = readl(port->membase + SUP_UART_LCR);
    190
    191	if (ctl)
    192		lcr |= SUP_UART_LCR_SBC; /* start break */
    193	else
    194		lcr &= ~SUP_UART_LCR_SBC; /* stop break */
    195
    196	writel(lcr, port->membase + SUP_UART_LCR);
    197
    198	spin_unlock_irqrestore(&port->lock, flags);
    199}
    200
    201static void transmit_chars(struct uart_port *port)
    202{
    203	struct circ_buf *xmit = &port->state->xmit;
    204
    205	if (port->x_char) {
    206		sp_uart_put_char(port, port->x_char);
    207		port->icount.tx++;
    208		port->x_char = 0;
    209		return;
    210	}
    211
    212	if (uart_circ_empty(xmit) || uart_tx_stopped(port)) {
    213		sunplus_stop_tx(port);
    214		return;
    215	}
    216
    217	do {
    218		sp_uart_put_char(port, xmit->buf[xmit->tail]);
    219		xmit->tail = (xmit->tail + 1) % UART_XMIT_SIZE;
    220		port->icount.tx++;
    221
    222		if (uart_circ_empty(xmit))
    223			break;
    224	} while (sunplus_tx_buf_not_full(port));
    225
    226	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
    227		uart_write_wakeup(port);
    228
    229	if (uart_circ_empty(xmit))
    230		sunplus_stop_tx(port);
    231}
    232
    233static void receive_chars(struct uart_port *port)
    234{
    235	unsigned int lsr = readl(port->membase + SUP_UART_LSR);
    236	unsigned int ch, flag;
    237
    238	do {
    239		ch = readl(port->membase + SUP_UART_DATA);
    240		flag = TTY_NORMAL;
    241		port->icount.rx++;
    242
    243		if (unlikely(lsr & SUP_UART_LSR_BRK_ERROR_BITS)) {
    244			if (lsr & SUP_UART_LSR_BC) {
    245				lsr &= ~(SUP_UART_LSR_FE | SUP_UART_LSR_PE);
    246				port->icount.brk++;
    247				flag = TTY_BREAK;
    248				if (uart_handle_break(port))
    249					goto ignore_char;
    250			} else if (lsr & SUP_UART_LSR_PE) {
    251				port->icount.parity++;
    252				flag = TTY_PARITY;
    253			} else if (lsr & SUP_UART_LSR_FE) {
    254				port->icount.frame++;
    255				flag = TTY_FRAME;
    256			}
    257
    258			if (lsr & SUP_UART_LSR_OE)
    259				port->icount.overrun++;
    260		}
    261
    262		if (port->ignore_status_mask & SUP_DUMMY_READ)
    263			goto ignore_char;
    264
    265		if (uart_handle_sysrq_char(port, ch))
    266			goto ignore_char;
    267
    268		uart_insert_char(port, lsr, SUP_UART_LSR_OE, ch, flag);
    269
    270ignore_char:
    271		lsr = readl(port->membase + SUP_UART_LSR);
    272	} while (lsr & SUP_UART_LSR_RX);
    273
    274	tty_flip_buffer_push(&port->state->port);
    275}
    276
    277static irqreturn_t sunplus_uart_irq(int irq, void *args)
    278{
    279	struct uart_port *port = args;
    280	unsigned int isc;
    281
    282	spin_lock(&port->lock);
    283
    284	isc = readl(port->membase + SUP_UART_ISC);
    285
    286	if (isc & SUP_UART_ISC_RX)
    287		receive_chars(port);
    288
    289	if (isc & SUP_UART_ISC_TX)
    290		transmit_chars(port);
    291
    292	spin_unlock(&port->lock);
    293
    294	return IRQ_HANDLED;
    295}
    296
    297static int sunplus_startup(struct uart_port *port)
    298{
    299	unsigned long flags;
    300	unsigned int isc = 0;
    301	int ret;
    302
    303	ret = request_irq(port->irq, sunplus_uart_irq, 0, "sunplus_uart", port);
    304	if (ret)
    305		return ret;
    306
    307	spin_lock_irqsave(&port->lock, flags);
    308	/* isc define Bit[7:4] int setting, Bit[3:0] int status
    309	 * isc register will clean Bit[3:0] int status after read
    310	 * only do a write to Bit[7:4] int setting
    311	 */
    312	isc |= SUP_UART_ISC_RXM;
    313	writel(isc, port->membase + SUP_UART_ISC);
    314	spin_unlock_irqrestore(&port->lock, flags);
    315
    316	return 0;
    317}
    318
    319static void sunplus_shutdown(struct uart_port *port)
    320{
    321	unsigned long flags;
    322
    323	spin_lock_irqsave(&port->lock, flags);
    324	/* isc define Bit[7:4] int setting, Bit[3:0] int status
    325	 * isc register will clean Bit[3:0] int status after read
    326	 * only do a write to Bit[7:4] int setting
    327	 */
    328	writel(0, port->membase + SUP_UART_ISC); /* disable all interrupt */
    329	spin_unlock_irqrestore(&port->lock, flags);
    330
    331	free_irq(port->irq, port);
    332}
    333
    334static void sunplus_set_termios(struct uart_port *port,
    335				struct ktermios *termios,
    336				struct ktermios *oldtermios)
    337{
    338	u32 ext, div, div_l, div_h, baud, lcr;
    339	u32 clk = port->uartclk;
    340	unsigned long flags;
    341
    342	baud = uart_get_baud_rate(port, termios, oldtermios, 0, port->uartclk / 16);
    343
    344	/* baud rate = uartclk / ((16 * divisor + 1) + divisor_ext) */
    345	clk += baud >> 1;
    346	div = clk / baud;
    347	ext = div & 0x0F;
    348	div = (div >> 4) - 1;
    349	div_l = (div & 0xFF) | (ext << 12);
    350	div_h = div >> 8;
    351
    352	switch (termios->c_cflag & CSIZE) {
    353	case CS5:
    354		lcr = UART_LCR_WLEN5;
    355		break;
    356	case CS6:
    357		lcr = UART_LCR_WLEN6;
    358		break;
    359	case CS7:
    360		lcr = UART_LCR_WLEN7;
    361		break;
    362	default:
    363		lcr = UART_LCR_WLEN8;
    364		break;
    365	}
    366
    367	if (termios->c_cflag & CSTOPB)
    368		lcr |= UART_LCR_STOP;
    369
    370	if (termios->c_cflag & PARENB) {
    371		lcr |= UART_LCR_PARITY;
    372
    373		if (!(termios->c_cflag & PARODD))
    374			lcr |= UART_LCR_EPAR;
    375	}
    376
    377	spin_lock_irqsave(&port->lock, flags);
    378
    379	uart_update_timeout(port, termios->c_cflag, baud);
    380
    381	port->read_status_mask = 0;
    382	if (termios->c_iflag & INPCK)
    383		port->read_status_mask |= SUP_UART_LSR_PE | SUP_UART_LSR_FE;
    384
    385	if (termios->c_iflag & (BRKINT | PARMRK))
    386		port->read_status_mask |= SUP_UART_LSR_BC;
    387
    388	/* Characters to ignore */
    389	port->ignore_status_mask = 0;
    390	if (termios->c_iflag & IGNPAR)
    391		port->ignore_status_mask |= SUP_UART_LSR_FE | SUP_UART_LSR_PE;
    392
    393	if (termios->c_iflag & IGNBRK) {
    394		port->ignore_status_mask |= SUP_UART_LSR_BC;
    395
    396		if (termios->c_iflag & IGNPAR)
    397			port->ignore_status_mask |= SUP_UART_LSR_OE;
    398	}
    399
    400	/* Ignore all characters if CREAD is not set */
    401	if ((termios->c_cflag & CREAD) == 0) {
    402		port->ignore_status_mask |= SUP_DUMMY_READ;
    403		/* flush rx data FIFO */
    404		writel(0, port->membase + SUP_UART_RX_RESIDUE);
    405	}
    406
    407	/* Settings for baud rate divisor and lcr */
    408	writel(div_h, port->membase + SUP_UART_DIV_H);
    409	writel(div_l, port->membase + SUP_UART_DIV_L);
    410	writel(lcr, port->membase + SUP_UART_LCR);
    411
    412	spin_unlock_irqrestore(&port->lock, flags);
    413}
    414
    415static void sunplus_set_ldisc(struct uart_port *port, struct ktermios *termios)
    416{
    417	int new = termios->c_line;
    418
    419	if (new == N_PPS)
    420		port->flags |= UPF_HARDPPS_CD;
    421	else
    422		port->flags &= ~UPF_HARDPPS_CD;
    423}
    424
    425static const char *sunplus_type(struct uart_port *port)
    426{
    427	return port->type == PORT_SUNPLUS ? "sunplus_uart" : NULL;
    428}
    429
    430static void sunplus_config_port(struct uart_port *port, int type)
    431{
    432	if (type & UART_CONFIG_TYPE)
    433		port->type = PORT_SUNPLUS;
    434}
    435
    436static int sunplus_verify_port(struct uart_port *port, struct serial_struct *ser)
    437{
    438	if (ser->type != PORT_UNKNOWN && ser->type != PORT_SUNPLUS)
    439		return -EINVAL;
    440
    441	return 0;
    442}
    443
    444#if defined(CONFIG_SERIAL_SUNPLUS_CONSOLE) || defined(CONFIG_CONSOLE_POLL)
    445static void wait_for_xmitr(struct uart_port *port)
    446{
    447	unsigned int val;
    448	int ret;
    449
    450	/* Wait while FIFO is full or timeout */
    451	ret = readl_poll_timeout_atomic(port->membase + SUP_UART_LSR, val,
    452					(val & SUP_UART_LSR_TX), 1, 10000);
    453
    454	if (ret == -ETIMEDOUT) {
    455		dev_err(port->dev, "Timeout waiting while UART TX FULL\n");
    456		return;
    457	}
    458}
    459#endif
    460
    461#ifdef CONFIG_CONSOLE_POLL
    462static void sunplus_poll_put_char(struct uart_port *port, unsigned char data)
    463{
    464	wait_for_xmitr(port);
    465	sp_uart_put_char(port, data);
    466}
    467
    468static int sunplus_poll_get_char(struct uart_port *port)
    469{
    470	unsigned int lsr = readl(port->membase + SUP_UART_LSR);
    471
    472	if (!(lsr & SUP_UART_LSR_RX))
    473		return NO_POLL_CHAR;
    474
    475	return readl(port->membase + SUP_UART_DATA);
    476}
    477#endif
    478
    479static const struct uart_ops sunplus_uart_ops = {
    480	.tx_empty	= sunplus_tx_empty,
    481	.set_mctrl	= sunplus_set_mctrl,
    482	.get_mctrl	= sunplus_get_mctrl,
    483	.stop_tx	= sunplus_stop_tx,
    484	.start_tx	= sunplus_start_tx,
    485	.stop_rx	= sunplus_stop_rx,
    486	.break_ctl	= sunplus_break_ctl,
    487	.startup	= sunplus_startup,
    488	.shutdown	= sunplus_shutdown,
    489	.set_termios	= sunplus_set_termios,
    490	.set_ldisc	= sunplus_set_ldisc,
    491	.type		= sunplus_type,
    492	.config_port	= sunplus_config_port,
    493	.verify_port	= sunplus_verify_port,
    494#ifdef CONFIG_CONSOLE_POLL
    495	.poll_put_char	= sunplus_poll_put_char,
    496	.poll_get_char	= sunplus_poll_get_char,
    497#endif
    498};
    499
    500#ifdef CONFIG_SERIAL_SUNPLUS_CONSOLE
    501static struct sunplus_uart_port *sunplus_console_ports[SUP_UART_NR];
    502
    503static void sunplus_uart_console_putchar(struct uart_port *port,
    504					 unsigned char ch)
    505{
    506	wait_for_xmitr(port);
    507	sp_uart_put_char(port, ch);
    508}
    509
    510static void sunplus_console_write(struct console *co,
    511				  const char *s,
    512				  unsigned int count)
    513{
    514	unsigned long flags;
    515	int locked = 1;
    516
    517	local_irq_save(flags);
    518
    519	if (sunplus_console_ports[co->index]->port.sysrq)
    520		locked = 0;
    521	else if (oops_in_progress)
    522		locked = spin_trylock(&sunplus_console_ports[co->index]->port.lock);
    523	else
    524		spin_lock(&sunplus_console_ports[co->index]->port.lock);
    525
    526	uart_console_write(&sunplus_console_ports[co->index]->port, s, count,
    527			   sunplus_uart_console_putchar);
    528
    529	if (locked)
    530		spin_unlock(&sunplus_console_ports[co->index]->port.lock);
    531
    532	local_irq_restore(flags);
    533}
    534
    535static int __init sunplus_console_setup(struct console *co, char *options)
    536{
    537	struct sunplus_uart_port *sup;
    538	int baud = 115200;
    539	int bits = 8;
    540	int parity = 'n';
    541	int flow = 'n';
    542
    543	if (co->index < 0 || co->index >= SUP_UART_NR)
    544		return -EINVAL;
    545
    546	sup = sunplus_console_ports[co->index];
    547	if (!sup)
    548		return -ENODEV;
    549
    550	if (options)
    551		uart_parse_options(options, &baud, &parity, &bits, &flow);
    552
    553	return uart_set_options(&sup->port, co, baud, parity, bits, flow);
    554}
    555
    556static struct uart_driver sunplus_uart_driver;
    557static struct console sunplus_uart_console = {
    558	.name		= "ttySUP",
    559	.write		= sunplus_console_write,
    560	.device		= uart_console_device,
    561	.setup		= sunplus_console_setup,
    562	.flags		= CON_PRINTBUFFER,
    563	.index		= -1,
    564	.data		= &sunplus_uart_driver
    565};
    566
    567#define	SERIAL_SUNPLUS_CONSOLE	(&sunplus_uart_console)
    568#else
    569#define	SERIAL_SUNPLUS_CONSOLE	NULL
    570#endif
    571
    572static struct uart_driver sunplus_uart_driver = {
    573	.owner		= THIS_MODULE,
    574	.driver_name	= "sunplus_uart",
    575	.dev_name	= "ttySUP",
    576	.major		= TTY_MAJOR,
    577	.minor		= 64,
    578	.nr		= SUP_UART_NR,
    579	.cons		= SERIAL_SUNPLUS_CONSOLE,
    580};
    581
    582static void sunplus_uart_disable_unprepare(void *data)
    583{
    584	clk_disable_unprepare(data);
    585}
    586
    587static void sunplus_uart_reset_control_assert(void *data)
    588{
    589	reset_control_assert(data);
    590}
    591
    592static int sunplus_uart_probe(struct platform_device *pdev)
    593{
    594	struct sunplus_uart_port *sup;
    595	struct uart_port *port;
    596	struct resource *res;
    597	int ret, irq;
    598
    599	pdev->id = of_alias_get_id(pdev->dev.of_node, "serial");
    600
    601	if (pdev->id < 0 || pdev->id >= SUP_UART_NR)
    602		return -EINVAL;
    603
    604	sup = devm_kzalloc(&pdev->dev, sizeof(*sup), GFP_KERNEL);
    605	if (!sup)
    606		return -ENOMEM;
    607
    608	sup->clk = devm_clk_get_optional(&pdev->dev, NULL);
    609	if (IS_ERR(sup->clk))
    610		return dev_err_probe(&pdev->dev, PTR_ERR(sup->clk), "clk not found\n");
    611
    612	ret = clk_prepare_enable(sup->clk);
    613	if (ret)
    614		return ret;
    615
    616	ret = devm_add_action_or_reset(&pdev->dev, sunplus_uart_disable_unprepare, sup->clk);
    617	if (ret)
    618		return ret;
    619
    620	sup->rstc = devm_reset_control_get_exclusive(&pdev->dev, NULL);
    621	if (IS_ERR(sup->rstc))
    622		return dev_err_probe(&pdev->dev, PTR_ERR(sup->rstc), "rstc not found\n");
    623
    624	port = &sup->port;
    625
    626	port->membase = devm_platform_get_and_ioremap_resource(pdev, 0, &res);
    627	if (IS_ERR(port->membase))
    628		return dev_err_probe(&pdev->dev, PTR_ERR(port->membase), "membase not found\n");
    629
    630	irq = platform_get_irq(pdev, 0);
    631	if (irq < 0)
    632		return irq;
    633
    634	port->mapbase = res->start;
    635	port->uartclk = clk_get_rate(sup->clk);
    636	port->line = pdev->id;
    637	port->irq = irq;
    638	port->dev = &pdev->dev;
    639	port->iotype = UPIO_MEM;
    640	port->ops = &sunplus_uart_ops;
    641	port->flags = UPF_BOOT_AUTOCONF;
    642	port->fifosize = 128;
    643
    644	ret = reset_control_deassert(sup->rstc);
    645	if (ret)
    646		return ret;
    647
    648	ret = devm_add_action_or_reset(&pdev->dev, sunplus_uart_reset_control_assert, sup->rstc);
    649	if (ret)
    650		return ret;
    651
    652#ifdef CONFIG_SERIAL_SUNPLUS_CONSOLE
    653	sunplus_console_ports[sup->port.line] = sup;
    654#endif
    655
    656	platform_set_drvdata(pdev, &sup->port);
    657
    658	ret = uart_add_one_port(&sunplus_uart_driver, &sup->port);
    659#ifdef CONFIG_SERIAL_SUNPLUS_CONSOLE
    660	if (ret)
    661		sunplus_console_ports[sup->port.line] = NULL;
    662#endif
    663
    664	return ret;
    665}
    666
    667static int sunplus_uart_remove(struct platform_device *pdev)
    668{
    669	struct sunplus_uart_port *sup = platform_get_drvdata(pdev);
    670
    671	uart_remove_one_port(&sunplus_uart_driver, &sup->port);
    672
    673	return 0;
    674}
    675
    676static int __maybe_unused sunplus_uart_suspend(struct device *dev)
    677{
    678	struct sunplus_uart_port *sup = dev_get_drvdata(dev);
    679
    680	if (!uart_console(&sup->port))
    681		uart_suspend_port(&sunplus_uart_driver, &sup->port);
    682
    683	return 0;
    684}
    685
    686static int __maybe_unused sunplus_uart_resume(struct device *dev)
    687{
    688	struct sunplus_uart_port *sup = dev_get_drvdata(dev);
    689
    690	if (!uart_console(&sup->port))
    691		uart_resume_port(&sunplus_uart_driver, &sup->port);
    692
    693	return 0;
    694}
    695
    696static const struct dev_pm_ops sunplus_uart_pm_ops = {
    697	SET_SYSTEM_SLEEP_PM_OPS(sunplus_uart_suspend, sunplus_uart_resume)
    698};
    699
    700static const struct of_device_id sp_uart_of_match[] = {
    701	{ .compatible = "sunplus,sp7021-uart" },
    702	{}
    703};
    704MODULE_DEVICE_TABLE(of, sp_uart_of_match);
    705
    706static struct platform_driver sunplus_uart_platform_driver = {
    707	.probe		= sunplus_uart_probe,
    708	.remove		= sunplus_uart_remove,
    709	.driver = {
    710		.name	= "sunplus_uart",
    711		.of_match_table = sp_uart_of_match,
    712		.pm     = &sunplus_uart_pm_ops,
    713	}
    714};
    715
    716static int __init sunplus_uart_init(void)
    717{
    718	int ret;
    719
    720	ret = uart_register_driver(&sunplus_uart_driver);
    721	if (ret)
    722		return ret;
    723
    724	ret = platform_driver_register(&sunplus_uart_platform_driver);
    725	if (ret)
    726		uart_unregister_driver(&sunplus_uart_driver);
    727
    728	return ret;
    729}
    730module_init(sunplus_uart_init);
    731
    732static void __exit sunplus_uart_exit(void)
    733{
    734	platform_driver_unregister(&sunplus_uart_platform_driver);
    735	uart_unregister_driver(&sunplus_uart_driver);
    736}
    737module_exit(sunplus_uart_exit);
    738
    739#ifdef CONFIG_SERIAL_EARLYCON
    740static void sunplus_uart_putc(struct uart_port *port, unsigned char c)
    741{
    742	unsigned int val;
    743	int ret;
    744
    745	ret = readl_poll_timeout_atomic(port->membase + SUP_UART_LSR, val,
    746					(val & UART_LSR_TEMT), 1, 10000);
    747	if (ret)
    748		return;
    749
    750	writel(c, port->membase + SUP_UART_DATA);
    751}
    752
    753static void sunplus_uart_early_write(struct console *con, const char *s, unsigned int n)
    754{
    755	struct earlycon_device *dev = con->data;
    756
    757	uart_console_write(&dev->port, s, n, sunplus_uart_putc);
    758}
    759
    760static int __init
    761sunplus_uart_early_setup(struct earlycon_device *dev, const char *opt)
    762{
    763	if (!(dev->port.membase || dev->port.iobase))
    764		return -ENODEV;
    765
    766	dev->con->write = sunplus_uart_early_write;
    767
    768	return 0;
    769}
    770OF_EARLYCON_DECLARE(sunplus_uart, "sunplus,sp7021-uart", sunplus_uart_early_setup);
    771#endif
    772
    773MODULE_DESCRIPTION("Sunplus UART driver");
    774MODULE_AUTHOR("Hammer Hsieh <hammerh0314@gmail.com>");
    775MODULE_LICENSE("GPL v2");