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