brintos

brintos / linux-shallow public Read only

0
0
Text · 22.9 KiB · 3b4206e Raw
832 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 *  MA35D1 serial driver4 *  Copyright (C) 2023 Nuvoton Technology Corp.5 */6 7#include <linux/bitfield.h>8#include <linux/clk.h>9#include <linux/delay.h>10#include <linux/of.h>11#include <linux/platform_device.h>12#include <linux/iopoll.h>13#include <linux/serial_core.h>14#include <linux/slab.h>15#include <linux/tty_flip.h>16#include <linux/units.h>17 18#define MA35_UART_NR		1719 20#define MA35_RBR_REG		0x0021#define MA35_THR_REG		0x0022#define MA35_IER_REG		0x0423#define MA35_FCR_REG		0x0824#define MA35_LCR_REG		0x0C25#define MA35_MCR_REG		0x1026#define MA35_MSR_REG		0x1427#define MA35_FSR_REG		0x1828#define MA35_ISR_REG		0x1C29#define MA35_TOR_REG		0x2030#define MA35_BAUD_REG		0x2431#define MA35_ALTCTL_REG		0x2C32#define MA35_FUN_SEL_REG	0x3033#define MA35_WKCTL_REG		0x4034#define MA35_WKSTS_REG		0x4435 36/* MA35_IER_REG - Interrupt Enable Register */37#define MA35_IER_RDA_IEN	BIT(0)  /* RBR Available Interrupt Enable */38#define MA35_IER_THRE_IEN	BIT(1)  /* THR Empty Interrupt Enable */39#define MA35_IER_RLS_IEN	BIT(2)  /* RX Line Status Interrupt Enable */40#define MA35_IER_RTO_IEN	BIT(4)  /* RX Time-out Interrupt Enable */41#define MA35_IER_BUFERR_IEN	BIT(5)  /* Buffer Error Interrupt Enable */42#define MA35_IER_TIME_OUT_EN	BIT(11) /* RX Buffer Time-out Counter Enable */43#define MA35_IER_AUTO_RTS	BIT(12) /* nRTS Auto-flow Control Enable */44#define MA35_IER_AUTO_CTS	BIT(13) /* nCTS Auto-flow Control Enable */45 46/* MA35_FCR_REG - FIFO Control Register */47#define MA35_FCR_RFR		BIT(1)  /* RX Field Software Reset */48#define MA35_FCR_TFR		BIT(2)  /* TX Field Software Reset */49#define MA35_FCR_RFITL_MASK	GENMASK(7, 4) /* RX FIFO Interrupt Trigger Level */50#define MA35_FCR_RFITL_1BYTE	FIELD_PREP(MA35_FCR_RFITL_MASK, 0)51#define MA35_FCR_RFITL_4BYTES	FIELD_PREP(MA35_FCR_RFITL_MASK, 1)52#define MA35_FCR_RFITL_8BYTES	FIELD_PREP(MA35_FCR_RFITL_MASK, 2)53#define MA35_FCR_RFITL_14BYTES	FIELD_PREP(MA35_FCR_RFITL_MASK, 3)54#define MA35_FCR_RFITL_30BYTES	FIELD_PREP(MA35_FCR_RFITL_MASK, 4)55#define MA35_FCR_RTSTL_MASK	GENMASK(19, 16) /* nRTS Trigger Level */56#define MA35_FCR_RTSTL_1BYTE	FIELD_PREP(MA35_FCR_RTSTL_MASK, 0)57#define MA35_FCR_RTSTL_4BYTES	FIELD_PREP(MA35_FCR_RTSTL_MASK, 1)58#define MA35_FCR_RTSTL_8BYTES	FIELD_PREP(MA35_FCR_RTSTL_MASK, 2)59#define MA35_FCR_RTSTL_14BYTES	FIELD_PREP(MA35_FCR_RTSTL_MASK, 3)60#define MA35_FCR_RTSTLL_30BYTES	FIELD_PREP(MA35_FCR_RTSTL_MASK, 4)61 62/* MA35_LCR_REG - Line Control Register */63#define	MA35_LCR_NSB		BIT(2)  /* Number of “STOP Bit” */64#define MA35_LCR_PBE		BIT(3)  /* Parity Bit Enable */65#define MA35_LCR_EPE		BIT(4)  /* Even Parity Enable */66#define MA35_LCR_SPE		BIT(5)  /* Stick Parity Enable */67#define MA35_LCR_BREAK		BIT(6)  /* Break Control */68#define MA35_LCR_WLS_MASK	GENMASK(1, 0) /* Word Length Selection */69#define MA35_LCR_WLS_5BITS	FIELD_PREP(MA35_LCR_WLS_MASK, 0)70#define MA35_LCR_WLS_6BITS	FIELD_PREP(MA35_LCR_WLS_MASK, 1)71#define MA35_LCR_WLS_7BITS	FIELD_PREP(MA35_LCR_WLS_MASK, 2)72#define MA35_LCR_WLS_8BITS	FIELD_PREP(MA35_LCR_WLS_MASK, 3)73 74/* MA35_MCR_REG - Modem Control Register */75#define MA35_MCR_RTS_CTRL	BIT(1)  /* nRTS Signal Control */76#define MA35_MCR_RTSACTLV	BIT(9)  /* nRTS Pin Active Level */77#define MA35_MCR_RTSSTS		BIT(13) /* nRTS Pin Status (Read Only) */78 79/* MA35_MSR_REG - Modem Status Register */80#define MA35_MSR_CTSDETF	BIT(0)  /* Detect nCTS State Change Flag */81#define MA35_MSR_CTSSTS		BIT(4)  /* nCTS Pin Status (Read Only) */82#define MA35_MSR_CTSACTLV	BIT(8)  /* nCTS Pin Active Level */83 84/* MA35_FSR_REG - FIFO Status Register */85#define MA35_FSR_RX_OVER_IF	BIT(0)  /* RX Overflow Error Interrupt Flag */86#define MA35_FSR_PEF		BIT(4)  /* Parity Error Flag*/87#define MA35_FSR_FEF		BIT(5)  /* Framing Error Flag */88#define MA35_FSR_BIF		BIT(6)  /* Break Interrupt Flag */89#define MA35_FSR_RX_EMPTY	BIT(14) /* Receiver FIFO Empty (Read Only) */90#define MA35_FSR_RX_FULL	BIT(15) /* Receiver FIFO Full (Read Only) */91#define MA35_FSR_TX_EMPTY	BIT(22) /* Transmitter FIFO Empty (Read Only) */92#define MA35_FSR_TX_FULL	BIT(23) /* Transmitter FIFO Full (Read Only) */93#define MA35_FSR_TX_OVER_IF	BIT(24) /* TX Overflow Error Interrupt Flag */94#define MA35_FSR_TE_FLAG	BIT(28) /* Transmitter Empty Flag (Read Only) */95#define MA35_FSR_RXPTR_MSK	GENMASK(13, 8) /* TX FIFO Pointer mask */96#define MA35_FSR_TXPTR_MSK	GENMASK(21, 16) /* RX FIFO Pointer mask */97 98/* MA35_ISR_REG - Interrupt Status Register */99#define MA35_ISR_RDA_IF		BIT(0)  /* RBR Available Interrupt Flag */100#define MA35_ISR_THRE_IF	BIT(1)  /* THR Empty Interrupt Flag */101#define MA35_ISR_RLSIF		BIT(2)  /* Receive Line Interrupt Flag */102#define MA35_ISR_MODEMIF	BIT(3)  /* MODEM Interrupt Flag */103#define MA35_ISR_RXTO_IF	BIT(4)  /* RX Time-out Interrupt Flag */104#define MA35_ISR_BUFEIF		BIT(5)  /* Buffer Error Interrupt Flag */105#define MA35_ISR_WK_IF		BIT(6)  /* UART Wake-up Interrupt Flag */106#define MA35_ISR_RDAINT		BIT(8)  /* RBR Available Interrupt Indicator */107#define MA35_ISR_THRE_INT	BIT(9)  /* THR Empty Interrupt Indicator */108#define MA35_ISR_ALL		0xFFFFFFFF109 110/* MA35_BAUD_REG - Baud Rate Divider Register */111#define	MA35_BAUD_MODE_MASK	GENMASK(29, 28)112#define MA35_BAUD_MODE0		FIELD_PREP(MA35_BAUD_MODE_MASK, 0)113#define MA35_BAUD_MODE1		FIELD_PREP(MA35_BAUD_MODE_MASK, 2)114#define MA35_BAUD_MODE2		FIELD_PREP(MA35_BAUD_MODE_MASK, 3)115#define	MA35_BAUD_MASK		GENMASK(15, 0)116 117/* MA35_ALTCTL_REG - Alternate Control/Status Register */118#define MA35_ALTCTL_RS485AUD	BIT(10) /* RS-485 Auto Direction Function */119 120/* MA35_FUN_SEL_REG - Function Select Register */121#define MA35_FUN_SEL_MASK	GENMASK(2, 0)122#define MA35_FUN_SEL_UART	FIELD_PREP(MA35_FUN_SEL_MASK, 0)123#define MA35_FUN_SEL_RS485	FIELD_PREP(MA35_FUN_SEL_MASK, 3)124 125/* The constrain for MA35D1 UART baud rate divider */126#define MA35_BAUD_DIV_MAX	0xFFFF127#define MA35_BAUD_DIV_MIN	11128 129/* UART FIFO depth */130#define MA35_UART_FIFO_DEPTH	32131/* UART console clock */132#define MA35_UART_CONSOLE_CLK	(24 * HZ_PER_MHZ)133/* UART register ioremap size */134#define MA35_UART_REG_SIZE	0x100135/* Rx Timeout */136#define MA35_UART_RX_TOUT	0x40137 138#define MA35_IER_CONFIG		(MA35_IER_RTO_IEN | MA35_IER_RDA_IEN | \139				 MA35_IER_TIME_OUT_EN | MA35_IER_BUFERR_IEN)140 141#define MA35_ISR_IF_CHECK	(MA35_ISR_RDA_IF | MA35_ISR_RXTO_IF | \142				 MA35_ISR_THRE_INT | MA35_ISR_BUFEIF)143 144#define MA35_FSR_TX_BOTH_EMPTY	(MA35_FSR_TE_FLAG | MA35_FSR_TX_EMPTY)145 146static struct uart_driver ma35d1serial_reg;147 148struct uart_ma35d1_port {149	struct uart_port port;150	struct clk *clk;151	u16 capabilities; /* port capabilities */152	u8 ier;153	u8 lcr;154	u8 mcr;155	u32 baud_rate;156	u32 console_baud_rate;157	u32 console_line;158	u32 console_int;159};160 161static struct uart_ma35d1_port ma35d1serial_ports[MA35_UART_NR];162 163static struct uart_ma35d1_port *to_ma35d1_uart_port(struct uart_port *uart)164{165	return container_of(uart, struct uart_ma35d1_port, port);166}167 168static u32 serial_in(struct uart_ma35d1_port *p, u32 offset)169{170	return readl_relaxed(p->port.membase + offset);171}172 173static void serial_out(struct uart_ma35d1_port *p, u32 offset, u32 value)174{175	writel_relaxed(value, p->port.membase + offset);176}177 178static void __stop_tx(struct uart_ma35d1_port *p)179{180	u32 ier;181 182	ier = serial_in(p, MA35_IER_REG);183	if (ier & MA35_IER_THRE_IEN)184		serial_out(p, MA35_IER_REG, ier & ~MA35_IER_THRE_IEN);185}186 187static void ma35d1serial_stop_tx(struct uart_port *port)188{189	struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);190 191	__stop_tx(up);192}193 194static void transmit_chars(struct uart_ma35d1_port *up)195{196	u32 count;197	u8 ch;198 199	if (uart_tx_stopped(&up->port)) {200		ma35d1serial_stop_tx(&up->port);201		return;202	}203	count = MA35_UART_FIFO_DEPTH - FIELD_GET(MA35_FSR_TXPTR_MSK,204						 serial_in(up, MA35_FSR_REG));205	uart_port_tx_limited(&up->port, ch, count,206			     !(serial_in(up, MA35_FSR_REG) & MA35_FSR_TX_FULL),207			     serial_out(up, MA35_THR_REG, ch),208			     ({}));209}210 211static void ma35d1serial_start_tx(struct uart_port *port)212{213	struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);214	u32 ier;215 216	ier = serial_in(up, MA35_IER_REG);217	serial_out(up, MA35_IER_REG, ier & ~MA35_IER_THRE_IEN);218	transmit_chars(up);219	serial_out(up, MA35_IER_REG, ier | MA35_IER_THRE_IEN);220}221 222static void ma35d1serial_stop_rx(struct uart_port *port)223{224	struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);225	u32 ier;226 227	ier = serial_in(up, MA35_IER_REG);228	ier &= ~MA35_IER_RDA_IEN;229	serial_out(up, MA35_IER_REG, ier);230}231 232static void receive_chars(struct uart_ma35d1_port *up)233{234	int max_count = 256;235	u8 ch, flag;236	u32 fsr;237 238	fsr = serial_in(up, MA35_FSR_REG);239	do {240		flag = TTY_NORMAL;241		up->port.icount.rx++;242 243		if (unlikely(fsr & (MA35_FSR_BIF | MA35_FSR_FEF |244				    MA35_FSR_PEF | MA35_FSR_RX_OVER_IF))) {245			if (fsr & MA35_FSR_BIF) {246				up->port.icount.brk++;247				if (uart_handle_break(&up->port))248					continue;249			}250			if (fsr & MA35_FSR_FEF)251				up->port.icount.frame++;252			if (fsr & MA35_FSR_PEF)253				up->port.icount.parity++;254			if (fsr & MA35_FSR_RX_OVER_IF)255				up->port.icount.overrun++;256 257			serial_out(up, MA35_FSR_REG,258				   fsr & (MA35_FSR_BIF | MA35_FSR_FEF |259					  MA35_FSR_PEF | MA35_FSR_RX_OVER_IF));260			if (fsr & MA35_FSR_BIF)261				flag = TTY_BREAK;262			else if (fsr & MA35_FSR_PEF)263				flag = TTY_PARITY;264			else if (fsr & MA35_FSR_FEF)265				flag = TTY_FRAME;266		}267 268		ch = serial_in(up, MA35_RBR_REG);269		if (uart_handle_sysrq_char(&up->port, ch))270			continue;271 272		uart_port_lock(&up->port);273		uart_insert_char(&up->port, fsr, MA35_FSR_RX_OVER_IF, ch, flag);274		uart_port_unlock(&up->port);275 276		fsr = serial_in(up, MA35_FSR_REG);277	} while (!(fsr & MA35_FSR_RX_EMPTY) && (max_count-- > 0));278 279	uart_port_lock(&up->port);280	tty_flip_buffer_push(&up->port.state->port);281	uart_port_unlock(&up->port);282}283 284static irqreturn_t ma35d1serial_interrupt(int irq, void *dev_id)285{286	struct uart_port *port = dev_id;287	struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);288	u32 isr, fsr;289 290	isr = serial_in(up, MA35_ISR_REG);291	fsr = serial_in(up, MA35_FSR_REG);292 293	if (!(isr & MA35_ISR_IF_CHECK))294		return IRQ_NONE;295 296	if (isr & (MA35_ISR_RDA_IF | MA35_ISR_RXTO_IF))297		receive_chars(up);298	if (isr & MA35_ISR_THRE_INT)299		transmit_chars(up);300	if (fsr & MA35_FSR_TX_OVER_IF)301		serial_out(up, MA35_FSR_REG, MA35_FSR_TX_OVER_IF);302 303	return IRQ_HANDLED;304}305 306static u32 ma35d1serial_tx_empty(struct uart_port *port)307{308	struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);309	u32 fsr;310 311	fsr = serial_in(up, MA35_FSR_REG);312	if ((fsr & MA35_FSR_TX_BOTH_EMPTY) == MA35_FSR_TX_BOTH_EMPTY)313		return TIOCSER_TEMT;314	else315		return 0;316}317 318static u32 ma35d1serial_get_mctrl(struct uart_port *port)319{320	struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);321	u32 status;322	u32 ret = 0;323 324	status = serial_in(up, MA35_MSR_REG);325	if (!(status & MA35_MSR_CTSSTS))326		ret |= TIOCM_CTS;327	return ret;328}329 330static void ma35d1serial_set_mctrl(struct uart_port *port, u32 mctrl)331{332	struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);333	u32 mcr, msr, ier;334 335	mcr = serial_in(up, MA35_MCR_REG);336	mcr &= ~MA35_MCR_RTS_CTRL;337 338	if (mctrl & TIOCM_RTS)339		mcr |= MA35_MCR_RTSACTLV;340	else341		mcr &= ~MA35_MCR_RTSACTLV;342 343	if (up->mcr & UART_MCR_AFE) {344		ier = serial_in(up, MA35_IER_REG);345		ier |= MA35_IER_AUTO_RTS | MA35_IER_AUTO_CTS;346		serial_out(up, MA35_IER_REG, ier);347		up->port.flags |= UPF_HARD_FLOW;348	} else {349		ier = serial_in(up, MA35_IER_REG);350		ier &= ~(MA35_IER_AUTO_RTS | MA35_IER_AUTO_CTS);351		serial_out(up, MA35_IER_REG, ier);352		up->port.flags &= ~UPF_HARD_FLOW;353	}354 355	msr = serial_in(up, MA35_MSR_REG);356	msr |= MA35_MSR_CTSACTLV;357	serial_out(up, MA35_MSR_REG, msr);358	serial_out(up, MA35_MCR_REG, mcr);359}360 361static void ma35d1serial_break_ctl(struct uart_port *port, int break_state)362{363	struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);364	unsigned long flags;365	u32 lcr;366 367	uart_port_lock_irqsave(&up->port, &flags);368	lcr = serial_in(up, MA35_LCR_REG);369	if (break_state != 0)370		lcr |= MA35_LCR_BREAK;371	else372		lcr &= ~MA35_LCR_BREAK;373	serial_out(up, MA35_LCR_REG, lcr);374	uart_port_unlock_irqrestore(&up->port, flags);375}376 377static int ma35d1serial_startup(struct uart_port *port)378{379	struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);380	u32 fcr;381	int retval;382 383	/* Reset FIFO */384	serial_out(up, MA35_FCR_REG, MA35_FCR_TFR | MA35_FCR_RFR);385 386	/* Clear pending interrupts */387	serial_out(up, MA35_ISR_REG, MA35_ISR_ALL);388 389	retval = request_irq(port->irq, ma35d1serial_interrupt, 0,390			     dev_name(port->dev), port);391	if (retval) {392		dev_err(up->port.dev, "request irq failed.\n");393		return retval;394	}395 396	fcr = serial_in(up, MA35_FCR_REG);397	fcr |= MA35_FCR_RFITL_4BYTES | MA35_FCR_RTSTL_8BYTES;398	serial_out(up, MA35_FCR_REG, fcr);399	serial_out(up, MA35_LCR_REG, MA35_LCR_WLS_8BITS);400	serial_out(up, MA35_TOR_REG, MA35_UART_RX_TOUT);401	serial_out(up, MA35_IER_REG, MA35_IER_CONFIG);402	return 0;403}404 405static void ma35d1serial_shutdown(struct uart_port *port)406{407	struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);408 409	serial_out(up, MA35_IER_REG, 0);410	free_irq(port->irq, port);411}412 413static void ma35d1serial_set_termios(struct uart_port *port,414				     struct ktermios *termios,415				     const struct ktermios *old)416{417	struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);418	unsigned long flags;419	u32 baud, quot;420	u32 lcr = 0;421 422	lcr = UART_LCR_WLEN(tty_get_char_size(termios->c_cflag));423 424	if (termios->c_cflag & CSTOPB)425		lcr |= MA35_LCR_NSB;426	if (termios->c_cflag & PARENB)427		lcr |= MA35_LCR_PBE;428	if (!(termios->c_cflag & PARODD))429		lcr |= MA35_LCR_EPE;430	if (termios->c_cflag & CMSPAR)431		lcr |= MA35_LCR_SPE;432 433	baud = uart_get_baud_rate(port, termios, old,434				  port->uartclk / MA35_BAUD_DIV_MAX,435				  port->uartclk / MA35_BAUD_DIV_MIN);436 437	/* MA35D1 UART baud rate equation: baudrate = UART_CLK / (quot + 2) */438	quot = (port->uartclk / baud) - 2;439 440	/*441	 * Ok, we're now changing the port state.  Do it with442	 * interrupts disabled.443	 */444	uart_port_lock_irqsave(&up->port, &flags);445 446	up->port.read_status_mask = MA35_FSR_RX_OVER_IF;447	if (termios->c_iflag & INPCK)448		up->port.read_status_mask |= MA35_FSR_FEF | MA35_FSR_PEF;449	if (termios->c_iflag & (BRKINT | PARMRK))450		up->port.read_status_mask |= MA35_FSR_BIF;451 452	/* Characteres to ignore */453	up->port.ignore_status_mask = 0;454	if (termios->c_iflag & IGNPAR)455		up->port.ignore_status_mask |= MA35_FSR_FEF | MA35_FSR_PEF;456	if (termios->c_iflag & IGNBRK) {457		up->port.ignore_status_mask |= MA35_FSR_BIF;458		/*459		 * If we're ignoring parity and break indicators,460		 * ignore overruns too (for real raw support).461		 */462		if (termios->c_iflag & IGNPAR)463			up->port.ignore_status_mask |= MA35_FSR_RX_OVER_IF;464	}465	if (termios->c_cflag & CRTSCTS)466		up->mcr |= UART_MCR_AFE;467	else468		up->mcr &= ~UART_MCR_AFE;469 470	uart_update_timeout(port, termios->c_cflag, baud);471 472	ma35d1serial_set_mctrl(&up->port, up->port.mctrl);473 474	serial_out(up, MA35_BAUD_REG, MA35_BAUD_MODE2 | FIELD_PREP(MA35_BAUD_MASK, quot));475 476	serial_out(up, MA35_LCR_REG, lcr);477 478	uart_port_unlock_irqrestore(&up->port, flags);479}480 481static const char *ma35d1serial_type(struct uart_port *port)482{483	return "ma35d1-uart";484}485 486static void ma35d1serial_config_port(struct uart_port *port, int flags)487{488	/*489	 * Driver core for serial ports forces a non-zero value for port type.490	 * Write an arbitrary value here to accommodate the serial core driver,491	 * as ID part of UAPI is redundant.492	 */493	port->type = 1;494}495 496static int ma35d1serial_verify_port(struct uart_port *port, struct serial_struct *ser)497{498	if (port->type != PORT_UNKNOWN && ser->type != 1)499		return -EINVAL;500 501	return 0;502}503 504static const struct uart_ops ma35d1serial_ops = {505	.tx_empty     = ma35d1serial_tx_empty,506	.set_mctrl    = ma35d1serial_set_mctrl,507	.get_mctrl    = ma35d1serial_get_mctrl,508	.stop_tx      = ma35d1serial_stop_tx,509	.start_tx     = ma35d1serial_start_tx,510	.stop_rx      = ma35d1serial_stop_rx,511	.break_ctl    = ma35d1serial_break_ctl,512	.startup      = ma35d1serial_startup,513	.shutdown     = ma35d1serial_shutdown,514	.set_termios  = ma35d1serial_set_termios,515	.type         = ma35d1serial_type,516	.config_port  = ma35d1serial_config_port,517	.verify_port  = ma35d1serial_verify_port,518};519 520static const struct of_device_id ma35d1_serial_of_match[] = {521	{ .compatible = "nuvoton,ma35d1-uart" },522	{},523};524MODULE_DEVICE_TABLE(of, ma35d1_serial_of_match);525 526#ifdef CONFIG_SERIAL_NUVOTON_MA35D1_CONSOLE527 528static struct device_node *ma35d1serial_uart_nodes[MA35_UART_NR];529 530static void wait_for_xmitr(struct uart_ma35d1_port *up)531{532	unsigned int reg = 0;533 534	read_poll_timeout_atomic(serial_in, reg, reg & MA35_FSR_TX_EMPTY,535				 1, 10000, false,536				 up, MA35_FSR_REG);537}538 539static void ma35d1serial_console_putchar(struct uart_port *port, unsigned char ch)540{541	struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);542 543	wait_for_xmitr(up);544	serial_out(up, MA35_THR_REG, ch);545}546 547/*548 *  Print a string to the serial port trying not to disturb549 *  any possible real use of the port...550 *551 *  The console_lock must be held when we get here.552 */553static void ma35d1serial_console_write(struct console *co, const char *s, u32 count)554{555	struct uart_ma35d1_port *up;556	unsigned long flags;557	int locked = 1;558	u32 ier;559 560	if ((co->index < 0) || (co->index >= MA35_UART_NR)) {561		pr_warn("Failed to write on console port %x, out of range\n",562			co->index);563		return;564	}565 566	up = &ma35d1serial_ports[co->index];567 568	if (up->port.sysrq)569		locked = 0;570	else if (oops_in_progress)571		locked = uart_port_trylock_irqsave(&up->port, &flags);572	else573		uart_port_lock_irqsave(&up->port, &flags);574 575	/*576	 *  First save the IER then disable the interrupts577	 */578	ier = serial_in(up, MA35_IER_REG);579	serial_out(up, MA35_IER_REG, 0);580 581	uart_console_write(&up->port, s, count, ma35d1serial_console_putchar);582 583	wait_for_xmitr(up);584	serial_out(up, MA35_IER_REG, ier);585 586	if (locked)587		uart_port_unlock_irqrestore(&up->port, flags);588}589 590static int __init ma35d1serial_console_setup(struct console *co, char *options)591{592	struct device_node *np;593	struct uart_ma35d1_port *p;594	u32 val32[4];595	struct uart_port *port;596	int baud = 115200;597	int bits = 8;598	int parity = 'n';599	int flow = 'n';600 601	if ((co->index < 0) || (co->index >= MA35_UART_NR)) {602		pr_debug("Console Port%x out of range\n", co->index);603		return -EINVAL;604	}605 606	np = ma35d1serial_uart_nodes[co->index];607	p = &ma35d1serial_ports[co->index];608	if (!np || !p)609		return -ENODEV;610 611	if (of_property_read_u32_array(np, "reg", val32, ARRAY_SIZE(val32)) != 0)612		return -EINVAL;613 614	p->port.iobase = val32[1];615	p->port.membase = ioremap(p->port.iobase, MA35_UART_REG_SIZE);616	if (!p->port.membase)617		return -ENOMEM;618 619	p->port.ops = &ma35d1serial_ops;620	p->port.line = 0;621	p->port.uartclk = MA35_UART_CONSOLE_CLK;622 623	port = &ma35d1serial_ports[co->index].port;624 625	if (options)626		uart_parse_options(options, &baud, &parity, &bits, &flow);627 628	return uart_set_options(port, co, baud, parity, bits, flow);629}630 631static struct console ma35d1serial_console = {632	.name    = "ttyNVT",633	.write   = ma35d1serial_console_write,634	.device  = uart_console_device,635	.setup   = ma35d1serial_console_setup,636	.flags   = CON_PRINTBUFFER | CON_ENABLED,637	.index   = -1,638	.data    = &ma35d1serial_reg,639};640 641static void ma35d1serial_console_init_port(void)642{643	u32 i = 0;644	struct device_node *np;645 646	for_each_matching_node(np, ma35d1_serial_of_match) {647		if (ma35d1serial_uart_nodes[i] == NULL) {648			of_node_get(np);649			ma35d1serial_uart_nodes[i] = np;650			i++;651			if (i == MA35_UART_NR)652				break;653		}654	}655}656 657static int __init ma35d1serial_console_init(void)658{659	ma35d1serial_console_init_port();660	register_console(&ma35d1serial_console);661	return 0;662}663console_initcall(ma35d1serial_console_init);664 665#define MA35D1SERIAL_CONSOLE    (&ma35d1serial_console)666#else667#define MA35D1SERIAL_CONSOLE    NULL668#endif669 670static struct uart_driver ma35d1serial_reg = {671	.owner        = THIS_MODULE,672	.driver_name  = "serial",673	.dev_name     = "ttyNVT",674	.major        = TTY_MAJOR,675	.minor        = 64,676	.cons         = MA35D1SERIAL_CONSOLE,677	.nr           = MA35_UART_NR,678};679 680/*681 * Register a set of serial devices attached to a platform device.682 * The list is terminated with a zero flags entry, which means we expect683 * all entries to have at least UPF_BOOT_AUTOCONF set.684 */685static int ma35d1serial_probe(struct platform_device *pdev)686{687	struct resource *res_mem;688	struct uart_ma35d1_port *up;689	int ret = 0;690 691	if (!pdev->dev.of_node)692		return -ENODEV;693 694	ret = of_alias_get_id(pdev->dev.of_node, "serial");695	if (ret < 0) {696		dev_err(&pdev->dev, "failed to get alias/pdev id, errno %d\n", ret);697		return ret;698	}699	up = &ma35d1serial_ports[ret];700	up->port.line = ret;701	res_mem = platform_get_resource(pdev, IORESOURCE_MEM, 0);702	if (!res_mem)703		return -ENODEV;704 705	up->port.iobase = res_mem->start;706	up->port.membase = ioremap(up->port.iobase, MA35_UART_REG_SIZE);707	if (!up->port.membase)708		return -ENOMEM;709 710	up->port.ops = &ma35d1serial_ops;711 712	spin_lock_init(&up->port.lock);713 714	up->clk = of_clk_get(pdev->dev.of_node, 0);715	if (IS_ERR(up->clk)) {716		ret = PTR_ERR(up->clk);717		dev_err(&pdev->dev, "failed to get core clk: %d\n", ret);718		goto err_iounmap;719	}720 721	ret = clk_prepare_enable(up->clk);722	if (ret)723		goto err_iounmap;724 725	if (up->port.line != 0)726		up->port.uartclk = clk_get_rate(up->clk);727 728	ret = platform_get_irq(pdev, 0);729	if (ret < 0)730		goto err_clk_disable;731 732	up->port.irq = ret;733	up->port.dev = &pdev->dev;734	up->port.flags = UPF_BOOT_AUTOCONF;735 736	platform_set_drvdata(pdev, up);737 738	ret = uart_add_one_port(&ma35d1serial_reg, &up->port);739	if (ret < 0)740		goto err_free_irq;741 742	return 0;743 744err_free_irq:745	free_irq(up->port.irq, &up->port);746 747err_clk_disable:748	clk_disable_unprepare(up->clk);749 750err_iounmap:751	iounmap(up->port.membase);752	return ret;753}754 755/*756 * Remove serial ports registered against a platform device.757 */758static void ma35d1serial_remove(struct platform_device *dev)759{760	struct uart_port *port = platform_get_drvdata(dev);761	struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);762 763	uart_remove_one_port(&ma35d1serial_reg, port);764	clk_disable_unprepare(up->clk);765}766 767static int ma35d1serial_suspend(struct platform_device *dev, pm_message_t state)768{769	struct uart_port *port = platform_get_drvdata(dev);770	struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);771 772	uart_suspend_port(&ma35d1serial_reg, &up->port);773	if (up->port.line == 0) {774		up->console_baud_rate = serial_in(up, MA35_BAUD_REG);775		up->console_line = serial_in(up, MA35_LCR_REG);776		up->console_int = serial_in(up, MA35_IER_REG);777	}778	return 0;779}780 781static int ma35d1serial_resume(struct platform_device *dev)782{783	struct uart_port *port = platform_get_drvdata(dev);784	struct uart_ma35d1_port *up = to_ma35d1_uart_port(port);785 786	if (up->port.line == 0) {787		serial_out(up, MA35_BAUD_REG, up->console_baud_rate);788		serial_out(up, MA35_LCR_REG, up->console_line);789		serial_out(up, MA35_IER_REG, up->console_int);790	}791	uart_resume_port(&ma35d1serial_reg, &up->port);792	return 0;793}794 795static struct platform_driver ma35d1serial_driver = {796	.probe      = ma35d1serial_probe,797	.remove_new = ma35d1serial_remove,798	.suspend    = ma35d1serial_suspend,799	.resume     = ma35d1serial_resume,800	.driver     = {801		.name   = "ma35d1-uart",802		.of_match_table = of_match_ptr(ma35d1_serial_of_match),803	},804};805 806static int __init ma35d1serial_init(void)807{808	int ret;809 810	ret = uart_register_driver(&ma35d1serial_reg);811	if (ret)812		return ret;813 814	ret = platform_driver_register(&ma35d1serial_driver);815	if (ret)816		uart_unregister_driver(&ma35d1serial_reg);817 818	return ret;819}820 821static void __exit ma35d1serial_exit(void)822{823	platform_driver_unregister(&ma35d1serial_driver);824	uart_unregister_driver(&ma35d1serial_reg);825}826 827module_init(ma35d1serial_init);828module_exit(ma35d1serial_exit);829 830MODULE_LICENSE("GPL");831MODULE_DESCRIPTION("MA35D1 serial driver");832