diff options
Diffstat (limited to 'drivers/of')
| -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 | */ |
