aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of/fdt.c
diff options
context:
space:
mode:
authorRob Herring <robh@kernel.org>2014-03-27 09:07:01 -0400
committerRob Herring <robh@kernel.org>2014-05-20 16:19:26 -0400
commitfb11ffe74c794a510a29ad8cd81d4e9e3b1c9158 (patch)
tree67a58a06a67ea7e0ac7374d604312d2207457498 /drivers/of/fdt.c
parente06e8b27082852bdab417af884241a4ed2037c73 (diff)
of/fdt: add FDT serial scanning for earlycon
This adds FDT parsing of {linux,}stdout-path to setup an early serial console. Enabling of the early console is triggered with "earlycon" (with no options) on the kernel command line. Platforms must either have fixmap permanent mapping support, have a functioning ioremap when early params are parsed, or explicitly call early_init_dt_scan_chosen_serial from architecture code. Signed-off-by: Rob Herring <robh@kernel.org> Acked-by: Grant Likely <grant.likely@linaro.org>
Diffstat (limited to 'drivers/of/fdt.c')
-rw-r--r--drivers/of/fdt.c56
1 files changed, 56 insertions, 0 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c
index a6f83ea107ae..1fbeab27075f 100644
--- a/drivers/of/fdt.c
+++ b/drivers/of/fdt.c
@@ -21,6 +21,7 @@
21#include <linux/slab.h> 21#include <linux/slab.h>
22#include <linux/libfdt.h> 22#include <linux/libfdt.h>
23#include <linux/debugfs.h> 23#include <linux/debugfs.h>
24#include <linux/serial_core.h>
24 25
25#include <asm/setup.h> /* for COMMAND_LINE_SIZE */ 26#include <asm/setup.h> /* for COMMAND_LINE_SIZE */
26#include <asm/page.h> 27#include <asm/page.h>
@@ -696,6 +697,61 @@ static inline void early_init_dt_check_for_initrd(unsigned long node)
696} 697}
697#endif /* CONFIG_BLK_DEV_INITRD */ 698#endif /* CONFIG_BLK_DEV_INITRD */
698 699
700#ifdef CONFIG_SERIAL_EARLYCON
701extern struct of_device_id __earlycon_of_table[];
702
703int __init early_init_dt_scan_chosen_serial(void)
704{
705 int offset;
706 const char *p;
707 int l;
708 const struct of_device_id *match = __earlycon_of_table;
709 const void *fdt = initial_boot_params;
710
711 offset = fdt_path_offset(fdt, "/chosen");
712 if (offset < 0)
713 offset = fdt_path_offset(fdt, "/chosen@0");
714 if (offset < 0)
715 return -ENOENT;
716
717 p = fdt_getprop(fdt, offset, "stdout-path", &l);
718 if (!p)
719 p = fdt_getprop(fdt, offset, "linux,stdout-path", &l);
720 if (!p || !l)
721 return -ENOENT;
722
723 /* Get the node specified by stdout-path */
724 offset = fdt_path_offset(fdt, p);
725 if (offset < 0)
726 return -ENODEV;
727
728 while (match->compatible) {
729 unsigned long addr;
730 if (fdt_node_check_compatible(fdt, offset, match->compatible)) {
731 match++;
732 continue;
733 }
734
735 addr = fdt_translate_address(fdt, offset);
736 if (!addr)
737 return -ENXIO;
738
739 of_setup_earlycon(addr, match->data);
740 return 0;
741 }
742 return -ENODEV;
743}
744
745static int __init setup_of_earlycon(char *buf)
746{
747 if (buf)
748 return 0;
749
750 return early_init_dt_scan_chosen_serial();
751}
752early_param("earlycon", setup_of_earlycon);
753#endif
754
699/** 755/**
700 * early_init_dt_scan_root - fetch the top level address and size cells 756 * early_init_dt_scan_root - fetch the top level address and size cells
701 */ 757 */