1 /*
2  * UART driver for PNX8XXX SoCs
3  *
4  * Author: Per Hallsmark per.hallsmark@mvista.com
5  * Ported to 2.6 kernel by EmbeddedAlley
6  * Reworked by Vitaly Wool <vitalywool@gmail.com>
7  *
8  * Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
9  * Copyright (C) 2000 Deep Blue Solutions Ltd.
10  *
11  * This file is licensed under the terms of the GNU General Public License
12  * version 2. This program is licensed "as is" without any warranty of
13  * any kind, whether express or implied.
14  *
15  */
16 
17 #if defined(CONFIG_SERIAL_PNX8XXX_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
18 #define SUPPORT_SYSRQ
19 #endif
20 
21 #include <linux/module.h>
22 #include <linux/ioport.h>
23 #include <linux/init.h>
24 #include <linux/console.h>
25 #include <linux/sysrq.h>
26 #include <linux/device.h>
27 #include <linux/platform_device.h>
28 #include <linux/tty.h>
29 #include <linux/tty_flip.h>
30 #include <linux/serial_core.h>
31 #include <linux/serial.h>
32 #include <linux/serial_pnx8xxx.h>
33 
34 #include <asm/io.h>
35 #include <asm/irq.h>
36 
37 /* We'll be using StrongARM sa1100 serial port major/minor */
38 #define SERIAL_PNX8XXX_MAJOR	204
39 #define MINOR_START		5
40 
41 #define NR_PORTS		2
42 
43 #define PNX8XXX_ISR_PASS_LIMIT	256
44 
45 /*
46  * Convert from ignore_status_mask or read_status_mask to FIFO
47  * and interrupt status bits
48  */
49 #define SM_TO_FIFO(x)	((x) >> 10)
50 #define SM_TO_ISTAT(x)	((x) & 0x000001ff)
51 #define FIFO_TO_SM(x)	((x) << 10)
52 #define ISTAT_TO_SM(x)	((x) & 0x000001ff)
53 
54 /*
55  * This is the size of our serial port register set.
56  */
57 #define UART_PORT_SIZE	0x1000
58 
59 /*
60  * This determines how often we check the modem status signals
61  * for any change.  They generally aren't connected to an IRQ
62  * so we have to poll them.  We also check immediately before
63  * filling the TX fifo incase CTS has been dropped.
64  */
65 #define MCTRL_TIMEOUT	(250*HZ/1000)
66 
67 extern struct pnx8xxx_port pnx8xxx_ports[];
68 
serial_in(struct pnx8xxx_port * sport,int offset)69 static inline int serial_in(struct pnx8xxx_port *sport, int offset)
70 {
71 	return (__raw_readl(sport->port.membase + offset));
72 }
73 
serial_out(struct pnx8xxx_port * sport,int offset,int value)74 static inline void serial_out(struct pnx8xxx_port *sport, int offset, int value)
75 {
76 	__raw_writel(value, sport->port.membase + offset);
77 }
78 
79 /*
80  * Handle any change of modem status signal since we were last called.
81  */
pnx8xxx_mctrl_check(struct pnx8xxx_port * sport)82 static void pnx8xxx_mctrl_check(struct pnx8xxx_port *sport)
83 {
84 	unsigned int status, changed;
85 
86 	status = sport->port.ops->get_mctrl(&sport->port);
87 	changed = status ^ sport->old_status;
88 
89 	if (changed == 0)
90 		return;
91 
92 	sport->old_status = status;
93 
94 	if (changed & TIOCM_RI)
95 		sport->port.icount.rng++;
96 	if (changed & TIOCM_DSR)
97 		sport->port.icount.dsr++;
98 	if (changed & TIOCM_CAR)
99 		uart_handle_dcd_change(&sport->port, status & TIOCM_CAR);
100 	if (changed & TIOCM_CTS)
101 		uart_handle_cts_change(&sport->port, status & TIOCM_CTS);
102 
103 	wake_up_interruptible(&sport->port.state->port.delta_msr_wait);
104 }
105 
106 /*
107  * This is our per-port timeout handler, for checking the
108  * modem status signals.
109  */
pnx8xxx_timeout(unsigned long data)110 static void pnx8xxx_timeout(unsigned long data)
111 {
112 	struct pnx8xxx_port *sport = (struct pnx8xxx_port *)data;
113 	unsigned long flags;
114 
115 	if (sport->port.state) {
116 		spin_lock_irqsave(&sport->port.lock, flags);
117 		pnx8xxx_mctrl_check(sport);
118 		spin_unlock_irqrestore(&sport->port.lock, flags);
119 
120 		mod_timer(&sport->timer, jiffies + MCTRL_TIMEOUT);
121 	}
122 }
123 
124 /*
125  * interrupts disabled on entry
126  */
pnx8xxx_stop_tx(struct uart_port * port)127 static void pnx8xxx_stop_tx(struct uart_port *port)
128 {
129 	struct pnx8xxx_port *sport =
130 		container_of(port, struct pnx8xxx_port, port);
131 	u32 ien;
132 
133 	/* Disable TX intr */
134 	ien = serial_in(sport, PNX8XXX_IEN);
135 	serial_out(sport, PNX8XXX_IEN, ien & ~PNX8XXX_UART_INT_ALLTX);
136 
137 	/* Clear all pending TX intr */
138 	serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLTX);
139 }
140 
141 /*
142  * interrupts may not be disabled on entry
143  */
pnx8xxx_start_tx(struct uart_port * port)144 static void pnx8xxx_start_tx(struct uart_port *port)
145 {
146 	struct pnx8xxx_port *sport =
147 		container_of(port, struct pnx8xxx_port, port);
148 	u32 ien;
149 
150 	/* Clear all pending TX intr */
151 	serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLTX);
152 
153 	/* Enable TX intr */
154 	ien = serial_in(sport, PNX8XXX_IEN);
155 	serial_out(sport, PNX8XXX_IEN, ien | PNX8XXX_UART_INT_ALLTX);
156 }
157 
158 /*
159  * Interrupts enabled
160  */
pnx8xxx_stop_rx(struct uart_port * port)161 static void pnx8xxx_stop_rx(struct uart_port *port)
162 {
163 	struct pnx8xxx_port *sport =
164 		container_of(port, struct pnx8xxx_port, port);
165 	u32 ien;
166 
167 	/* Disable RX intr */
168 	ien = serial_in(sport, PNX8XXX_IEN);
169 	serial_out(sport, PNX8XXX_IEN, ien & ~PNX8XXX_UART_INT_ALLRX);
170 
171 	/* Clear all pending RX intr */
172 	serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLRX);
173 }
174 
175 /*
176  * Set the modem control timer to fire immediately.
177  */
pnx8xxx_enable_ms(struct uart_port * port)178 static void pnx8xxx_enable_ms(struct uart_port *port)
179 {
180 	struct pnx8xxx_port *sport =
181 		container_of(port, struct pnx8xxx_port, port);
182 
183 	mod_timer(&sport->timer, jiffies);
184 }
185 
pnx8xxx_rx_chars(struct pnx8xxx_port * sport)186 static void pnx8xxx_rx_chars(struct pnx8xxx_port *sport)
187 {
188 	unsigned int status, ch, flg;
189 
190 	status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) |
191 		 ISTAT_TO_SM(serial_in(sport, PNX8XXX_ISTAT));
192 	while (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFIFO)) {
193 		ch = serial_in(sport, PNX8XXX_FIFO) & 0xff;
194 
195 		sport->port.icount.rx++;
196 
197 		flg = TTY_NORMAL;
198 
199 		/*
200 		 * note that the error handling code is
201 		 * out of the main execution path
202 		 */
203 		if (status & (FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE |
204 					PNX8XXX_UART_FIFO_RXPAR |
205 					PNX8XXX_UART_FIFO_RXBRK) |
206 			      ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN))) {
207 			if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXBRK)) {
208 				status &= ~(FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) |
209 					FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR));
210 				sport->port.icount.brk++;
211 				if (uart_handle_break(&sport->port))
212 					goto ignore_char;
213 			} else if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR))
214 				sport->port.icount.parity++;
215 			else if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE))
216 				sport->port.icount.frame++;
217 			if (status & ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN))
218 				sport->port.icount.overrun++;
219 
220 			status &= sport->port.read_status_mask;
221 
222 			if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR))
223 				flg = TTY_PARITY;
224 			else if (status & FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE))
225 				flg = TTY_FRAME;
226 
227 #ifdef SUPPORT_SYSRQ
228 			sport->port.sysrq = 0;
229 #endif
230 		}
231 
232 		if (uart_handle_sysrq_char(&sport->port, ch))
233 			goto ignore_char;
234 
235 		uart_insert_char(&sport->port, status,
236 				ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN), ch, flg);
237 
238 	ignore_char:
239 		serial_out(sport, PNX8XXX_LCR, serial_in(sport, PNX8XXX_LCR) |
240 				PNX8XXX_UART_LCR_RX_NEXT);
241 		status = FIFO_TO_SM(serial_in(sport, PNX8XXX_FIFO)) |
242 			 ISTAT_TO_SM(serial_in(sport, PNX8XXX_ISTAT));
243 	}
244 
245 	spin_unlock(&sport->port.lock);
246 	tty_flip_buffer_push(&sport->port.state->port);
247 	spin_lock(&sport->port.lock);
248 }
249 
pnx8xxx_tx_chars(struct pnx8xxx_port * sport)250 static void pnx8xxx_tx_chars(struct pnx8xxx_port *sport)
251 {
252 	struct circ_buf *xmit = &sport->port.state->xmit;
253 
254 	if (sport->port.x_char) {
255 		serial_out(sport, PNX8XXX_FIFO, sport->port.x_char);
256 		sport->port.icount.tx++;
257 		sport->port.x_char = 0;
258 		return;
259 	}
260 
261 	/*
262 	 * Check the modem control lines before
263 	 * transmitting anything.
264 	 */
265 	pnx8xxx_mctrl_check(sport);
266 
267 	if (uart_circ_empty(xmit) || uart_tx_stopped(&sport->port)) {
268 		pnx8xxx_stop_tx(&sport->port);
269 		return;
270 	}
271 
272 	/*
273 	 * TX while bytes available
274 	 */
275 	while (((serial_in(sport, PNX8XXX_FIFO) &
276 					PNX8XXX_UART_FIFO_TXFIFO) >> 16) < 16) {
277 		serial_out(sport, PNX8XXX_FIFO, xmit->buf[xmit->tail]);
278 		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
279 		sport->port.icount.tx++;
280 		if (uart_circ_empty(xmit))
281 			break;
282 	}
283 
284 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
285 		uart_write_wakeup(&sport->port);
286 
287 	if (uart_circ_empty(xmit))
288 		pnx8xxx_stop_tx(&sport->port);
289 }
290 
pnx8xxx_int(int irq,void * dev_id)291 static irqreturn_t pnx8xxx_int(int irq, void *dev_id)
292 {
293 	struct pnx8xxx_port *sport = dev_id;
294 	unsigned int status;
295 
296 	spin_lock(&sport->port.lock);
297 	/* Get the interrupts */
298 	status  = serial_in(sport, PNX8XXX_ISTAT) & serial_in(sport, PNX8XXX_IEN);
299 
300 	/* Byte or break signal received */
301 	if (status & (PNX8XXX_UART_INT_RX | PNX8XXX_UART_INT_BREAK))
302 		pnx8xxx_rx_chars(sport);
303 
304 	/* TX holding register empty - transmit a byte */
305 	if (status & PNX8XXX_UART_INT_TX)
306 		pnx8xxx_tx_chars(sport);
307 
308 	/* Clear the ISTAT register */
309 	serial_out(sport, PNX8XXX_ICLR, status);
310 
311 	spin_unlock(&sport->port.lock);
312 	return IRQ_HANDLED;
313 }
314 
315 /*
316  * Return TIOCSER_TEMT when transmitter is not busy.
317  */
pnx8xxx_tx_empty(struct uart_port * port)318 static unsigned int pnx8xxx_tx_empty(struct uart_port *port)
319 {
320 	struct pnx8xxx_port *sport =
321 		container_of(port, struct pnx8xxx_port, port);
322 
323 	return serial_in(sport, PNX8XXX_FIFO) & PNX8XXX_UART_FIFO_TXFIFO_STA ? 0 : TIOCSER_TEMT;
324 }
325 
pnx8xxx_get_mctrl(struct uart_port * port)326 static unsigned int pnx8xxx_get_mctrl(struct uart_port *port)
327 {
328 	struct pnx8xxx_port *sport =
329 		container_of(port, struct pnx8xxx_port, port);
330 	unsigned int mctrl = TIOCM_DSR;
331 	unsigned int msr;
332 
333 	/* REVISIT */
334 
335 	msr = serial_in(sport, PNX8XXX_MCR);
336 
337 	mctrl |= msr & PNX8XXX_UART_MCR_CTS ? TIOCM_CTS : 0;
338 	mctrl |= msr & PNX8XXX_UART_MCR_DCD ? TIOCM_CAR : 0;
339 
340 	return mctrl;
341 }
342 
pnx8xxx_set_mctrl(struct uart_port * port,unsigned int mctrl)343 static void pnx8xxx_set_mctrl(struct uart_port *port, unsigned int mctrl)
344 {
345 #if	0	/* FIXME */
346 	struct pnx8xxx_port *sport = (struct pnx8xxx_port *)port;
347 	unsigned int msr;
348 #endif
349 }
350 
351 /*
352  * Interrupts always disabled.
353  */
pnx8xxx_break_ctl(struct uart_port * port,int break_state)354 static void pnx8xxx_break_ctl(struct uart_port *port, int break_state)
355 {
356 	struct pnx8xxx_port *sport =
357 		container_of(port, struct pnx8xxx_port, port);
358 	unsigned long flags;
359 	unsigned int lcr;
360 
361 	spin_lock_irqsave(&sport->port.lock, flags);
362 	lcr = serial_in(sport, PNX8XXX_LCR);
363 	if (break_state == -1)
364 		lcr |= PNX8XXX_UART_LCR_TXBREAK;
365 	else
366 		lcr &= ~PNX8XXX_UART_LCR_TXBREAK;
367 	serial_out(sport, PNX8XXX_LCR, lcr);
368 	spin_unlock_irqrestore(&sport->port.lock, flags);
369 }
370 
pnx8xxx_startup(struct uart_port * port)371 static int pnx8xxx_startup(struct uart_port *port)
372 {
373 	struct pnx8xxx_port *sport =
374 		container_of(port, struct pnx8xxx_port, port);
375 	int retval;
376 
377 	/*
378 	 * Allocate the IRQ
379 	 */
380 	retval = request_irq(sport->port.irq, pnx8xxx_int, 0,
381 			     "pnx8xxx-uart", sport);
382 	if (retval)
383 		return retval;
384 
385 	/*
386 	 * Finally, clear and enable interrupts
387 	 */
388 
389 	serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLRX |
390 			     PNX8XXX_UART_INT_ALLTX);
391 
392 	serial_out(sport, PNX8XXX_IEN, serial_in(sport, PNX8XXX_IEN) |
393 			    PNX8XXX_UART_INT_ALLRX |
394 			    PNX8XXX_UART_INT_ALLTX);
395 
396 	/*
397 	 * Enable modem status interrupts
398 	 */
399 	spin_lock_irq(&sport->port.lock);
400 	pnx8xxx_enable_ms(&sport->port);
401 	spin_unlock_irq(&sport->port.lock);
402 
403 	return 0;
404 }
405 
pnx8xxx_shutdown(struct uart_port * port)406 static void pnx8xxx_shutdown(struct uart_port *port)
407 {
408 	struct pnx8xxx_port *sport =
409 		container_of(port, struct pnx8xxx_port, port);
410 	int lcr;
411 
412 	/*
413 	 * Stop our timer.
414 	 */
415 	del_timer_sync(&sport->timer);
416 
417 	/*
418 	 * Disable all interrupts
419 	 */
420 	serial_out(sport, PNX8XXX_IEN, 0);
421 
422 	/*
423 	 * Reset the Tx and Rx FIFOS, disable the break condition
424 	 */
425 	lcr = serial_in(sport, PNX8XXX_LCR);
426 	lcr &= ~PNX8XXX_UART_LCR_TXBREAK;
427 	lcr |= PNX8XXX_UART_LCR_TX_RST | PNX8XXX_UART_LCR_RX_RST;
428 	serial_out(sport, PNX8XXX_LCR, lcr);
429 
430 	/*
431 	 * Clear all interrupts
432 	 */
433 	serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_ALLRX |
434 			     PNX8XXX_UART_INT_ALLTX);
435 
436 	/*
437 	 * Free the interrupt
438 	 */
439 	free_irq(sport->port.irq, sport);
440 }
441 
442 static void
pnx8xxx_set_termios(struct uart_port * port,struct ktermios * termios,struct ktermios * old)443 pnx8xxx_set_termios(struct uart_port *port, struct ktermios *termios,
444 		   struct ktermios *old)
445 {
446 	struct pnx8xxx_port *sport =
447 		container_of(port, struct pnx8xxx_port, port);
448 	unsigned long flags;
449 	unsigned int lcr_fcr, old_ien, baud, quot;
450 	unsigned int old_csize = old ? old->c_cflag & CSIZE : CS8;
451 
452 	/*
453 	 * We only support CS7 and CS8.
454 	 */
455 	while ((termios->c_cflag & CSIZE) != CS7 &&
456 	       (termios->c_cflag & CSIZE) != CS8) {
457 		termios->c_cflag &= ~CSIZE;
458 		termios->c_cflag |= old_csize;
459 		old_csize = CS8;
460 	}
461 
462 	if ((termios->c_cflag & CSIZE) == CS8)
463 		lcr_fcr = PNX8XXX_UART_LCR_8BIT;
464 	else
465 		lcr_fcr = 0;
466 
467 	if (termios->c_cflag & CSTOPB)
468 		lcr_fcr |= PNX8XXX_UART_LCR_2STOPB;
469 	if (termios->c_cflag & PARENB) {
470 		lcr_fcr |= PNX8XXX_UART_LCR_PAREN;
471 		if (!(termios->c_cflag & PARODD))
472 			lcr_fcr |= PNX8XXX_UART_LCR_PAREVN;
473 	}
474 
475 	/*
476 	 * Ask the core to calculate the divisor for us.
477 	 */
478 	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
479 	quot = uart_get_divisor(port, baud);
480 
481 	spin_lock_irqsave(&sport->port.lock, flags);
482 
483 	sport->port.read_status_mask = ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN) |
484 				ISTAT_TO_SM(PNX8XXX_UART_INT_EMPTY) |
485 				ISTAT_TO_SM(PNX8XXX_UART_INT_RX);
486 	if (termios->c_iflag & INPCK)
487 		sport->port.read_status_mask |=
488 			FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) |
489 			FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR);
490 	if (termios->c_iflag & (IGNBRK | BRKINT | PARMRK))
491 		sport->port.read_status_mask |=
492 			ISTAT_TO_SM(PNX8XXX_UART_INT_BREAK);
493 
494 	/*
495 	 * Characters to ignore
496 	 */
497 	sport->port.ignore_status_mask = 0;
498 	if (termios->c_iflag & IGNPAR)
499 		sport->port.ignore_status_mask |=
500 			FIFO_TO_SM(PNX8XXX_UART_FIFO_RXFE) |
501 			FIFO_TO_SM(PNX8XXX_UART_FIFO_RXPAR);
502 	if (termios->c_iflag & IGNBRK) {
503 		sport->port.ignore_status_mask |=
504 			ISTAT_TO_SM(PNX8XXX_UART_INT_BREAK);
505 		/*
506 		 * If we're ignoring parity and break indicators,
507 		 * ignore overruns too (for real raw support).
508 		 */
509 		if (termios->c_iflag & IGNPAR)
510 			sport->port.ignore_status_mask |=
511 				ISTAT_TO_SM(PNX8XXX_UART_INT_RXOVRN);
512 	}
513 
514 	/*
515 	 * ignore all characters if CREAD is not set
516 	 */
517 	if ((termios->c_cflag & CREAD) == 0)
518 		sport->port.ignore_status_mask |=
519 			ISTAT_TO_SM(PNX8XXX_UART_INT_RX);
520 
521 	del_timer_sync(&sport->timer);
522 
523 	/*
524 	 * Update the per-port timeout.
525 	 */
526 	uart_update_timeout(port, termios->c_cflag, baud);
527 
528 	/*
529 	 * disable interrupts and drain transmitter
530 	 */
531 	old_ien = serial_in(sport, PNX8XXX_IEN);
532 	serial_out(sport, PNX8XXX_IEN, old_ien & ~(PNX8XXX_UART_INT_ALLTX |
533 					PNX8XXX_UART_INT_ALLRX));
534 
535 	while (serial_in(sport, PNX8XXX_FIFO) & PNX8XXX_UART_FIFO_TXFIFO_STA)
536 		barrier();
537 
538 	/* then, disable everything */
539 	serial_out(sport, PNX8XXX_IEN, 0);
540 
541 	/* Reset the Rx and Tx FIFOs too */
542 	lcr_fcr |= PNX8XXX_UART_LCR_TX_RST;
543 	lcr_fcr |= PNX8XXX_UART_LCR_RX_RST;
544 
545 	/* set the parity, stop bits and data size */
546 	serial_out(sport, PNX8XXX_LCR, lcr_fcr);
547 
548 	/* set the baud rate */
549 	quot -= 1;
550 	serial_out(sport, PNX8XXX_BAUD, quot);
551 
552 	serial_out(sport, PNX8XXX_ICLR, -1);
553 
554 	serial_out(sport, PNX8XXX_IEN, old_ien);
555 
556 	if (UART_ENABLE_MS(&sport->port, termios->c_cflag))
557 		pnx8xxx_enable_ms(&sport->port);
558 
559 	spin_unlock_irqrestore(&sport->port.lock, flags);
560 }
561 
pnx8xxx_type(struct uart_port * port)562 static const char *pnx8xxx_type(struct uart_port *port)
563 {
564 	struct pnx8xxx_port *sport =
565 		container_of(port, struct pnx8xxx_port, port);
566 
567 	return sport->port.type == PORT_PNX8XXX ? "PNX8XXX" : NULL;
568 }
569 
570 /*
571  * Release the memory region(s) being used by 'port'.
572  */
pnx8xxx_release_port(struct uart_port * port)573 static void pnx8xxx_release_port(struct uart_port *port)
574 {
575 	struct pnx8xxx_port *sport =
576 		container_of(port, struct pnx8xxx_port, port);
577 
578 	release_mem_region(sport->port.mapbase, UART_PORT_SIZE);
579 }
580 
581 /*
582  * Request the memory region(s) being used by 'port'.
583  */
pnx8xxx_request_port(struct uart_port * port)584 static int pnx8xxx_request_port(struct uart_port *port)
585 {
586 	struct pnx8xxx_port *sport =
587 		container_of(port, struct pnx8xxx_port, port);
588 	return request_mem_region(sport->port.mapbase, UART_PORT_SIZE,
589 			"pnx8xxx-uart") != NULL ? 0 : -EBUSY;
590 }
591 
592 /*
593  * Configure/autoconfigure the port.
594  */
pnx8xxx_config_port(struct uart_port * port,int flags)595 static void pnx8xxx_config_port(struct uart_port *port, int flags)
596 {
597 	struct pnx8xxx_port *sport =
598 		container_of(port, struct pnx8xxx_port, port);
599 
600 	if (flags & UART_CONFIG_TYPE &&
601 	    pnx8xxx_request_port(&sport->port) == 0)
602 		sport->port.type = PORT_PNX8XXX;
603 }
604 
605 /*
606  * Verify the new serial_struct (for TIOCSSERIAL).
607  * The only change we allow are to the flags and type, and
608  * even then only between PORT_PNX8XXX and PORT_UNKNOWN
609  */
610 static int
pnx8xxx_verify_port(struct uart_port * port,struct serial_struct * ser)611 pnx8xxx_verify_port(struct uart_port *port, struct serial_struct *ser)
612 {
613 	struct pnx8xxx_port *sport =
614 		container_of(port, struct pnx8xxx_port,	port);
615 	int ret = 0;
616 
617 	if (ser->type != PORT_UNKNOWN && ser->type != PORT_PNX8XXX)
618 		ret = -EINVAL;
619 	if (sport->port.irq != ser->irq)
620 		ret = -EINVAL;
621 	if (ser->io_type != SERIAL_IO_MEM)
622 		ret = -EINVAL;
623 	if (sport->port.uartclk / 16 != ser->baud_base)
624 		ret = -EINVAL;
625 	if ((void *)sport->port.mapbase != ser->iomem_base)
626 		ret = -EINVAL;
627 	if (sport->port.iobase != ser->port)
628 		ret = -EINVAL;
629 	if (ser->hub6 != 0)
630 		ret = -EINVAL;
631 	return ret;
632 }
633 
634 static struct uart_ops pnx8xxx_pops = {
635 	.tx_empty	= pnx8xxx_tx_empty,
636 	.set_mctrl	= pnx8xxx_set_mctrl,
637 	.get_mctrl	= pnx8xxx_get_mctrl,
638 	.stop_tx	= pnx8xxx_stop_tx,
639 	.start_tx	= pnx8xxx_start_tx,
640 	.stop_rx	= pnx8xxx_stop_rx,
641 	.enable_ms	= pnx8xxx_enable_ms,
642 	.break_ctl	= pnx8xxx_break_ctl,
643 	.startup	= pnx8xxx_startup,
644 	.shutdown	= pnx8xxx_shutdown,
645 	.set_termios	= pnx8xxx_set_termios,
646 	.type		= pnx8xxx_type,
647 	.release_port	= pnx8xxx_release_port,
648 	.request_port	= pnx8xxx_request_port,
649 	.config_port	= pnx8xxx_config_port,
650 	.verify_port	= pnx8xxx_verify_port,
651 };
652 
653 
654 /*
655  * Setup the PNX8XXX serial ports.
656  *
657  * Note also that we support "console=ttySx" where "x" is either 0 or 1.
658  */
pnx8xxx_init_ports(void)659 static void __init pnx8xxx_init_ports(void)
660 {
661 	static int first = 1;
662 	int i;
663 
664 	if (!first)
665 		return;
666 	first = 0;
667 
668 	for (i = 0; i < NR_PORTS; i++) {
669 		init_timer(&pnx8xxx_ports[i].timer);
670 		pnx8xxx_ports[i].timer.function = pnx8xxx_timeout;
671 		pnx8xxx_ports[i].timer.data     = (unsigned long)&pnx8xxx_ports[i];
672 		pnx8xxx_ports[i].port.ops = &pnx8xxx_pops;
673 	}
674 }
675 
676 #ifdef CONFIG_SERIAL_PNX8XXX_CONSOLE
677 
pnx8xxx_console_putchar(struct uart_port * port,int ch)678 static void pnx8xxx_console_putchar(struct uart_port *port, int ch)
679 {
680 	struct pnx8xxx_port *sport =
681 		container_of(port, struct pnx8xxx_port, port);
682 	int status;
683 
684 	do {
685 		/* Wait for UART_TX register to empty */
686 		status = serial_in(sport, PNX8XXX_FIFO);
687 	} while (status & PNX8XXX_UART_FIFO_TXFIFO);
688 	serial_out(sport, PNX8XXX_FIFO, ch);
689 }
690 
691 /*
692  * Interrupts are disabled on entering
693  */static void
pnx8xxx_console_write(struct console * co,const char * s,unsigned int count)694 pnx8xxx_console_write(struct console *co, const char *s, unsigned int count)
695 {
696 	struct pnx8xxx_port *sport = &pnx8xxx_ports[co->index];
697 	unsigned int old_ien, status;
698 
699 	/*
700 	 *	First, save IEN and then disable interrupts
701 	 */
702 	old_ien = serial_in(sport, PNX8XXX_IEN);
703 	serial_out(sport, PNX8XXX_IEN, old_ien & ~(PNX8XXX_UART_INT_ALLTX |
704 					PNX8XXX_UART_INT_ALLRX));
705 
706 	uart_console_write(&sport->port, s, count, pnx8xxx_console_putchar);
707 
708 	/*
709 	 *	Finally, wait for transmitter to become empty
710 	 *	and restore IEN
711 	 */
712 	do {
713 		/* Wait for UART_TX register to empty */
714 		status = serial_in(sport, PNX8XXX_FIFO);
715 	} while (status & PNX8XXX_UART_FIFO_TXFIFO);
716 
717 	/* Clear TX and EMPTY interrupt */
718 	serial_out(sport, PNX8XXX_ICLR, PNX8XXX_UART_INT_TX |
719 			     PNX8XXX_UART_INT_EMPTY);
720 
721 	serial_out(sport, PNX8XXX_IEN, old_ien);
722 }
723 
724 static int __init
pnx8xxx_console_setup(struct console * co,char * options)725 pnx8xxx_console_setup(struct console *co, char *options)
726 {
727 	struct pnx8xxx_port *sport;
728 	int baud = 38400;
729 	int bits = 8;
730 	int parity = 'n';
731 	int flow = 'n';
732 
733 	/*
734 	 * Check whether an invalid uart number has been specified, and
735 	 * if so, search for the first available port that does have
736 	 * console support.
737 	 */
738 	if (co->index == -1 || co->index >= NR_PORTS)
739 		co->index = 0;
740 	sport = &pnx8xxx_ports[co->index];
741 
742 	if (options)
743 		uart_parse_options(options, &baud, &parity, &bits, &flow);
744 
745 	return uart_set_options(&sport->port, co, baud, parity, bits, flow);
746 }
747 
748 static struct uart_driver pnx8xxx_reg;
749 static struct console pnx8xxx_console = {
750 	.name		= "ttyS",
751 	.write		= pnx8xxx_console_write,
752 	.device		= uart_console_device,
753 	.setup		= pnx8xxx_console_setup,
754 	.flags		= CON_PRINTBUFFER,
755 	.index		= -1,
756 	.data		= &pnx8xxx_reg,
757 };
758 
pnx8xxx_rs_console_init(void)759 static int __init pnx8xxx_rs_console_init(void)
760 {
761 	pnx8xxx_init_ports();
762 	register_console(&pnx8xxx_console);
763 	return 0;
764 }
765 console_initcall(pnx8xxx_rs_console_init);
766 
767 #define PNX8XXX_CONSOLE	&pnx8xxx_console
768 #else
769 #define PNX8XXX_CONSOLE	NULL
770 #endif
771 
772 static struct uart_driver pnx8xxx_reg = {
773 	.owner			= THIS_MODULE,
774 	.driver_name		= "ttyS",
775 	.dev_name		= "ttyS",
776 	.major			= SERIAL_PNX8XXX_MAJOR,
777 	.minor			= MINOR_START,
778 	.nr			= NR_PORTS,
779 	.cons			= PNX8XXX_CONSOLE,
780 };
781 
pnx8xxx_serial_suspend(struct platform_device * pdev,pm_message_t state)782 static int pnx8xxx_serial_suspend(struct platform_device *pdev, pm_message_t state)
783 {
784 	struct pnx8xxx_port *sport = platform_get_drvdata(pdev);
785 
786 	return uart_suspend_port(&pnx8xxx_reg, &sport->port);
787 }
788 
pnx8xxx_serial_resume(struct platform_device * pdev)789 static int pnx8xxx_serial_resume(struct platform_device *pdev)
790 {
791 	struct pnx8xxx_port *sport = platform_get_drvdata(pdev);
792 
793 	return uart_resume_port(&pnx8xxx_reg, &sport->port);
794 }
795 
pnx8xxx_serial_probe(struct platform_device * pdev)796 static int pnx8xxx_serial_probe(struct platform_device *pdev)
797 {
798 	struct resource *res = pdev->resource;
799 	int i;
800 
801 	for (i = 0; i < pdev->num_resources; i++, res++) {
802 		if (!(res->flags & IORESOURCE_MEM))
803 			continue;
804 
805 		for (i = 0; i < NR_PORTS; i++) {
806 			if (pnx8xxx_ports[i].port.mapbase != res->start)
807 				continue;
808 
809 			pnx8xxx_ports[i].port.dev = &pdev->dev;
810 			uart_add_one_port(&pnx8xxx_reg, &pnx8xxx_ports[i].port);
811 			platform_set_drvdata(pdev, &pnx8xxx_ports[i]);
812 			break;
813 		}
814 	}
815 
816 	return 0;
817 }
818 
pnx8xxx_serial_remove(struct platform_device * pdev)819 static int pnx8xxx_serial_remove(struct platform_device *pdev)
820 {
821 	struct pnx8xxx_port *sport = platform_get_drvdata(pdev);
822 
823 	if (sport)
824 		uart_remove_one_port(&pnx8xxx_reg, &sport->port);
825 
826 	return 0;
827 }
828 
829 static struct platform_driver pnx8xxx_serial_driver = {
830 	.driver		= {
831 		.name	= "pnx8xxx-uart",
832 	},
833 	.probe		= pnx8xxx_serial_probe,
834 	.remove		= pnx8xxx_serial_remove,
835 	.suspend	= pnx8xxx_serial_suspend,
836 	.resume		= pnx8xxx_serial_resume,
837 };
838 
pnx8xxx_serial_init(void)839 static int __init pnx8xxx_serial_init(void)
840 {
841 	int ret;
842 
843 	printk(KERN_INFO "Serial: PNX8XXX driver\n");
844 
845 	pnx8xxx_init_ports();
846 
847 	ret = uart_register_driver(&pnx8xxx_reg);
848 	if (ret == 0) {
849 		ret = platform_driver_register(&pnx8xxx_serial_driver);
850 		if (ret)
851 			uart_unregister_driver(&pnx8xxx_reg);
852 	}
853 	return ret;
854 }
855 
pnx8xxx_serial_exit(void)856 static void __exit pnx8xxx_serial_exit(void)
857 {
858 	platform_driver_unregister(&pnx8xxx_serial_driver);
859 	uart_unregister_driver(&pnx8xxx_reg);
860 }
861 
862 module_init(pnx8xxx_serial_init);
863 module_exit(pnx8xxx_serial_exit);
864 
865 MODULE_AUTHOR("Embedded Alley Solutions, Inc.");
866 MODULE_DESCRIPTION("PNX8XXX SoCs serial port driver");
867 MODULE_LICENSE("GPL");
868 MODULE_ALIAS_CHARDEV_MAJOR(SERIAL_PNX8XXX_MAJOR);
869 MODULE_ALIAS("platform:pnx8xxx-uart");
870