aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of
diff options
context:
space:
mode:
authorLinus Torvalds <torvalds@linux-foundation.org>2013-11-12 02:52:17 -0500
committerLinus Torvalds <torvalds@linux-foundation.org>2013-11-12 02:52:17 -0500
commit10d0c9705e80bbd3d587c5fad24599aabaca6688 (patch)
tree9456083a1b04b8d98da08d88e937cfeff80e2a7d /drivers/of
parent85b656cf1560e27a89354a23f2c10ba229d2f173 (diff)
parentc11eede69b6ad0ac44ebc1e021a8d2699c5f1f8f (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/Kconfig1
-rw-r--r--drivers/of/address.c18
-rw-r--r--drivers/of/base.c65
-rw-r--r--drivers/of/fdt.c138
-rw-r--r--drivers/of/irq.c164
-rw-r--r--drivers/of/of_pci.c1
-rw-r--r--drivers/of/of_pci_irq.c41
-rw-r--r--drivers/of/pdt.c1
-rw-r--r--drivers/of/platform.c2
-rw-r--r--drivers/of/selftest.c161
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
18config OF_SELFTEST 18config 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}
627EXPORT_SYMBOL(of_get_address); 627EXPORT_SYMBOL(of_get_address);
628 628
629unsigned 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
629static int __of_address_to_resource(struct device_node *dev, 637static 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}
75EXPORT_SYMBOL(of_n_size_cells); 75EXPORT_SYMBOL(of_n_size_cells);
76 76
77#ifdef CONFIG_NUMA
78int __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 */
296bool __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 */
301struct device_node *of_get_cpu_node(int cpu, unsigned int *thread) 333struct 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}
1175EXPORT_SYMBOL_GPL(of_property_count_strings); 1193EXPORT_SYMBOL_GPL(of_property_count_strings);
1176 1194
1195void 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
1177static int __of_parse_phandle_with_args(const struct device_node *np, 1204static 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
621const 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 */
641const 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 */
626void __init early_init_dt_check_for_initrd(unsigned long node) 686static 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
649inline void early_init_dt_check_for_initrd(unsigned long node) 712static 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
840void __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
869bool __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 */
923void __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 */
37unsigned int irq_of_parse_and_map(struct device_node *dev, int index) 37unsigned 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}
47EXPORT_SYMBOL_GPL(irq_of_parse_and_map); 46EXPORT_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 */
96int of_irq_map_raw(struct device_node *parent, const __be32 *intspec, 95int 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}
272EXPORT_SYMBOL_GPL(of_irq_map_raw); 276EXPORT_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 */
283int of_irq_map_one(struct device_node *device, int index, struct of_irq *out_irq) 288int 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}
331EXPORT_SYMBOL_GPL(of_irq_map_one); 348EXPORT_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 */
369int of_irq_count(struct device_node *dev) 386int 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
7static inline int __of_pci_pci_compare(struct device_node *node, 6static 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 */
18int of_irq_map_pci(const struct pci_dev *pdev, struct of_irq *out_irq) 17int 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}
93EXPORT_SYMBOL_GPL(of_irq_map_pci); 95EXPORT_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 */
106int 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}
119EXPORT_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
27static struct of_pdt_ops *of_pdt_prom_ops __initdata; 26static 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
17static bool selftest_passed = true; 18static 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
162static 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
234static 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
157static int __init of_selftest(void) 303static 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}
174late_initcall(of_selftest); 323late_initcall(of_selftest);