diff options
author | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-12 02:52:17 -0500 |
---|---|---|
committer | Linus Torvalds <torvalds@linux-foundation.org> | 2013-11-12 02:52:17 -0500 |
commit | 10d0c9705e80bbd3d587c5fad24599aabaca6688 (patch) | |
tree | 9456083a1b04b8d98da08d88e937cfeff80e2a7d /drivers/of/fdt.c | |
parent | 85b656cf1560e27a89354a23f2c10ba229d2f173 (diff) | |
parent | c11eede69b6ad0ac44ebc1e021a8d2699c5f1f8f (diff) |
Merge tag 'devicetree-for-3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux
Pull devicetree updates from Rob Herring:
"DeviceTree updates for 3.13. This is a bit larger pull request than
usual for this cycle with lots of clean-up.
- Cross arch clean-up and consolidation of early DT scanning code.
- Clean-up and removal of arch prom.h headers. Makes arch specific
prom.h optional on all but Sparc.
- Addition of interrupts-extended property for devices connected to
multiple interrupt controllers.
- Refactoring of DT interrupt parsing code in preparation for
deferred probe of interrupts.
- ARM cpu and cpu topology bindings documentation.
- Various DT vendor binding documentation updates"
* tag 'devicetree-for-3.13' of git://git.kernel.org/pub/scm/linux/kernel/git/robh/linux: (82 commits)
powerpc: add missing explicit OF includes for ppc
dt/irq: add empty of_irq_count for !OF_IRQ
dt: disable self-tests for !OF_IRQ
of: irq: Fix interrupt-map entry matching
MIPS: Netlogic: replace early_init_devtree() call
of: Add Panasonic Corporation vendor prefix
of: Add Chunghwa Picture Tubes Ltd. vendor prefix
of: Add AU Optronics Corporation vendor prefix
of/irq: Fix potential buffer overflow
of/irq: Fix bug in interrupt parsing refactor.
of: set dma_mask to point to coherent_dma_mask
of: add vendor prefix for PHYTEC Messtechnik GmbH
DT: sort vendor-prefixes.txt
of: Add vendor prefix for Cadence
of: Add empty for_each_available_child_of_node() macro definition
arm/versatile: Fix versatile irq specifications.
of/irq: create interrupts-extended property
microblaze/pci: Drop PowerPC-ism from irq parsing
of/irq: Create of_irq_parse_and_map_pci() to consolidate arch code.
of/irq: Use irq_of_parse_and_map()
...
Diffstat (limited to 'drivers/of/fdt.c')
-rw-r--r-- | drivers/of/fdt.c | 138 |
1 files changed, 135 insertions, 3 deletions
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index a4fa9ad31b8f..2fa024b97c43 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
@@ -618,12 +618,72 @@ int __init of_scan_flat_dt_by_path(const char *path, | |||
618 | return ret; | 618 | return ret; |
619 | } | 619 | } |
620 | 620 | ||
621 | const char * __init of_flat_dt_get_machine_name(void) | ||
622 | { | ||
623 | const char *name; | ||
624 | unsigned long dt_root = of_get_flat_dt_root(); | ||
625 | |||
626 | name = of_get_flat_dt_prop(dt_root, "model", NULL); | ||
627 | if (!name) | ||
628 | name = of_get_flat_dt_prop(dt_root, "compatible", NULL); | ||
629 | return name; | ||
630 | } | ||
631 | |||
632 | /** | ||
633 | * of_flat_dt_match_machine - Iterate match tables to find matching machine. | ||
634 | * | ||
635 | * @default_match: A machine specific ptr to return in case of no match. | ||
636 | * @get_next_compat: callback function to return next compatible match table. | ||
637 | * | ||
638 | * Iterate through machine match tables to find the best match for the machine | ||
639 | * compatible string in the FDT. | ||
640 | */ | ||
641 | const void * __init of_flat_dt_match_machine(const void *default_match, | ||
642 | const void * (*get_next_compat)(const char * const**)) | ||
643 | { | ||
644 | const void *data = NULL; | ||
645 | const void *best_data = default_match; | ||
646 | const char *const *compat; | ||
647 | unsigned long dt_root; | ||
648 | unsigned int best_score = ~1, score = 0; | ||
649 | |||
650 | dt_root = of_get_flat_dt_root(); | ||
651 | while ((data = get_next_compat(&compat))) { | ||
652 | score = of_flat_dt_match(dt_root, compat); | ||
653 | if (score > 0 && score < best_score) { | ||
654 | best_data = data; | ||
655 | best_score = score; | ||
656 | } | ||
657 | } | ||
658 | if (!best_data) { | ||
659 | const char *prop; | ||
660 | long size; | ||
661 | |||
662 | pr_err("\n unrecognized device tree list:\n[ "); | ||
663 | |||
664 | prop = of_get_flat_dt_prop(dt_root, "compatible", &size); | ||
665 | if (prop) { | ||
666 | while (size > 0) { | ||
667 | printk("'%s' ", prop); | ||
668 | size -= strlen(prop) + 1; | ||
669 | prop += strlen(prop) + 1; | ||
670 | } | ||
671 | } | ||
672 | printk("]\n\n"); | ||
673 | return NULL; | ||
674 | } | ||
675 | |||
676 | pr_info("Machine model: %s\n", of_flat_dt_get_machine_name()); | ||
677 | |||
678 | return best_data; | ||
679 | } | ||
680 | |||
621 | #ifdef CONFIG_BLK_DEV_INITRD | 681 | #ifdef CONFIG_BLK_DEV_INITRD |
622 | /** | 682 | /** |
623 | * early_init_dt_check_for_initrd - Decode initrd location from flat tree | 683 | * early_init_dt_check_for_initrd - Decode initrd location from flat tree |
624 | * @node: reference to node containing initrd location ('chosen') | 684 | * @node: reference to node containing initrd location ('chosen') |
625 | */ | 685 | */ |
626 | void __init early_init_dt_check_for_initrd(unsigned long node) | 686 | static void __init early_init_dt_check_for_initrd(unsigned long node) |
627 | { | 687 | { |
628 | u64 start, end; | 688 | u64 start, end; |
629 | unsigned long len; | 689 | unsigned long len; |
@@ -641,12 +701,15 @@ void __init early_init_dt_check_for_initrd(unsigned long node) | |||
641 | return; | 701 | return; |
642 | end = of_read_number(prop, len/4); | 702 | end = of_read_number(prop, len/4); |
643 | 703 | ||
644 | early_init_dt_setup_initrd_arch(start, end); | 704 | initrd_start = (unsigned long)__va(start); |
705 | initrd_end = (unsigned long)__va(end); | ||
706 | initrd_below_start_ok = 1; | ||
707 | |||
645 | pr_debug("initrd_start=0x%llx initrd_end=0x%llx\n", | 708 | pr_debug("initrd_start=0x%llx initrd_end=0x%llx\n", |
646 | (unsigned long long)start, (unsigned long long)end); | 709 | (unsigned long long)start, (unsigned long long)end); |
647 | } | 710 | } |
648 | #else | 711 | #else |
649 | inline void early_init_dt_check_for_initrd(unsigned long node) | 712 | static inline void early_init_dt_check_for_initrd(unsigned long node) |
650 | { | 713 | { |
651 | } | 714 | } |
652 | #endif /* CONFIG_BLK_DEV_INITRD */ | 715 | #endif /* CONFIG_BLK_DEV_INITRD */ |
@@ -774,6 +837,25 @@ int __init early_init_dt_scan_chosen(unsigned long node, const char *uname, | |||
774 | } | 837 | } |
775 | 838 | ||
776 | #ifdef CONFIG_HAVE_MEMBLOCK | 839 | #ifdef CONFIG_HAVE_MEMBLOCK |
840 | void __init __weak early_init_dt_add_memory_arch(u64 base, u64 size) | ||
841 | { | ||
842 | const u64 phys_offset = __pa(PAGE_OFFSET); | ||
843 | base &= PAGE_MASK; | ||
844 | size &= PAGE_MASK; | ||
845 | if (base + size < phys_offset) { | ||
846 | pr_warning("Ignoring memory block 0x%llx - 0x%llx\n", | ||
847 | base, base + size); | ||
848 | return; | ||
849 | } | ||
850 | if (base < phys_offset) { | ||
851 | pr_warning("Ignoring memory range 0x%llx - 0x%llx\n", | ||
852 | base, phys_offset); | ||
853 | size -= phys_offset - base; | ||
854 | base = phys_offset; | ||
855 | } | ||
856 | memblock_add(base, size); | ||
857 | } | ||
858 | |||
777 | /* | 859 | /* |
778 | * called from unflatten_device_tree() to bootstrap devicetree itself | 860 | * called from unflatten_device_tree() to bootstrap devicetree itself |
779 | * Architectures can override this definition if memblock isn't used | 861 | * Architectures can override this definition if memblock isn't used |
@@ -784,6 +866,32 @@ void * __init __weak early_init_dt_alloc_memory_arch(u64 size, u64 align) | |||
784 | } | 866 | } |
785 | #endif | 867 | #endif |
786 | 868 | ||
869 | bool __init early_init_dt_scan(void *params) | ||
870 | { | ||
871 | if (!params) | ||
872 | return false; | ||
873 | |||
874 | /* Setup flat device-tree pointer */ | ||
875 | initial_boot_params = params; | ||
876 | |||
877 | /* check device tree validity */ | ||
878 | if (be32_to_cpu(initial_boot_params->magic) != OF_DT_HEADER) { | ||
879 | initial_boot_params = NULL; | ||
880 | return false; | ||
881 | } | ||
882 | |||
883 | /* Retrieve various information from the /chosen node */ | ||
884 | of_scan_flat_dt(early_init_dt_scan_chosen, boot_command_line); | ||
885 | |||
886 | /* Initialize {size,address}-cells info */ | ||
887 | of_scan_flat_dt(early_init_dt_scan_root, NULL); | ||
888 | |||
889 | /* Setup memory, calling early_init_dt_add_memory_arch */ | ||
890 | of_scan_flat_dt(early_init_dt_scan_memory, NULL); | ||
891 | |||
892 | return true; | ||
893 | } | ||
894 | |||
787 | /** | 895 | /** |
788 | * unflatten_device_tree - create tree of device_nodes from flat blob | 896 | * unflatten_device_tree - create tree of device_nodes from flat blob |
789 | * | 897 | * |
@@ -801,4 +909,28 @@ void __init unflatten_device_tree(void) | |||
801 | of_alias_scan(early_init_dt_alloc_memory_arch); | 909 | of_alias_scan(early_init_dt_alloc_memory_arch); |
802 | } | 910 | } |
803 | 911 | ||
912 | /** | ||
913 | * unflatten_and_copy_device_tree - copy and create tree of device_nodes from flat blob | ||
914 | * | ||
915 | * Copies and unflattens the device-tree passed by the firmware, creating the | ||
916 | * tree of struct device_node. It also fills the "name" and "type" | ||
917 | * pointers of the nodes so the normal device-tree walking functions | ||
918 | * can be used. This should only be used when the FDT memory has not been | ||
919 | * reserved such is the case when the FDT is built-in to the kernel init | ||
920 | * section. If the FDT memory is reserved already then unflatten_device_tree | ||
921 | * should be used instead. | ||
922 | */ | ||
923 | void __init unflatten_and_copy_device_tree(void) | ||
924 | { | ||
925 | int size = __be32_to_cpu(initial_boot_params->totalsize); | ||
926 | void *dt = early_init_dt_alloc_memory_arch(size, | ||
927 | __alignof__(struct boot_param_header)); | ||
928 | |||
929 | if (dt) { | ||
930 | memcpy(dt, initial_boot_params, size); | ||
931 | initial_boot_params = dt; | ||
932 | } | ||
933 | unflatten_device_tree(); | ||
934 | } | ||
935 | |||
804 | #endif /* CONFIG_OF_EARLY_FLATTREE */ | 936 | #endif /* CONFIG_OF_EARLY_FLATTREE */ |