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

bcm63xx_uart.c (21769B)


      1// SPDX-License-Identifier: GPL-2.0
      2/*
      3 * Derived from many drivers using generic_serial interface.
      4 *
      5 * Copyright (C) 2008 Maxime Bizon <mbizon@freebox.fr>
      6 *
      7 *  Serial driver for BCM63xx integrated UART.
      8 *
      9 * Hardware flow control was _not_ tested since I only have RX/TX on
     10 * my board.
     11 */
     12
     13#include <linux/kernel.h>
     14#include <linux/platform_device.h>
     15#include <linux/init.h>
     16#include <linux/delay.h>
     17#include <linux/module.h>
     18#include <linux/console.h>
     19#include <linux/clk.h>
     20#include <linux/tty.h>
     21#include <linux/tty_flip.h>
     22#include <linux/sysrq.h>
     23#include <linux/serial.h>
     24#include <linux/serial_core.h>
     25#include <linux/serial_bcm63xx.h>
     26#include <linux/io.h>
     27#include <linux/of.h>
     28
     29#define BCM63XX_NR_UARTS	2
     30
     31static struct uart_port ports[BCM63XX_NR_UARTS];
     32
     33/*
     34 * rx interrupt mask / stat
     35 *
     36 * mask:
     37 *  - rx fifo full
     38 *  - rx fifo above threshold
     39 *  - rx fifo not empty for too long
     40 */
     41#define UART_RX_INT_MASK	(UART_IR_MASK(UART_IR_RXOVER) |		\
     42				UART_IR_MASK(UART_IR_RXTHRESH) |	\
     43				UART_IR_MASK(UART_IR_RXTIMEOUT))
     44
     45#define UART_RX_INT_STAT	(UART_IR_STAT(UART_IR_RXOVER) |		\
     46				UART_IR_STAT(UART_IR_RXTHRESH) |	\
     47				UART_IR_STAT(UART_IR_RXTIMEOUT))
     48
     49/*
     50 * tx interrupt mask / stat
     51 *
     52 * mask:
     53 * - tx fifo empty
     54 * - tx fifo below threshold
     55 */
     56#define UART_TX_INT_MASK	(UART_IR_MASK(UART_IR_TXEMPTY) |	\
     57				UART_IR_MASK(UART_IR_TXTRESH))
     58
     59#define UART_TX_INT_STAT	(UART_IR_STAT(UART_IR_TXEMPTY) |	\
     60				UART_IR_STAT(UART_IR_TXTRESH))
     61
     62/*
     63 * external input interrupt
     64 *
     65 * mask: any edge on CTS, DCD
     66 */
     67#define UART_EXTINP_INT_MASK	(UART_EXTINP_IRMASK(UART_EXTINP_IR_CTS) | \
     68				 UART_EXTINP_IRMASK(UART_EXTINP_IR_DCD))
     69
     70/*
     71 * handy uart register accessor
     72 */
     73static inline unsigned int bcm_uart_readl(struct uart_port *port,
     74					 unsigned int offset)
     75{
     76	return __raw_readl(port->membase + offset);
     77}
     78
     79static inline void bcm_uart_writel(struct uart_port *port,
     80				  unsigned int value, unsigned int offset)
     81{
     82	__raw_writel(value, port->membase + offset);
     83}
     84
     85/*
     86 * serial core request to check if uart tx fifo is empty
     87 */
     88static unsigned int bcm_uart_tx_empty(struct uart_port *port)
     89{
     90	unsigned int val;
     91
     92	val = bcm_uart_readl(port, UART_IR_REG);
     93	return (val & UART_IR_STAT(UART_IR_TXEMPTY)) ? 1 : 0;
     94}
     95
     96/*
     97 * serial core request to set RTS and DTR pin state and loopback mode
     98 */
     99static void bcm_uart_set_mctrl(struct uart_port *port, unsigned int mctrl)
    100{
    101	unsigned int val;
    102
    103	val = bcm_uart_readl(port, UART_MCTL_REG);
    104	val &= ~(UART_MCTL_DTR_MASK | UART_MCTL_RTS_MASK);
    105	/* invert of written value is reflected on the pin */
    106	if (!(mctrl & TIOCM_DTR))
    107		val |= UART_MCTL_DTR_MASK;
    108	if (!(mctrl & TIOCM_RTS))
    109		val |= UART_MCTL_RTS_MASK;
    110	bcm_uart_writel(port, val, UART_MCTL_REG);
    111
    112	val = bcm_uart_readl(port, UART_CTL_REG);
    113	if (mctrl & TIOCM_LOOP)
    114		val |= UART_CTL_LOOPBACK_MASK;
    115	else
    116		val &= ~UART_CTL_LOOPBACK_MASK;
    117	bcm_uart_writel(port, val, UART_CTL_REG);
    118}
    119
    120/*
    121 * serial core request to return RI, CTS, DCD and DSR pin state
    122 */
    123static unsigned int bcm_uart_get_mctrl(struct uart_port *port)
    124{
    125	unsigned int val, mctrl;
    126
    127	mctrl = 0;
    128	val = bcm_uart_readl(port, UART_EXTINP_REG);
    129	if (val & UART_EXTINP_RI_MASK)
    130		mctrl |= TIOCM_RI;
    131	if (val & UART_EXTINP_CTS_MASK)
    132		mctrl |= TIOCM_CTS;
    133	if (val & UART_EXTINP_DCD_MASK)
    134		mctrl |= TIOCM_CD;
    135	if (val & UART_EXTINP_DSR_MASK)
    136		mctrl |= TIOCM_DSR;
    137	return mctrl;
    138}
    139
    140/*
    141 * serial core request to disable tx ASAP (used for flow control)
    142 */
    143static void bcm_uart_stop_tx(struct uart_port *port)
    144{
    145	unsigned int val;
    146
    147	val = bcm_uart_readl(port, UART_CTL_REG);
    148	val &= ~(UART_CTL_TXEN_MASK);
    149	bcm_uart_writel(port, val, UART_CTL_REG);
    150
    151	val = bcm_uart_readl(port, UART_IR_REG);
    152	val &= ~UART_TX_INT_MASK;
    153	bcm_uart_writel(port, val, UART_IR_REG);
    154}
    155
    156/*
    157 * serial core request to (re)enable tx
    158 */
    159static void bcm_uart_start_tx(struct uart_port *port)
    160{
    161	unsigned int val;
    162
    163	val = bcm_uart_readl(port, UART_IR_REG);
    164	val |= UART_TX_INT_MASK;
    165	bcm_uart_writel(port, val, UART_IR_REG);
    166
    167	val = bcm_uart_readl(port, UART_CTL_REG);
    168	val |= UART_CTL_TXEN_MASK;
    169	bcm_uart_writel(port, val, UART_CTL_REG);
    170}
    171
    172/*
    173 * serial core request to stop rx, called before port shutdown
    174 */
    175static void bcm_uart_stop_rx(struct uart_port *port)
    176{
    177	unsigned int val;
    178
    179	val = bcm_uart_readl(port, UART_IR_REG);
    180	val &= ~UART_RX_INT_MASK;
    181	bcm_uart_writel(port, val, UART_IR_REG);
    182}
    183
    184/*
    185 * serial core request to enable modem status interrupt reporting
    186 */
    187static void bcm_uart_enable_ms(struct uart_port *port)
    188{
    189	unsigned int val;
    190
    191	val = bcm_uart_readl(port, UART_IR_REG);
    192	val |= UART_IR_MASK(UART_IR_EXTIP);
    193	bcm_uart_writel(port, val, UART_IR_REG);
    194}
    195
    196/*
    197 * serial core request to start/stop emitting break char
    198 */
    199static void bcm_uart_break_ctl(struct uart_port *port, int ctl)
    200{
    201	unsigned long flags;
    202	unsigned int val;
    203
    204	spin_lock_irqsave(&port->lock, flags);
    205
    206	val = bcm_uart_readl(port, UART_CTL_REG);
    207	if (ctl)
    208		val |= UART_CTL_XMITBRK_MASK;
    209	else
    210		val &= ~UART_CTL_XMITBRK_MASK;
    211	bcm_uart_writel(port, val, UART_CTL_REG);
    212
    213	spin_unlock_irqrestore(&port->lock, flags);
    214}
    215
    216/*
    217 * return port type in string format
    218 */
    219static const char *bcm_uart_type(struct uart_port *port)
    220{
    221	return (port->type == PORT_BCM63XX) ? "bcm63xx_uart" : NULL;
    222}
    223
    224/*
    225 * read all chars in rx fifo and send them to core
    226 */
    227static void bcm_uart_do_rx(struct uart_port *port)
    228{
    229	struct tty_port *tty_port = &port->state->port;
    230	unsigned int max_count;
    231
    232	/* limit number of char read in interrupt, should not be
    233	 * higher than fifo size anyway since we're much faster than
    234	 * serial port */
    235	max_count = 32;
    236	do {
    237		unsigned int iestat, c, cstat;
    238		char flag;
    239
    240		/* get overrun/fifo empty information from ier
    241		 * register */
    242		iestat = bcm_uart_readl(port, UART_IR_REG);
    243
    244		if (unlikely(iestat & UART_IR_STAT(UART_IR_RXOVER))) {
    245			unsigned int val;
    246
    247			/* fifo reset is required to clear
    248			 * interrupt */
    249			val = bcm_uart_readl(port, UART_CTL_REG);
    250			val |= UART_CTL_RSTRXFIFO_MASK;
    251			bcm_uart_writel(port, val, UART_CTL_REG);
    252
    253			port->icount.overrun++;
    254			tty_insert_flip_char(tty_port, 0, TTY_OVERRUN);
    255		}
    256
    257		if (!(iestat & UART_IR_STAT(UART_IR_RXNOTEMPTY)))
    258			break;
    259
    260		cstat = c = bcm_uart_readl(port, UART_FIFO_REG);
    261		port->icount.rx++;
    262		flag = TTY_NORMAL;
    263		c &= 0xff;
    264
    265		if (unlikely((cstat & UART_FIFO_ANYERR_MASK))) {
    266			/* do stats first */
    267			if (cstat & UART_FIFO_BRKDET_MASK) {
    268				port->icount.brk++;
    269				if (uart_handle_break(port))
    270					continue;
    271			}
    272
    273			if (cstat & UART_FIFO_PARERR_MASK)
    274				port->icount.parity++;
    275			if (cstat & UART_FIFO_FRAMEERR_MASK)
    276				port->icount.frame++;
    277
    278			/* update flag wrt read_status_mask */
    279			cstat &= port->read_status_mask;
    280			if (cstat & UART_FIFO_BRKDET_MASK)
    281				flag = TTY_BREAK;
    282			if (cstat & UART_FIFO_FRAMEERR_MASK)
    283				flag = TTY_FRAME;
    284			if (cstat & UART_FIFO_PARERR_MASK)
    285				flag = TTY_PARITY;
    286		}
    287
    288		if (uart_handle_sysrq_char(port, c))
    289			continue;
    290
    291
    292		if ((cstat & port->ignore_status_mask) == 0)
    293			tty_insert_flip_char(tty_port, c, flag);
    294
    295	} while (--max_count);
    296
    297	tty_flip_buffer_push(tty_port);
    298}
    299
    300/*
    301 * fill tx fifo with chars to send, stop when fifo is about to be full
    302 * or when all chars have been sent.
    303 */
    304static void bcm_uart_do_tx(struct uart_port *port)
    305{
    306	struct circ_buf *xmit;
    307	unsigned int val, max_count;
    308
    309	if (port->x_char) {
    310		bcm_uart_writel(port, port->x_char, UART_FIFO_REG);
    311		port->icount.tx++;
    312		port->x_char = 0;
    313		return;
    314	}
    315
    316	if (uart_tx_stopped(port)) {
    317		bcm_uart_stop_tx(port);
    318		return;
    319	}
    320
    321	xmit = &port->state->xmit;
    322	if (uart_circ_empty(xmit))
    323		goto txq_empty;
    324
    325	val = bcm_uart_readl(port, UART_MCTL_REG);
    326	val = (val & UART_MCTL_TXFIFOFILL_MASK) >> UART_MCTL_TXFIFOFILL_SHIFT;
    327	max_count = port->fifosize - val;
    328
    329	while (max_count--) {
    330		unsigned int c;
    331
    332		c = xmit->buf[xmit->tail];
    333		bcm_uart_writel(port, c, UART_FIFO_REG);
    334		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
    335		port->icount.tx++;
    336		if (uart_circ_empty(xmit))
    337			break;
    338	}
    339
    340	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
    341		uart_write_wakeup(port);
    342
    343	if (uart_circ_empty(xmit))
    344		goto txq_empty;
    345	return;
    346
    347txq_empty:
    348	/* nothing to send, disable transmit interrupt */
    349	val = bcm_uart_readl(port, UART_IR_REG);
    350	val &= ~UART_TX_INT_MASK;
    351	bcm_uart_writel(port, val, UART_IR_REG);
    352	return;
    353}
    354
    355/*
    356 * process uart interrupt
    357 */
    358static irqreturn_t bcm_uart_interrupt(int irq, void *dev_id)
    359{
    360	struct uart_port *port;
    361	unsigned int irqstat;
    362
    363	port = dev_id;
    364	spin_lock(&port->lock);
    365
    366	irqstat = bcm_uart_readl(port, UART_IR_REG);
    367	if (irqstat & UART_RX_INT_STAT)
    368		bcm_uart_do_rx(port);
    369
    370	if (irqstat & UART_TX_INT_STAT)
    371		bcm_uart_do_tx(port);
    372
    373	if (irqstat & UART_IR_MASK(UART_IR_EXTIP)) {
    374		unsigned int estat;
    375
    376		estat = bcm_uart_readl(port, UART_EXTINP_REG);
    377		if (estat & UART_EXTINP_IRSTAT(UART_EXTINP_IR_CTS))
    378			uart_handle_cts_change(port,
    379					       estat & UART_EXTINP_CTS_MASK);
    380		if (estat & UART_EXTINP_IRSTAT(UART_EXTINP_IR_DCD))
    381			uart_handle_dcd_change(port,
    382					       estat & UART_EXTINP_DCD_MASK);
    383	}
    384
    385	spin_unlock(&port->lock);
    386	return IRQ_HANDLED;
    387}
    388
    389/*
    390 * enable rx & tx operation on uart
    391 */
    392static void bcm_uart_enable(struct uart_port *port)
    393{
    394	unsigned int val;
    395
    396	val = bcm_uart_readl(port, UART_CTL_REG);
    397	val |= (UART_CTL_BRGEN_MASK | UART_CTL_TXEN_MASK | UART_CTL_RXEN_MASK);
    398	bcm_uart_writel(port, val, UART_CTL_REG);
    399}
    400
    401/*
    402 * disable rx & tx operation on uart
    403 */
    404static void bcm_uart_disable(struct uart_port *port)
    405{
    406	unsigned int val;
    407
    408	val = bcm_uart_readl(port, UART_CTL_REG);
    409	val &= ~(UART_CTL_BRGEN_MASK | UART_CTL_TXEN_MASK |
    410		 UART_CTL_RXEN_MASK);
    411	bcm_uart_writel(port, val, UART_CTL_REG);
    412}
    413
    414/*
    415 * clear all unread data in rx fifo and unsent data in tx fifo
    416 */
    417static void bcm_uart_flush(struct uart_port *port)
    418{
    419	unsigned int val;
    420
    421	/* empty rx and tx fifo */
    422	val = bcm_uart_readl(port, UART_CTL_REG);
    423	val |= UART_CTL_RSTRXFIFO_MASK | UART_CTL_RSTTXFIFO_MASK;
    424	bcm_uart_writel(port, val, UART_CTL_REG);
    425
    426	/* read any pending char to make sure all irq status are
    427	 * cleared */
    428	(void)bcm_uart_readl(port, UART_FIFO_REG);
    429}
    430
    431/*
    432 * serial core request to initialize uart and start rx operation
    433 */
    434static int bcm_uart_startup(struct uart_port *port)
    435{
    436	unsigned int val;
    437	int ret;
    438
    439	/* mask all irq and flush port */
    440	bcm_uart_disable(port);
    441	bcm_uart_writel(port, 0, UART_IR_REG);
    442	bcm_uart_flush(port);
    443
    444	/* clear any pending external input interrupt */
    445	(void)bcm_uart_readl(port, UART_EXTINP_REG);
    446
    447	/* set rx/tx fifo thresh to fifo half size */
    448	val = bcm_uart_readl(port, UART_MCTL_REG);
    449	val &= ~(UART_MCTL_RXFIFOTHRESH_MASK | UART_MCTL_TXFIFOTHRESH_MASK);
    450	val |= (port->fifosize / 2) << UART_MCTL_RXFIFOTHRESH_SHIFT;
    451	val |= (port->fifosize / 2) << UART_MCTL_TXFIFOTHRESH_SHIFT;
    452	bcm_uart_writel(port, val, UART_MCTL_REG);
    453
    454	/* set rx fifo timeout to 1 char time */
    455	val = bcm_uart_readl(port, UART_CTL_REG);
    456	val &= ~UART_CTL_RXTMOUTCNT_MASK;
    457	val |= 1 << UART_CTL_RXTMOUTCNT_SHIFT;
    458	bcm_uart_writel(port, val, UART_CTL_REG);
    459
    460	/* report any edge on dcd and cts */
    461	val = UART_EXTINP_INT_MASK;
    462	val |= UART_EXTINP_DCD_NOSENSE_MASK;
    463	val |= UART_EXTINP_CTS_NOSENSE_MASK;
    464	bcm_uart_writel(port, val, UART_EXTINP_REG);
    465
    466	/* register irq and enable rx interrupts */
    467	ret = request_irq(port->irq, bcm_uart_interrupt, 0,
    468			  dev_name(port->dev), port);
    469	if (ret)
    470		return ret;
    471	bcm_uart_writel(port, UART_RX_INT_MASK, UART_IR_REG);
    472	bcm_uart_enable(port);
    473	return 0;
    474}
    475
    476/*
    477 * serial core request to flush & disable uart
    478 */
    479static void bcm_uart_shutdown(struct uart_port *port)
    480{
    481	unsigned long flags;
    482
    483	spin_lock_irqsave(&port->lock, flags);
    484	bcm_uart_writel(port, 0, UART_IR_REG);
    485	spin_unlock_irqrestore(&port->lock, flags);
    486
    487	bcm_uart_disable(port);
    488	bcm_uart_flush(port);
    489	free_irq(port->irq, port);
    490}
    491
    492/*
    493 * serial core request to change current uart setting
    494 */
    495static void bcm_uart_set_termios(struct uart_port *port,
    496				 struct ktermios *new,
    497				 struct ktermios *old)
    498{
    499	unsigned int ctl, baud, quot, ier;
    500	unsigned long flags;
    501	int tries;
    502
    503	spin_lock_irqsave(&port->lock, flags);
    504
    505	/* Drain the hot tub fully before we power it off for the winter. */
    506	for (tries = 3; !bcm_uart_tx_empty(port) && tries; tries--)
    507		mdelay(10);
    508
    509	/* disable uart while changing speed */
    510	bcm_uart_disable(port);
    511	bcm_uart_flush(port);
    512
    513	/* update Control register */
    514	ctl = bcm_uart_readl(port, UART_CTL_REG);
    515	ctl &= ~UART_CTL_BITSPERSYM_MASK;
    516
    517	switch (new->c_cflag & CSIZE) {
    518	case CS5:
    519		ctl |= (0 << UART_CTL_BITSPERSYM_SHIFT);
    520		break;
    521	case CS6:
    522		ctl |= (1 << UART_CTL_BITSPERSYM_SHIFT);
    523		break;
    524	case CS7:
    525		ctl |= (2 << UART_CTL_BITSPERSYM_SHIFT);
    526		break;
    527	default:
    528		ctl |= (3 << UART_CTL_BITSPERSYM_SHIFT);
    529		break;
    530	}
    531
    532	ctl &= ~UART_CTL_STOPBITS_MASK;
    533	if (new->c_cflag & CSTOPB)
    534		ctl |= UART_CTL_STOPBITS_2;
    535	else
    536		ctl |= UART_CTL_STOPBITS_1;
    537
    538	ctl &= ~(UART_CTL_RXPAREN_MASK | UART_CTL_TXPAREN_MASK);
    539	if (new->c_cflag & PARENB)
    540		ctl |= (UART_CTL_RXPAREN_MASK | UART_CTL_TXPAREN_MASK);
    541	ctl &= ~(UART_CTL_RXPAREVEN_MASK | UART_CTL_TXPAREVEN_MASK);
    542	if (new->c_cflag & PARODD)
    543		ctl |= (UART_CTL_RXPAREVEN_MASK | UART_CTL_TXPAREVEN_MASK);
    544	bcm_uart_writel(port, ctl, UART_CTL_REG);
    545
    546	/* update Baudword register */
    547	baud = uart_get_baud_rate(port, new, old, 0, port->uartclk / 16);
    548	quot = uart_get_divisor(port, baud) - 1;
    549	bcm_uart_writel(port, quot, UART_BAUD_REG);
    550
    551	/* update Interrupt register */
    552	ier = bcm_uart_readl(port, UART_IR_REG);
    553
    554	ier &= ~UART_IR_MASK(UART_IR_EXTIP);
    555	if (UART_ENABLE_MS(port, new->c_cflag))
    556		ier |= UART_IR_MASK(UART_IR_EXTIP);
    557
    558	bcm_uart_writel(port, ier, UART_IR_REG);
    559
    560	/* update read/ignore mask */
    561	port->read_status_mask = UART_FIFO_VALID_MASK;
    562	if (new->c_iflag & INPCK) {
    563		port->read_status_mask |= UART_FIFO_FRAMEERR_MASK;
    564		port->read_status_mask |= UART_FIFO_PARERR_MASK;
    565	}
    566	if (new->c_iflag & (IGNBRK | BRKINT))
    567		port->read_status_mask |= UART_FIFO_BRKDET_MASK;
    568
    569	port->ignore_status_mask = 0;
    570	if (new->c_iflag & IGNPAR)
    571		port->ignore_status_mask |= UART_FIFO_PARERR_MASK;
    572	if (new->c_iflag & IGNBRK)
    573		port->ignore_status_mask |= UART_FIFO_BRKDET_MASK;
    574	if (!(new->c_cflag & CREAD))
    575		port->ignore_status_mask |= UART_FIFO_VALID_MASK;
    576
    577	uart_update_timeout(port, new->c_cflag, baud);
    578	bcm_uart_enable(port);
    579	spin_unlock_irqrestore(&port->lock, flags);
    580}
    581
    582/*
    583 * serial core request to claim uart iomem
    584 */
    585static int bcm_uart_request_port(struct uart_port *port)
    586{
    587	/* UARTs always present */
    588	return 0;
    589}
    590
    591/*
    592 * serial core request to release uart iomem
    593 */
    594static void bcm_uart_release_port(struct uart_port *port)
    595{
    596	/* Nothing to release ... */
    597}
    598
    599/*
    600 * serial core request to do any port required autoconfiguration
    601 */
    602static void bcm_uart_config_port(struct uart_port *port, int flags)
    603{
    604	if (flags & UART_CONFIG_TYPE) {
    605		if (bcm_uart_request_port(port))
    606			return;
    607		port->type = PORT_BCM63XX;
    608	}
    609}
    610
    611/*
    612 * serial core request to check that port information in serinfo are
    613 * suitable
    614 */
    615static int bcm_uart_verify_port(struct uart_port *port,
    616				struct serial_struct *serinfo)
    617{
    618	if (port->type != PORT_BCM63XX)
    619		return -EINVAL;
    620	if (port->irq != serinfo->irq)
    621		return -EINVAL;
    622	if (port->iotype != serinfo->io_type)
    623		return -EINVAL;
    624	if (port->mapbase != (unsigned long)serinfo->iomem_base)
    625		return -EINVAL;
    626	return 0;
    627}
    628
    629/* serial core callbacks */
    630static const struct uart_ops bcm_uart_ops = {
    631	.tx_empty	= bcm_uart_tx_empty,
    632	.get_mctrl	= bcm_uart_get_mctrl,
    633	.set_mctrl	= bcm_uart_set_mctrl,
    634	.start_tx	= bcm_uart_start_tx,
    635	.stop_tx	= bcm_uart_stop_tx,
    636	.stop_rx	= bcm_uart_stop_rx,
    637	.enable_ms	= bcm_uart_enable_ms,
    638	.break_ctl	= bcm_uart_break_ctl,
    639	.startup	= bcm_uart_startup,
    640	.shutdown	= bcm_uart_shutdown,
    641	.set_termios	= bcm_uart_set_termios,
    642	.type		= bcm_uart_type,
    643	.release_port	= bcm_uart_release_port,
    644	.request_port	= bcm_uart_request_port,
    645	.config_port	= bcm_uart_config_port,
    646	.verify_port	= bcm_uart_verify_port,
    647};
    648
    649
    650
    651#ifdef CONFIG_SERIAL_BCM63XX_CONSOLE
    652static void wait_for_xmitr(struct uart_port *port)
    653{
    654	unsigned int tmout;
    655
    656	/* Wait up to 10ms for the character(s) to be sent. */
    657	tmout = 10000;
    658	while (--tmout) {
    659		unsigned int val;
    660
    661		val = bcm_uart_readl(port, UART_IR_REG);
    662		if (val & UART_IR_STAT(UART_IR_TXEMPTY))
    663			break;
    664		udelay(1);
    665	}
    666
    667	/* Wait up to 1s for flow control if necessary */
    668	if (port->flags & UPF_CONS_FLOW) {
    669		tmout = 1000000;
    670		while (--tmout) {
    671			unsigned int val;
    672
    673			val = bcm_uart_readl(port, UART_EXTINP_REG);
    674			if (val & UART_EXTINP_CTS_MASK)
    675				break;
    676			udelay(1);
    677		}
    678	}
    679}
    680
    681/*
    682 * output given char
    683 */
    684static void bcm_console_putchar(struct uart_port *port, unsigned char ch)
    685{
    686	wait_for_xmitr(port);
    687	bcm_uart_writel(port, ch, UART_FIFO_REG);
    688}
    689
    690/*
    691 * console core request to output given string
    692 */
    693static void bcm_console_write(struct console *co, const char *s,
    694			      unsigned int count)
    695{
    696	struct uart_port *port;
    697	unsigned long flags;
    698	int locked;
    699
    700	port = &ports[co->index];
    701
    702	local_irq_save(flags);
    703	if (port->sysrq) {
    704		/* bcm_uart_interrupt() already took the lock */
    705		locked = 0;
    706	} else if (oops_in_progress) {
    707		locked = spin_trylock(&port->lock);
    708	} else {
    709		spin_lock(&port->lock);
    710		locked = 1;
    711	}
    712
    713	/* call helper to deal with \r\n */
    714	uart_console_write(port, s, count, bcm_console_putchar);
    715
    716	/* and wait for char to be transmitted */
    717	wait_for_xmitr(port);
    718
    719	if (locked)
    720		spin_unlock(&port->lock);
    721	local_irq_restore(flags);
    722}
    723
    724/*
    725 * console core request to setup given console, find matching uart
    726 * port and setup it.
    727 */
    728static int bcm_console_setup(struct console *co, char *options)
    729{
    730	struct uart_port *port;
    731	int baud = 9600;
    732	int bits = 8;
    733	int parity = 'n';
    734	int flow = 'n';
    735
    736	if (co->index < 0 || co->index >= BCM63XX_NR_UARTS)
    737		return -EINVAL;
    738	port = &ports[co->index];
    739	if (!port->membase)
    740		return -ENODEV;
    741	if (options)
    742		uart_parse_options(options, &baud, &parity, &bits, &flow);
    743
    744	return uart_set_options(port, co, baud, parity, bits, flow);
    745}
    746
    747static struct uart_driver bcm_uart_driver;
    748
    749static struct console bcm63xx_console = {
    750	.name		= "ttyS",
    751	.write		= bcm_console_write,
    752	.device		= uart_console_device,
    753	.setup		= bcm_console_setup,
    754	.flags		= CON_PRINTBUFFER,
    755	.index		= -1,
    756	.data		= &bcm_uart_driver,
    757};
    758
    759static int __init bcm63xx_console_init(void)
    760{
    761	register_console(&bcm63xx_console);
    762	return 0;
    763}
    764
    765console_initcall(bcm63xx_console_init);
    766
    767static void bcm_early_write(struct console *con, const char *s, unsigned n)
    768{
    769	struct earlycon_device *dev = con->data;
    770
    771	uart_console_write(&dev->port, s, n, bcm_console_putchar);
    772	wait_for_xmitr(&dev->port);
    773}
    774
    775static int __init bcm_early_console_setup(struct earlycon_device *device,
    776					  const char *opt)
    777{
    778	if (!device->port.membase)
    779		return -ENODEV;
    780
    781	device->con->write = bcm_early_write;
    782	return 0;
    783}
    784
    785OF_EARLYCON_DECLARE(bcm63xx_uart, "brcm,bcm6345-uart", bcm_early_console_setup);
    786
    787#define BCM63XX_CONSOLE	(&bcm63xx_console)
    788#else
    789#define BCM63XX_CONSOLE	NULL
    790#endif /* CONFIG_SERIAL_BCM63XX_CONSOLE */
    791
    792static struct uart_driver bcm_uart_driver = {
    793	.owner		= THIS_MODULE,
    794	.driver_name	= "bcm63xx_uart",
    795	.dev_name	= "ttyS",
    796	.major		= TTY_MAJOR,
    797	.minor		= 64,
    798	.nr		= BCM63XX_NR_UARTS,
    799	.cons		= BCM63XX_CONSOLE,
    800};
    801
    802/*
    803 * platform driver probe/remove callback
    804 */
    805static int bcm_uart_probe(struct platform_device *pdev)
    806{
    807	struct resource *res_mem;
    808	struct uart_port *port;
    809	struct clk *clk;
    810	int ret;
    811
    812	if (pdev->dev.of_node) {
    813		pdev->id = of_alias_get_id(pdev->dev.of_node, "serial");
    814
    815		if (pdev->id < 0)
    816			pdev->id = of_alias_get_id(pdev->dev.of_node, "uart");
    817	}
    818
    819	if (pdev->id < 0 || pdev->id >= BCM63XX_NR_UARTS)
    820		return -EINVAL;
    821
    822	port = &ports[pdev->id];
    823	if (port->membase)
    824		return -EBUSY;
    825	memset(port, 0, sizeof(*port));
    826
    827	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);
    828	if (!res_mem)
    829		return -ENODEV;
    830
    831	port->mapbase = res_mem->start;
    832	port->membase = devm_ioremap_resource(&pdev->dev, res_mem);
    833	if (IS_ERR(port->membase))
    834		return PTR_ERR(port->membase);
    835
    836	ret = platform_get_irq(pdev, 0);
    837	if (ret < 0)
    838		return ret;
    839	port->irq = ret;
    840
    841	clk = clk_get(&pdev->dev, "refclk");
    842	if (IS_ERR(clk) && pdev->dev.of_node)
    843		clk = of_clk_get(pdev->dev.of_node, 0);
    844
    845	if (IS_ERR(clk))
    846		return -ENODEV;
    847
    848	port->iotype = UPIO_MEM;
    849	port->ops = &bcm_uart_ops;
    850	port->flags = UPF_BOOT_AUTOCONF;
    851	port->dev = &pdev->dev;
    852	port->fifosize = 16;
    853	port->uartclk = clk_get_rate(clk) / 2;
    854	port->line = pdev->id;
    855	port->has_sysrq = IS_ENABLED(CONFIG_SERIAL_BCM63XX_CONSOLE);
    856	clk_put(clk);
    857
    858	ret = uart_add_one_port(&bcm_uart_driver, port);
    859	if (ret) {
    860		ports[pdev->id].membase = NULL;
    861		return ret;
    862	}
    863	platform_set_drvdata(pdev, port);
    864	return 0;
    865}
    866
    867static int bcm_uart_remove(struct platform_device *pdev)
    868{
    869	struct uart_port *port;
    870
    871	port = platform_get_drvdata(pdev);
    872	uart_remove_one_port(&bcm_uart_driver, port);
    873	/* mark port as free */
    874	ports[pdev->id].membase = NULL;
    875	return 0;
    876}
    877
    878static const struct of_device_id bcm63xx_of_match[] = {
    879	{ .compatible = "brcm,bcm6345-uart" },
    880	{ /* sentinel */ }
    881};
    882MODULE_DEVICE_TABLE(of, bcm63xx_of_match);
    883
    884/*
    885 * platform driver stuff
    886 */
    887static struct platform_driver bcm_uart_platform_driver = {
    888	.probe	= bcm_uart_probe,
    889	.remove	= bcm_uart_remove,
    890	.driver	= {
    891		.name  = "bcm63xx_uart",
    892		.of_match_table = bcm63xx_of_match,
    893	},
    894};
    895
    896static int __init bcm_uart_init(void)
    897{
    898	int ret;
    899
    900	ret = uart_register_driver(&bcm_uart_driver);
    901	if (ret)
    902		return ret;
    903
    904	ret = platform_driver_register(&bcm_uart_platform_driver);
    905	if (ret)
    906		uart_unregister_driver(&bcm_uart_driver);
    907
    908	return ret;
    909}
    910
    911static void __exit bcm_uart_exit(void)
    912{
    913	platform_driver_unregister(&bcm_uart_platform_driver);
    914	uart_unregister_driver(&bcm_uart_driver);
    915}
    916
    917module_init(bcm_uart_init);
    918module_exit(bcm_uart_exit);
    919
    920MODULE_AUTHOR("Maxime Bizon <mbizon@freebox.fr>");
    921MODULE_DESCRIPTION("Broadcom 63xx integrated uart driver");
    922MODULE_LICENSE("GPL");