uart[8250],io,<addr>[,options]
uart[8250],mmio,<addr>[,options]
+ uart[8250],mmio16,<addr>[,options]
uart[8250],mmio32,<addr>[,options]
uart[8250],0x<addr>[,options]
Start an early, polled-mode console on the 8250/16550
UART at the specified I/O port or MMIO address,
switching to the matching ttyS device later.
MMIO inter-register address stride is either 8-bit
- (mmio) or 32-bit (mmio32).
- If none of [io|mmio|mmio32], <addr> is assumed to be
- equivalent to 'mmio'. 'options' are specified in the
- same format described for ttyS above; if unspecified,
+ (mmio), 16-bit (mmio16), or 32-bit (mmio32).
+ If none of [io|mmio|mmio16|mmio32], <addr> is assumed
+ to be equivalent to 'mmio'. 'options' are specified in
+ the same format described for ttyS above; if unspecified,
the h/w is not re-initialized.
hvc<n> Use the hypervisor console device <n>. This is for
* @options: ptr to option string from console command line
*
* Only attempts to match console command lines of the form:
- * console=uart[8250],io|mmio|mmio32,<addr>[,<options>]
+ * console=uart[8250],io|mmio|mmio16|mmio32,<addr>[,<options>]
* console=uart[8250],0x<addr>[,<options>]
* This form is used to register an initial earlycon boot console and
* replace it with the serial8250_console at 8250 driver init.
if (port->iotype != iotype)
continue;
- if ((iotype == UPIO_MEM || iotype == UPIO_MEM32) &&
- (port->mapbase != addr))
+ if ((iotype == UPIO_MEM || iotype == UPIO_MEM16 ||
+ iotype == UPIO_MEM32 || iotype == UPIO_MEM32BE)
+ && (port->mapbase != addr))
continue;
if (iotype == UPIO_PORT && port->iobase != addr)
continue;
switch (port->iotype) {
case UPIO_MEM:
return readb(port->membase + offset);
+ case UPIO_MEM16:
+ return readw(port->membase + (offset << 1));
case UPIO_MEM32:
return readl(port->membase + (offset << 2));
case UPIO_MEM32BE:
case UPIO_MEM:
writeb(value, port->membase + offset);
break;
+ case UPIO_MEM16:
+ writew(value, port->membase + (offset << 1));
+ break;
case UPIO_MEM32:
writel(value, port->membase + (offset << 2));
break;
writeb(value, p->membase + offset);
}
+static void mem16_serial_out(struct uart_port *p, int offset, int value)
+{
+ offset = offset << p->regshift;
+ writew(value, p->membase + offset);
+}
+
+static unsigned int mem16_serial_in(struct uart_port *p, int offset)
+{
+ offset = offset << p->regshift;
+ return readw(p->membase + offset);
+}
+
static void mem32_serial_out(struct uart_port *p, int offset, int value)
{
offset = offset << p->regshift;
p->serial_out = mem_serial_out;
break;
+ case UPIO_MEM16:
+ p->serial_in = mem16_serial_in;
+ p->serial_out = mem16_serial_out;
+ break;
+
case UPIO_MEM32:
p->serial_in = mem32_serial_in;
p->serial_out = mem32_serial_out;
{
switch (p->iotype) {
case UPIO_MEM:
+ case UPIO_MEM16:
case UPIO_MEM32:
case UPIO_MEM32BE:
case UPIO_AU:
case UPIO_TSI:
case UPIO_MEM32:
case UPIO_MEM32BE:
+ case UPIO_MEM16:
case UPIO_MEM:
if (!port->mapbase)
break;
case UPIO_TSI:
case UPIO_MEM32:
case UPIO_MEM32BE:
+ case UPIO_MEM16:
case UPIO_MEM:
if (!port->mapbase)
break;
return -EINVAL;
switch (port->iotype) {
+ case UPIO_MEM:
+ port->mapbase = addr;
+ break;
+ case UPIO_MEM16:
+ port->regshift = 1;
+ port->mapbase = addr;
+ break;
case UPIO_MEM32:
case UPIO_MEM32BE:
- port->regshift = 2; /* fall-through */
- case UPIO_MEM:
+ port->regshift = 2;
port->mapbase = addr;
break;
case UPIO_PORT:
strlcpy(device->options, options, length);
}
- if (port->iotype == UPIO_MEM || port->iotype == UPIO_MEM32 ||
- port->iotype == UPIO_MEM32BE)
+ if (port->iotype == UPIO_MEM || port->iotype == UPIO_MEM16 ||
+ port->iotype == UPIO_MEM32 || port->iotype == UPIO_MEM32BE)
pr_info("Early serial console at MMIO%s 0x%llx (options '%s')\n",
(port->iotype == UPIO_MEM) ? "" :
+ (port->iotype == UPIO_MEM16) ? "16" :
(port->iotype == UPIO_MEM32) ? "32" : "32be",
(unsigned long long)port->mapbase,
device->options);
case 1:
port->iotype = UPIO_MEM;
break;
+ case 2:
+ port->iotype = UPIO_MEM16;
+ break;
case 4:
port->iotype = of_device_is_big_endian(np) ?
UPIO_MEM32BE : UPIO_MEM32;
* @options: ptr for <options> field; NULL if not present (out)
*
* Decodes earlycon kernel command line parameters of the form
- * earlycon=<name>,io|mmio|mmio32|mmio32be|mmio32native,<addr>,<options>
- * console=<name>,io|mmio|mmio32|mmio32be|mmio32native,<addr>,<options>
+ * earlycon=<name>,io|mmio|mmio16|mmio32|mmio32be|mmio32native,<addr>,<options>
+ * console=<name>,io|mmio|mmio16|mmio32|mmio32be|mmio32native,<addr>,<options>
*
* The optional form
* earlycon=<name>,0x<addr>,<options>
if (strncmp(p, "mmio,", 5) == 0) {
*iotype = UPIO_MEM;
p += 5;
+ } else if (strncmp(p, "mmio16,", 7) == 0) {
+ *iotype = UPIO_MEM16;
+ p += 7;
} else if (strncmp(p, "mmio32,", 7) == 0) {
*iotype = UPIO_MEM32;
p += 7;
"I/O 0x%lx offset 0x%x", port->iobase, port->hub6);
break;
case UPIO_MEM:
+ case UPIO_MEM16:
case UPIO_MEM32:
case UPIO_MEM32BE:
case UPIO_AU:
return (port1->iobase == port2->iobase) &&
(port1->hub6 == port2->hub6);
case UPIO_MEM:
+ case UPIO_MEM16:
case UPIO_MEM32:
case UPIO_MEM32BE:
case UPIO_AU:
#define UPIO_AU (SERIAL_IO_AU) /* Au1x00 and RT288x type IO */
#define UPIO_TSI (SERIAL_IO_TSI) /* Tsi108/109 type IO */
#define UPIO_MEM32BE (SERIAL_IO_MEM32BE) /* 32b big endian */
+#define UPIO_MEM16 (SERIAL_IO_MEM16) /* 16b little endian */
unsigned int read_status_mask; /* driver specific */
unsigned int ignore_status_mask; /* driver specific */
#define SERIAL_IO_AU 4
#define SERIAL_IO_TSI 5
#define SERIAL_IO_MEM32BE 6
+#define SERIAL_IO_MEM16 7
#define UART_CLEAR_FIFO 0x01
#define UART_USE_FIFO 0x02