brintos

brintos / linux-shallow public Read only

0
0
Text · 23.8 KiB · b4e1b90 Raw
966 lines · c
1// SPDX-License-Identifier: GPL-2.0+2/*3 *	Support for the asynchronous serial interface (DUART) included4 *	in the BCM1250 and derived System-On-a-Chip (SOC) devices.5 *6 *	Copyright (c) 2007  Maciej W. Rozycki7 *8 *	Derived from drivers/char/sb1250_duart.c for which the following9 *	copyright applies:10 *11 *	Copyright (c) 2000, 2001, 2002, 2003, 2004  Broadcom Corporation12 *13 *	References:14 *15 *	"BCM1250/BCM1125/BCM1125H User Manual", Broadcom Corporation16 */17 18#include <linux/compiler.h>19#include <linux/console.h>20#include <linux/delay.h>21#include <linux/errno.h>22#include <linux/init.h>23#include <linux/interrupt.h>24#include <linux/ioport.h>25#include <linux/kernel.h>26#include <linux/module.h>27#include <linux/major.h>28#include <linux/serial.h>29#include <linux/serial_core.h>30#include <linux/spinlock.h>31#include <linux/sysrq.h>32#include <linux/tty.h>33#include <linux/tty_flip.h>34#include <linux/types.h>35 36#include <linux/refcount.h>37#include <linux/io.h>38 39#include <asm/sibyte/sb1250.h>40#include <asm/sibyte/sb1250_uart.h>41#include <asm/sibyte/swarm.h>42 43 44#if defined(CONFIG_SIBYTE_BCM1x80)45#include <asm/sibyte/bcm1480_regs.h>46#include <asm/sibyte/bcm1480_int.h>47 48#define SBD_CHANREGS(line)	A_BCM1480_DUART_CHANREG((line), 0)49#define SBD_CTRLREGS(line)	A_BCM1480_DUART_CTRLREG((line), 0)50#define SBD_INT(line)		(K_BCM1480_INT_UART_0 + (line))51 52#define DUART_CHANREG_SPACING	BCM1480_DUART_CHANREG_SPACING53 54#define R_DUART_IMRREG(line)	R_BCM1480_DUART_IMRREG(line)55#define R_DUART_INCHREG(line)	R_BCM1480_DUART_INCHREG(line)56#define R_DUART_ISRREG(line)	R_BCM1480_DUART_ISRREG(line)57 58#elif defined(CONFIG_SIBYTE_SB1250) || defined(CONFIG_SIBYTE_BCM112X)59#include <asm/sibyte/sb1250_regs.h>60#include <asm/sibyte/sb1250_int.h>61 62#define SBD_CHANREGS(line)	A_DUART_CHANREG((line), 0)63#define SBD_CTRLREGS(line)	A_DUART_CTRLREG(0)64#define SBD_INT(line)		(K_INT_UART_0 + (line))65 66#else67#error invalid SB1250 UART configuration68 69#endif70 71 72MODULE_AUTHOR("Maciej W. Rozycki <macro@linux-mips.org>");73MODULE_DESCRIPTION("BCM1xxx on-chip DUART serial driver");74MODULE_LICENSE("GPL");75 76 77#define DUART_MAX_CHIP 278#define DUART_MAX_SIDE 279 80/*81 * Per-port state.82 */83struct sbd_port {84	struct sbd_duart	*duart;85	struct uart_port	port;86	unsigned char __iomem	*memctrl;87	int			tx_stopped;88	int			initialised;89};90 91/*92 * Per-DUART state for the shared register space.93 */94struct sbd_duart {95	struct sbd_port		sport[2];96	unsigned long		mapctrl;97	refcount_t		map_guard;98};99 100#define to_sport(uport) container_of(uport, struct sbd_port, port)101 102static struct sbd_duart sbd_duarts[DUART_MAX_CHIP];103 104 105/*106 * Reading and writing SB1250 DUART registers.107 *108 * There are three register spaces: two per-channel ones and109 * a shared one.  We have to define accessors appropriately.110 * All registers are 64-bit and all but the Baud Rate Clock111 * registers only define 8 least significant bits.  There is112 * also a workaround to take into account.  Raw accessors use113 * the full register width, but cooked ones truncate it114 * intentionally so that the rest of the driver does not care.115 */116static u64 __read_sbdchn(struct sbd_port *sport, int reg)117{118	void __iomem *csr = sport->port.membase + reg;119 120	return __raw_readq(csr);121}122 123static u64 __read_sbdshr(struct sbd_port *sport, int reg)124{125	void __iomem *csr = sport->memctrl + reg;126 127	return __raw_readq(csr);128}129 130static void __write_sbdchn(struct sbd_port *sport, int reg, u64 value)131{132	void __iomem *csr = sport->port.membase + reg;133 134	__raw_writeq(value, csr);135}136 137static void __write_sbdshr(struct sbd_port *sport, int reg, u64 value)138{139	void __iomem *csr = sport->memctrl + reg;140 141	__raw_writeq(value, csr);142}143 144/*145 * In bug 1956, we get glitches that can mess up uart registers.  This146 * "read-mode-reg after any register access" is an accepted workaround.147 */148static void __war_sbd1956(struct sbd_port *sport)149{150	__read_sbdchn(sport, R_DUART_MODE_REG_1);151	__read_sbdchn(sport, R_DUART_MODE_REG_2);152}153 154static unsigned char read_sbdchn(struct sbd_port *sport, int reg)155{156	unsigned char retval;157 158	retval = __read_sbdchn(sport, reg);159	if (IS_ENABLED(CONFIG_SB1_PASS_2_WORKAROUNDS))160		__war_sbd1956(sport);161	return retval;162}163 164static unsigned char read_sbdshr(struct sbd_port *sport, int reg)165{166	unsigned char retval;167 168	retval = __read_sbdshr(sport, reg);169	if (IS_ENABLED(CONFIG_SB1_PASS_2_WORKAROUNDS))170		__war_sbd1956(sport);171	return retval;172}173 174static void write_sbdchn(struct sbd_port *sport, int reg, unsigned int value)175{176	__write_sbdchn(sport, reg, value);177	if (IS_ENABLED(CONFIG_SB1_PASS_2_WORKAROUNDS))178		__war_sbd1956(sport);179}180 181static void write_sbdshr(struct sbd_port *sport, int reg, unsigned int value)182{183	__write_sbdshr(sport, reg, value);184	if (IS_ENABLED(CONFIG_SB1_PASS_2_WORKAROUNDS))185		__war_sbd1956(sport);186}187 188 189static int sbd_receive_ready(struct sbd_port *sport)190{191	return read_sbdchn(sport, R_DUART_STATUS) & M_DUART_RX_RDY;192}193 194static int sbd_receive_drain(struct sbd_port *sport)195{196	int loops = 10000;197 198	while (sbd_receive_ready(sport) && --loops)199		read_sbdchn(sport, R_DUART_RX_HOLD);200	return loops;201}202 203static int __maybe_unused sbd_transmit_ready(struct sbd_port *sport)204{205	return read_sbdchn(sport, R_DUART_STATUS) & M_DUART_TX_RDY;206}207 208static int __maybe_unused sbd_transmit_drain(struct sbd_port *sport)209{210	int loops = 10000;211 212	while (!sbd_transmit_ready(sport) && --loops)213		udelay(2);214	return loops;215}216 217static int sbd_transmit_empty(struct sbd_port *sport)218{219	return read_sbdchn(sport, R_DUART_STATUS) & M_DUART_TX_EMT;220}221 222static int sbd_line_drain(struct sbd_port *sport)223{224	int loops = 10000;225 226	while (!sbd_transmit_empty(sport) && --loops)227		udelay(2);228	return loops;229}230 231 232static unsigned int sbd_tx_empty(struct uart_port *uport)233{234	struct sbd_port *sport = to_sport(uport);235 236	return sbd_transmit_empty(sport) ? TIOCSER_TEMT : 0;237}238 239static unsigned int sbd_get_mctrl(struct uart_port *uport)240{241	struct sbd_port *sport = to_sport(uport);242	unsigned int mctrl, status;243 244	status = read_sbdshr(sport, R_DUART_IN_PORT);245	status >>= (uport->line) % 2;246	mctrl = (!(status & M_DUART_IN_PIN0_VAL) ? TIOCM_CTS : 0) |247		(!(status & M_DUART_IN_PIN4_VAL) ? TIOCM_CAR : 0) |248		(!(status & M_DUART_RIN0_PIN) ? TIOCM_RNG : 0) |249		(!(status & M_DUART_IN_PIN2_VAL) ? TIOCM_DSR : 0);250	return mctrl;251}252 253static void sbd_set_mctrl(struct uart_port *uport, unsigned int mctrl)254{255	struct sbd_port *sport = to_sport(uport);256	unsigned int clr = 0, set = 0, mode2;257 258	if (mctrl & TIOCM_DTR)259		set |= M_DUART_SET_OPR2;260	else261		clr |= M_DUART_CLR_OPR2;262	if (mctrl & TIOCM_RTS)263		set |= M_DUART_SET_OPR0;264	else265		clr |= M_DUART_CLR_OPR0;266	clr <<= (uport->line) % 2;267	set <<= (uport->line) % 2;268 269	mode2 = read_sbdchn(sport, R_DUART_MODE_REG_2);270	mode2 &= ~M_DUART_CHAN_MODE;271	if (mctrl & TIOCM_LOOP)272		mode2 |= V_DUART_CHAN_MODE_LCL_LOOP;273	else274		mode2 |= V_DUART_CHAN_MODE_NORMAL;275 276	write_sbdshr(sport, R_DUART_CLEAR_OPR, clr);277	write_sbdshr(sport, R_DUART_SET_OPR, set);278	write_sbdchn(sport, R_DUART_MODE_REG_2, mode2);279}280 281static void sbd_stop_tx(struct uart_port *uport)282{283	struct sbd_port *sport = to_sport(uport);284 285	write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_DIS);286	sport->tx_stopped = 1;287};288 289static void sbd_start_tx(struct uart_port *uport)290{291	struct sbd_port *sport = to_sport(uport);292	unsigned int mask;293 294	/* Enable tx interrupts.  */295	mask = read_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2));296	mask |= M_DUART_IMR_TX;297	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), mask);298 299	/* Go!, go!, go!...  */300	write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_EN);301	sport->tx_stopped = 0;302};303 304static void sbd_stop_rx(struct uart_port *uport)305{306	struct sbd_port *sport = to_sport(uport);307 308	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), 0);309};310 311static void sbd_enable_ms(struct uart_port *uport)312{313	struct sbd_port *sport = to_sport(uport);314 315	write_sbdchn(sport, R_DUART_AUXCTL_X,316		     M_DUART_CIN_CHNG_ENA | M_DUART_CTS_CHNG_ENA);317}318 319static void sbd_break_ctl(struct uart_port *uport, int break_state)320{321	struct sbd_port *sport = to_sport(uport);322 323	if (break_state == -1)324		write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_START_BREAK);325	else326		write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_STOP_BREAK);327}328 329 330static void sbd_receive_chars(struct sbd_port *sport)331{332	struct uart_port *uport = &sport->port;333	struct uart_icount *icount;334	unsigned int status;335	int count;336	u8 ch, flag;337 338	for (count = 16; count; count--) {339		status = read_sbdchn(sport, R_DUART_STATUS);340		if (!(status & M_DUART_RX_RDY))341			break;342 343		ch = read_sbdchn(sport, R_DUART_RX_HOLD);344 345		flag = TTY_NORMAL;346 347		icount = &uport->icount;348		icount->rx++;349 350		if (unlikely(status &351			     (M_DUART_RCVD_BRK | M_DUART_FRM_ERR |352			      M_DUART_PARITY_ERR | M_DUART_OVRUN_ERR))) {353			if (status & M_DUART_RCVD_BRK) {354				icount->brk++;355				if (uart_handle_break(uport))356					continue;357			} else if (status & M_DUART_FRM_ERR)358				icount->frame++;359			else if (status & M_DUART_PARITY_ERR)360				icount->parity++;361			if (status & M_DUART_OVRUN_ERR)362				icount->overrun++;363 364			status &= uport->read_status_mask;365			if (status & M_DUART_RCVD_BRK)366				flag = TTY_BREAK;367			else if (status & M_DUART_FRM_ERR)368				flag = TTY_FRAME;369			else if (status & M_DUART_PARITY_ERR)370				flag = TTY_PARITY;371		}372 373		if (uart_handle_sysrq_char(uport, ch))374			continue;375 376		uart_insert_char(uport, status, M_DUART_OVRUN_ERR, ch, flag);377	}378 379	tty_flip_buffer_push(&uport->state->port);380}381 382static void sbd_transmit_chars(struct sbd_port *sport)383{384	struct uart_port *uport = &sport->port;385	struct tty_port *tport = &sport->port.state->port;386	unsigned char ch;387	unsigned int mask;388	int stop_tx;389 390	/* XON/XOFF chars.  */391	if (sport->port.x_char) {392		write_sbdchn(sport, R_DUART_TX_HOLD, sport->port.x_char);393		sport->port.icount.tx++;394		sport->port.x_char = 0;395		return;396	}397 398	/* If nothing to do or stopped or hardware stopped.  */399	stop_tx = uart_tx_stopped(&sport->port) ||400		!uart_fifo_get(&sport->port, &ch);401 402	/* Send char.  */403	if (!stop_tx) {404		write_sbdchn(sport, R_DUART_TX_HOLD, ch);405 406		if (kfifo_len(&tport->xmit_fifo) < WAKEUP_CHARS)407			uart_write_wakeup(&sport->port);408	}409 410	/* Are we are done?  */411	if (stop_tx || kfifo_is_empty(&tport->xmit_fifo)) {412		/* Disable tx interrupts.  */413		mask = read_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2));414		mask &= ~M_DUART_IMR_TX;415		write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), mask);416	}417}418 419static void sbd_status_handle(struct sbd_port *sport)420{421	struct uart_port *uport = &sport->port;422	unsigned int delta;423 424	delta = read_sbdshr(sport, R_DUART_INCHREG((uport->line) % 2));425	delta >>= (uport->line) % 2;426 427	if (delta & (M_DUART_IN_PIN0_VAL << S_DUART_IN_PIN_CHNG))428		uart_handle_cts_change(uport, !(delta & M_DUART_IN_PIN0_VAL));429 430	if (delta & (M_DUART_IN_PIN2_VAL << S_DUART_IN_PIN_CHNG))431		uport->icount.dsr++;432 433	if (delta & ((M_DUART_IN_PIN2_VAL | M_DUART_IN_PIN0_VAL) <<434		     S_DUART_IN_PIN_CHNG))435		wake_up_interruptible(&uport->state->port.delta_msr_wait);436}437 438static irqreturn_t sbd_interrupt(int irq, void *dev_id)439{440	struct sbd_port *sport = dev_id;441	struct uart_port *uport = &sport->port;442	irqreturn_t status = IRQ_NONE;443	unsigned int intstat;444	int count;445 446	for (count = 16; count; count--) {447		intstat = read_sbdshr(sport,448				      R_DUART_ISRREG((uport->line) % 2));449		intstat &= read_sbdshr(sport,450				       R_DUART_IMRREG((uport->line) % 2));451		intstat &= M_DUART_ISR_ALL;452		if (!intstat)453			break;454 455		if (intstat & M_DUART_ISR_RX)456			sbd_receive_chars(sport);457		if (intstat & M_DUART_ISR_IN)458			sbd_status_handle(sport);459		if (intstat & M_DUART_ISR_TX)460			sbd_transmit_chars(sport);461 462		status = IRQ_HANDLED;463	}464 465	return status;466}467 468 469static int sbd_startup(struct uart_port *uport)470{471	struct sbd_port *sport = to_sport(uport);472	unsigned int mode1;473	int ret;474 475	ret = request_irq(sport->port.irq, sbd_interrupt,476			  IRQF_SHARED, "sb1250-duart", sport);477	if (ret)478		return ret;479 480	/* Clear the receive FIFO.  */481	sbd_receive_drain(sport);482 483	/* Clear the interrupt registers.  */484	write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_RESET_BREAK_INT);485	read_sbdshr(sport, R_DUART_INCHREG((uport->line) % 2));486 487	/* Set rx/tx interrupt to FIFO available.  */488	mode1 = read_sbdchn(sport, R_DUART_MODE_REG_1);489	mode1 &= ~(M_DUART_RX_IRQ_SEL_RXFULL | M_DUART_TX_IRQ_SEL_TXEMPT);490	write_sbdchn(sport, R_DUART_MODE_REG_1, mode1);491 492	/* Disable tx, enable rx.  */493	write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_DIS | M_DUART_RX_EN);494	sport->tx_stopped = 1;495 496	/* Enable interrupts.  */497	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2),498		     M_DUART_IMR_IN | M_DUART_IMR_RX);499 500	return 0;501}502 503static void sbd_shutdown(struct uart_port *uport)504{505	struct sbd_port *sport = to_sport(uport);506 507	write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_DIS | M_DUART_RX_DIS);508	sport->tx_stopped = 1;509	free_irq(sport->port.irq, sport);510}511 512 513static void sbd_init_port(struct sbd_port *sport)514{515	struct uart_port *uport = &sport->port;516 517	if (sport->initialised)518		return;519 520	/* There is no DUART reset feature, so just set some sane defaults.  */521	write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_RESET_TX);522	write_sbdchn(sport, R_DUART_CMD, V_DUART_MISC_CMD_RESET_RX);523	write_sbdchn(sport, R_DUART_MODE_REG_1, V_DUART_BITS_PER_CHAR_8);524	write_sbdchn(sport, R_DUART_MODE_REG_2, 0);525	write_sbdchn(sport, R_DUART_FULL_CTL,526		     V_DUART_INT_TIME(0) | V_DUART_SIG_FULL(15));527	write_sbdchn(sport, R_DUART_OPCR_X, 0);528	write_sbdchn(sport, R_DUART_AUXCTL_X, 0);529	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), 0);530 531	sport->initialised = 1;532}533 534static void sbd_set_termios(struct uart_port *uport, struct ktermios *termios,535			    const struct ktermios *old_termios)536{537	struct sbd_port *sport = to_sport(uport);538	unsigned int mode1 = 0, mode2 = 0, aux = 0;539	unsigned int mode1mask = 0, mode2mask = 0, auxmask = 0;540	unsigned int oldmode1, oldmode2, oldaux;541	unsigned int baud, brg;542	unsigned int command;543 544	mode1mask |= ~(M_DUART_PARITY_MODE | M_DUART_PARITY_TYPE_ODD |545		       M_DUART_BITS_PER_CHAR);546	mode2mask |= ~M_DUART_STOP_BIT_LEN_2;547	auxmask |= ~M_DUART_CTS_CHNG_ENA;548 549	/* Byte size.  */550	switch (termios->c_cflag & CSIZE) {551	case CS5:552	case CS6:553		/* Unsupported, leave unchanged.  */554		mode1mask |= M_DUART_PARITY_MODE;555		break;556	case CS7:557		mode1 |= V_DUART_BITS_PER_CHAR_7;558		break;559	case CS8:560	default:561		mode1 |= V_DUART_BITS_PER_CHAR_8;562		break;563	}564 565	/* Parity and stop bits.  */566	if (termios->c_cflag & CSTOPB)567		mode2 |= M_DUART_STOP_BIT_LEN_2;568	else569		mode2 |= M_DUART_STOP_BIT_LEN_1;570	if (termios->c_cflag & PARENB)571		mode1 |= V_DUART_PARITY_MODE_ADD;572	else573		mode1 |= V_DUART_PARITY_MODE_NONE;574	if (termios->c_cflag & PARODD)575		mode1 |= M_DUART_PARITY_TYPE_ODD;576	else577		mode1 |= M_DUART_PARITY_TYPE_EVEN;578 579	baud = uart_get_baud_rate(uport, termios, old_termios, 1200, 5000000);580	brg = V_DUART_BAUD_RATE(baud);581	/* The actual lower bound is 1221bps, so compensate.  */582	if (brg > M_DUART_CLK_COUNTER)583		brg = M_DUART_CLK_COUNTER;584 585	uart_update_timeout(uport, termios->c_cflag, baud);586 587	uport->read_status_mask = M_DUART_OVRUN_ERR;588	if (termios->c_iflag & INPCK)589		uport->read_status_mask |= M_DUART_FRM_ERR |590					   M_DUART_PARITY_ERR;591	if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))592		uport->read_status_mask |= M_DUART_RCVD_BRK;593 594	uport->ignore_status_mask = 0;595	if (termios->c_iflag & IGNPAR)596		uport->ignore_status_mask |= M_DUART_FRM_ERR |597					     M_DUART_PARITY_ERR;598	if (termios->c_iflag & IGNBRK) {599		uport->ignore_status_mask |= M_DUART_RCVD_BRK;600		if (termios->c_iflag & IGNPAR)601			uport->ignore_status_mask |= M_DUART_OVRUN_ERR;602	}603 604	if (termios->c_cflag & CREAD)605		command = M_DUART_RX_EN;606	else607		command = M_DUART_RX_DIS;608 609	if (termios->c_cflag & CRTSCTS)610		aux |= M_DUART_CTS_CHNG_ENA;611	else612		aux &= ~M_DUART_CTS_CHNG_ENA;613 614	uart_port_lock(uport);615 616	if (sport->tx_stopped)617		command |= M_DUART_TX_DIS;618	else619		command |= M_DUART_TX_EN;620 621	oldmode1 = read_sbdchn(sport, R_DUART_MODE_REG_1) & mode1mask;622	oldmode2 = read_sbdchn(sport, R_DUART_MODE_REG_2) & mode2mask;623	oldaux = read_sbdchn(sport, R_DUART_AUXCTL_X) & auxmask;624 625	if (!sport->tx_stopped)626		sbd_line_drain(sport);627	write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_DIS | M_DUART_RX_DIS);628 629	write_sbdchn(sport, R_DUART_MODE_REG_1, mode1 | oldmode1);630	write_sbdchn(sport, R_DUART_MODE_REG_2, mode2 | oldmode2);631	write_sbdchn(sport, R_DUART_CLK_SEL, brg);632	write_sbdchn(sport, R_DUART_AUXCTL_X, aux | oldaux);633 634	write_sbdchn(sport, R_DUART_CMD, command);635 636	uart_port_unlock(uport);637}638 639 640static const char *sbd_type(struct uart_port *uport)641{642	return "SB1250 DUART";643}644 645static void sbd_release_port(struct uart_port *uport)646{647	struct sbd_port *sport = to_sport(uport);648	struct sbd_duart *duart = sport->duart;649 650	iounmap(sport->memctrl);651	sport->memctrl = NULL;652	iounmap(uport->membase);653	uport->membase = NULL;654 655	if(refcount_dec_and_test(&duart->map_guard))656		release_mem_region(duart->mapctrl, DUART_CHANREG_SPACING);657	release_mem_region(uport->mapbase, DUART_CHANREG_SPACING);658}659 660static int sbd_map_port(struct uart_port *uport)661{662	const char *err = KERN_ERR "sbd: Cannot map MMIO\n";663	struct sbd_port *sport = to_sport(uport);664	struct sbd_duart *duart = sport->duart;665 666	if (!uport->membase)667		uport->membase = ioremap(uport->mapbase,668						 DUART_CHANREG_SPACING);669	if (!uport->membase) {670		printk(err);671		return -ENOMEM;672	}673 674	if (!sport->memctrl)675		sport->memctrl = ioremap(duart->mapctrl,676						 DUART_CHANREG_SPACING);677	if (!sport->memctrl) {678		printk(err);679		iounmap(uport->membase);680		uport->membase = NULL;681		return -ENOMEM;682	}683 684	return 0;685}686 687static int sbd_request_port(struct uart_port *uport)688{689	const char *err = KERN_ERR "sbd: Unable to reserve MMIO resource\n";690	struct sbd_duart *duart = to_sport(uport)->duart;691	int ret = 0;692 693	if (!request_mem_region(uport->mapbase, DUART_CHANREG_SPACING,694				"sb1250-duart")) {695		printk(err);696		return -EBUSY;697	}698	refcount_inc(&duart->map_guard);699	if (refcount_read(&duart->map_guard) == 1) {700		if (!request_mem_region(duart->mapctrl, DUART_CHANREG_SPACING,701					"sb1250-duart")) {702			refcount_dec(&duart->map_guard);703			printk(err);704			ret = -EBUSY;705		}706	}707	if (!ret) {708		ret = sbd_map_port(uport);709		if (ret) {710			if (refcount_dec_and_test(&duart->map_guard))711				release_mem_region(duart->mapctrl,712						   DUART_CHANREG_SPACING);713		}714	}715	if (ret) {716		release_mem_region(uport->mapbase, DUART_CHANREG_SPACING);717		return ret;718	}719	return 0;720}721 722static void sbd_config_port(struct uart_port *uport, int flags)723{724	struct sbd_port *sport = to_sport(uport);725 726	if (flags & UART_CONFIG_TYPE) {727		if (sbd_request_port(uport))728			return;729 730		uport->type = PORT_SB1250_DUART;731 732		sbd_init_port(sport);733	}734}735 736static int sbd_verify_port(struct uart_port *uport, struct serial_struct *ser)737{738	int ret = 0;739 740	if (ser->type != PORT_UNKNOWN && ser->type != PORT_SB1250_DUART)741		ret = -EINVAL;742	if (ser->irq != uport->irq)743		ret = -EINVAL;744	if (ser->baud_base != uport->uartclk / 16)745		ret = -EINVAL;746	return ret;747}748 749 750static const struct uart_ops sbd_ops = {751	.tx_empty	= sbd_tx_empty,752	.set_mctrl	= sbd_set_mctrl,753	.get_mctrl	= sbd_get_mctrl,754	.stop_tx	= sbd_stop_tx,755	.start_tx	= sbd_start_tx,756	.stop_rx	= sbd_stop_rx,757	.enable_ms	= sbd_enable_ms,758	.break_ctl	= sbd_break_ctl,759	.startup	= sbd_startup,760	.shutdown	= sbd_shutdown,761	.set_termios	= sbd_set_termios,762	.type		= sbd_type,763	.release_port	= sbd_release_port,764	.request_port	= sbd_request_port,765	.config_port	= sbd_config_port,766	.verify_port	= sbd_verify_port,767};768 769/* Initialize SB1250 DUART port structures.  */770static void __init sbd_probe_duarts(void)771{772	static int probed;773	int chip, side;774	int max_lines, line;775 776	if (probed)777		return;778 779	/* Set the number of available units based on the SOC type.  */780	switch (soc_type) {781	case K_SYS_SOC_TYPE_BCM1x55:782	case K_SYS_SOC_TYPE_BCM1x80:783		max_lines = 4;784		break;785	default:786		/* Assume at least two serial ports at the normal address.  */787		max_lines = 2;788		break;789	}790 791	probed = 1;792 793	for (chip = 0, line = 0; chip < DUART_MAX_CHIP && line < max_lines;794	     chip++) {795		sbd_duarts[chip].mapctrl = SBD_CTRLREGS(line);796 797		for (side = 0; side < DUART_MAX_SIDE && line < max_lines;798		     side++, line++) {799			struct sbd_port *sport = &sbd_duarts[chip].sport[side];800			struct uart_port *uport = &sport->port;801 802			sport->duart	= &sbd_duarts[chip];803 804			uport->irq	= SBD_INT(line);805			uport->uartclk	= 100000000 / 20 * 16;806			uport->fifosize	= 16;807			uport->iotype	= UPIO_MEM;808			uport->flags	= UPF_BOOT_AUTOCONF;809			uport->ops	= &sbd_ops;810			uport->line	= line;811			uport->mapbase	= SBD_CHANREGS(line);812			uport->has_sysrq = IS_ENABLED(CONFIG_SERIAL_SB1250_DUART_CONSOLE);813		}814	}815}816 817 818#ifdef CONFIG_SERIAL_SB1250_DUART_CONSOLE819/*820 * Serial console stuff.  Very basic, polling driver for doing serial821 * console output.  The console_lock is held by the caller, so we822 * shouldn't be interrupted for more console activity.823 */824static void sbd_console_putchar(struct uart_port *uport, unsigned char ch)825{826	struct sbd_port *sport = to_sport(uport);827 828	sbd_transmit_drain(sport);829	write_sbdchn(sport, R_DUART_TX_HOLD, ch);830}831 832static void sbd_console_write(struct console *co, const char *s,833			      unsigned int count)834{835	int chip = co->index / DUART_MAX_SIDE;836	int side = co->index % DUART_MAX_SIDE;837	struct sbd_port *sport = &sbd_duarts[chip].sport[side];838	struct uart_port *uport = &sport->port;839	unsigned long flags;840	unsigned int mask;841 842	/* Disable transmit interrupts and enable the transmitter. */843	uart_port_lock_irqsave(uport, &flags);844	mask = read_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2));845	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2),846		     mask & ~M_DUART_IMR_TX);847	write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_EN);848	uart_port_unlock_irqrestore(uport, flags);849 850	uart_console_write(&sport->port, s, count, sbd_console_putchar);851 852	/* Restore transmit interrupts and the transmitter enable. */853	uart_port_lock_irqsave(uport, &flags);854	sbd_line_drain(sport);855	if (sport->tx_stopped)856		write_sbdchn(sport, R_DUART_CMD, M_DUART_TX_DIS);857	write_sbdshr(sport, R_DUART_IMRREG((uport->line) % 2), mask);858	uart_port_unlock_irqrestore(uport, flags);859}860 861static int __init sbd_console_setup(struct console *co, char *options)862{863	int chip = co->index / DUART_MAX_SIDE;864	int side = co->index % DUART_MAX_SIDE;865	struct sbd_port *sport = &sbd_duarts[chip].sport[side];866	struct uart_port *uport = &sport->port;867	int baud = 115200;868	int bits = 8;869	int parity = 'n';870	int flow = 'n';871	int ret;872 873	if (!sport->duart)874		return -ENXIO;875 876	ret = sbd_map_port(uport);877	if (ret)878		return ret;879 880	sbd_init_port(sport);881 882	if (options)883		uart_parse_options(options, &baud, &parity, &bits, &flow);884	return uart_set_options(uport, co, baud, parity, bits, flow);885}886 887static struct uart_driver sbd_reg;888static struct console sbd_console = {889	.name	= "duart",890	.write	= sbd_console_write,891	.device	= uart_console_device,892	.setup	= sbd_console_setup,893	.flags	= CON_PRINTBUFFER,894	.index	= -1,895	.data	= &sbd_reg896};897 898static int __init sbd_serial_console_init(void)899{900	sbd_probe_duarts();901	register_console(&sbd_console);902 903	return 0;904}905 906console_initcall(sbd_serial_console_init);907 908#define SERIAL_SB1250_DUART_CONSOLE	&sbd_console909#else910#define SERIAL_SB1250_DUART_CONSOLE	NULL911#endif /* CONFIG_SERIAL_SB1250_DUART_CONSOLE */912 913 914static struct uart_driver sbd_reg = {915	.owner		= THIS_MODULE,916	.driver_name	= "sb1250_duart",917	.dev_name	= "duart",918	.major		= TTY_MAJOR,919	.minor		= SB1250_DUART_MINOR_BASE,920	.nr		= DUART_MAX_CHIP * DUART_MAX_SIDE,921	.cons		= SERIAL_SB1250_DUART_CONSOLE,922};923 924/* Set up the driver and register it.  */925static int __init sbd_init(void)926{927	int i, ret;928 929	sbd_probe_duarts();930 931	ret = uart_register_driver(&sbd_reg);932	if (ret)933		return ret;934 935	for (i = 0; i < DUART_MAX_CHIP * DUART_MAX_SIDE; i++) {936		struct sbd_duart *duart = &sbd_duarts[i / DUART_MAX_SIDE];937		struct sbd_port *sport = &duart->sport[i % DUART_MAX_SIDE];938		struct uart_port *uport = &sport->port;939 940		if (sport->duart)941			uart_add_one_port(&sbd_reg, uport);942	}943 944	return 0;945}946 947/* Unload the driver.  Unregister stuff, get ready to go away.  */948static void __exit sbd_exit(void)949{950	int i;951 952	for (i = DUART_MAX_CHIP * DUART_MAX_SIDE - 1; i >= 0; i--) {953		struct sbd_duart *duart = &sbd_duarts[i / DUART_MAX_SIDE];954		struct sbd_port *sport = &duart->sport[i % DUART_MAX_SIDE];955		struct uart_port *uport = &sport->port;956 957		if (sport->duart)958			uart_remove_one_port(&sbd_reg, uport);959	}960 961	uart_unregister_driver(&sbd_reg);962}963 964module_init(sbd_init);965module_exit(sbd_exit);966