diff options
-rw-r--r-- | drivers/of/fdt.c | 56 |
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 | ||
701 | extern struct of_device_id __earlycon_of_table[]; | ||
702 | |||
703 | int __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 | |||
745 | static int __init setup_of_earlycon(char *buf) | ||
746 | { | ||
747 | if (buf) | ||
748 | return 0; | ||
749 | |||
750 | return early_init_dt_scan_chosen_serial(); | ||
751 | } | ||
752 | early_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 | */ |