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