• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  *  linux/drivers/char/amba.c
3  *
4  *  Driver for AMBA serial ports
5  *
6  *  Based on drivers/char/serial.c, by Linus Torvalds, Theodore Ts'o.
7  *
8  *  Copyright 1999 ARM Limited
9  *  Copyright (C) 2000 Deep Blue Solutions Ltd.
10  *
11  * This program is free software; you can redistribute it and/or modify
12  * it under the terms of the GNU General Public License as published by
13  * the Free Software Foundation; either version 2 of the License, or
14  * (at your option) any later version.
15  *
16  * This program is distributed in the hope that it will be useful,
17  * but WITHOUT ANY WARRANTY; without even the implied warranty of
18  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
19  * GNU General Public License for more details.
20  *
21  * You should have received a copy of the GNU General Public License
22  * along with this program; if not, write to the Free Software
23  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
24  *
25  * This is a generic driver for ARM AMBA-type serial ports.  They
26  * have a lot of 16550-like features, but are not register compatible.
27  * Note that although they do have CTS, DCD and DSR inputs, they do
28  * not have an RI input, nor do they have DTR or RTS outputs.  If
29  * required, these have to be supplied via some other means (eg, GPIO)
30  * and hooked into this driver.
31  */
32 
33 #if defined(CONFIG_SERIAL_AMBA_PL011_CONSOLE) && defined(CONFIG_MAGIC_SYSRQ)
34 #define SUPPORT_SYSRQ
35 #endif
36 
37 #include <linux/module.h>
38 #include <linux/ioport.h>
39 #include <linux/init.h>
40 #include <linux/console.h>
41 #include <linux/sysrq.h>
42 #include <linux/device.h>
43 #include <linux/tty.h>
44 #include <linux/tty_flip.h>
45 #include <linux/serial_core.h>
46 #include <linux/serial.h>
47 #include <linux/amba/bus.h>
48 #include <linux/amba/serial.h>
49 #include <linux/clk.h>
50 
51 #include <asm/io.h>
52 #include <asm/sizes.h>
53 
54 #define UART_NR			14
55 
56 #define SERIAL_AMBA_MAJOR	204
57 #define SERIAL_AMBA_MINOR	64
58 #define SERIAL_AMBA_NR		UART_NR
59 
60 #define AMBA_ISR_PASS_LIMIT	256
61 
62 #define UART_DR_ERROR		(UART011_DR_OE|UART011_DR_BE|UART011_DR_PE|UART011_DR_FE)
63 #define UART_DUMMY_DR_RX	(1 << 16)
64 
65 /*
66  * We wrap our port structure around the generic uart_port.
67  */
68 struct uart_amba_port {
69 	struct uart_port	port;
70 	struct clk		*clk;
71 	unsigned int		im;	/* interrupt mask */
72 	unsigned int		old_status;
73 };
74 
pl011_stop_tx(struct uart_port * port)75 static void pl011_stop_tx(struct uart_port *port)
76 {
77 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
78 
79 	uap->im &= ~UART011_TXIM;
80 	writew(uap->im, uap->port.membase + UART011_IMSC);
81 }
82 
pl011_start_tx(struct uart_port * port)83 static void pl011_start_tx(struct uart_port *port)
84 {
85 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
86 
87 	uap->im |= UART011_TXIM;
88 	writew(uap->im, uap->port.membase + UART011_IMSC);
89 }
90 
pl011_stop_rx(struct uart_port * port)91 static void pl011_stop_rx(struct uart_port *port)
92 {
93 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
94 
95 	uap->im &= ~(UART011_RXIM|UART011_RTIM|UART011_FEIM|
96 		     UART011_PEIM|UART011_BEIM|UART011_OEIM);
97 	writew(uap->im, uap->port.membase + UART011_IMSC);
98 }
99 
pl011_enable_ms(struct uart_port * port)100 static void pl011_enable_ms(struct uart_port *port)
101 {
102 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
103 
104 	uap->im |= UART011_RIMIM|UART011_CTSMIM|UART011_DCDMIM|UART011_DSRMIM;
105 	writew(uap->im, uap->port.membase + UART011_IMSC);
106 }
107 
pl011_rx_chars(struct uart_amba_port * uap)108 static void pl011_rx_chars(struct uart_amba_port *uap)
109 {
110 	struct tty_struct *tty = uap->port.info->port.tty;
111 	unsigned int status, ch, flag, max_count = 256;
112 
113 	status = readw(uap->port.membase + UART01x_FR);
114 	while ((status & UART01x_FR_RXFE) == 0 && max_count--) {
115 		ch = readw(uap->port.membase + UART01x_DR) | UART_DUMMY_DR_RX;
116 		flag = TTY_NORMAL;
117 		uap->port.icount.rx++;
118 
119 		/*
120 		 * Note that the error handling code is
121 		 * out of the main execution path
122 		 */
123 		if (unlikely(ch & UART_DR_ERROR)) {
124 			if (ch & UART011_DR_BE) {
125 				ch &= ~(UART011_DR_FE | UART011_DR_PE);
126 				uap->port.icount.brk++;
127 				if (uart_handle_break(&uap->port))
128 					goto ignore_char;
129 			} else if (ch & UART011_DR_PE)
130 				uap->port.icount.parity++;
131 			else if (ch & UART011_DR_FE)
132 				uap->port.icount.frame++;
133 			if (ch & UART011_DR_OE)
134 				uap->port.icount.overrun++;
135 
136 			ch &= uap->port.read_status_mask;
137 
138 			if (ch & UART011_DR_BE)
139 				flag = TTY_BREAK;
140 			else if (ch & UART011_DR_PE)
141 				flag = TTY_PARITY;
142 			else if (ch & UART011_DR_FE)
143 				flag = TTY_FRAME;
144 		}
145 
146 		if (uart_handle_sysrq_char(&uap->port, ch & 255))
147 			goto ignore_char;
148 
149 		uart_insert_char(&uap->port, ch, UART011_DR_OE, ch, flag);
150 
151 	ignore_char:
152 		status = readw(uap->port.membase + UART01x_FR);
153 	}
154 	spin_unlock(&uap->port.lock);
155 	tty_flip_buffer_push(tty);
156 	spin_lock(&uap->port.lock);
157 }
158 
pl011_tx_chars(struct uart_amba_port * uap)159 static void pl011_tx_chars(struct uart_amba_port *uap)
160 {
161 	struct circ_buf *xmit = &uap->port.info->xmit;
162 	int count;
163 
164 	if (uap->port.x_char) {
165 		writew(uap->port.x_char, uap->port.membase + UART01x_DR);
166 		uap->port.icount.tx++;
167 		uap->port.x_char = 0;
168 		return;
169 	}
170 	if (uart_circ_empty(xmit) || uart_tx_stopped(&uap->port)) {
171 		pl011_stop_tx(&uap->port);
172 		return;
173 	}
174 
175 	count = uap->port.fifosize >> 1;
176 	do {
177 		writew(xmit->buf[xmit->tail], uap->port.membase + UART01x_DR);
178 		xmit->tail = (xmit->tail + 1) & (UART_XMIT_SIZE - 1);
179 		uap->port.icount.tx++;
180 		if (uart_circ_empty(xmit))
181 			break;
182 	} while (--count > 0);
183 
184 	if (uart_circ_chars_pending(xmit) < WAKEUP_CHARS)
185 		uart_write_wakeup(&uap->port);
186 
187 	if (uart_circ_empty(xmit))
188 		pl011_stop_tx(&uap->port);
189 }
190 
pl011_modem_status(struct uart_amba_port * uap)191 static void pl011_modem_status(struct uart_amba_port *uap)
192 {
193 	unsigned int status, delta;
194 
195 	status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
196 
197 	delta = status ^ uap->old_status;
198 	uap->old_status = status;
199 
200 	if (!delta)
201 		return;
202 
203 	if (delta & UART01x_FR_DCD)
204 		uart_handle_dcd_change(&uap->port, status & UART01x_FR_DCD);
205 
206 	if (delta & UART01x_FR_DSR)
207 		uap->port.icount.dsr++;
208 
209 	if (delta & UART01x_FR_CTS)
210 		uart_handle_cts_change(&uap->port, status & UART01x_FR_CTS);
211 
212 	wake_up_interruptible(&uap->port.info->delta_msr_wait);
213 }
214 
pl011_int(int irq,void * dev_id)215 static irqreturn_t pl011_int(int irq, void *dev_id)
216 {
217 	struct uart_amba_port *uap = dev_id;
218 	unsigned int status, pass_counter = AMBA_ISR_PASS_LIMIT;
219 	int handled = 0;
220 
221 	spin_lock(&uap->port.lock);
222 
223 	status = readw(uap->port.membase + UART011_MIS);
224 	if (status) {
225 		do {
226 			writew(status & ~(UART011_TXIS|UART011_RTIS|
227 					  UART011_RXIS),
228 			       uap->port.membase + UART011_ICR);
229 
230 			if (status & (UART011_RTIS|UART011_RXIS))
231 				pl011_rx_chars(uap);
232 			if (status & (UART011_DSRMIS|UART011_DCDMIS|
233 				      UART011_CTSMIS|UART011_RIMIS))
234 				pl011_modem_status(uap);
235 			if (status & UART011_TXIS)
236 				pl011_tx_chars(uap);
237 
238 			if (pass_counter-- == 0)
239 				break;
240 
241 			status = readw(uap->port.membase + UART011_MIS);
242 		} while (status != 0);
243 		handled = 1;
244 	}
245 
246 	spin_unlock(&uap->port.lock);
247 
248 	return IRQ_RETVAL(handled);
249 }
250 
pl01x_tx_empty(struct uart_port * port)251 static unsigned int pl01x_tx_empty(struct uart_port *port)
252 {
253 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
254 	unsigned int status = readw(uap->port.membase + UART01x_FR);
255 	return status & (UART01x_FR_BUSY|UART01x_FR_TXFF) ? 0 : TIOCSER_TEMT;
256 }
257 
pl01x_get_mctrl(struct uart_port * port)258 static unsigned int pl01x_get_mctrl(struct uart_port *port)
259 {
260 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
261 	unsigned int result = 0;
262 	unsigned int status = readw(uap->port.membase + UART01x_FR);
263 
264 #define TIOCMBIT(uartbit, tiocmbit)	\
265 	if (status & uartbit)		\
266 		result |= tiocmbit
267 
268 	TIOCMBIT(UART01x_FR_DCD, TIOCM_CAR);
269 	TIOCMBIT(UART01x_FR_DSR, TIOCM_DSR);
270 	TIOCMBIT(UART01x_FR_CTS, TIOCM_CTS);
271 	TIOCMBIT(UART011_FR_RI, TIOCM_RNG);
272 #undef TIOCMBIT
273 	return result;
274 }
275 
pl011_set_mctrl(struct uart_port * port,unsigned int mctrl)276 static void pl011_set_mctrl(struct uart_port *port, unsigned int mctrl)
277 {
278 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
279 	unsigned int cr;
280 
281 	cr = readw(uap->port.membase + UART011_CR);
282 
283 #define	TIOCMBIT(tiocmbit, uartbit)		\
284 	if (mctrl & tiocmbit)		\
285 		cr |= uartbit;		\
286 	else				\
287 		cr &= ~uartbit
288 
289 	TIOCMBIT(TIOCM_RTS, UART011_CR_RTS);
290 	TIOCMBIT(TIOCM_DTR, UART011_CR_DTR);
291 	TIOCMBIT(TIOCM_OUT1, UART011_CR_OUT1);
292 	TIOCMBIT(TIOCM_OUT2, UART011_CR_OUT2);
293 	TIOCMBIT(TIOCM_LOOP, UART011_CR_LBE);
294 #undef TIOCMBIT
295 
296 	writew(cr, uap->port.membase + UART011_CR);
297 }
298 
pl011_break_ctl(struct uart_port * port,int break_state)299 static void pl011_break_ctl(struct uart_port *port, int break_state)
300 {
301 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
302 	unsigned long flags;
303 	unsigned int lcr_h;
304 
305 	spin_lock_irqsave(&uap->port.lock, flags);
306 	lcr_h = readw(uap->port.membase + UART011_LCRH);
307 	if (break_state == -1)
308 		lcr_h |= UART01x_LCRH_BRK;
309 	else
310 		lcr_h &= ~UART01x_LCRH_BRK;
311 	writew(lcr_h, uap->port.membase + UART011_LCRH);
312 	spin_unlock_irqrestore(&uap->port.lock, flags);
313 }
314 
315 #ifdef CONFIG_CONSOLE_POLL
pl010_get_poll_char(struct uart_port * port)316 static int pl010_get_poll_char(struct uart_port *port)
317 {
318 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
319 	unsigned int status;
320 
321 	do {
322 		status = readw(uap->port.membase + UART01x_FR);
323 	} while (status & UART01x_FR_RXFE);
324 
325 	return readw(uap->port.membase + UART01x_DR);
326 }
327 
pl010_put_poll_char(struct uart_port * port,unsigned char ch)328 static void pl010_put_poll_char(struct uart_port *port,
329 			 unsigned char ch)
330 {
331 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
332 
333 	while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF)
334 		barrier();
335 
336 	writew(ch, uap->port.membase + UART01x_DR);
337 }
338 
339 #endif /* CONFIG_CONSOLE_POLL */
340 
pl011_startup(struct uart_port * port)341 static int pl011_startup(struct uart_port *port)
342 {
343 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
344 	unsigned int cr;
345 	int retval;
346 
347 	/*
348 	 * Try to enable the clock producer.
349 	 */
350 	retval = clk_enable(uap->clk);
351 	if (retval)
352 		goto out;
353 
354 	uap->port.uartclk = clk_get_rate(uap->clk);
355 
356 	/*
357 	 * Allocate the IRQ
358 	 */
359 	retval = request_irq(uap->port.irq, pl011_int, 0, "uart-pl011", uap);
360 	if (retval)
361 		goto clk_dis;
362 
363 	writew(UART011_IFLS_RX4_8|UART011_IFLS_TX4_8,
364 	       uap->port.membase + UART011_IFLS);
365 
366 	/*
367 	 * Provoke TX FIFO interrupt into asserting.
368 	 */
369 	cr = UART01x_CR_UARTEN | UART011_CR_TXE | UART011_CR_LBE;
370 	writew(cr, uap->port.membase + UART011_CR);
371 	writew(0, uap->port.membase + UART011_FBRD);
372 	writew(1, uap->port.membase + UART011_IBRD);
373 	writew(0, uap->port.membase + UART011_LCRH);
374 	writew(0, uap->port.membase + UART01x_DR);
375 	while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_BUSY)
376 		barrier();
377 
378 	cr = UART01x_CR_UARTEN | UART011_CR_RXE | UART011_CR_TXE;
379 	writew(cr, uap->port.membase + UART011_CR);
380 
381 	/*
382 	 * initialise the old status of the modem signals
383 	 */
384 	uap->old_status = readw(uap->port.membase + UART01x_FR) & UART01x_FR_MODEM_ANY;
385 
386 	/*
387 	 * Finally, enable interrupts
388 	 */
389 	spin_lock_irq(&uap->port.lock);
390 	uap->im = UART011_RXIM | UART011_RTIM;
391 	writew(uap->im, uap->port.membase + UART011_IMSC);
392 	spin_unlock_irq(&uap->port.lock);
393 
394 	return 0;
395 
396  clk_dis:
397 	clk_disable(uap->clk);
398  out:
399 	return retval;
400 }
401 
pl011_shutdown(struct uart_port * port)402 static void pl011_shutdown(struct uart_port *port)
403 {
404 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
405 	unsigned long val;
406 
407 	/*
408 	 * disable all interrupts
409 	 */
410 	spin_lock_irq(&uap->port.lock);
411 	uap->im = 0;
412 	writew(uap->im, uap->port.membase + UART011_IMSC);
413 	writew(0xffff, uap->port.membase + UART011_ICR);
414 	spin_unlock_irq(&uap->port.lock);
415 
416 	/*
417 	 * Free the interrupt
418 	 */
419 	free_irq(uap->port.irq, uap);
420 
421 	/*
422 	 * disable the port
423 	 */
424 	writew(UART01x_CR_UARTEN | UART011_CR_TXE, uap->port.membase + UART011_CR);
425 
426 	/*
427 	 * disable break condition and fifos
428 	 */
429 	val = readw(uap->port.membase + UART011_LCRH);
430 	val &= ~(UART01x_LCRH_BRK | UART01x_LCRH_FEN);
431 	writew(val, uap->port.membase + UART011_LCRH);
432 
433 	/*
434 	 * Shut down the clock producer
435 	 */
436 	clk_disable(uap->clk);
437 }
438 
439 static void
pl011_set_termios(struct uart_port * port,struct ktermios * termios,struct ktermios * old)440 pl011_set_termios(struct uart_port *port, struct ktermios *termios,
441 		     struct ktermios *old)
442 {
443 	unsigned int lcr_h, old_cr;
444 	unsigned long flags;
445 	unsigned int baud, quot;
446 
447 	/*
448 	 * Ask the core to calculate the divisor for us.
449 	 */
450 	baud = uart_get_baud_rate(port, termios, old, 0, port->uartclk/16);
451 	quot = port->uartclk * 4 / baud;
452 
453 	switch (termios->c_cflag & CSIZE) {
454 	case CS5:
455 		lcr_h = UART01x_LCRH_WLEN_5;
456 		break;
457 	case CS6:
458 		lcr_h = UART01x_LCRH_WLEN_6;
459 		break;
460 	case CS7:
461 		lcr_h = UART01x_LCRH_WLEN_7;
462 		break;
463 	default: // CS8
464 		lcr_h = UART01x_LCRH_WLEN_8;
465 		break;
466 	}
467 	if (termios->c_cflag & CSTOPB)
468 		lcr_h |= UART01x_LCRH_STP2;
469 	if (termios->c_cflag & PARENB) {
470 		lcr_h |= UART01x_LCRH_PEN;
471 		if (!(termios->c_cflag & PARODD))
472 			lcr_h |= UART01x_LCRH_EPS;
473 	}
474 	if (port->fifosize > 1)
475 		lcr_h |= UART01x_LCRH_FEN;
476 
477 	spin_lock_irqsave(&port->lock, flags);
478 
479 	/*
480 	 * Update the per-port timeout.
481 	 */
482 	uart_update_timeout(port, termios->c_cflag, baud);
483 
484 	port->read_status_mask = UART011_DR_OE | 255;
485 	if (termios->c_iflag & INPCK)
486 		port->read_status_mask |= UART011_DR_FE | UART011_DR_PE;
487 	if (termios->c_iflag & (BRKINT | PARMRK))
488 		port->read_status_mask |= UART011_DR_BE;
489 
490 	/*
491 	 * Characters to ignore
492 	 */
493 	port->ignore_status_mask = 0;
494 	if (termios->c_iflag & IGNPAR)
495 		port->ignore_status_mask |= UART011_DR_FE | UART011_DR_PE;
496 	if (termios->c_iflag & IGNBRK) {
497 		port->ignore_status_mask |= UART011_DR_BE;
498 		/*
499 		 * If we're ignoring parity and break indicators,
500 		 * ignore overruns too (for real raw support).
501 		 */
502 		if (termios->c_iflag & IGNPAR)
503 			port->ignore_status_mask |= UART011_DR_OE;
504 	}
505 
506 	/*
507 	 * Ignore all characters if CREAD is not set.
508 	 */
509 	if ((termios->c_cflag & CREAD) == 0)
510 		port->ignore_status_mask |= UART_DUMMY_DR_RX;
511 
512 	if (UART_ENABLE_MS(port, termios->c_cflag))
513 		pl011_enable_ms(port);
514 
515 	/* first, disable everything */
516 	old_cr = readw(port->membase + UART011_CR);
517 	writew(0, port->membase + UART011_CR);
518 
519 	/* Set baud rate */
520 	writew(quot & 0x3f, port->membase + UART011_FBRD);
521 	writew(quot >> 6, port->membase + UART011_IBRD);
522 
523 	/*
524 	 * ----------v----------v----------v----------v-----
525 	 * NOTE: MUST BE WRITTEN AFTER UARTLCR_M & UARTLCR_L
526 	 * ----------^----------^----------^----------^-----
527 	 */
528 	writew(lcr_h, port->membase + UART011_LCRH);
529 	writew(old_cr, port->membase + UART011_CR);
530 
531 	spin_unlock_irqrestore(&port->lock, flags);
532 }
533 
pl011_type(struct uart_port * port)534 static const char *pl011_type(struct uart_port *port)
535 {
536 	return port->type == PORT_AMBA ? "AMBA/PL011" : NULL;
537 }
538 
539 /*
540  * Release the memory region(s) being used by 'port'
541  */
pl010_release_port(struct uart_port * port)542 static void pl010_release_port(struct uart_port *port)
543 {
544 	release_mem_region(port->mapbase, SZ_4K);
545 }
546 
547 /*
548  * Request the memory region(s) being used by 'port'
549  */
pl010_request_port(struct uart_port * port)550 static int pl010_request_port(struct uart_port *port)
551 {
552 	return request_mem_region(port->mapbase, SZ_4K, "uart-pl011")
553 			!= NULL ? 0 : -EBUSY;
554 }
555 
556 /*
557  * Configure/autoconfigure the port.
558  */
pl010_config_port(struct uart_port * port,int flags)559 static void pl010_config_port(struct uart_port *port, int flags)
560 {
561 	if (flags & UART_CONFIG_TYPE) {
562 		port->type = PORT_AMBA;
563 		pl010_request_port(port);
564 	}
565 }
566 
567 /*
568  * verify the new serial_struct (for TIOCSSERIAL).
569  */
pl010_verify_port(struct uart_port * port,struct serial_struct * ser)570 static int pl010_verify_port(struct uart_port *port, struct serial_struct *ser)
571 {
572 	int ret = 0;
573 	if (ser->type != PORT_UNKNOWN && ser->type != PORT_AMBA)
574 		ret = -EINVAL;
575 	if (ser->irq < 0 || ser->irq >= nr_irqs)
576 		ret = -EINVAL;
577 	if (ser->baud_base < 9600)
578 		ret = -EINVAL;
579 	return ret;
580 }
581 
582 static struct uart_ops amba_pl011_pops = {
583 	.tx_empty	= pl01x_tx_empty,
584 	.set_mctrl	= pl011_set_mctrl,
585 	.get_mctrl	= pl01x_get_mctrl,
586 	.stop_tx	= pl011_stop_tx,
587 	.start_tx	= pl011_start_tx,
588 	.stop_rx	= pl011_stop_rx,
589 	.enable_ms	= pl011_enable_ms,
590 	.break_ctl	= pl011_break_ctl,
591 	.startup	= pl011_startup,
592 	.shutdown	= pl011_shutdown,
593 	.set_termios	= pl011_set_termios,
594 	.type		= pl011_type,
595 	.release_port	= pl010_release_port,
596 	.request_port	= pl010_request_port,
597 	.config_port	= pl010_config_port,
598 	.verify_port	= pl010_verify_port,
599 #ifdef CONFIG_CONSOLE_POLL
600 	.poll_get_char = pl010_get_poll_char,
601 	.poll_put_char = pl010_put_poll_char,
602 #endif
603 };
604 
605 static struct uart_amba_port *amba_ports[UART_NR];
606 
607 #ifdef CONFIG_SERIAL_AMBA_PL011_CONSOLE
608 
pl011_console_putchar(struct uart_port * port,int ch)609 static void pl011_console_putchar(struct uart_port *port, int ch)
610 {
611 	struct uart_amba_port *uap = (struct uart_amba_port *)port;
612 
613 	while (readw(uap->port.membase + UART01x_FR) & UART01x_FR_TXFF)
614 		barrier();
615 	writew(ch, uap->port.membase + UART01x_DR);
616 }
617 
618 static void
pl011_console_write(struct console * co,const char * s,unsigned int count)619 pl011_console_write(struct console *co, const char *s, unsigned int count)
620 {
621 	struct uart_amba_port *uap = amba_ports[co->index];
622 	unsigned int status, old_cr, new_cr;
623 
624 	clk_enable(uap->clk);
625 
626 	/*
627 	 *	First save the CR then disable the interrupts
628 	 */
629 	old_cr = readw(uap->port.membase + UART011_CR);
630 	new_cr = old_cr & ~UART011_CR_CTSEN;
631 	new_cr |= UART01x_CR_UARTEN | UART011_CR_TXE;
632 	writew(new_cr, uap->port.membase + UART011_CR);
633 
634 	uart_console_write(&uap->port, s, count, pl011_console_putchar);
635 
636 	/*
637 	 *	Finally, wait for transmitter to become empty
638 	 *	and restore the TCR
639 	 */
640 	do {
641 		status = readw(uap->port.membase + UART01x_FR);
642 	} while (status & UART01x_FR_BUSY);
643 	writew(old_cr, uap->port.membase + UART011_CR);
644 
645 	clk_disable(uap->clk);
646 }
647 
648 static void __init
pl011_console_get_options(struct uart_amba_port * uap,int * baud,int * parity,int * bits)649 pl011_console_get_options(struct uart_amba_port *uap, int *baud,
650 			     int *parity, int *bits)
651 {
652 	if (readw(uap->port.membase + UART011_CR) & UART01x_CR_UARTEN) {
653 		unsigned int lcr_h, ibrd, fbrd;
654 
655 		lcr_h = readw(uap->port.membase + UART011_LCRH);
656 
657 		*parity = 'n';
658 		if (lcr_h & UART01x_LCRH_PEN) {
659 			if (lcr_h & UART01x_LCRH_EPS)
660 				*parity = 'e';
661 			else
662 				*parity = 'o';
663 		}
664 
665 		if ((lcr_h & 0x60) == UART01x_LCRH_WLEN_7)
666 			*bits = 7;
667 		else
668 			*bits = 8;
669 
670 		ibrd = readw(uap->port.membase + UART011_IBRD);
671 		fbrd = readw(uap->port.membase + UART011_FBRD);
672 
673 		*baud = uap->port.uartclk * 4 / (64 * ibrd + fbrd);
674 	}
675 }
676 
pl011_console_setup(struct console * co,char * options)677 static int __init pl011_console_setup(struct console *co, char *options)
678 {
679 	struct uart_amba_port *uap;
680 	int baud = 38400;
681 	int bits = 8;
682 	int parity = 'n';
683 	int flow = 'n';
684 
685 	/*
686 	 * Check whether an invalid uart number has been specified, and
687 	 * if so, search for the first available port that does have
688 	 * console support.
689 	 */
690 	if (co->index >= UART_NR)
691 		co->index = 0;
692 	uap = amba_ports[co->index];
693 	if (!uap)
694 		return -ENODEV;
695 
696 	uap->port.uartclk = clk_get_rate(uap->clk);
697 
698 	if (options)
699 		uart_parse_options(options, &baud, &parity, &bits, &flow);
700 	else
701 		pl011_console_get_options(uap, &baud, &parity, &bits);
702 
703 	return uart_set_options(&uap->port, co, baud, parity, bits, flow);
704 }
705 
706 static struct uart_driver amba_reg;
707 static struct console amba_console = {
708 	.name		= "ttyAMA",
709 	.write		= pl011_console_write,
710 	.device		= uart_console_device,
711 	.setup		= pl011_console_setup,
712 	.flags		= CON_PRINTBUFFER,
713 	.index		= -1,
714 	.data		= &amba_reg,
715 };
716 
717 #define AMBA_CONSOLE	(&amba_console)
718 #else
719 #define AMBA_CONSOLE	NULL
720 #endif
721 
722 static struct uart_driver amba_reg = {
723 	.owner			= THIS_MODULE,
724 	.driver_name		= "ttyAMA",
725 	.dev_name		= "ttyAMA",
726 	.major			= SERIAL_AMBA_MAJOR,
727 	.minor			= SERIAL_AMBA_MINOR,
728 	.nr			= UART_NR,
729 	.cons			= AMBA_CONSOLE,
730 };
731 
pl011_probe(struct amba_device * dev,void * id)732 static int pl011_probe(struct amba_device *dev, void *id)
733 {
734 	struct uart_amba_port *uap;
735 	void __iomem *base;
736 	int i, ret;
737 
738 	for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
739 		if (amba_ports[i] == NULL)
740 			break;
741 
742 	if (i == ARRAY_SIZE(amba_ports)) {
743 		ret = -EBUSY;
744 		goto out;
745 	}
746 
747 	uap = kzalloc(sizeof(struct uart_amba_port), GFP_KERNEL);
748 	if (uap == NULL) {
749 		ret = -ENOMEM;
750 		goto out;
751 	}
752 
753 	base = ioremap(dev->res.start, PAGE_SIZE);
754 	if (!base) {
755 		ret = -ENOMEM;
756 		goto free;
757 	}
758 
759 	uap->clk = clk_get(&dev->dev, NULL);
760 	if (IS_ERR(uap->clk)) {
761 		ret = PTR_ERR(uap->clk);
762 		goto unmap;
763 	}
764 
765 	uap->port.dev = &dev->dev;
766 	uap->port.mapbase = dev->res.start;
767 	uap->port.membase = base;
768 	uap->port.iotype = UPIO_MEM;
769 	uap->port.irq = dev->irq[0];
770 	uap->port.fifosize = 16;
771 	uap->port.ops = &amba_pl011_pops;
772 	uap->port.flags = UPF_BOOT_AUTOCONF;
773 	uap->port.line = i;
774 
775 	amba_ports[i] = uap;
776 
777 	amba_set_drvdata(dev, uap);
778 	ret = uart_add_one_port(&amba_reg, &uap->port);
779 	if (ret) {
780 		amba_set_drvdata(dev, NULL);
781 		amba_ports[i] = NULL;
782 		clk_put(uap->clk);
783  unmap:
784 		iounmap(base);
785  free:
786 		kfree(uap);
787 	}
788  out:
789 	return ret;
790 }
791 
pl011_remove(struct amba_device * dev)792 static int pl011_remove(struct amba_device *dev)
793 {
794 	struct uart_amba_port *uap = amba_get_drvdata(dev);
795 	int i;
796 
797 	amba_set_drvdata(dev, NULL);
798 
799 	uart_remove_one_port(&amba_reg, &uap->port);
800 
801 	for (i = 0; i < ARRAY_SIZE(amba_ports); i++)
802 		if (amba_ports[i] == uap)
803 			amba_ports[i] = NULL;
804 
805 	iounmap(uap->port.membase);
806 	clk_put(uap->clk);
807 	kfree(uap);
808 	return 0;
809 }
810 
811 static struct amba_id pl011_ids[] __initdata = {
812 	{
813 		.id	= 0x00041011,
814 		.mask	= 0x000fffff,
815 	},
816 	{ 0, 0 },
817 };
818 
819 static struct amba_driver pl011_driver = {
820 	.drv = {
821 		.name	= "uart-pl011",
822 	},
823 	.id_table	= pl011_ids,
824 	.probe		= pl011_probe,
825 	.remove		= pl011_remove,
826 };
827 
pl011_init(void)828 static int __init pl011_init(void)
829 {
830 	int ret;
831 	printk(KERN_INFO "Serial: AMBA PL011 UART driver\n");
832 
833 	ret = uart_register_driver(&amba_reg);
834 	if (ret == 0) {
835 		ret = amba_driver_register(&pl011_driver);
836 		if (ret)
837 			uart_unregister_driver(&amba_reg);
838 	}
839 	return ret;
840 }
841 
pl011_exit(void)842 static void __exit pl011_exit(void)
843 {
844 	amba_driver_unregister(&pl011_driver);
845 	uart_unregister_driver(&amba_reg);
846 }
847 
848 module_init(pl011_init);
849 module_exit(pl011_exit);
850 
851 MODULE_AUTHOR("ARM Ltd/Deep Blue Solutions Ltd");
852 MODULE_DESCRIPTION("ARM AMBA serial port driver");
853 MODULE_LICENSE("GPL");
854