xref: /openbmc/linux/drivers/tty/serial/arc_uart.c (revision 2ac4ad2a1468123f6bb439a547880a9c0d302e0a)
1*2ac4ad2aSVineet Gupta /*
2*2ac4ad2aSVineet Gupta  * ARC On-Chip(fpga) UART Driver
3*2ac4ad2aSVineet Gupta  *
4*2ac4ad2aSVineet Gupta  * Copyright (C) 2010-2012 Synopsys, Inc. (www.synopsys.com)
5*2ac4ad2aSVineet Gupta  *
6*2ac4ad2aSVineet Gupta  * This program is free software; you can redistribute it and/or modify
7*2ac4ad2aSVineet Gupta  * it under the terms of the GNU General Public License version 2 as
8*2ac4ad2aSVineet Gupta  * published by the Free Software Foundation.
9*2ac4ad2aSVineet Gupta  *
10*2ac4ad2aSVineet Gupta  * vineetg: July 10th 2012
11*2ac4ad2aSVineet Gupta  *  -Decoupled the driver from arch/arc
12*2ac4ad2aSVineet Gupta  *    +Using platform_get_resource() for irq/membase (thx to bfin_uart.c)
13*2ac4ad2aSVineet Gupta  *    +Using early_platform_xxx() for early console (thx to mach-shmobile/xxx)
14*2ac4ad2aSVineet Gupta  *
15*2ac4ad2aSVineet Gupta  * Vineetg: Aug 21st 2010
16*2ac4ad2aSVineet Gupta  *  -Is uart_tx_stopped() not done in tty write path as it has already been
17*2ac4ad2aSVineet Gupta  *   taken care of, in serial core
18*2ac4ad2aSVineet Gupta  *
19*2ac4ad2aSVineet Gupta  * Vineetg: Aug 18th 2010
20*2ac4ad2aSVineet Gupta  *  -New Serial Core based ARC UART driver
21*2ac4ad2aSVineet Gupta  *  -Derived largely from blackfin driver albiet with some major tweaks
22*2ac4ad2aSVineet Gupta  *
23*2ac4ad2aSVineet Gupta  * TODO:
24*2ac4ad2aSVineet Gupta  *  -check if sysreq works
25*2ac4ad2aSVineet Gupta  */
26*2ac4ad2aSVineet Gupta 
27*2ac4ad2aSVineet Gupta #if defined(CONFIG_SERIAL_ARC_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
28*2ac4ad2aSVineet Gupta #define SUPPORT_SYSRQ
29*2ac4ad2aSVineet Gupta #endif
30*2ac4ad2aSVineet Gupta 
31*2ac4ad2aSVineet Gupta #include <linux/module.h>
32*2ac4ad2aSVineet Gupta #include <linux/serial.h>
33*2ac4ad2aSVineet Gupta #include <linux/console.h>
34*2ac4ad2aSVineet Gupta #include <linux/sysrq.h>
35*2ac4ad2aSVineet Gupta #include <linux/platform_device.h>
36*2ac4ad2aSVineet Gupta #include <linux/tty.h>
37*2ac4ad2aSVineet Gupta #include <linux/tty_flip.h>
38*2ac4ad2aSVineet Gupta #include <linux/serial_core.h>
39*2ac4ad2aSVineet Gupta #include <linux/io.h>
40*2ac4ad2aSVineet Gupta 
41*2ac4ad2aSVineet Gupta /*************************************
42*2ac4ad2aSVineet Gupta  * ARC UART Hardware Specs
43*2ac4ad2aSVineet Gupta  ************************************/
44*2ac4ad2aSVineet Gupta #define ARC_UART_TX_FIFO_SIZE  1
45*2ac4ad2aSVineet Gupta 
46*2ac4ad2aSVineet Gupta /*
47*2ac4ad2aSVineet Gupta  * UART Register set (this is not a Standards Compliant IP)
48*2ac4ad2aSVineet Gupta  * Also each reg is Word aligned, but only 8 bits wide
49*2ac4ad2aSVineet Gupta  */
50*2ac4ad2aSVineet Gupta #define R_ID0	0
51*2ac4ad2aSVineet Gupta #define R_ID1	4
52*2ac4ad2aSVineet Gupta #define R_ID2	8
53*2ac4ad2aSVineet Gupta #define R_ID3	12
54*2ac4ad2aSVineet Gupta #define R_DATA	16
55*2ac4ad2aSVineet Gupta #define R_STS	20
56*2ac4ad2aSVineet Gupta #define R_BAUDL	24
57*2ac4ad2aSVineet Gupta #define R_BAUDH	28
58*2ac4ad2aSVineet Gupta 
59*2ac4ad2aSVineet Gupta /* Bits for UART Status Reg (R/W) */
60*2ac4ad2aSVineet Gupta #define RXIENB  0x04	/* Receive Interrupt Enable */
61*2ac4ad2aSVineet Gupta #define TXIENB  0x40	/* Transmit Interrupt Enable */
62*2ac4ad2aSVineet Gupta 
63*2ac4ad2aSVineet Gupta #define RXEMPTY 0x20	/* Receive FIFO Empty: No char receivede */
64*2ac4ad2aSVineet Gupta #define TXEMPTY 0x80	/* Transmit FIFO Empty, thus char can be written into */
65*2ac4ad2aSVineet Gupta 
66*2ac4ad2aSVineet Gupta #define RXFULL  0x08	/* Receive FIFO full */
67*2ac4ad2aSVineet Gupta #define RXFULL1 0x10	/* Receive FIFO has space for 1 char (tot space=4) */
68*2ac4ad2aSVineet Gupta 
69*2ac4ad2aSVineet Gupta #define RXFERR  0x01	/* Frame Error: Stop Bit not detected */
70*2ac4ad2aSVineet Gupta #define RXOERR  0x02	/* OverFlow Err: Char recv but RXFULL still set */
71*2ac4ad2aSVineet Gupta 
72*2ac4ad2aSVineet Gupta /* Uart bit fiddling helpers: lowest level */
73*2ac4ad2aSVineet Gupta #define RBASE(uart, reg)      (uart->port.membase + reg)
74*2ac4ad2aSVineet Gupta #define UART_REG_SET(u, r, v) writeb((v), RBASE(u, r))
75*2ac4ad2aSVineet Gupta #define UART_REG_GET(u, r)    readb(RBASE(u, r))
76*2ac4ad2aSVineet Gupta 
77*2ac4ad2aSVineet Gupta #define UART_REG_OR(u, r, v)  UART_REG_SET(u, r, UART_REG_GET(u, r) | (v))
78*2ac4ad2aSVineet Gupta #define UART_REG_CLR(u, r, v) UART_REG_SET(u, r, UART_REG_GET(u, r) & ~(v))
79*2ac4ad2aSVineet Gupta 
80*2ac4ad2aSVineet Gupta /* Uart bit fiddling helpers: API level */
81*2ac4ad2aSVineet Gupta #define UART_SET_DATA(uart, val)   UART_REG_SET(uart, R_DATA, val)
82*2ac4ad2aSVineet Gupta #define UART_GET_DATA(uart)        UART_REG_GET(uart, R_DATA)
83*2ac4ad2aSVineet Gupta 
84*2ac4ad2aSVineet Gupta #define UART_SET_BAUDH(uart, val)  UART_REG_SET(uart, R_BAUDH, val)
85*2ac4ad2aSVineet Gupta #define UART_SET_BAUDL(uart, val)  UART_REG_SET(uart, R_BAUDL, val)
86*2ac4ad2aSVineet Gupta 
87*2ac4ad2aSVineet Gupta #define UART_CLR_STATUS(uart, val) UART_REG_CLR(uart, R_STS, val)
88*2ac4ad2aSVineet Gupta #define UART_GET_STATUS(uart)      UART_REG_GET(uart, R_STS)
89*2ac4ad2aSVineet Gupta 
90*2ac4ad2aSVineet Gupta #define UART_ALL_IRQ_DISABLE(uart) UART_REG_CLR(uart, R_STS, RXIENB|TXIENB)
91*2ac4ad2aSVineet Gupta #define UART_RX_IRQ_DISABLE(uart)  UART_REG_CLR(uart, R_STS, RXIENB)
92*2ac4ad2aSVineet Gupta #define UART_TX_IRQ_DISABLE(uart)  UART_REG_CLR(uart, R_STS, TXIENB)
93*2ac4ad2aSVineet Gupta 
94*2ac4ad2aSVineet Gupta #define UART_ALL_IRQ_ENABLE(uart)  UART_REG_OR(uart, R_STS, RXIENB|TXIENB)
95*2ac4ad2aSVineet Gupta #define UART_RX_IRQ_ENABLE(uart)   UART_REG_OR(uart, R_STS, RXIENB)
96*2ac4ad2aSVineet Gupta #define UART_TX_IRQ_ENABLE(uart)   UART_REG_OR(uart, R_STS, TXIENB)
97*2ac4ad2aSVineet Gupta 
98*2ac4ad2aSVineet Gupta #define ARC_SERIAL_DEV_NAME	"ttyARC"
99*2ac4ad2aSVineet Gupta 
100*2ac4ad2aSVineet Gupta struct arc_uart_port {
101*2ac4ad2aSVineet Gupta 	struct uart_port port;
102*2ac4ad2aSVineet Gupta 	unsigned long baud;
103*2ac4ad2aSVineet Gupta 	int is_emulated;	/* H/w vs. Instruction Set Simulator */
104*2ac4ad2aSVineet Gupta };
105*2ac4ad2aSVineet Gupta 
106*2ac4ad2aSVineet Gupta #define to_arc_port(uport)  container_of(uport, struct arc_uart_port, port)
107*2ac4ad2aSVineet Gupta 
108*2ac4ad2aSVineet Gupta static struct arc_uart_port arc_uart_ports[CONFIG_SERIAL_ARC_NR_PORTS];
109*2ac4ad2aSVineet Gupta 
110*2ac4ad2aSVineet Gupta #ifdef CONFIG_SERIAL_ARC_CONSOLE
111*2ac4ad2aSVineet Gupta static struct console arc_console;
112*2ac4ad2aSVineet Gupta #endif
113*2ac4ad2aSVineet Gupta 
114*2ac4ad2aSVineet Gupta #define DRIVER_NAME	"arc-uart"
115*2ac4ad2aSVineet Gupta 
116*2ac4ad2aSVineet Gupta static struct uart_driver arc_uart_driver = {
117*2ac4ad2aSVineet Gupta 	.owner		= THIS_MODULE,
118*2ac4ad2aSVineet Gupta 	.driver_name	= DRIVER_NAME,
119*2ac4ad2aSVineet Gupta 	.dev_name	= ARC_SERIAL_DEV_NAME,
120*2ac4ad2aSVineet Gupta 	.major		= 0,
121*2ac4ad2aSVineet Gupta 	.minor		= 0,
122*2ac4ad2aSVineet Gupta 	.nr		= CONFIG_SERIAL_ARC_NR_PORTS,
123*2ac4ad2aSVineet Gupta #ifdef CONFIG_SERIAL_ARC_CONSOLE
124*2ac4ad2aSVineet Gupta 	.cons		= &arc_console,
125*2ac4ad2aSVineet Gupta #endif
126*2ac4ad2aSVineet Gupta };
127*2ac4ad2aSVineet Gupta 
128*2ac4ad2aSVineet Gupta static void arc_serial_stop_rx(struct uart_port *port)
129*2ac4ad2aSVineet Gupta {
130*2ac4ad2aSVineet Gupta 	struct arc_uart_port *uart = to_arc_port(port);
131*2ac4ad2aSVineet Gupta 
132*2ac4ad2aSVineet Gupta 	UART_RX_IRQ_DISABLE(uart);
133*2ac4ad2aSVineet Gupta }
134*2ac4ad2aSVineet Gupta 
135*2ac4ad2aSVineet Gupta static void arc_serial_stop_tx(struct uart_port *port)
136*2ac4ad2aSVineet Gupta {
137*2ac4ad2aSVineet Gupta 	struct arc_uart_port *uart = to_arc_port(port);
138*2ac4ad2aSVineet Gupta 
139*2ac4ad2aSVineet Gupta 	while (!(UART_GET_STATUS(uart) & TXEMPTY))
140*2ac4ad2aSVineet Gupta 		cpu_relax();
141*2ac4ad2aSVineet Gupta 
142*2ac4ad2aSVineet Gupta 	UART_TX_IRQ_DISABLE(uart);
143*2ac4ad2aSVineet Gupta }
144*2ac4ad2aSVineet Gupta 
145*2ac4ad2aSVineet Gupta /*
146*2ac4ad2aSVineet Gupta  * Return TIOCSER_TEMT when transmitter is not busy.
147*2ac4ad2aSVineet Gupta  */
148*2ac4ad2aSVineet Gupta static unsigned int arc_serial_tx_empty(struct uart_port *port)
149*2ac4ad2aSVineet Gupta {
150*2ac4ad2aSVineet Gupta 	struct arc_uart_port *uart = to_arc_port(port);
151*2ac4ad2aSVineet Gupta 	unsigned int stat;
152*2ac4ad2aSVineet Gupta 
153*2ac4ad2aSVineet Gupta 	stat = UART_GET_STATUS(uart);
154*2ac4ad2aSVineet Gupta 	if (stat & TXEMPTY)
155*2ac4ad2aSVineet Gupta 		return TIOCSER_TEMT;
156*2ac4ad2aSVineet Gupta 
157*2ac4ad2aSVineet Gupta 	return 0;
158*2ac4ad2aSVineet Gupta }
159*2ac4ad2aSVineet Gupta 
160*2ac4ad2aSVineet Gupta /*
161*2ac4ad2aSVineet Gupta  * Driver internal routine, used by both tty(serial core) as well as tx-isr
162*2ac4ad2aSVineet Gupta  *  -Called under spinlock in either cases
163*2ac4ad2aSVineet Gupta  *  -also tty->stopped / tty->hw_stopped has already been checked
164*2ac4ad2aSVineet Gupta  *     = by uart_start( ) before calling us
165*2ac4ad2aSVineet Gupta  *     = tx_ist checks that too before calling
166*2ac4ad2aSVineet Gupta  */
167*2ac4ad2aSVineet Gupta static void arc_serial_tx_chars(struct arc_uart_port *uart)
168*2ac4ad2aSVineet Gupta {
169*2ac4ad2aSVineet Gupta 	struct circ_buf *xmit = &uart->port.state->xmit;
170*2ac4ad2aSVineet Gupta 	int sent = 0;
171*2ac4ad2aSVineet Gupta 	unsigned char ch;
172*2ac4ad2aSVineet Gupta 
173*2ac4ad2aSVineet Gupta 	if (unlikely(uart->port.x_char)) {
174*2ac4ad2aSVineet Gupta 		UART_SET_DATA(uart, uart->port.x_char);
175*2ac4ad2aSVineet Gupta 		uart->port.icount.tx++;
176*2ac4ad2aSVineet Gupta 		uart->port.x_char = 0;
177*2ac4ad2aSVineet Gupta 		sent = 1;
178*2ac4ad2aSVineet Gupta 	} else if (xmit->tail != xmit->head) {	/* TODO: uart_circ_empty */
179*2ac4ad2aSVineet Gupta 		ch = xmit->buf[xmit->tail];
180*2ac4ad2aSVineet Gupta 		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
181*2ac4ad2aSVineet Gupta 		uart->port.icount.tx++;
182*2ac4ad2aSVineet Gupta 		while (!(UART_GET_STATUS(uart) & TXEMPTY))
183*2ac4ad2aSVineet Gupta 			cpu_relax();
184*2ac4ad2aSVineet Gupta 		UART_SET_DATA(uart, ch);
185*2ac4ad2aSVineet Gupta 		sent = 1;
186*2ac4ad2aSVineet Gupta 	}
187*2ac4ad2aSVineet Gupta 
188*2ac4ad2aSVineet Gupta 	/*
189*2ac4ad2aSVineet Gupta 	 * If num chars in xmit buffer are too few, ask tty layer for more.
190*2ac4ad2aSVineet Gupta 	 * By Hard ISR to schedule processing in software interrupt part
191*2ac4ad2aSVineet Gupta 	 */
192*2ac4ad2aSVineet Gupta 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
193*2ac4ad2aSVineet Gupta 		uart_write_wakeup(&uart->port);
194*2ac4ad2aSVineet Gupta 
195*2ac4ad2aSVineet Gupta 	if (sent)
196*2ac4ad2aSVineet Gupta 		UART_TX_IRQ_ENABLE(uart);
197*2ac4ad2aSVineet Gupta }
198*2ac4ad2aSVineet Gupta 
199*2ac4ad2aSVineet Gupta /*
200*2ac4ad2aSVineet Gupta  * port is locked and interrupts are disabled
201*2ac4ad2aSVineet Gupta  * uart_start( ) calls us under the port spinlock irqsave
202*2ac4ad2aSVineet Gupta  */
203*2ac4ad2aSVineet Gupta static void arc_serial_start_tx(struct uart_port *port)
204*2ac4ad2aSVineet Gupta {
205*2ac4ad2aSVineet Gupta 	struct arc_uart_port *uart = to_arc_port(port);
206*2ac4ad2aSVineet Gupta 
207*2ac4ad2aSVineet Gupta 	arc_serial_tx_chars(uart);
208*2ac4ad2aSVineet Gupta }
209*2ac4ad2aSVineet Gupta 
210*2ac4ad2aSVineet Gupta static void arc_serial_rx_chars(struct arc_uart_port *uart)
211*2ac4ad2aSVineet Gupta {
212*2ac4ad2aSVineet Gupta 	struct tty_struct *tty = tty_port_tty_get(&uart->port.state->port);
213*2ac4ad2aSVineet Gupta 	unsigned int status, ch, flg = 0;
214*2ac4ad2aSVineet Gupta 
215*2ac4ad2aSVineet Gupta 	if (!tty)
216*2ac4ad2aSVineet Gupta 		return;
217*2ac4ad2aSVineet Gupta 
218*2ac4ad2aSVineet Gupta 	/*
219*2ac4ad2aSVineet Gupta 	 * UART has 4 deep RX-FIFO. Driver's recongnition of this fact
220*2ac4ad2aSVineet Gupta 	 * is very subtle. Here's how ...
221*2ac4ad2aSVineet Gupta 	 * Upon getting a RX-Intr, such that RX-EMPTY=0, meaning data available,
222*2ac4ad2aSVineet Gupta 	 * driver reads the DATA Reg and keeps doing that in a loop, until
223*2ac4ad2aSVineet Gupta 	 * RX-EMPTY=1. Multiple chars being avail, with a single Interrupt,
224*2ac4ad2aSVineet Gupta 	 * before RX-EMPTY=0, implies some sort of buffering going on in the
225*2ac4ad2aSVineet Gupta 	 * controller, which is indeed the Rx-FIFO.
226*2ac4ad2aSVineet Gupta 	 */
227*2ac4ad2aSVineet Gupta 	while (!((status = UART_GET_STATUS(uart)) & RXEMPTY)) {
228*2ac4ad2aSVineet Gupta 
229*2ac4ad2aSVineet Gupta 		ch = UART_GET_DATA(uart);
230*2ac4ad2aSVineet Gupta 		uart->port.icount.rx++;
231*2ac4ad2aSVineet Gupta 
232*2ac4ad2aSVineet Gupta 		if (unlikely(status & (RXOERR | RXFERR))) {
233*2ac4ad2aSVineet Gupta 			if (status & RXOERR) {
234*2ac4ad2aSVineet Gupta 				uart->port.icount.overrun++;
235*2ac4ad2aSVineet Gupta 				flg = TTY_OVERRUN;
236*2ac4ad2aSVineet Gupta 				UART_CLR_STATUS(uart, RXOERR);
237*2ac4ad2aSVineet Gupta 			}
238*2ac4ad2aSVineet Gupta 
239*2ac4ad2aSVineet Gupta 			if (status & RXFERR) {
240*2ac4ad2aSVineet Gupta 				uart->port.icount.frame++;
241*2ac4ad2aSVineet Gupta 				flg = TTY_FRAME;
242*2ac4ad2aSVineet Gupta 				UART_CLR_STATUS(uart, RXFERR);
243*2ac4ad2aSVineet Gupta 			}
244*2ac4ad2aSVineet Gupta 		} else
245*2ac4ad2aSVineet Gupta 			flg = TTY_NORMAL;
246*2ac4ad2aSVineet Gupta 
247*2ac4ad2aSVineet Gupta 		if (unlikely(uart_handle_sysrq_char(&uart->port, ch)))
248*2ac4ad2aSVineet Gupta 			goto done;
249*2ac4ad2aSVineet Gupta 
250*2ac4ad2aSVineet Gupta 		uart_insert_char(&uart->port, status, RXOERR, ch, flg);
251*2ac4ad2aSVineet Gupta 
252*2ac4ad2aSVineet Gupta done:
253*2ac4ad2aSVineet Gupta 		tty_flip_buffer_push(tty);
254*2ac4ad2aSVineet Gupta 	}
255*2ac4ad2aSVineet Gupta 
256*2ac4ad2aSVineet Gupta 	tty_kref_put(tty);
257*2ac4ad2aSVineet Gupta }
258*2ac4ad2aSVineet Gupta 
259*2ac4ad2aSVineet Gupta /*
260*2ac4ad2aSVineet Gupta  * A note on the Interrupt handling state machine of this driver
261*2ac4ad2aSVineet Gupta  *
262*2ac4ad2aSVineet Gupta  * kernel printk writes funnel thru the console driver framework and in order
263*2ac4ad2aSVineet Gupta  * to keep things simple as well as efficient, it writes to UART in polled
264*2ac4ad2aSVineet Gupta  * mode, in one shot, and exits.
265*2ac4ad2aSVineet Gupta  *
266*2ac4ad2aSVineet Gupta  * OTOH, Userland output (via tty layer), uses interrupt based writes as there
267*2ac4ad2aSVineet Gupta  * can be undeterministic delay between char writes.
268*2ac4ad2aSVineet Gupta  *
269*2ac4ad2aSVineet Gupta  * Thus Rx-interrupts are always enabled, while tx-interrupts are by default
270*2ac4ad2aSVineet Gupta  * disabled.
271*2ac4ad2aSVineet Gupta  *
272*2ac4ad2aSVineet Gupta  * When tty has some data to send out, serial core calls driver's start_tx
273*2ac4ad2aSVineet Gupta  * which
274*2ac4ad2aSVineet Gupta  *   -checks-if-tty-buffer-has-char-to-send
275*2ac4ad2aSVineet Gupta  *   -writes-data-to-uart
276*2ac4ad2aSVineet Gupta  *   -enable-tx-intr
277*2ac4ad2aSVineet Gupta  *
278*2ac4ad2aSVineet Gupta  * Once data bits are pushed out, controller raises the Tx-room-avail-Interrupt.
279*2ac4ad2aSVineet Gupta  * The first thing Tx ISR does is disable further Tx interrupts (as this could
280*2ac4ad2aSVineet Gupta  * be the last char to send, before settling down into the quiet polled mode).
281*2ac4ad2aSVineet Gupta  * It then calls the exact routine used by tty layer write to send out any
282*2ac4ad2aSVineet Gupta  * more char in tty buffer. In case of sending, it re-enables Tx-intr. In case
283*2ac4ad2aSVineet Gupta  * of no data, it remains disabled.
284*2ac4ad2aSVineet Gupta  * This is how the transmit state machine is dynamically switched on/off
285*2ac4ad2aSVineet Gupta  */
286*2ac4ad2aSVineet Gupta 
287*2ac4ad2aSVineet Gupta static irqreturn_t arc_serial_isr(int irq, void *dev_id)
288*2ac4ad2aSVineet Gupta {
289*2ac4ad2aSVineet Gupta 	struct arc_uart_port *uart = dev_id;
290*2ac4ad2aSVineet Gupta 	unsigned int status;
291*2ac4ad2aSVineet Gupta 
292*2ac4ad2aSVineet Gupta 	status = UART_GET_STATUS(uart);
293*2ac4ad2aSVineet Gupta 
294*2ac4ad2aSVineet Gupta 	/*
295*2ac4ad2aSVineet Gupta 	 * Single IRQ for both Rx (data available) Tx (room available) Interrupt
296*2ac4ad2aSVineet Gupta 	 * notifications from the UART Controller.
297*2ac4ad2aSVineet Gupta 	 * To demultiplex between the two, we check the relevant bits
298*2ac4ad2aSVineet Gupta 	 */
299*2ac4ad2aSVineet Gupta 	if ((status & RXIENB) && !(status & RXEMPTY)) {
300*2ac4ad2aSVineet Gupta 
301*2ac4ad2aSVineet Gupta 		/* already in ISR, no need of xx_irqsave */
302*2ac4ad2aSVineet Gupta 		spin_lock(&uart->port.lock);
303*2ac4ad2aSVineet Gupta 		arc_serial_rx_chars(uart);
304*2ac4ad2aSVineet Gupta 		spin_unlock(&uart->port.lock);
305*2ac4ad2aSVineet Gupta 	}
306*2ac4ad2aSVineet Gupta 
307*2ac4ad2aSVineet Gupta 	if ((status & TXIENB) && (status & TXEMPTY)) {
308*2ac4ad2aSVineet Gupta 
309*2ac4ad2aSVineet Gupta 		/* Unconditionally disable further Tx-Interrupts.
310*2ac4ad2aSVineet Gupta 		 * will be enabled by tx_chars() if needed.
311*2ac4ad2aSVineet Gupta 		 */
312*2ac4ad2aSVineet Gupta 		UART_TX_IRQ_DISABLE(uart);
313*2ac4ad2aSVineet Gupta 
314*2ac4ad2aSVineet Gupta 		spin_lock(&uart->port.lock);
315*2ac4ad2aSVineet Gupta 
316*2ac4ad2aSVineet Gupta 		if (!uart_tx_stopped(&uart->port))
317*2ac4ad2aSVineet Gupta 			arc_serial_tx_chars(uart);
318*2ac4ad2aSVineet Gupta 
319*2ac4ad2aSVineet Gupta 		spin_unlock(&uart->port.lock);
320*2ac4ad2aSVineet Gupta 	}
321*2ac4ad2aSVineet Gupta 
322*2ac4ad2aSVineet Gupta 	return IRQ_HANDLED;
323*2ac4ad2aSVineet Gupta }
324*2ac4ad2aSVineet Gupta 
325*2ac4ad2aSVineet Gupta static unsigned int arc_serial_get_mctrl(struct uart_port *port)
326*2ac4ad2aSVineet Gupta {
327*2ac4ad2aSVineet Gupta 	/*
328*2ac4ad2aSVineet Gupta 	 * Pretend we have a Modem status reg and following bits are
329*2ac4ad2aSVineet Gupta 	 *  always set, to satify the serial core state machine
330*2ac4ad2aSVineet Gupta 	 *  (DSR) Data Set Ready
331*2ac4ad2aSVineet Gupta 	 *  (CTS) Clear To Send
332*2ac4ad2aSVineet Gupta 	 *  (CAR) Carrier Detect
333*2ac4ad2aSVineet Gupta 	 */
334*2ac4ad2aSVineet Gupta 	return TIOCM_CTS | TIOCM_DSR | TIOCM_CAR;
335*2ac4ad2aSVineet Gupta }
336*2ac4ad2aSVineet Gupta 
337*2ac4ad2aSVineet Gupta static void arc_serial_set_mctrl(struct uart_port *port, unsigned int mctrl)
338*2ac4ad2aSVineet Gupta {
339*2ac4ad2aSVineet Gupta 	/* MCR not present */
340*2ac4ad2aSVineet Gupta }
341*2ac4ad2aSVineet Gupta 
342*2ac4ad2aSVineet Gupta /* Enable Modem Status Interrupts */
343*2ac4ad2aSVineet Gupta 
344*2ac4ad2aSVineet Gupta static void arc_serial_enable_ms(struct uart_port *port)
345*2ac4ad2aSVineet Gupta {
346*2ac4ad2aSVineet Gupta 	/* MSR not present */
347*2ac4ad2aSVineet Gupta }
348*2ac4ad2aSVineet Gupta 
349*2ac4ad2aSVineet Gupta static void arc_serial_break_ctl(struct uart_port *port, int break_state)
350*2ac4ad2aSVineet Gupta {
351*2ac4ad2aSVineet Gupta 	/* ARC UART doesn't support sending Break signal */
352*2ac4ad2aSVineet Gupta }
353*2ac4ad2aSVineet Gupta 
354*2ac4ad2aSVineet Gupta static int arc_serial_startup(struct uart_port *port)
355*2ac4ad2aSVineet Gupta {
356*2ac4ad2aSVineet Gupta 	struct arc_uart_port *uart = to_arc_port(port);
357*2ac4ad2aSVineet Gupta 
358*2ac4ad2aSVineet Gupta 	/* Before we hook up the ISR, Disable all UART Interrupts */
359*2ac4ad2aSVineet Gupta 	UART_ALL_IRQ_DISABLE(uart);
360*2ac4ad2aSVineet Gupta 
361*2ac4ad2aSVineet Gupta 	if (request_irq(uart->port.irq, arc_serial_isr, 0, "arc uart rx-tx",
362*2ac4ad2aSVineet Gupta 			uart)) {
363*2ac4ad2aSVineet Gupta 		dev_warn(uart->port.dev, "Unable to attach ARC UART intr\n");
364*2ac4ad2aSVineet Gupta 		return -EBUSY;
365*2ac4ad2aSVineet Gupta 	}
366*2ac4ad2aSVineet Gupta 
367*2ac4ad2aSVineet Gupta 	UART_RX_IRQ_ENABLE(uart); /* Only Rx IRQ enabled to begin with */
368*2ac4ad2aSVineet Gupta 
369*2ac4ad2aSVineet Gupta 	return 0;
370*2ac4ad2aSVineet Gupta }
371*2ac4ad2aSVineet Gupta 
372*2ac4ad2aSVineet Gupta /* This is not really needed */
373*2ac4ad2aSVineet Gupta static void arc_serial_shutdown(struct uart_port *port)
374*2ac4ad2aSVineet Gupta {
375*2ac4ad2aSVineet Gupta 	struct arc_uart_port *uart = to_arc_port(port);
376*2ac4ad2aSVineet Gupta 	free_irq(uart->port.irq, uart);
377*2ac4ad2aSVineet Gupta }
378*2ac4ad2aSVineet Gupta 
379*2ac4ad2aSVineet Gupta static void
380*2ac4ad2aSVineet Gupta arc_serial_set_termios(struct uart_port *port, struct ktermios *new,
381*2ac4ad2aSVineet Gupta 		       struct ktermios *old)
382*2ac4ad2aSVineet Gupta {
383*2ac4ad2aSVineet Gupta 	struct arc_uart_port *uart = to_arc_port(port);
384*2ac4ad2aSVineet Gupta 	unsigned int baud, uartl, uarth, hw_val;
385*2ac4ad2aSVineet Gupta 	unsigned long flags;
386*2ac4ad2aSVineet Gupta 
387*2ac4ad2aSVineet Gupta 	/*
388*2ac4ad2aSVineet Gupta 	 * Use the generic handler so that any specially encoded baud rates
389*2ac4ad2aSVineet Gupta 	 * such as SPD_xx flags or "%B0" can be handled
390*2ac4ad2aSVineet Gupta 	 * Max Baud I suppose will not be more than current 115K * 4
391*2ac4ad2aSVineet Gupta 	 * Formula for ARC UART is: hw-val = ((CLK/(BAUD*4)) -1)
392*2ac4ad2aSVineet Gupta 	 * spread over two 8-bit registers
393*2ac4ad2aSVineet Gupta 	 */
394*2ac4ad2aSVineet Gupta 	baud = uart_get_baud_rate(port, new, old, 0, 460800);
395*2ac4ad2aSVineet Gupta 
396*2ac4ad2aSVineet Gupta 	hw_val = port->uartclk / (uart->baud * 4) - 1;
397*2ac4ad2aSVineet Gupta 	uartl = hw_val & 0xFF;
398*2ac4ad2aSVineet Gupta 	uarth = (hw_val >> 8) & 0xFF;
399*2ac4ad2aSVineet Gupta 
400*2ac4ad2aSVineet Gupta 	/*
401*2ac4ad2aSVineet Gupta 	 * UART ISS(Instruction Set simulator) emulation has a subtle bug:
402*2ac4ad2aSVineet Gupta 	 * A existing value of Baudh = 0 is used as a indication to startup
403*2ac4ad2aSVineet Gupta 	 * it's internal state machine.
404*2ac4ad2aSVineet Gupta 	 * Thus if baudh is set to 0, 2 times, it chokes.
405*2ac4ad2aSVineet Gupta 	 * This happens with BAUD=115200 and the formaula above
406*2ac4ad2aSVineet Gupta 	 * Until that is fixed, when running on ISS, we will set baudh to !0
407*2ac4ad2aSVineet Gupta 	 */
408*2ac4ad2aSVineet Gupta 	if (uart->is_emulated)
409*2ac4ad2aSVineet Gupta 		uarth = 1;
410*2ac4ad2aSVineet Gupta 
411*2ac4ad2aSVineet Gupta 	spin_lock_irqsave(&port->lock, flags);
412*2ac4ad2aSVineet Gupta 
413*2ac4ad2aSVineet Gupta 	UART_ALL_IRQ_DISABLE(uart);
414*2ac4ad2aSVineet Gupta 
415*2ac4ad2aSVineet Gupta 	UART_SET_BAUDL(uart, uartl);
416*2ac4ad2aSVineet Gupta 	UART_SET_BAUDH(uart, uarth);
417*2ac4ad2aSVineet Gupta 
418*2ac4ad2aSVineet Gupta 	UART_RX_IRQ_ENABLE(uart);
419*2ac4ad2aSVineet Gupta 
420*2ac4ad2aSVineet Gupta 	/*
421*2ac4ad2aSVineet Gupta 	 * UART doesn't support Parity/Hardware Flow Control;
422*2ac4ad2aSVineet Gupta 	 * Only supports 8N1 character size
423*2ac4ad2aSVineet Gupta 	 */
424*2ac4ad2aSVineet Gupta 	new->c_cflag &= ~(CMSPAR|CRTSCTS|CSIZE);
425*2ac4ad2aSVineet Gupta 	new->c_cflag |= CS8;
426*2ac4ad2aSVineet Gupta 
427*2ac4ad2aSVineet Gupta 	if (old)
428*2ac4ad2aSVineet Gupta 		tty_termios_copy_hw(new, old);
429*2ac4ad2aSVineet Gupta 
430*2ac4ad2aSVineet Gupta 	/* Don't rewrite B0 */
431*2ac4ad2aSVineet Gupta 	if (tty_termios_baud_rate(new))
432*2ac4ad2aSVineet Gupta 		tty_termios_encode_baud_rate(new, baud, baud);
433*2ac4ad2aSVineet Gupta 
434*2ac4ad2aSVineet Gupta 	uart_update_timeout(port, new->c_cflag, baud);
435*2ac4ad2aSVineet Gupta 
436*2ac4ad2aSVineet Gupta 	spin_unlock_irqrestore(&port->lock, flags);
437*2ac4ad2aSVineet Gupta }
438*2ac4ad2aSVineet Gupta 
439*2ac4ad2aSVineet Gupta static const char *arc_serial_type(struct uart_port *port)
440*2ac4ad2aSVineet Gupta {
441*2ac4ad2aSVineet Gupta 	struct arc_uart_port *uart = to_arc_port(port);
442*2ac4ad2aSVineet Gupta 
443*2ac4ad2aSVineet Gupta 	return uart->port.type == PORT_ARC ? DRIVER_NAME : NULL;
444*2ac4ad2aSVineet Gupta }
445*2ac4ad2aSVineet Gupta 
446*2ac4ad2aSVineet Gupta static void arc_serial_release_port(struct uart_port *port)
447*2ac4ad2aSVineet Gupta {
448*2ac4ad2aSVineet Gupta }
449*2ac4ad2aSVineet Gupta 
450*2ac4ad2aSVineet Gupta static int arc_serial_request_port(struct uart_port *port)
451*2ac4ad2aSVineet Gupta {
452*2ac4ad2aSVineet Gupta 	return 0;
453*2ac4ad2aSVineet Gupta }
454*2ac4ad2aSVineet Gupta 
455*2ac4ad2aSVineet Gupta /*
456*2ac4ad2aSVineet Gupta  * Verify the new serial_struct (for TIOCSSERIAL).
457*2ac4ad2aSVineet Gupta  */
458*2ac4ad2aSVineet Gupta static int
459*2ac4ad2aSVineet Gupta arc_serial_verify_port(struct uart_port *port, struct serial_struct *ser)
460*2ac4ad2aSVineet Gupta {
461*2ac4ad2aSVineet Gupta 	if (port->type != PORT_UNKNOWN && ser->type != PORT_ARC)
462*2ac4ad2aSVineet Gupta 		return -EINVAL;
463*2ac4ad2aSVineet Gupta 
464*2ac4ad2aSVineet Gupta 	return 0;
465*2ac4ad2aSVineet Gupta }
466*2ac4ad2aSVineet Gupta 
467*2ac4ad2aSVineet Gupta /*
468*2ac4ad2aSVineet Gupta  * Configure/autoconfigure the port.
469*2ac4ad2aSVineet Gupta  */
470*2ac4ad2aSVineet Gupta static void arc_serial_config_port(struct uart_port *port, int flags)
471*2ac4ad2aSVineet Gupta {
472*2ac4ad2aSVineet Gupta 	struct arc_uart_port *uart = to_arc_port(port);
473*2ac4ad2aSVineet Gupta 
474*2ac4ad2aSVineet Gupta 	if (flags & UART_CONFIG_TYPE)
475*2ac4ad2aSVineet Gupta 		uart->port.type = PORT_ARC;
476*2ac4ad2aSVineet Gupta }
477*2ac4ad2aSVineet Gupta 
478*2ac4ad2aSVineet Gupta #if defined(CONFIG_CONSOLE_POLL) || defined(CONFIG_SERIAL_ARC_CONSOLE)
479*2ac4ad2aSVineet Gupta 
480*2ac4ad2aSVineet Gupta static void arc_serial_poll_putchar(struct uart_port *port, unsigned char chr)
481*2ac4ad2aSVineet Gupta {
482*2ac4ad2aSVineet Gupta 	struct arc_uart_port *uart = to_arc_port(port);
483*2ac4ad2aSVineet Gupta 
484*2ac4ad2aSVineet Gupta 	while (!(UART_GET_STATUS(uart) & TXEMPTY))
485*2ac4ad2aSVineet Gupta 		cpu_relax();
486*2ac4ad2aSVineet Gupta 
487*2ac4ad2aSVineet Gupta 	UART_SET_DATA(uart, chr);
488*2ac4ad2aSVineet Gupta }
489*2ac4ad2aSVineet Gupta #endif
490*2ac4ad2aSVineet Gupta 
491*2ac4ad2aSVineet Gupta #ifdef CONFIG_CONSOLE_POLL
492*2ac4ad2aSVineet Gupta static int arc_serial_poll_getchar(struct uart_port *port)
493*2ac4ad2aSVineet Gupta {
494*2ac4ad2aSVineet Gupta 	struct arc_uart_port *uart = to_arc_port(port);
495*2ac4ad2aSVineet Gupta 	unsigned char chr;
496*2ac4ad2aSVineet Gupta 
497*2ac4ad2aSVineet Gupta 	while (!(UART_GET_STATUS(uart) & RXEMPTY))
498*2ac4ad2aSVineet Gupta 		cpu_relax();
499*2ac4ad2aSVineet Gupta 
500*2ac4ad2aSVineet Gupta 	chr = UART_GET_DATA(uart);
501*2ac4ad2aSVineet Gupta 	return chr;
502*2ac4ad2aSVineet Gupta }
503*2ac4ad2aSVineet Gupta #endif
504*2ac4ad2aSVineet Gupta 
505*2ac4ad2aSVineet Gupta static struct uart_ops arc_serial_pops = {
506*2ac4ad2aSVineet Gupta 	.tx_empty	= arc_serial_tx_empty,
507*2ac4ad2aSVineet Gupta 	.set_mctrl	= arc_serial_set_mctrl,
508*2ac4ad2aSVineet Gupta 	.get_mctrl	= arc_serial_get_mctrl,
509*2ac4ad2aSVineet Gupta 	.stop_tx	= arc_serial_stop_tx,
510*2ac4ad2aSVineet Gupta 	.start_tx	= arc_serial_start_tx,
511*2ac4ad2aSVineet Gupta 	.stop_rx	= arc_serial_stop_rx,
512*2ac4ad2aSVineet Gupta 	.enable_ms	= arc_serial_enable_ms,
513*2ac4ad2aSVineet Gupta 	.break_ctl	= arc_serial_break_ctl,
514*2ac4ad2aSVineet Gupta 	.startup	= arc_serial_startup,
515*2ac4ad2aSVineet Gupta 	.shutdown	= arc_serial_shutdown,
516*2ac4ad2aSVineet Gupta 	.set_termios	= arc_serial_set_termios,
517*2ac4ad2aSVineet Gupta 	.type		= arc_serial_type,
518*2ac4ad2aSVineet Gupta 	.release_port	= arc_serial_release_port,
519*2ac4ad2aSVineet Gupta 	.request_port	= arc_serial_request_port,
520*2ac4ad2aSVineet Gupta 	.config_port	= arc_serial_config_port,
521*2ac4ad2aSVineet Gupta 	.verify_port	= arc_serial_verify_port,
522*2ac4ad2aSVineet Gupta #ifdef CONFIG_CONSOLE_POLL
523*2ac4ad2aSVineet Gupta 	.poll_put_char = arc_serial_poll_putchar,
524*2ac4ad2aSVineet Gupta 	.poll_get_char = arc_serial_poll_getchar,
525*2ac4ad2aSVineet Gupta #endif
526*2ac4ad2aSVineet Gupta };
527*2ac4ad2aSVineet Gupta 
528*2ac4ad2aSVineet Gupta static int __devinit
529*2ac4ad2aSVineet Gupta arc_uart_init_one(struct platform_device *pdev, struct arc_uart_port *uart)
530*2ac4ad2aSVineet Gupta {
531*2ac4ad2aSVineet Gupta 	struct resource *res, *res2;
532*2ac4ad2aSVineet Gupta 	unsigned long *plat_data;
533*2ac4ad2aSVineet Gupta 
534*2ac4ad2aSVineet Gupta 	if (pdev->id < 0 || pdev->id >= CONFIG_SERIAL_ARC_NR_PORTS) {
535*2ac4ad2aSVineet Gupta 		dev_err(&pdev->dev, "Wrong uart platform device id.\n");
536*2ac4ad2aSVineet Gupta 		return -ENOENT;
537*2ac4ad2aSVineet Gupta 	}
538*2ac4ad2aSVineet Gupta 
539*2ac4ad2aSVineet Gupta 	plat_data = ((unsigned long *)(pdev->dev.platform_data));
540*2ac4ad2aSVineet Gupta 	uart->baud = plat_data[0];
541*2ac4ad2aSVineet Gupta 
542*2ac4ad2aSVineet Gupta 	res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
543*2ac4ad2aSVineet Gupta 	if (!res)
544*2ac4ad2aSVineet Gupta 		return -ENODEV;
545*2ac4ad2aSVineet Gupta 
546*2ac4ad2aSVineet Gupta 	res2 = platform_get_resource(pdev, IORESOURCE_IRQ, 0);
547*2ac4ad2aSVineet Gupta 	if (!res2)
548*2ac4ad2aSVineet Gupta 		return -ENODEV;
549*2ac4ad2aSVineet Gupta 
550*2ac4ad2aSVineet Gupta 	uart->port.mapbase = res->start;
551*2ac4ad2aSVineet Gupta 	uart->port.membase = ioremap_nocache(res->start, resource_size(res));
552*2ac4ad2aSVineet Gupta 	if (!uart->port.membase)
553*2ac4ad2aSVineet Gupta 		/* No point of dev_err since UART itself is hosed here */
554*2ac4ad2aSVineet Gupta 		return -ENXIO;
555*2ac4ad2aSVineet Gupta 
556*2ac4ad2aSVineet Gupta 	uart->port.irq = res2->start;
557*2ac4ad2aSVineet Gupta 	uart->port.dev = &pdev->dev;
558*2ac4ad2aSVineet Gupta 	uart->port.iotype = UPIO_MEM;
559*2ac4ad2aSVineet Gupta 	uart->port.flags = UPF_BOOT_AUTOCONF;
560*2ac4ad2aSVineet Gupta 	uart->port.line = pdev->id;
561*2ac4ad2aSVineet Gupta 	uart->port.ops = &arc_serial_pops;
562*2ac4ad2aSVineet Gupta 
563*2ac4ad2aSVineet Gupta 	uart->port.uartclk = plat_data[1];
564*2ac4ad2aSVineet Gupta 	uart->port.fifosize = ARC_UART_TX_FIFO_SIZE;
565*2ac4ad2aSVineet Gupta 
566*2ac4ad2aSVineet Gupta 	/*
567*2ac4ad2aSVineet Gupta 	 * uart_insert_char( ) uses it in decideding whether to ignore a
568*2ac4ad2aSVineet Gupta 	 * char or not. Explicitly setting it here, removes the subtelty
569*2ac4ad2aSVineet Gupta 	 */
570*2ac4ad2aSVineet Gupta 	uart->port.ignore_status_mask = 0;
571*2ac4ad2aSVineet Gupta 
572*2ac4ad2aSVineet Gupta 	/* Real Hardware vs. emulated to work around a bug */
573*2ac4ad2aSVineet Gupta 	uart->is_emulated = !!plat_data[2];
574*2ac4ad2aSVineet Gupta 
575*2ac4ad2aSVineet Gupta 	return 0;
576*2ac4ad2aSVineet Gupta }
577*2ac4ad2aSVineet Gupta 
578*2ac4ad2aSVineet Gupta #ifdef CONFIG_SERIAL_ARC_CONSOLE
579*2ac4ad2aSVineet Gupta 
580*2ac4ad2aSVineet Gupta static int __devinit arc_serial_console_setup(struct console *co, char *options)
581*2ac4ad2aSVineet Gupta {
582*2ac4ad2aSVineet Gupta 	struct uart_port *port;
583*2ac4ad2aSVineet Gupta 	int baud = 115200;
584*2ac4ad2aSVineet Gupta 	int bits = 8;
585*2ac4ad2aSVineet Gupta 	int parity = 'n';
586*2ac4ad2aSVineet Gupta 	int flow = 'n';
587*2ac4ad2aSVineet Gupta 
588*2ac4ad2aSVineet Gupta 	if (co->index < 0 || co->index >= CONFIG_SERIAL_ARC_NR_PORTS)
589*2ac4ad2aSVineet Gupta 		return -ENODEV;
590*2ac4ad2aSVineet Gupta 
591*2ac4ad2aSVineet Gupta 	/*
592*2ac4ad2aSVineet Gupta 	 * The uart port backing the console (e.g. ttyARC1) might not have been
593*2ac4ad2aSVineet Gupta 	 * init yet. If so, defer the console setup to after the port.
594*2ac4ad2aSVineet Gupta 	 */
595*2ac4ad2aSVineet Gupta 	port = &arc_uart_ports[co->index].port;
596*2ac4ad2aSVineet Gupta 	if (!port->membase)
597*2ac4ad2aSVineet Gupta 		return -ENODEV;
598*2ac4ad2aSVineet Gupta 
599*2ac4ad2aSVineet Gupta 	if (options)
600*2ac4ad2aSVineet Gupta 		uart_parse_options(options, &baud, &parity, &bits, &flow);
601*2ac4ad2aSVineet Gupta 
602*2ac4ad2aSVineet Gupta 	/*
603*2ac4ad2aSVineet Gupta 	 * Serial core will call port->ops->set_termios( )
604*2ac4ad2aSVineet Gupta 	 * which will set the baud reg
605*2ac4ad2aSVineet Gupta 	 */
606*2ac4ad2aSVineet Gupta 	return uart_set_options(port, co, baud, parity, bits, flow);
607*2ac4ad2aSVineet Gupta }
608*2ac4ad2aSVineet Gupta 
609*2ac4ad2aSVineet Gupta static void arc_serial_console_putchar(struct uart_port *port, int ch)
610*2ac4ad2aSVineet Gupta {
611*2ac4ad2aSVineet Gupta 	arc_serial_poll_putchar(port, (unsigned char)ch);
612*2ac4ad2aSVineet Gupta }
613*2ac4ad2aSVineet Gupta 
614*2ac4ad2aSVineet Gupta /*
615*2ac4ad2aSVineet Gupta  * Interrupts are disabled on entering
616*2ac4ad2aSVineet Gupta  */
617*2ac4ad2aSVineet Gupta static void arc_serial_console_write(struct console *co, const char *s,
618*2ac4ad2aSVineet Gupta 				     unsigned int count)
619*2ac4ad2aSVineet Gupta {
620*2ac4ad2aSVineet Gupta 	struct uart_port *port = &arc_uart_ports[co->index].port;
621*2ac4ad2aSVineet Gupta 	unsigned long flags;
622*2ac4ad2aSVineet Gupta 
623*2ac4ad2aSVineet Gupta 	spin_lock_irqsave(&port->lock, flags);
624*2ac4ad2aSVineet Gupta 	uart_console_write(port, s, count, arc_serial_console_putchar);
625*2ac4ad2aSVineet Gupta 	spin_unlock_irqrestore(&port->lock, flags);
626*2ac4ad2aSVineet Gupta }
627*2ac4ad2aSVineet Gupta 
628*2ac4ad2aSVineet Gupta static struct console arc_console = {
629*2ac4ad2aSVineet Gupta 	.name	= ARC_SERIAL_DEV_NAME,
630*2ac4ad2aSVineet Gupta 	.write	= arc_serial_console_write,
631*2ac4ad2aSVineet Gupta 	.device	= uart_console_device,
632*2ac4ad2aSVineet Gupta 	.setup	= arc_serial_console_setup,
633*2ac4ad2aSVineet Gupta 	.flags	= CON_PRINTBUFFER,
634*2ac4ad2aSVineet Gupta 	.index	= -1,
635*2ac4ad2aSVineet Gupta 	.data	= &arc_uart_driver
636*2ac4ad2aSVineet Gupta };
637*2ac4ad2aSVineet Gupta 
638*2ac4ad2aSVineet Gupta static __init void early_serial_write(struct console *con, const char *s,
639*2ac4ad2aSVineet Gupta 					unsigned int n)
640*2ac4ad2aSVineet Gupta {
641*2ac4ad2aSVineet Gupta 	struct uart_port *port = &arc_uart_ports[con->index].port;
642*2ac4ad2aSVineet Gupta 	unsigned int i;
643*2ac4ad2aSVineet Gupta 
644*2ac4ad2aSVineet Gupta 	for (i = 0; i < n; i++, s++) {
645*2ac4ad2aSVineet Gupta 		if (*s == '\n')
646*2ac4ad2aSVineet Gupta 			arc_serial_poll_putchar(port, '\r');
647*2ac4ad2aSVineet Gupta 		arc_serial_poll_putchar(port, *s);
648*2ac4ad2aSVineet Gupta 	}
649*2ac4ad2aSVineet Gupta }
650*2ac4ad2aSVineet Gupta 
651*2ac4ad2aSVineet Gupta static struct __initdata console arc_early_serial_console = {
652*2ac4ad2aSVineet Gupta 	.name = "early_ARCuart",
653*2ac4ad2aSVineet Gupta 	.write = early_serial_write,
654*2ac4ad2aSVineet Gupta 	.flags = CON_PRINTBUFFER | CON_BOOT,
655*2ac4ad2aSVineet Gupta 	.index = -1
656*2ac4ad2aSVineet Gupta };
657*2ac4ad2aSVineet Gupta 
658*2ac4ad2aSVineet Gupta static int __devinit arc_serial_probe_earlyprintk(struct platform_device *pdev)
659*2ac4ad2aSVineet Gupta {
660*2ac4ad2aSVineet Gupta 	arc_early_serial_console.index = pdev->id;
661*2ac4ad2aSVineet Gupta 
662*2ac4ad2aSVineet Gupta 	arc_uart_init_one(pdev, &arc_uart_ports[pdev->id]);
663*2ac4ad2aSVineet Gupta 
664*2ac4ad2aSVineet Gupta 	arc_serial_console_setup(&arc_early_serial_console, NULL);
665*2ac4ad2aSVineet Gupta 
666*2ac4ad2aSVineet Gupta 	register_console(&arc_early_serial_console);
667*2ac4ad2aSVineet Gupta 	return 0;
668*2ac4ad2aSVineet Gupta }
669*2ac4ad2aSVineet Gupta #else
670*2ac4ad2aSVineet Gupta static int __devinit arc_serial_probe_earlyprintk(struct platform_device *pdev)
671*2ac4ad2aSVineet Gupta {
672*2ac4ad2aSVineet Gupta 	return -ENODEV;
673*2ac4ad2aSVineet Gupta }
674*2ac4ad2aSVineet Gupta #endif	/* CONFIG_SERIAL_ARC_CONSOLE */
675*2ac4ad2aSVineet Gupta 
676*2ac4ad2aSVineet Gupta static int __devinit arc_serial_probe(struct platform_device *pdev)
677*2ac4ad2aSVineet Gupta {
678*2ac4ad2aSVineet Gupta 	struct arc_uart_port *uart;
679*2ac4ad2aSVineet Gupta 	int rc;
680*2ac4ad2aSVineet Gupta 
681*2ac4ad2aSVineet Gupta 	if (is_early_platform_device(pdev))
682*2ac4ad2aSVineet Gupta 		return arc_serial_probe_earlyprintk(pdev);
683*2ac4ad2aSVineet Gupta 
684*2ac4ad2aSVineet Gupta 	uart = &arc_uart_ports[pdev->id];
685*2ac4ad2aSVineet Gupta 	rc = arc_uart_init_one(pdev, uart);
686*2ac4ad2aSVineet Gupta 	if (rc)
687*2ac4ad2aSVineet Gupta 		return rc;
688*2ac4ad2aSVineet Gupta 
689*2ac4ad2aSVineet Gupta 	return uart_add_one_port(&arc_uart_driver, &uart->port);
690*2ac4ad2aSVineet Gupta }
691*2ac4ad2aSVineet Gupta 
692*2ac4ad2aSVineet Gupta static int __devexit arc_serial_remove(struct platform_device *pdev)
693*2ac4ad2aSVineet Gupta {
694*2ac4ad2aSVineet Gupta 	/* This will never be called */
695*2ac4ad2aSVineet Gupta 	return 0;
696*2ac4ad2aSVineet Gupta }
697*2ac4ad2aSVineet Gupta 
698*2ac4ad2aSVineet Gupta static struct platform_driver arc_platform_driver = {
699*2ac4ad2aSVineet Gupta 	.probe = arc_serial_probe,
700*2ac4ad2aSVineet Gupta 	.remove = __devexit_p(arc_serial_remove),
701*2ac4ad2aSVineet Gupta 	.driver = {
702*2ac4ad2aSVineet Gupta 		.name = DRIVER_NAME,
703*2ac4ad2aSVineet Gupta 		.owner = THIS_MODULE,
704*2ac4ad2aSVineet Gupta 	 },
705*2ac4ad2aSVineet Gupta };
706*2ac4ad2aSVineet Gupta 
707*2ac4ad2aSVineet Gupta #ifdef CONFIG_SERIAL_ARC_CONSOLE
708*2ac4ad2aSVineet Gupta /*
709*2ac4ad2aSVineet Gupta  * Register an early platform driver of "earlyprintk" class.
710*2ac4ad2aSVineet Gupta  * ARCH platform code installs the driver and probes the early devices
711*2ac4ad2aSVineet Gupta  * The installation could rely on user specifying earlyprintk=xyx in cmd line
712*2ac4ad2aSVineet Gupta  * or it could be done independently, for all "earlyprintk" class drivers.
713*2ac4ad2aSVineet Gupta  * [see arch/arc/plat-arcfpga/platform.c]
714*2ac4ad2aSVineet Gupta  */
715*2ac4ad2aSVineet Gupta early_platform_init("earlyprintk", &arc_platform_driver);
716*2ac4ad2aSVineet Gupta 
717*2ac4ad2aSVineet Gupta #endif  /* CONFIG_SERIAL_ARC_CONSOLE */
718*2ac4ad2aSVineet Gupta 
719*2ac4ad2aSVineet Gupta static int __init arc_serial_init(void)
720*2ac4ad2aSVineet Gupta {
721*2ac4ad2aSVineet Gupta 	int ret;
722*2ac4ad2aSVineet Gupta 
723*2ac4ad2aSVineet Gupta 	ret = uart_register_driver(&arc_uart_driver);
724*2ac4ad2aSVineet Gupta 	if (ret)
725*2ac4ad2aSVineet Gupta 		return ret;
726*2ac4ad2aSVineet Gupta 
727*2ac4ad2aSVineet Gupta 	ret = platform_driver_register(&arc_platform_driver);
728*2ac4ad2aSVineet Gupta 	if (ret)
729*2ac4ad2aSVineet Gupta 		uart_unregister_driver(&arc_uart_driver);
730*2ac4ad2aSVineet Gupta 
731*2ac4ad2aSVineet Gupta 	return ret;
732*2ac4ad2aSVineet Gupta }
733*2ac4ad2aSVineet Gupta 
734*2ac4ad2aSVineet Gupta static void __exit arc_serial_exit(void)
735*2ac4ad2aSVineet Gupta {
736*2ac4ad2aSVineet Gupta 	platform_driver_unregister(&arc_platform_driver);
737*2ac4ad2aSVineet Gupta 	uart_unregister_driver(&arc_uart_driver);
738*2ac4ad2aSVineet Gupta }
739*2ac4ad2aSVineet Gupta 
740*2ac4ad2aSVineet Gupta module_init(arc_serial_init);
741*2ac4ad2aSVineet Gupta module_exit(arc_serial_exit);
742*2ac4ad2aSVineet Gupta 
743*2ac4ad2aSVineet Gupta MODULE_LICENSE("GPL");
744*2ac4ad2aSVineet Gupta MODULE_ALIAS("plat-arcfpga/uart");
745*2ac4ad2aSVineet Gupta MODULE_AUTHOR("Vineet Gupta");
746*2ac4ad2aSVineet Gupta MODULE_DESCRIPTION("ARC(Synopsys) On-Chip(fpga) serial driver");
747