diff options
| -rw-r--r-- | Documentation/devicetree/bindings/interrupt-controller/interrupts.txt | 12 | ||||
| -rw-r--r-- | drivers/of/fdt.c | 2 | ||||
| -rw-r--r-- | drivers/of/irq.c | 17 | ||||
| -rw-r--r-- | drivers/of/selftest.c | 40 |
4 files changed, 48 insertions, 23 deletions
diff --git a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt index 1486497a24c1..ce6a1a072028 100644 --- a/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt +++ b/Documentation/devicetree/bindings/interrupt-controller/interrupts.txt | |||
| @@ -4,11 +4,13 @@ Specifying interrupt information for devices | |||
| 4 | 1) Interrupt client nodes | 4 | 1) Interrupt client nodes |
| 5 | ------------------------- | 5 | ------------------------- |
| 6 | 6 | ||
| 7 | Nodes that describe devices which generate interrupts must contain an either an | 7 | Nodes that describe devices which generate interrupts must contain an |
| 8 | "interrupts" property or an "interrupts-extended" property. These properties | 8 | "interrupts" property, an "interrupts-extended" property, or both. If both are |
| 9 | contain a list of interrupt specifiers, one per output interrupt. The format of | 9 | present, the latter should take precedence; the former may be provided simply |
| 10 | the interrupt specifier is determined by the interrupt controller to which the | 10 | for compatibility with software that does not recognize the latter. These |
| 11 | interrupts are routed; see section 2 below for details. | 11 | properties contain a list of interrupt specifiers, one per output interrupt. The |
| 12 | format of the interrupt specifier is determined by the interrupt controller to | ||
| 13 | which the interrupts are routed; see section 2 below for details. | ||
| 12 | 14 | ||
| 13 | Example: | 15 | Example: |
| 14 | interrupt-parent = <&intc1>; | 16 | interrupt-parent = <&intc1>; |
diff --git a/drivers/of/fdt.c b/drivers/of/fdt.c index f46a24ffa3fe..79cb8313c7d8 100644 --- a/drivers/of/fdt.c +++ b/drivers/of/fdt.c | |||
| @@ -453,7 +453,7 @@ static int __init __reserved_mem_reserve_reg(unsigned long node, | |||
| 453 | base = dt_mem_next_cell(dt_root_addr_cells, &prop); | 453 | base = dt_mem_next_cell(dt_root_addr_cells, &prop); |
| 454 | size = dt_mem_next_cell(dt_root_size_cells, &prop); | 454 | size = dt_mem_next_cell(dt_root_size_cells, &prop); |
| 455 | 455 | ||
| 456 | if (base && size && | 456 | if (size && |
| 457 | early_init_dt_reserve_memory_arch(base, size, nomap) == 0) | 457 | early_init_dt_reserve_memory_arch(base, size, nomap) == 0) |
| 458 | pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n", | 458 | pr_debug("Reserved memory: reserved region for node '%s': base %pa, size %ld MiB\n", |
| 459 | uname, &base, (unsigned long)size / SZ_1M); | 459 | uname, &base, (unsigned long)size / SZ_1M); |
diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 3e06a699352d..1471e0a223a5 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c | |||
| @@ -301,16 +301,17 @@ int of_irq_parse_one(struct device_node *device, int index, struct of_phandle_ar | |||
| 301 | /* Get the reg property (if any) */ | 301 | /* Get the reg property (if any) */ |
| 302 | addr = of_get_property(device, "reg", NULL); | 302 | addr = of_get_property(device, "reg", NULL); |
| 303 | 303 | ||
| 304 | /* Try the new-style interrupts-extended first */ | ||
| 305 | res = of_parse_phandle_with_args(device, "interrupts-extended", | ||
| 306 | "#interrupt-cells", index, out_irq); | ||
| 307 | if (!res) | ||
| 308 | return of_irq_parse_raw(addr, out_irq); | ||
| 309 | |||
| 304 | /* Get the interrupts property */ | 310 | /* Get the interrupts property */ |
| 305 | intspec = of_get_property(device, "interrupts", &intlen); | 311 | intspec = of_get_property(device, "interrupts", &intlen); |
| 306 | if (intspec == NULL) { | 312 | if (intspec == NULL) |
| 307 | /* Try the new-style interrupts-extended */ | 313 | return -EINVAL; |
| 308 | res = of_parse_phandle_with_args(device, "interrupts-extended", | 314 | |
| 309 | "#interrupt-cells", index, out_irq); | ||
| 310 | if (res) | ||
| 311 | return -EINVAL; | ||
| 312 | return of_irq_parse_raw(addr, out_irq); | ||
| 313 | } | ||
| 314 | intlen /= sizeof(*intspec); | 315 | intlen /= sizeof(*intspec); |
| 315 | 316 | ||
| 316 | pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen); | 317 | pr_debug(" intspec=%d intlen=%d\n", be32_to_cpup(intspec), intlen); |
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index d41002667833..a737cb5974de 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c | |||
| @@ -27,6 +27,7 @@ static struct selftest_results { | |||
| 27 | #define NO_OF_NODES 2 | 27 | #define NO_OF_NODES 2 |
| 28 | static struct device_node *nodes[NO_OF_NODES]; | 28 | static struct device_node *nodes[NO_OF_NODES]; |
| 29 | static int last_node_index; | 29 | static int last_node_index; |
| 30 | static bool selftest_live_tree; | ||
| 30 | 31 | ||
| 31 | #define selftest(result, fmt, ...) { \ | 32 | #define selftest(result, fmt, ...) { \ |
| 32 | if (!(result)) { \ | 33 | if (!(result)) { \ |
| @@ -630,13 +631,6 @@ static int attach_node_and_children(struct device_node *np) | |||
| 630 | { | 631 | { |
| 631 | struct device_node *next, *root = np, *dup; | 632 | struct device_node *next, *root = np, *dup; |
| 632 | 633 | ||
| 633 | if (!np) { | ||
| 634 | pr_warn("%s: No tree to attach; not running tests\n", | ||
| 635 | __func__); | ||
| 636 | return -ENODATA; | ||
| 637 | } | ||
| 638 | |||
| 639 | |||
| 640 | /* skip root node */ | 634 | /* skip root node */ |
| 641 | np = np->child; | 635 | np = np->child; |
| 642 | /* storing a copy in temporary node */ | 636 | /* storing a copy in temporary node */ |
| @@ -672,12 +666,12 @@ static int attach_node_and_children(struct device_node *np) | |||
| 672 | static int __init selftest_data_add(void) | 666 | static int __init selftest_data_add(void) |
| 673 | { | 667 | { |
| 674 | void *selftest_data; | 668 | void *selftest_data; |
| 675 | struct device_node *selftest_data_node; | 669 | struct device_node *selftest_data_node, *np; |
| 676 | extern uint8_t __dtb_testcases_begin[]; | 670 | extern uint8_t __dtb_testcases_begin[]; |
| 677 | extern uint8_t __dtb_testcases_end[]; | 671 | extern uint8_t __dtb_testcases_end[]; |
| 678 | const int size = __dtb_testcases_end - __dtb_testcases_begin; | 672 | const int size = __dtb_testcases_end - __dtb_testcases_begin; |
| 679 | 673 | ||
| 680 | if (!size || !of_allnodes) { | 674 | if (!size) { |
| 681 | pr_warn("%s: No testcase data to attach; not running tests\n", | 675 | pr_warn("%s: No testcase data to attach; not running tests\n", |
| 682 | __func__); | 676 | __func__); |
| 683 | return -ENODATA; | 677 | return -ENODATA; |
| @@ -692,6 +686,22 @@ static int __init selftest_data_add(void) | |||
| 692 | return -ENOMEM; | 686 | return -ENOMEM; |
| 693 | } | 687 | } |
| 694 | of_fdt_unflatten_tree(selftest_data, &selftest_data_node); | 688 | of_fdt_unflatten_tree(selftest_data, &selftest_data_node); |
| 689 | if (!selftest_data_node) { | ||
| 690 | pr_warn("%s: No tree to attach; not running tests\n", __func__); | ||
| 691 | return -ENODATA; | ||
| 692 | } | ||
| 693 | |||
| 694 | if (!of_allnodes) { | ||
| 695 | /* enabling flag for removing nodes */ | ||
| 696 | selftest_live_tree = true; | ||
| 697 | of_allnodes = selftest_data_node; | ||
| 698 | |||
| 699 | for_each_of_allnodes(np) | ||
| 700 | __of_attach_node_sysfs(np); | ||
| 701 | of_aliases = of_find_node_by_path("/aliases"); | ||
| 702 | of_chosen = of_find_node_by_path("/chosen"); | ||
| 703 | return 0; | ||
| 704 | } | ||
| 695 | 705 | ||
| 696 | /* attach the sub-tree to live tree */ | 706 | /* attach the sub-tree to live tree */ |
| 697 | return attach_node_and_children(selftest_data_node); | 707 | return attach_node_and_children(selftest_data_node); |
| @@ -723,6 +733,18 @@ static void selftest_data_remove(void) | |||
| 723 | struct device_node *np; | 733 | struct device_node *np; |
| 724 | struct property *prop; | 734 | struct property *prop; |
| 725 | 735 | ||
| 736 | if (selftest_live_tree) { | ||
| 737 | of_node_put(of_aliases); | ||
| 738 | of_node_put(of_chosen); | ||
| 739 | of_aliases = NULL; | ||
| 740 | of_chosen = NULL; | ||
| 741 | for_each_child_of_node(of_allnodes, np) | ||
| 742 | detach_node_and_children(np); | ||
| 743 | __of_detach_node_sysfs(of_allnodes); | ||
| 744 | of_allnodes = NULL; | ||
| 745 | return; | ||
| 746 | } | ||
| 747 | |||
| 726 | while (last_node_index >= 0) { | 748 | while (last_node_index >= 0) { |
| 727 | if (nodes[last_node_index]) { | 749 | if (nodes[last_node_index]) { |
| 728 | np = of_find_node_by_path(nodes[last_node_index]->full_name); | 750 | np = of_find_node_by_path(nodes[last_node_index]->full_name); |
