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 | |
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')
-rw-r--r-- | drivers/of/Kconfig | 1 | ||||
-rw-r--r-- | drivers/of/address.c | 18 | ||||
-rw-r--r-- | drivers/of/base.c | 65 | ||||
-rw-r--r-- | drivers/of/fdt.c | 138 | ||||
-rw-r--r-- | drivers/of/irq.c | 164 | ||||
-rw-r--r-- | drivers/of/of_pci.c | 1 | ||||
-rw-r--r-- | drivers/of/of_pci_irq.c | 41 | ||||
-rw-r--r-- | drivers/of/pdt.c | 1 | ||||
-rw-r--r-- | drivers/of/platform.c | 2 | ||||
-rw-r--r-- | drivers/of/selftest.c | 161 |
10 files changed, 477 insertions, 115 deletions
diff --git a/drivers/of/Kconfig b/drivers/of/Kconfig index 78cc76053328..de6f8990246f 100644 --- a/drivers/of/Kconfig +++ b/drivers/of/Kconfig | |||
@@ -17,6 +17,7 @@ config PROC_DEVICETREE | |||
17 | 17 | ||
18 | config OF_SELFTEST | 18 | config OF_SELFTEST |
19 | bool "Device Tree Runtime self tests" | 19 | bool "Device Tree Runtime self tests" |
20 | depends on OF_IRQ | ||
20 | help | 21 | help |
21 | This option builds in test cases for the device tree infrastructure | 22 | This option builds in test cases for the device tree infrastructure |
22 | that are executed one at boot time, and the results dumped to the | 23 | that are executed one at boot time, and the results dumped to the |
diff --git a/drivers/of/address.c b/drivers/of/address.c index b55c21890760..4b9317bdb81c 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c | |||
@@ -489,7 +489,7 @@ static u64 __of_translate_address(struct device_node *dev, | |||
489 | int na, ns, pna, pns; | 489 | int na, ns, pna, pns; |
490 | u64 result = OF_BAD_ADDR; | 490 | u64 result = OF_BAD_ADDR; |
491 | 491 | ||
492 | pr_debug("OF: ** translation for device %s **\n", dev->full_name); | 492 | pr_debug("OF: ** translation for device %s **\n", of_node_full_name(dev)); |
493 | 493 | ||
494 | /* Increase refcount at current level */ | 494 | /* Increase refcount at current level */ |
495 | of_node_get(dev); | 495 | of_node_get(dev); |
@@ -504,13 +504,13 @@ static u64 __of_translate_address(struct device_node *dev, | |||
504 | bus->count_cells(dev, &na, &ns); | 504 | bus->count_cells(dev, &na, &ns); |
505 | if (!OF_CHECK_COUNTS(na, ns)) { | 505 | if (!OF_CHECK_COUNTS(na, ns)) { |
506 | printk(KERN_ERR "prom_parse: Bad cell count for %s\n", | 506 | printk(KERN_ERR "prom_parse: Bad cell count for %s\n", |
507 | dev->full_name); | 507 | of_node_full_name(dev)); |
508 | goto bail; | 508 | goto bail; |
509 | } | 509 | } |
510 | memcpy(addr, in_addr, na * 4); | 510 | memcpy(addr, in_addr, na * 4); |
511 | 511 | ||
512 | pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n", | 512 | pr_debug("OF: bus is %s (na=%d, ns=%d) on %s\n", |
513 | bus->name, na, ns, parent->full_name); | 513 | bus->name, na, ns, of_node_full_name(parent)); |
514 | of_dump_addr("OF: translating address:", addr, na); | 514 | of_dump_addr("OF: translating address:", addr, na); |
515 | 515 | ||
516 | /* Translate */ | 516 | /* Translate */ |
@@ -532,12 +532,12 @@ static u64 __of_translate_address(struct device_node *dev, | |||
532 | pbus->count_cells(dev, &pna, &pns); | 532 | pbus->count_cells(dev, &pna, &pns); |
533 | if (!OF_CHECK_COUNTS(pna, pns)) { | 533 | if (!OF_CHECK_COUNTS(pna, pns)) { |
534 | printk(KERN_ERR "prom_parse: Bad cell count for %s\n", | 534 | printk(KERN_ERR "prom_parse: Bad cell count for %s\n", |
535 | dev->full_name); | 535 | of_node_full_name(dev)); |
536 | break; | 536 | break; |
537 | } | 537 | } |
538 | 538 | ||
539 | pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n", | 539 | pr_debug("OF: parent bus is %s (na=%d, ns=%d) on %s\n", |
540 | pbus->name, pna, pns, parent->full_name); | 540 | pbus->name, pna, pns, of_node_full_name(parent)); |
541 | 541 | ||
542 | /* Apply bus translation */ | 542 | /* Apply bus translation */ |
543 | if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop)) | 543 | if (of_translate_one(dev, bus, pbus, addr, na, ns, pna, rprop)) |
@@ -626,6 +626,14 @@ const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, | |||
626 | } | 626 | } |
627 | EXPORT_SYMBOL(of_get_address); | 627 | EXPORT_SYMBOL(of_get_address); |
628 | 628 | ||
629 | unsigned long __weak pci_address_to_pio(phys_addr_t address) | ||
630 | { | ||
631 | if (address > IO_SPACE_LIMIT) | ||
632 | return (unsigned long)-1; | ||
633 | |||
634 | return (unsigned long) address; | ||
635 | } | ||
636 | |||
629 | static int __of_address_to_resource(struct device_node *dev, | 637 | static int __of_address_to_resource(struct device_node *dev, |
630 | const __be32 *addrp, u64 size, unsigned int flags, | 638 | const __be32 *addrp, u64 size, unsigned int flags, |
631 | const char *name, struct resource *r) | 639 | const char *name, struct resource *r) |
diff --git a/drivers/of/base.c b/drivers/of/base.c index aace017fc452..f807d0edabf3 100644 --- a/drivers/of/base.c +++ b/drivers/of/base.c | |||
@@ -74,6 +74,13 @@ int of_n_size_cells(struct device_node *np) | |||
74 | } | 74 | } |
75 | EXPORT_SYMBOL(of_n_size_cells); | 75 | EXPORT_SYMBOL(of_n_size_cells); |
76 | 76 | ||
77 | #ifdef CONFIG_NUMA | ||
78 | int __weak of_node_to_nid(struct device_node *np) | ||
79 | { | ||
80 | return numa_node_id(); | ||
81 | } | ||
82 | #endif | ||
83 | |||
77 | #if defined(CONFIG_OF_DYNAMIC) | 84 | #if defined(CONFIG_OF_DYNAMIC) |
78 | /** | 85 | /** |
79 | * of_node_get - Increment refcount of a node | 86 | * of_node_get - Increment refcount of a node |
@@ -265,9 +272,9 @@ static bool __of_find_n_match_cpu_property(struct device_node *cpun, | |||
265 | 272 | ||
266 | ac = of_n_addr_cells(cpun); | 273 | ac = of_n_addr_cells(cpun); |
267 | cell = of_get_property(cpun, prop_name, &prop_len); | 274 | cell = of_get_property(cpun, prop_name, &prop_len); |
268 | if (!cell) | 275 | if (!cell || !ac) |
269 | return false; | 276 | return false; |
270 | prop_len /= sizeof(*cell); | 277 | prop_len /= sizeof(*cell) * ac; |
271 | for (tid = 0; tid < prop_len; tid++) { | 278 | for (tid = 0; tid < prop_len; tid++) { |
272 | hwid = of_read_number(cell, ac); | 279 | hwid = of_read_number(cell, ac); |
273 | if (arch_match_cpu_phys_id(cpu, hwid)) { | 280 | if (arch_match_cpu_phys_id(cpu, hwid)) { |
@@ -280,6 +287,31 @@ static bool __of_find_n_match_cpu_property(struct device_node *cpun, | |||
280 | return false; | 287 | return false; |
281 | } | 288 | } |
282 | 289 | ||
290 | /* | ||
291 | * arch_find_n_match_cpu_physical_id - See if the given device node is | ||
292 | * for the cpu corresponding to logical cpu 'cpu'. Return true if so, | ||
293 | * else false. If 'thread' is non-NULL, the local thread number within the | ||
294 | * core is returned in it. | ||
295 | */ | ||
296 | bool __weak arch_find_n_match_cpu_physical_id(struct device_node *cpun, | ||
297 | int cpu, unsigned int *thread) | ||
298 | { | ||
299 | /* Check for non-standard "ibm,ppc-interrupt-server#s" property | ||
300 | * for thread ids on PowerPC. If it doesn't exist fallback to | ||
301 | * standard "reg" property. | ||
302 | */ | ||
303 | if (IS_ENABLED(CONFIG_PPC) && | ||
304 | __of_find_n_match_cpu_property(cpun, | ||
305 | "ibm,ppc-interrupt-server#s", | ||
306 | cpu, thread)) | ||
307 | return true; | ||
308 | |||
309 | if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread)) | ||
310 | return true; | ||
311 | |||
312 | return false; | ||
313 | } | ||
314 | |||
283 | /** | 315 | /** |
284 | * of_get_cpu_node - Get device node associated with the given logical CPU | 316 | * of_get_cpu_node - Get device node associated with the given logical CPU |
285 | * | 317 | * |
@@ -300,24 +332,10 @@ static bool __of_find_n_match_cpu_property(struct device_node *cpun, | |||
300 | */ | 332 | */ |
301 | struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) | 333 | struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) |
302 | { | 334 | { |
303 | struct device_node *cpun, *cpus; | 335 | struct device_node *cpun; |
304 | |||
305 | cpus = of_find_node_by_path("/cpus"); | ||
306 | if (!cpus) | ||
307 | return NULL; | ||
308 | 336 | ||
309 | for_each_child_of_node(cpus, cpun) { | 337 | for_each_node_by_type(cpun, "cpu") { |
310 | if (of_node_cmp(cpun->type, "cpu")) | 338 | if (arch_find_n_match_cpu_physical_id(cpun, cpu, thread)) |
311 | continue; | ||
312 | /* Check for non-standard "ibm,ppc-interrupt-server#s" property | ||
313 | * for thread ids on PowerPC. If it doesn't exist fallback to | ||
314 | * standard "reg" property. | ||
315 | */ | ||
316 | if (IS_ENABLED(CONFIG_PPC) && | ||
317 | __of_find_n_match_cpu_property(cpun, | ||
318 | "ibm,ppc-interrupt-server#s", cpu, thread)) | ||
319 | return cpun; | ||
320 | if (__of_find_n_match_cpu_property(cpun, "reg", cpu, thread)) | ||
321 | return cpun; | 339 | return cpun; |
322 | } | 340 | } |
323 | return NULL; | 341 | return NULL; |
@@ -1174,6 +1192,15 @@ int of_property_count_strings(struct device_node *np, const char *propname) | |||
1174 | } | 1192 | } |
1175 | EXPORT_SYMBOL_GPL(of_property_count_strings); | 1193 | EXPORT_SYMBOL_GPL(of_property_count_strings); |
1176 | 1194 | ||
1195 | void of_print_phandle_args(const char *msg, const struct of_phandle_args *args) | ||
1196 | { | ||
1197 | int i; | ||
1198 | printk("%s %s", msg, of_node_full_name(args->np)); | ||
1199 | for (i = 0; i < args->args_count; i++) | ||
1200 | printk(i ? ",%08x" : ":%08x", args->args[i]); | ||
1201 | printk("\n"); | ||
1202 | } | ||
1203 | |||
1177 | static int __of_parse_phandle_with_args(const struct device_node *np, | 1204 | static int __of_parse_phandle_with_args(const struct device_node *np, |
1178 | const char *list_name, | 1205 | const char *list_name, |
1179 | const char *cells_name, | 1206 | const char *cells_name, |
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 */ |
diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 1752988d6aa8..786b0b47fae4 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c | |||
@@ -31,18 +31,17 @@ | |||
31 | * @dev: Device node of the device whose interrupt is to be mapped | 31 | * @dev: Device node of the device whose interrupt is to be mapped |
32 | * @index: Index of the interrupt to map | 32 | * @index: Index of the interrupt to map |
33 | * | 33 | * |
34 | * This function is a wrapper that chains of_irq_map_one() and | 34 | * This function is a wrapper that chains of_irq_parse_one() and |
35 | * irq_create_of_mapping() to make things easier to callers | 35 | * irq_create_of_mapping() to make things easier to callers |
36 | */ | 36 | */ |
37 | unsigned int irq_of_parse_and_map(struct device_node *dev, int index) | 37 | unsigned int irq_of_parse_and_map(struct device_node *dev, int index) |
38 | { | 38 | { |
39 | struct of_irq oirq; | 39 | struct of_phandle_args oirq; |
40 | 40 | ||
41 | if (of_irq_map_one(dev, index, &oirq)) | 41 | if (of_irq_parse_one(dev, index, &oirq)) |
42 | return 0; | 42 | return 0; |
43 | 43 | ||
44 | return irq_create_of_mapping(oirq.controller, oirq.specifier, | 44 | return irq_create_of_mapping(&oirq); |
45 | oirq.size); | ||
46 | } | 45 | } |
47 | EXPORT_SYMBOL_GPL(irq_of_parse_and_map); | 46 | EXPORT_SYMBOL_GPL(irq_of_parse_and_map); |
48 | 47 | ||
@@ -79,33 +78,34 @@ struct device_node *of_irq_find_parent(struct device_node *child) | |||
79 | } | 78 | } |
80 | 79 | ||
81 | /** | 80 | /** |
82 | * of_irq_map_raw - Low level interrupt tree parsing | 81 | * of_irq_parse_raw - Low level interrupt tree parsing |
83 | * @parent: the device interrupt parent | 82 | * @parent: the device interrupt parent |
84 | * @intspec: interrupt specifier ("interrupts" property of the device) | 83 | * @addr: address specifier (start of "reg" property of the device) in be32 format |
85 | * @ointsize: size of the passed in interrupt specifier | 84 | * @out_irq: structure of_irq updated by this function |
86 | * @addr: address specifier (start of "reg" property of the device) | ||
87 | * @out_irq: structure of_irq filled by this function | ||
88 | * | 85 | * |
89 | * Returns 0 on success and a negative number on error | 86 | * Returns 0 on success and a negative number on error |
90 | * | 87 | * |
91 | * This function is a low-level interrupt tree walking function. It | 88 | * This function is a low-level interrupt tree walking function. It |
92 | * can be used to do a partial walk with synthetized reg and interrupts | 89 | * can be used to do a partial walk with synthetized reg and interrupts |
93 | * properties, for example when resolving PCI interrupts when no device | 90 | * properties, for example when resolving PCI interrupts when no device |
94 | * node exist for the parent. | 91 | * node exist for the parent. It takes an interrupt specifier structure as |
92 | * input, walks the tree looking for any interrupt-map properties, translates | ||
93 | * the specifier for each map, and then returns the translated map. | ||
95 | */ | 94 | */ |
96 | int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, | 95 | int of_irq_parse_raw(const __be32 *addr, struct of_phandle_args *out_irq) |
97 | u32 ointsize, const __be32 *addr, struct of_irq *out_irq) | ||
98 | { | 96 | { |
99 | struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; | 97 | struct device_node *ipar, *tnode, *old = NULL, *newpar = NULL; |
100 | const __be32 *tmp, *imap, *imask; | 98 | __be32 initial_match_array[MAX_PHANDLE_ARGS]; |
99 | const __be32 *match_array = initial_match_array; | ||
100 | const __be32 *tmp, *imap, *imask, dummy_imask[] = { [0 ... MAX_PHANDLE_ARGS] = ~0 }; | ||
101 | u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; | 101 | u32 intsize = 1, addrsize, newintsize = 0, newaddrsize = 0; |
102 | int imaplen, match, i; | 102 | int imaplen, match, i; |
103 | 103 | ||
104 | pr_debug("of_irq_map_raw: par=%s,intspec=[0x%08x 0x%08x...],ointsize=%d\n", | 104 | #ifdef DEBUG |
105 | parent->full_name, be32_to_cpup(intspec), | 105 | of_print_phandle_args("of_irq_parse_raw: ", out_irq); |
106 | be32_to_cpup(intspec + 1), ointsize); | 106 | #endif |
107 | 107 | ||
108 | ipar = of_node_get(parent); | 108 | ipar = of_node_get(out_irq->np); |
109 | 109 | ||
110 | /* First get the #interrupt-cells property of the current cursor | 110 | /* First get the #interrupt-cells property of the current cursor |
111 | * that tells us how to interpret the passed-in intspec. If there | 111 | * that tells us how to interpret the passed-in intspec. If there |
@@ -126,9 +126,9 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, | |||
126 | goto fail; | 126 | goto fail; |
127 | } | 127 | } |
128 | 128 | ||
129 | pr_debug("of_irq_map_raw: ipar=%s, size=%d\n", ipar->full_name, intsize); | 129 | pr_debug("of_irq_parse_raw: ipar=%s, size=%d\n", of_node_full_name(ipar), intsize); |
130 | 130 | ||
131 | if (ointsize != intsize) | 131 | if (out_irq->args_count != intsize) |
132 | return -EINVAL; | 132 | return -EINVAL; |
133 | 133 | ||
134 | /* Look for this #address-cells. We have to implement the old linux | 134 | /* Look for this #address-cells. We have to implement the old linux |
@@ -147,6 +147,16 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, | |||
147 | 147 | ||
148 | pr_debug(" -> addrsize=%d\n", addrsize); | 148 | pr_debug(" -> addrsize=%d\n", addrsize); |
149 | 149 | ||
150 | /* Range check so that the temporary buffer doesn't overflow */ | ||
151 | if (WARN_ON(addrsize + intsize > MAX_PHANDLE_ARGS)) | ||
152 | goto fail; | ||
153 | |||
154 | /* Precalculate the match array - this simplifies match loop */ | ||
155 | for (i = 0; i < addrsize; i++) | ||
156 | initial_match_array[i] = addr ? addr[i] : 0; | ||
157 | for (i = 0; i < intsize; i++) | ||
158 | initial_match_array[addrsize + i] = cpu_to_be32(out_irq->args[i]); | ||
159 | |||
150 | /* Now start the actual "proper" walk of the interrupt tree */ | 160 | /* Now start the actual "proper" walk of the interrupt tree */ |
151 | while (ipar != NULL) { | 161 | while (ipar != NULL) { |
152 | /* Now check if cursor is an interrupt-controller and if it is | 162 | /* Now check if cursor is an interrupt-controller and if it is |
@@ -155,15 +165,19 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, | |||
155 | if (of_get_property(ipar, "interrupt-controller", NULL) != | 165 | if (of_get_property(ipar, "interrupt-controller", NULL) != |
156 | NULL) { | 166 | NULL) { |
157 | pr_debug(" -> got it !\n"); | 167 | pr_debug(" -> got it !\n"); |
158 | for (i = 0; i < intsize; i++) | ||
159 | out_irq->specifier[i] = | ||
160 | of_read_number(intspec +i, 1); | ||
161 | out_irq->size = intsize; | ||
162 | out_irq->controller = ipar; | ||
163 | of_node_put(old); | 168 | of_node_put(old); |
164 | return 0; | 169 | return 0; |
165 | } | 170 | } |
166 | 171 | ||
172 | /* | ||
173 | * interrupt-map parsing does not work without a reg | ||
174 | * property when #address-cells != 0 | ||
175 | */ | ||
176 | if (addrsize && !addr) { | ||
177 | pr_debug(" -> no reg passed in when needed !\n"); | ||
178 | goto fail; | ||
179 | } | ||
180 | |||
167 | /* Now look for an interrupt-map */ | 181 | /* Now look for an interrupt-map */ |
168 | imap = of_get_property(ipar, "interrupt-map", &imaplen); | 182 | imap = of_get_property(ipar, "interrupt-map", &imaplen); |
169 | /* No interrupt map, check for an interrupt parent */ | 183 | /* No interrupt map, check for an interrupt parent */ |
@@ -176,34 +190,16 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, | |||
176 | 190 | ||
177 | /* Look for a mask */ | 191 | /* Look for a mask */ |
178 | imask = of_get_property(ipar, "interrupt-map-mask", NULL); | 192 | imask = of_get_property(ipar, "interrupt-map-mask", NULL); |
179 | 193 | if (!imask) | |
180 | /* If we were passed no "reg" property and we attempt to parse | 194 | imask = dummy_imask; |
181 | * an interrupt-map, then #address-cells must be 0. | ||
182 | * Fail if it's not. | ||
183 | */ | ||
184 | if (addr == NULL && addrsize != 0) { | ||
185 | pr_debug(" -> no reg passed in when needed !\n"); | ||
186 | goto fail; | ||
187 | } | ||
188 | 195 | ||
189 | /* Parse interrupt-map */ | 196 | /* Parse interrupt-map */ |
190 | match = 0; | 197 | match = 0; |
191 | while (imaplen > (addrsize + intsize + 1) && !match) { | 198 | while (imaplen > (addrsize + intsize + 1) && !match) { |
192 | /* Compare specifiers */ | 199 | /* Compare specifiers */ |
193 | match = 1; | 200 | match = 1; |
194 | for (i = 0; i < addrsize && match; ++i) { | 201 | for (i = 0; i < (addrsize + intsize); i++, imaplen--) |
195 | __be32 mask = imask ? imask[i] | 202 | match &= !((match_array[i] ^ *imap++) & imask[i]); |
196 | : cpu_to_be32(0xffffffffu); | ||
197 | match = ((addr[i] ^ imap[i]) & mask) == 0; | ||
198 | } | ||
199 | for (; i < (addrsize + intsize) && match; ++i) { | ||
200 | __be32 mask = imask ? imask[i] | ||
201 | : cpu_to_be32(0xffffffffu); | ||
202 | match = | ||
203 | ((intspec[i-addrsize] ^ imap[i]) & mask) == 0; | ||
204 | } | ||
205 | imap += addrsize + intsize; | ||
206 | imaplen -= addrsize + intsize; | ||
207 | 203 | ||
208 | pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen); | 204 | pr_debug(" -> match=%d (imaplen=%d)\n", match, imaplen); |
209 | 205 | ||
@@ -237,6 +233,8 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, | |||
237 | newintsize, newaddrsize); | 233 | newintsize, newaddrsize); |
238 | 234 | ||
239 | /* Check for malformed properties */ | 235 | /* Check for malformed properties */ |
236 | if (WARN_ON(newaddrsize + newintsize > MAX_PHANDLE_ARGS)) | ||
237 | goto fail; | ||
240 | if (imaplen < (newaddrsize + newintsize)) | 238 | if (imaplen < (newaddrsize + newintsize)) |
241 | goto fail; | 239 | goto fail; |
242 | 240 | ||
@@ -248,12 +246,18 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, | |||
248 | if (!match) | 246 | if (!match) |
249 | goto fail; | 247 | goto fail; |
250 | 248 | ||
251 | of_node_put(old); | 249 | /* |
252 | old = of_node_get(newpar); | 250 | * Successfully parsed an interrrupt-map translation; copy new |
251 | * interrupt specifier into the out_irq structure | ||
252 | */ | ||
253 | of_node_put(out_irq->np); | ||
254 | out_irq->np = of_node_get(newpar); | ||
255 | |||
256 | match_array = imap - newaddrsize - newintsize; | ||
257 | for (i = 0; i < newintsize; i++) | ||
258 | out_irq->args[i] = be32_to_cpup(imap - newintsize + i); | ||
259 | out_irq->args_count = intsize = newintsize; | ||
253 | addrsize = newaddrsize; | 260 | addrsize = newaddrsize; |
254 | intsize = newintsize; | ||
255 | intspec = imap - intsize; | ||
256 | addr = intspec - addrsize; | ||
257 | 261 | ||
258 | skiplevel: | 262 | skiplevel: |
259 | /* Iterate again with new parent */ | 263 | /* Iterate again with new parent */ |
@@ -264,46 +268,53 @@ int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, | |||
264 | } | 268 | } |
265 | fail: | 269 | fail: |
266 | of_node_put(ipar); | 270 | of_node_put(ipar); |
267 | of_node_put(old); | 271 | of_node_put(out_irq->np); |
268 | of_node_put(newpar); | 272 | of_node_put(newpar); |
269 | 273 | ||
270 | return -EINVAL; | 274 | return -EINVAL; |
271 | } | 275 | } |
272 | EXPORT_SYMBOL_GPL(of_irq_map_raw); | 276 | EXPORT_SYMBOL_GPL(of_irq_parse_raw); |
273 | 277 | ||
274 | /** | 278 | /** |
275 | * of_irq_map_one - Resolve an interrupt for a device | 279 | * of_irq_parse_one - Resolve an interrupt for a device |
276 | * @device: the device whose interrupt is to be resolved | 280 | * @device: the device whose interrupt is to be resolved |
277 | * @index: index of the interrupt to resolve | 281 | * @index: index of the interrupt to resolve |
278 | * @out_irq: structure of_irq filled by this function | 282 | * @out_irq: structure of_irq filled by this function |
279 | * | 283 | * |
280 | * This function resolves an interrupt, walking the tree, for a given | 284 | * This function resolves an interrupt for a node by walking the interrupt tree, |
281 | * device-tree node. It's the high level pendant to of_irq_map_raw(). | 285 | * finding which interrupt controller node it is attached to, and returning the |
286 | * interrupt specifier that can be used to retrieve a Linux IRQ number. | ||
282 | */ | 287 | */ |
283 | int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq) | 288 | int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_args *out_irq) |
284 | { | 289 | { |
285 | struct device_node *p; | 290 | struct device_node *p; |
286 | const __be32 *intspec, *tmp, *addr; | 291 | const __be32 *intspec, *tmp, *addr; |
287 | u32 intsize, intlen; | 292 | u32 intsize, intlen; |
288 | int res = -EINVAL; | 293 | int i, res = -EINVAL; |
289 | 294 | ||
290 | pr_debug("of_irq_map_one: dev=%s, index=%d\n", device->full_name, index); | 295 | pr_debug("of_irq_parse_one: dev=%s, index=%d\n", of_node_full_name(device), index); |
291 | 296 | ||
292 | /* OldWorld mac stuff is "special", handle out of line */ | 297 | /* OldWorld mac stuff is "special", handle out of line */ |
293 | if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC) | 298 | if (of_irq_workarounds & OF_IMAP_OLDWORLD_MAC) |
294 | return of_irq_map_oldworld(device, index, out_irq); | 299 | return of_irq_parse_oldworld(device, index, out_irq); |
300 | |||
301 | /* Get the reg property (if any) */ | ||
302 | addr = of_get_property(device, "reg", NULL); | ||
295 | 303 | ||
296 | /* Get the interrupts property */ | 304 | /* Get the interrupts property */ |
297 | intspec = of_get_property(device, "interrupts", &intlen); | 305 | intspec = of_get_property(device, "interrupts", &intlen); |
298 | if (intspec == NULL) | 306 | if (intspec == NULL) { |
299 | return -EINVAL; | 307 | /* Try the new-style interrupts-extended */ |
308 | res = of_parse_phandle_with_args(device, "interrupts-extended", | ||
309 | "#interrupt-cells", index, out_irq); | ||
310 | if (res) | ||
311 | return -EINVAL; | ||
312 | return of_irq_parse_raw(addr, out_irq); | ||
313 | } | ||
300 | intlen /= sizeof(*intspec); | 314 | intlen /= sizeof(*intspec); |
301 | 315 | ||
302 | pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen); | 316 | pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen); |
303 | 317 | ||
304 | /* Get the reg property (if any) */ | ||
305 | addr = of_get_property(device, "reg", NULL); | ||
306 | |||
307 | /* Look for the interrupt parent. */ | 318 | /* Look for the interrupt parent. */ |
308 | p = of_irq_find_parent(device); | 319 | p = of_irq_find_parent(device); |
309 | if (p == NULL) | 320 | if (p == NULL) |
@@ -321,14 +332,20 @@ int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq | |||
321 | if ((index + 1) * intsize > intlen) | 332 | if ((index + 1) * intsize > intlen) |
322 | goto out; | 333 | goto out; |
323 | 334 | ||
324 | /* Get new specifier and map it */ | 335 | /* Copy intspec into irq structure */ |
325 | res = of_irq_map_raw(p, intspec + index * intsize, intsize, | 336 | intspec += index * intsize; |
326 | addr, out_irq); | 337 | out_irq->np = p; |
338 | out_irq->args_count = intsize; | ||
339 | for (i = 0; i < intsize; i++) | ||
340 | out_irq->args[i] = be32_to_cpup(intspec++); | ||
341 | |||
342 | /* Check if there are any interrupt-map translations to process */ | ||
343 | res = of_irq_parse_raw(addr, out_irq); | ||
327 | out: | 344 | out: |
328 | of_node_put(p); | 345 | of_node_put(p); |
329 | return res; | 346 | return res; |
330 | } | 347 | } |
331 | EXPORT_SYMBOL_GPL(of_irq_map_one); | 348 | EXPORT_SYMBOL_GPL(of_irq_parse_one); |
332 | 349 | ||
333 | /** | 350 | /** |
334 | * of_irq_to_resource - Decode a node's IRQ and return it as a resource | 351 | * of_irq_to_resource - Decode a node's IRQ and return it as a resource |
@@ -354,8 +371,8 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) | |||
354 | &name); | 371 | &name); |
355 | 372 | ||
356 | r->start = r->end = irq; | 373 | r->start = r->end = irq; |
357 | r->flags = IORESOURCE_IRQ; | 374 | r->flags = IORESOURCE_IRQ | irqd_get_trigger_type(irq_get_irq_data(irq)); |
358 | r->name = name ? name : dev->full_name; | 375 | r->name = name ? name : of_node_full_name(dev); |
359 | } | 376 | } |
360 | 377 | ||
361 | return irq; | 378 | return irq; |
@@ -368,9 +385,10 @@ EXPORT_SYMBOL_GPL(of_irq_to_resource); | |||
368 | */ | 385 | */ |
369 | int of_irq_count(struct device_node *dev) | 386 | int of_irq_count(struct device_node *dev) |
370 | { | 387 | { |
388 | struct of_phandle_args irq; | ||
371 | int nr = 0; | 389 | int nr = 0; |
372 | 390 | ||
373 | while (of_irq_to_resource(dev, nr, NULL)) | 391 | while (of_irq_parse_one(dev, nr, &irq) == 0) |
374 | nr++; | 392 | nr++; |
375 | 393 | ||
376 | return nr; | 394 | return nr; |
diff --git a/drivers/of/of_pci.c b/drivers/of/of_pci.c index e5ca00893c0c..848199633798 100644 --- a/drivers/of/of_pci.c +++ b/drivers/of/of_pci.c | |||
@@ -2,7 +2,6 @@ | |||
2 | #include <linux/export.h> | 2 | #include <linux/export.h> |
3 | #include <linux/of.h> | 3 | #include <linux/of.h> |
4 | #include <linux/of_pci.h> | 4 | #include <linux/of_pci.h> |
5 | #include <asm/prom.h> | ||
6 | 5 | ||
7 | static inline int __of_pci_pci_compare(struct device_node *node, | 6 | static inline int __of_pci_pci_compare(struct device_node *node, |
8 | unsigned int data) | 7 | unsigned int data) |
diff --git a/drivers/of/of_pci_irq.c b/drivers/of/of_pci_irq.c index 677053813211..8736bc7676c5 100644 --- a/drivers/of/of_pci_irq.c +++ b/drivers/of/of_pci_irq.c | |||
@@ -2,10 +2,9 @@ | |||
2 | #include <linux/of_pci.h> | 2 | #include <linux/of_pci.h> |
3 | #include <linux/of_irq.h> | 3 | #include <linux/of_irq.h> |
4 | #include <linux/export.h> | 4 | #include <linux/export.h> |
5 | #include <asm/prom.h> | ||
6 | 5 | ||
7 | /** | 6 | /** |
8 | * of_irq_map_pci - Resolve the interrupt for a PCI device | 7 | * of_irq_parse_pci - Resolve the interrupt for a PCI device |
9 | * @pdev: the device whose interrupt is to be resolved | 8 | * @pdev: the device whose interrupt is to be resolved |
10 | * @out_irq: structure of_irq filled by this function | 9 | * @out_irq: structure of_irq filled by this function |
11 | * | 10 | * |
@@ -15,7 +14,7 @@ | |||
15 | * PCI tree until an device-node is found, at which point it will finish | 14 | * PCI tree until an device-node is found, at which point it will finish |
16 | * resolving using the OF tree walking. | 15 | * resolving using the OF tree walking. |
17 | */ | 16 | */ |
18 | int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq) | 17 | int of_irq_parse_pci(const struct pci_dev *pdev, struct of_phandle_args *out_irq) |
19 | { | 18 | { |
20 | struct device_node *dn, *ppnode; | 19 | struct device_node *dn, *ppnode; |
21 | struct pci_dev *ppdev; | 20 | struct pci_dev *ppdev; |
@@ -30,7 +29,7 @@ int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq) | |||
30 | */ | 29 | */ |
31 | dn = pci_device_to_OF_node(pdev); | 30 | dn = pci_device_to_OF_node(pdev); |
32 | if (dn) { | 31 | if (dn) { |
33 | rc = of_irq_map_one(dn, 0, out_irq); | 32 | rc = of_irq_parse_one(dn, 0, out_irq); |
34 | if (!rc) | 33 | if (!rc) |
35 | return rc; | 34 | return rc; |
36 | } | 35 | } |
@@ -85,9 +84,37 @@ int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq) | |||
85 | pdev = ppdev; | 84 | pdev = ppdev; |
86 | } | 85 | } |
87 | 86 | ||
87 | out_irq->np = ppnode; | ||
88 | out_irq->args_count = 1; | ||
89 | out_irq->args[0] = lspec; | ||
88 | lspec_be = cpu_to_be32(lspec); | 90 | lspec_be = cpu_to_be32(lspec); |
89 | laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8)); | 91 | laddr[0] = cpu_to_be32((pdev->bus->number << 16) | (pdev->devfn << 8)); |
90 | laddr[1] = laddr[2] = cpu_to_be32(0); | 92 | laddr[1] = laddr[2] = cpu_to_be32(0); |
91 | return of_irq_map_raw(ppnode, &lspec_be, 1, laddr, out_irq); | 93 | return of_irq_parse_raw(laddr, out_irq); |
92 | } | 94 | } |
93 | EXPORT_SYMBOL_GPL(of_irq_map_pci); | 95 | EXPORT_SYMBOL_GPL(of_irq_parse_pci); |
96 | |||
97 | /** | ||
98 | * of_irq_parse_and_map_pci() - Decode a PCI irq from the device tree and map to a virq | ||
99 | * @dev: The pci device needing an irq | ||
100 | * @slot: PCI slot number; passed when used as map_irq callback. Unused | ||
101 | * @pin: PCI irq pin number; passed when used as map_irq callback. Unused | ||
102 | * | ||
103 | * @slot and @pin are unused, but included in the function so that this | ||
104 | * function can be used directly as the map_irq callback to pci_fixup_irqs(). | ||
105 | */ | ||
106 | int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin) | ||
107 | { | ||
108 | struct of_phandle_args oirq; | ||
109 | int ret; | ||
110 | |||
111 | ret = of_irq_parse_pci(dev, &oirq); | ||
112 | if (ret) { | ||
113 | dev_err(&dev->dev, "of_irq_parse_pci() failed with rc=%d\n", ret); | ||
114 | return 0; /* Proper return code 0 == NO_IRQ */ | ||
115 | } | ||
116 | |||
117 | return irq_create_of_mapping(&oirq); | ||
118 | } | ||
119 | EXPORT_SYMBOL_GPL(of_irq_parse_and_map_pci); | ||
120 | |||
diff --git a/drivers/of/pdt.c b/drivers/of/pdt.c index 4ec19cbee57f..7b666736c168 100644 --- a/drivers/of/pdt.c +++ b/drivers/of/pdt.c | |||
@@ -22,7 +22,6 @@ | |||
22 | #include <linux/slab.h> | 22 | #include <linux/slab.h> |
23 | #include <linux/of.h> | 23 | #include <linux/of.h> |
24 | #include <linux/of_pdt.h> | 24 | #include <linux/of_pdt.h> |
25 | #include <asm/prom.h> | ||
26 | 25 | ||
27 | static struct of_pdt_ops *of_pdt_prom_ops __initdata; | 26 | static struct of_pdt_ops *of_pdt_prom_ops __initdata; |
28 | 27 | ||
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index f6dcde220821..fce088e6f54e 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
@@ -215,6 +215,8 @@ static struct platform_device *of_platform_device_create_pdata( | |||
215 | dev->archdata.dma_mask = 0xffffffffUL; | 215 | dev->archdata.dma_mask = 0xffffffffUL; |
216 | #endif | 216 | #endif |
217 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); | 217 | dev->dev.coherent_dma_mask = DMA_BIT_MASK(32); |
218 | if (!dev->dev.dma_mask) | ||
219 | dev->dev.dma_mask = &dev->dev.coherent_dma_mask; | ||
218 | dev->dev.bus = &platform_bus_type; | 220 | dev->dev.bus = &platform_bus_type; |
219 | dev->dev.platform_data = platform_data; | 221 | dev->dev.platform_data = platform_data; |
220 | 222 | ||
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index 0eb5c38b4e07..e21012bde639 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c | |||
@@ -9,18 +9,24 @@ | |||
9 | #include <linux/errno.h> | 9 | #include <linux/errno.h> |
10 | #include <linux/module.h> | 10 | #include <linux/module.h> |
11 | #include <linux/of.h> | 11 | #include <linux/of.h> |
12 | #include <linux/of_irq.h> | ||
12 | #include <linux/list.h> | 13 | #include <linux/list.h> |
13 | #include <linux/mutex.h> | 14 | #include <linux/mutex.h> |
14 | #include <linux/slab.h> | 15 | #include <linux/slab.h> |
15 | #include <linux/device.h> | 16 | #include <linux/device.h> |
16 | 17 | ||
17 | static bool selftest_passed = true; | 18 | static struct selftest_results { |
19 | int passed; | ||
20 | int failed; | ||
21 | } selftest_results; | ||
22 | |||
18 | #define selftest(result, fmt, ...) { \ | 23 | #define selftest(result, fmt, ...) { \ |
19 | if (!(result)) { \ | 24 | if (!(result)) { \ |
20 | pr_err("FAIL %s:%i " fmt, __FILE__, __LINE__, ##__VA_ARGS__); \ | 25 | selftest_results.failed++; \ |
21 | selftest_passed = false; \ | 26 | pr_err("FAIL %s():%i " fmt, __func__, __LINE__, ##__VA_ARGS__); \ |
22 | } else { \ | 27 | } else { \ |
23 | pr_info("pass %s:%i\n", __FILE__, __LINE__); \ | 28 | selftest_results.passed++; \ |
29 | pr_debug("pass %s():%i\n", __func__, __LINE__); \ | ||
24 | } \ | 30 | } \ |
25 | } | 31 | } |
26 | 32 | ||
@@ -131,7 +137,6 @@ static void __init of_selftest_property_match_string(void) | |||
131 | struct device_node *np; | 137 | struct device_node *np; |
132 | int rc; | 138 | int rc; |
133 | 139 | ||
134 | pr_info("start\n"); | ||
135 | np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); | 140 | np = of_find_node_by_path("/testcase-data/phandle-tests/consumer-a"); |
136 | if (!np) { | 141 | if (!np) { |
137 | pr_err("No testcase data in device tree\n"); | 142 | pr_err("No testcase data in device tree\n"); |
@@ -154,6 +159,147 @@ static void __init of_selftest_property_match_string(void) | |||
154 | selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc); | 159 | selftest(rc == -EILSEQ, "unterminated string; rc=%i", rc); |
155 | } | 160 | } |
156 | 161 | ||
162 | static void __init of_selftest_parse_interrupts(void) | ||
163 | { | ||
164 | struct device_node *np; | ||
165 | struct of_phandle_args args; | ||
166 | int i, rc; | ||
167 | |||
168 | np = of_find_node_by_path("/testcase-data/interrupts/interrupts0"); | ||
169 | if (!np) { | ||
170 | pr_err("missing testcase data\n"); | ||
171 | return; | ||
172 | } | ||
173 | |||
174 | for (i = 0; i < 4; i++) { | ||
175 | bool passed = true; | ||
176 | args.args_count = 0; | ||
177 | rc = of_irq_parse_one(np, i, &args); | ||
178 | |||
179 | passed &= !rc; | ||
180 | passed &= (args.args_count == 1); | ||
181 | passed &= (args.args[0] == (i + 1)); | ||
182 | |||
183 | selftest(passed, "index %i - data error on node %s rc=%i\n", | ||
184 | i, args.np->full_name, rc); | ||
185 | } | ||
186 | of_node_put(np); | ||
187 | |||
188 | np = of_find_node_by_path("/testcase-data/interrupts/interrupts1"); | ||
189 | if (!np) { | ||
190 | pr_err("missing testcase data\n"); | ||
191 | return; | ||
192 | } | ||
193 | |||
194 | for (i = 0; i < 4; i++) { | ||
195 | bool passed = true; | ||
196 | args.args_count = 0; | ||
197 | rc = of_irq_parse_one(np, i, &args); | ||
198 | |||
199 | /* Test the values from tests-phandle.dtsi */ | ||
200 | switch (i) { | ||
201 | case 0: | ||
202 | passed &= !rc; | ||
203 | passed &= (args.args_count == 1); | ||
204 | passed &= (args.args[0] == 9); | ||
205 | break; | ||
206 | case 1: | ||
207 | passed &= !rc; | ||
208 | passed &= (args.args_count == 3); | ||
209 | passed &= (args.args[0] == 10); | ||
210 | passed &= (args.args[1] == 11); | ||
211 | passed &= (args.args[2] == 12); | ||
212 | break; | ||
213 | case 2: | ||
214 | passed &= !rc; | ||
215 | passed &= (args.args_count == 2); | ||
216 | passed &= (args.args[0] == 13); | ||
217 | passed &= (args.args[1] == 14); | ||
218 | break; | ||
219 | case 3: | ||
220 | passed &= !rc; | ||
221 | passed &= (args.args_count == 2); | ||
222 | passed &= (args.args[0] == 15); | ||
223 | passed &= (args.args[1] == 16); | ||
224 | break; | ||
225 | default: | ||
226 | passed = false; | ||
227 | } | ||
228 | selftest(passed, "index %i - data error on node %s rc=%i\n", | ||
229 | i, args.np->full_name, rc); | ||
230 | } | ||
231 | of_node_put(np); | ||
232 | } | ||
233 | |||
234 | static void __init of_selftest_parse_interrupts_extended(void) | ||
235 | { | ||
236 | struct device_node *np; | ||
237 | struct of_phandle_args args; | ||
238 | int i, rc; | ||
239 | |||
240 | np = of_find_node_by_path("/testcase-data/interrupts/interrupts-extended0"); | ||
241 | if (!np) { | ||
242 | pr_err("missing testcase data\n"); | ||
243 | return; | ||
244 | } | ||
245 | |||
246 | for (i = 0; i < 7; i++) { | ||
247 | bool passed = true; | ||
248 | rc = of_irq_parse_one(np, i, &args); | ||
249 | |||
250 | /* Test the values from tests-phandle.dtsi */ | ||
251 | switch (i) { | ||
252 | case 0: | ||
253 | passed &= !rc; | ||
254 | passed &= (args.args_count == 1); | ||
255 | passed &= (args.args[0] == 1); | ||
256 | break; | ||
257 | case 1: | ||
258 | passed &= !rc; | ||
259 | passed &= (args.args_count == 3); | ||
260 | passed &= (args.args[0] == 2); | ||
261 | passed &= (args.args[1] == 3); | ||
262 | passed &= (args.args[2] == 4); | ||
263 | break; | ||
264 | case 2: | ||
265 | passed &= !rc; | ||
266 | passed &= (args.args_count == 2); | ||
267 | passed &= (args.args[0] == 5); | ||
268 | passed &= (args.args[1] == 6); | ||
269 | break; | ||
270 | case 3: | ||
271 | passed &= !rc; | ||
272 | passed &= (args.args_count == 1); | ||
273 | passed &= (args.args[0] == 9); | ||
274 | break; | ||
275 | case 4: | ||
276 | passed &= !rc; | ||
277 | passed &= (args.args_count == 3); | ||
278 | passed &= (args.args[0] == 10); | ||
279 | passed &= (args.args[1] == 11); | ||
280 | passed &= (args.args[2] == 12); | ||
281 | break; | ||
282 | case 5: | ||
283 | passed &= !rc; | ||
284 | passed &= (args.args_count == 2); | ||
285 | passed &= (args.args[0] == 13); | ||
286 | passed &= (args.args[1] == 14); | ||
287 | break; | ||
288 | case 6: | ||
289 | passed &= !rc; | ||
290 | passed &= (args.args_count == 1); | ||
291 | passed &= (args.args[0] == 15); | ||
292 | break; | ||
293 | default: | ||
294 | passed = false; | ||
295 | } | ||
296 | |||
297 | selftest(passed, "index %i - data error on node %s rc=%i\n", | ||
298 | i, args.np->full_name, rc); | ||
299 | } | ||
300 | of_node_put(np); | ||
301 | } | ||
302 | |||
157 | static int __init of_selftest(void) | 303 | static int __init of_selftest(void) |
158 | { | 304 | { |
159 | struct device_node *np; | 305 | struct device_node *np; |
@@ -168,7 +314,10 @@ static int __init of_selftest(void) | |||
168 | pr_info("start of selftest - you will see error messages\n"); | 314 | pr_info("start of selftest - you will see error messages\n"); |
169 | of_selftest_parse_phandle_with_args(); | 315 | of_selftest_parse_phandle_with_args(); |
170 | of_selftest_property_match_string(); | 316 | of_selftest_property_match_string(); |
171 | pr_info("end of selftest - %s\n", selftest_passed ? "PASS" : "FAIL"); | 317 | of_selftest_parse_interrupts(); |
318 | of_selftest_parse_interrupts_extended(); | ||
319 | pr_info("end of selftest - %i passed, %i failed\n", | ||
320 | selftest_results.passed, selftest_results.failed); | ||
172 | return 0; | 321 | return 0; |
173 | } | 322 | } |
174 | late_initcall(of_selftest); | 323 | late_initcall(of_selftest); |