Browse Source

tty/serial: pl011: add generic earlycon support

Add earlycon support for the pl011 serial port. This allows enabling
the pl011 for console when early_params are processed. This is based
on the arm64 earlyprintk support and is intended to replace it.

Signed-off-by: Rob Herring <robh@kernel.org>
Cc: Russell King <linux@arm.linux.org.uk>
Cc: Jiri Slaby <jslaby@suse.cz>
Signed-off-by: Greg Kroah-Hartman <gregkh@linuxfoundation.org>
Rob Herring 11 years ago
parent
commit
0d3c673e78

+ 7 - 0
Documentation/kernel-parameters.txt

@@ -883,6 +883,7 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			which are not unmapped.
 			which are not unmapped.
 
 
 	earlycon=	[KNL] Output early console device and options.
 	earlycon=	[KNL] Output early console device and options.
+
 		uart[8250],io,<addr>[,options]
 		uart[8250],io,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
 		uart[8250],mmio,<addr>[,options]
 		uart[8250],mmio32,<addr>[,options]
 		uart[8250],mmio32,<addr>[,options]
@@ -892,6 +893,12 @@ bytes respectively. Such letter suffixes can also be entirely omitted.
 			(mmio) or 32-bit (mmio32).
 			(mmio) or 32-bit (mmio32).
 			The options are the same as for ttyS, above.
 			The options are the same as for ttyS, above.
 
 
+		pl011,<addr>
+			Start an early, polled-mode console on a pl011 serial
+			port at the specified address. The pl011 serial port
+			must already be setup and configured. Options are not
+			yet supported.
+
 	earlyprintk=	[X86,SH,BLACKFIN,ARM]
 	earlyprintk=	[X86,SH,BLACKFIN,ARM]
 			earlyprintk=vga
 			earlyprintk=vga
 			earlyprintk=efi
 			earlyprintk=efi

+ 1 - 0
drivers/tty/serial/Kconfig

@@ -60,6 +60,7 @@ config SERIAL_AMBA_PL011_CONSOLE
 	bool "Support for console on AMBA serial port"
 	bool "Support for console on AMBA serial port"
 	depends on SERIAL_AMBA_PL011=y
 	depends on SERIAL_AMBA_PL011=y
 	select SERIAL_CORE_CONSOLE
 	select SERIAL_CORE_CONSOLE
+	select SERIAL_EARLYCON
 	---help---
 	---help---
 	  Say Y here if you wish to use an AMBA PrimeCell UART as the system
 	  Say Y here if you wish to use an AMBA PrimeCell UART as the system
 	  console (the system console is the device which receives all kernel
 	  console (the system console is the device which receives all kernel

+ 29 - 1
drivers/tty/serial/amba-pl011.c

@@ -303,7 +303,7 @@ static void pl011_dma_probe_initcall(struct device *dev, struct uart_amba_port *
 
 
 	/* Optionally make use of an RX channel as well */
 	/* Optionally make use of an RX channel as well */
 	chan = dma_request_slave_channel(dev, "rx");
 	chan = dma_request_slave_channel(dev, "rx");
-	
+
 	if (!chan && plat->dma_rx_param) {
 	if (!chan && plat->dma_rx_param) {
 		chan = dma_request_channel(mask, plat->dma_filter, plat->dma_rx_param);
 		chan = dma_request_channel(mask, plat->dma_filter, plat->dma_rx_param);
 
 
@@ -2045,6 +2045,34 @@ static struct console amba_console = {
 };
 };
 
 
 #define AMBA_CONSOLE	(&amba_console)
 #define AMBA_CONSOLE	(&amba_console)
+
+static void pl011_putc(struct uart_port *port, int c)
+{
+	while (readl(port->membase + UART01x_FR) & UART01x_FR_TXFF)
+		;
+	writeb(c, port->membase + UART01x_DR);
+	while (readl(port->membase + UART01x_FR) & UART01x_FR_BUSY)
+		;
+}
+
+static void pl011_early_write(struct console *con, const char *s, unsigned n)
+{
+	struct earlycon_device *dev = con->data;
+
+	uart_console_write(&dev->port, s, n, pl011_putc);
+}
+
+static int __init pl011_early_console_setup(struct earlycon_device *device,
+					    const char *opt)
+{
+	if (!device->port.membase)
+		return -ENODEV;
+
+	device->con->write = pl011_early_write;
+	return 0;
+}
+EARLYCON_DECLARE(pl011, pl011_early_console_setup);
+
 #else
 #else
 #define AMBA_CONSOLE	NULL
 #define AMBA_CONSOLE	NULL
 #endif
 #endif