4 * Copyright (C) 2012 ARM Ltd.
5 * Author: Catalin Marinas <catalin.marinas@arm.com>
7 * This program is free software: you can redistribute it and/or modify
8 * it under the terms of the GNU General Public License version 2 as
9 * published by the Free Software Foundation.
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
16 * You should have received a copy of the GNU General Public License
17 * along with this program. If not, see <http://www.gnu.org/licenses/>.
19 #include <linux/kernel.h>
20 #include <linux/console.h>
21 #include <linux/init.h>
22 #include <linux/string.h>
26 #include <linux/amba/serial.h>
28 static void __iomem
*early_base
;
29 static void (*printch
)(char ch
);
32 * PL011 single character TX.
34 static void pl011_printch(char ch
)
36 while (readl_relaxed(early_base
+ UART01x_FR
) & UART01x_FR_TXFF
)
38 writeb_relaxed(ch
, early_base
+ UART01x_DR
);
39 while (readl_relaxed(early_base
+ UART01x_FR
) & UART01x_FR_BUSY
)
43 struct earlycon_match
{
45 void (*printch
)(char ch
);
48 static const struct earlycon_match earlycon_match
[] __initconst
= {
49 { .name
= "pl011", .printch
= pl011_printch
, },
53 static void early_write(struct console
*con
, const char *s
, unsigned n
)
63 static struct console early_console
= {
66 .flags
= CON_PRINTBUFFER
| CON_BOOT
,
71 * Parse earlyprintk=... parameter in the format:
73 * <name>[,<addr>][,<options>]
75 * and register the early console. It is assumed that the UART has been
76 * initialised by the bootloader already.
78 static int __init
setup_early_printk(char *buf
)
80 const struct earlycon_match
*match
= earlycon_match
;
81 phys_addr_t paddr
= 0;
84 pr_warning("No earlyprintk arguments passed.\n");
89 size_t len
= strlen(match
->name
);
90 if (!strncmp(buf
, match
->name
, len
)) {
97 pr_warning("Unknown earlyprintk arguments: %s\n", buf
);
102 if (!strncmp(buf
, ",0x", 3)) {
104 paddr
= simple_strtoul(buf
+ 1, &e
, 16);
107 /* no options parsing yet */
110 early_base
= early_io_map(paddr
, EARLYCON_IOBASE
);
112 printch
= match
->printch
;
113 register_console(&early_console
);
118 early_param("earlyprintk", setup_early_printk
);