diff options
author | Rob Herring <robh@kernel.org> | 2014-05-13 19:34:35 -0400 |
---|---|---|
committer | Rob Herring <robh@kernel.org> | 2014-05-13 19:34:35 -0400 |
commit | eafd370dfe487facfdef499057f4eac9aa0b4bf5 (patch) | |
tree | 0925a67cd658cdf4811f49b4cd2073f663166bd0 /drivers/of | |
parent | c3fc952d2fbe3ec78defd70cf73d5d76d27092ec (diff) | |
parent | fb2caa50fbacd21719a90dd66b617ce3cb4fd6d7 (diff) |
Merge branch 'dt-bus-name' into for-next
Diffstat (limited to 'drivers/of')
-rw-r--r-- | drivers/of/address.c | 22 | ||||
-rw-r--r-- | drivers/of/irq.c | 28 | ||||
-rw-r--r-- | drivers/of/platform.c | 20 | ||||
-rw-r--r-- | drivers/of/selftest.c | 46 | ||||
-rw-r--r-- | drivers/of/testcase-data/testcases.dtsi | 1 | ||||
-rw-r--r-- | drivers/of/testcase-data/tests-interrupts.dtsi | 13 | ||||
-rw-r--r-- | drivers/of/testcase-data/tests-platform.dtsi | 35 |
7 files changed, 129 insertions, 36 deletions
diff --git a/drivers/of/address.c b/drivers/of/address.c index cb4242a69cd5..95351b2a112c 100644 --- a/drivers/of/address.c +++ b/drivers/of/address.c | |||
@@ -498,8 +498,7 @@ static u64 __of_translate_address(struct device_node *dev, | |||
498 | /* Count address cells & copy address locally */ | 498 | /* Count address cells & copy address locally */ |
499 | bus->count_cells(dev, &na, &ns); | 499 | bus->count_cells(dev, &na, &ns); |
500 | if (!OF_CHECK_COUNTS(na, ns)) { | 500 | if (!OF_CHECK_COUNTS(na, ns)) { |
501 | printk(KERN_ERR "prom_parse: Bad cell count for %s\n", | 501 | pr_debug("OF: Bad cell count for %s\n", of_node_full_name(dev)); |
502 | of_node_full_name(dev)); | ||
503 | goto bail; | 502 | goto bail; |
504 | } | 503 | } |
505 | memcpy(addr, in_addr, na * 4); | 504 | memcpy(addr, in_addr, na * 4); |
@@ -564,25 +563,6 @@ u64 of_translate_dma_address(struct device_node *dev, const __be32 *in_addr) | |||
564 | } | 563 | } |
565 | EXPORT_SYMBOL(of_translate_dma_address); | 564 | EXPORT_SYMBOL(of_translate_dma_address); |
566 | 565 | ||
567 | bool of_can_translate_address(struct device_node *dev) | ||
568 | { | ||
569 | struct device_node *parent; | ||
570 | struct of_bus *bus; | ||
571 | int na, ns; | ||
572 | |||
573 | parent = of_get_parent(dev); | ||
574 | if (parent == NULL) | ||
575 | return false; | ||
576 | |||
577 | bus = of_match_bus(parent); | ||
578 | bus->count_cells(dev, &na, &ns); | ||
579 | |||
580 | of_node_put(parent); | ||
581 | |||
582 | return OF_CHECK_COUNTS(na, ns); | ||
583 | } | ||
584 | EXPORT_SYMBOL(of_can_translate_address); | ||
585 | |||
586 | const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, | 566 | const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, |
587 | unsigned int *flags) | 567 | unsigned int *flags) |
588 | { | 568 | { |
diff --git a/drivers/of/irq.c b/drivers/of/irq.c index 9bcf2cf19357..5aeb89411350 100644 --- a/drivers/of/irq.c +++ b/drivers/of/irq.c | |||
@@ -364,7 +364,7 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) | |||
364 | 364 | ||
365 | memset(r, 0, sizeof(*r)); | 365 | memset(r, 0, sizeof(*r)); |
366 | /* | 366 | /* |
367 | * Get optional "interrupts-names" property to add a name | 367 | * Get optional "interrupt-names" property to add a name |
368 | * to the resource. | 368 | * to the resource. |
369 | */ | 369 | */ |
370 | of_property_read_string_index(dev, "interrupt-names", index, | 370 | of_property_read_string_index(dev, "interrupt-names", index, |
@@ -380,6 +380,32 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r) | |||
380 | EXPORT_SYMBOL_GPL(of_irq_to_resource); | 380 | EXPORT_SYMBOL_GPL(of_irq_to_resource); |
381 | 381 | ||
382 | /** | 382 | /** |
383 | * of_irq_get - Decode a node's IRQ and return it as a Linux irq number | ||
384 | * @dev: pointer to device tree node | ||
385 | * @index: zero-based index of the irq | ||
386 | * | ||
387 | * Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain | ||
388 | * is not yet created. | ||
389 | * | ||
390 | */ | ||
391 | int of_irq_get(struct device_node *dev, int index) | ||
392 | { | ||
393 | int rc; | ||
394 | struct of_phandle_args oirq; | ||
395 | struct irq_domain *domain; | ||
396 | |||
397 | rc = of_irq_parse_one(dev, index, &oirq); | ||
398 | if (rc) | ||
399 | return rc; | ||
400 | |||
401 | domain = irq_find_host(oirq.np); | ||
402 | if (!domain) | ||
403 | return -EPROBE_DEFER; | ||
404 | |||
405 | return irq_create_of_mapping(&oirq); | ||
406 | } | ||
407 | |||
408 | /** | ||
383 | * of_irq_count - Count the number of IRQs a node uses | 409 | * of_irq_count - Count the number of IRQs a node uses |
384 | * @dev: pointer to device tree node | 410 | * @dev: pointer to device tree node |
385 | */ | 411 | */ |
diff --git a/drivers/of/platform.c b/drivers/of/platform.c index 404d1daebefa..d0009b3614af 100644 --- a/drivers/of/platform.c +++ b/drivers/of/platform.c | |||
@@ -78,7 +78,6 @@ void of_device_make_bus_id(struct device *dev) | |||
78 | struct device_node *node = dev->of_node; | 78 | struct device_node *node = dev->of_node; |
79 | const __be32 *reg; | 79 | const __be32 *reg; |
80 | u64 addr; | 80 | u64 addr; |
81 | const __be32 *addrp; | ||
82 | int magic; | 81 | int magic; |
83 | 82 | ||
84 | #ifdef CONFIG_PPC_DCR | 83 | #ifdef CONFIG_PPC_DCR |
@@ -106,15 +105,7 @@ void of_device_make_bus_id(struct device *dev) | |||
106 | */ | 105 | */ |
107 | reg = of_get_property(node, "reg", NULL); | 106 | reg = of_get_property(node, "reg", NULL); |
108 | if (reg) { | 107 | if (reg) { |
109 | if (of_can_translate_address(node)) { | 108 | addr = of_translate_address(node, reg); |
110 | addr = of_translate_address(node, reg); | ||
111 | } else { | ||
112 | addrp = of_get_address(node, 0, NULL, NULL); | ||
113 | if (addrp) | ||
114 | addr = of_read_number(addrp, 1); | ||
115 | else | ||
116 | addr = OF_BAD_ADDR; | ||
117 | } | ||
118 | if (addr != OF_BAD_ADDR) { | 109 | if (addr != OF_BAD_ADDR) { |
119 | dev_set_name(dev, "%llx.%s", | 110 | dev_set_name(dev, "%llx.%s", |
120 | (unsigned long long)addr, node->name); | 111 | (unsigned long long)addr, node->name); |
@@ -149,9 +140,8 @@ struct platform_device *of_device_alloc(struct device_node *np, | |||
149 | return NULL; | 140 | return NULL; |
150 | 141 | ||
151 | /* count the io and irq resources */ | 142 | /* count the io and irq resources */ |
152 | if (of_can_translate_address(np)) | 143 | while (of_address_to_resource(np, num_reg, &temp_res) == 0) |
153 | while (of_address_to_resource(np, num_reg, &temp_res) == 0) | 144 | num_reg++; |
154 | num_reg++; | ||
155 | num_irq = of_irq_count(np); | 145 | num_irq = of_irq_count(np); |
156 | 146 | ||
157 | /* Populate the resource table */ | 147 | /* Populate the resource table */ |
@@ -168,7 +158,9 @@ struct platform_device *of_device_alloc(struct device_node *np, | |||
168 | rc = of_address_to_resource(np, i, res); | 158 | rc = of_address_to_resource(np, i, res); |
169 | WARN_ON(rc); | 159 | WARN_ON(rc); |
170 | } | 160 | } |
171 | WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq); | 161 | if (of_irq_to_resource_table(np, res, num_irq) != num_irq) |
162 | pr_debug("not all legacy IRQ resources mapped for %s\n", | ||
163 | np->name); | ||
172 | } | 164 | } |
173 | 165 | ||
174 | dev->dev.of_node = of_node_get(np); | 166 | dev->dev.of_node = of_node_get(np); |
diff --git a/drivers/of/selftest.c b/drivers/of/selftest.c index ae4450070503..2588faaaa305 100644 --- a/drivers/of/selftest.c +++ b/drivers/of/selftest.c | |||
@@ -10,6 +10,7 @@ | |||
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/of_irq.h> |
13 | #include <linux/of_platform.h> | ||
13 | #include <linux/list.h> | 14 | #include <linux/list.h> |
14 | #include <linux/mutex.h> | 15 | #include <linux/mutex.h> |
15 | #include <linux/slab.h> | 16 | #include <linux/slab.h> |
@@ -427,6 +428,50 @@ static void __init of_selftest_match_node(void) | |||
427 | } | 428 | } |
428 | } | 429 | } |
429 | 430 | ||
431 | static void __init of_selftest_platform_populate(void) | ||
432 | { | ||
433 | int irq; | ||
434 | struct device_node *np, *child; | ||
435 | struct platform_device *pdev; | ||
436 | struct of_device_id match[] = { | ||
437 | { .compatible = "test-device", }, | ||
438 | {} | ||
439 | }; | ||
440 | |||
441 | np = of_find_node_by_path("/testcase-data"); | ||
442 | of_platform_populate(np, of_default_bus_match_table, NULL, NULL); | ||
443 | |||
444 | /* Test that a missing irq domain returns -EPROBE_DEFER */ | ||
445 | np = of_find_node_by_path("/testcase-data/testcase-device1"); | ||
446 | pdev = of_find_device_by_node(np); | ||
447 | selftest(pdev, "device 1 creation failed\n"); | ||
448 | |||
449 | irq = platform_get_irq(pdev, 0); | ||
450 | selftest(irq == -EPROBE_DEFER, "device deferred probe failed - %d\n", irq); | ||
451 | |||
452 | /* Test that a parsing failure does not return -EPROBE_DEFER */ | ||
453 | np = of_find_node_by_path("/testcase-data/testcase-device2"); | ||
454 | pdev = of_find_device_by_node(np); | ||
455 | selftest(pdev, "device 2 creation failed\n"); | ||
456 | irq = platform_get_irq(pdev, 0); | ||
457 | selftest(irq < 0 && irq != -EPROBE_DEFER, "device parsing error failed - %d\n", irq); | ||
458 | |||
459 | np = of_find_node_by_path("/testcase-data/platform-tests"); | ||
460 | if (!np) { | ||
461 | pr_err("No testcase data in device tree\n"); | ||
462 | return; | ||
463 | } | ||
464 | |||
465 | for_each_child_of_node(np, child) { | ||
466 | struct device_node *grandchild; | ||
467 | of_platform_populate(child, match, NULL, NULL); | ||
468 | for_each_child_of_node(child, grandchild) | ||
469 | selftest(of_find_device_by_node(grandchild), | ||
470 | "Could not create device for node '%s'\n", | ||
471 | grandchild->name); | ||
472 | } | ||
473 | } | ||
474 | |||
430 | static int __init of_selftest(void) | 475 | static int __init of_selftest(void) |
431 | { | 476 | { |
432 | struct device_node *np; | 477 | struct device_node *np; |
@@ -445,6 +490,7 @@ static int __init of_selftest(void) | |||
445 | of_selftest_parse_interrupts(); | 490 | of_selftest_parse_interrupts(); |
446 | of_selftest_parse_interrupts_extended(); | 491 | of_selftest_parse_interrupts_extended(); |
447 | of_selftest_match_node(); | 492 | of_selftest_match_node(); |
493 | of_selftest_platform_populate(); | ||
448 | pr_info("end of selftest - %i passed, %i failed\n", | 494 | pr_info("end of selftest - %i passed, %i failed\n", |
449 | selftest_results.passed, selftest_results.failed); | 495 | selftest_results.passed, selftest_results.failed); |
450 | return 0; | 496 | return 0; |
diff --git a/drivers/of/testcase-data/testcases.dtsi b/drivers/of/testcase-data/testcases.dtsi index 3a5b75a8e4d7..6d8d980ac858 100644 --- a/drivers/of/testcase-data/testcases.dtsi +++ b/drivers/of/testcase-data/testcases.dtsi | |||
@@ -1,3 +1,4 @@ | |||
1 | #include "tests-phandle.dtsi" | 1 | #include "tests-phandle.dtsi" |
2 | #include "tests-interrupts.dtsi" | 2 | #include "tests-interrupts.dtsi" |
3 | #include "tests-match.dtsi" | 3 | #include "tests-match.dtsi" |
4 | #include "tests-platform.dtsi" | ||
diff --git a/drivers/of/testcase-data/tests-interrupts.dtsi b/drivers/of/testcase-data/tests-interrupts.dtsi index c843720bd3e5..da4695f60351 100644 --- a/drivers/of/testcase-data/tests-interrupts.dtsi +++ b/drivers/of/testcase-data/tests-interrupts.dtsi | |||
@@ -54,5 +54,18 @@ | |||
54 | <&test_intmap1 1 2>; | 54 | <&test_intmap1 1 2>; |
55 | }; | 55 | }; |
56 | }; | 56 | }; |
57 | |||
58 | testcase-device1 { | ||
59 | compatible = "testcase-device"; | ||
60 | interrupt-parent = <&test_intc0>; | ||
61 | interrupts = <1>; | ||
62 | }; | ||
63 | |||
64 | testcase-device2 { | ||
65 | compatible = "testcase-device"; | ||
66 | interrupt-parent = <&test_intc2>; | ||
67 | interrupts = <1>; /* invalid specifier - too short */ | ||
68 | }; | ||
57 | }; | 69 | }; |
70 | |||
58 | }; | 71 | }; |
diff --git a/drivers/of/testcase-data/tests-platform.dtsi b/drivers/of/testcase-data/tests-platform.dtsi new file mode 100644 index 000000000000..eb20eeb2b062 --- /dev/null +++ b/drivers/of/testcase-data/tests-platform.dtsi | |||
@@ -0,0 +1,35 @@ | |||
1 | |||
2 | / { | ||
3 | testcase-data { | ||
4 | platform-tests { | ||
5 | #address-cells = <1>; | ||
6 | #size-cells = <0>; | ||
7 | |||
8 | test-device@0 { | ||
9 | compatible = "test-device"; | ||
10 | reg = <0x0>; | ||
11 | |||
12 | #address-cells = <1>; | ||
13 | #size-cells = <0>; | ||
14 | |||
15 | dev@100 { | ||
16 | compatible = "test-sub-device"; | ||
17 | reg = <0x100>; | ||
18 | }; | ||
19 | }; | ||
20 | |||
21 | test-device@1 { | ||
22 | compatible = "test-device"; | ||
23 | reg = <0x1>; | ||
24 | |||
25 | #address-cells = <1>; | ||
26 | #size-cells = <0>; | ||
27 | |||
28 | dev@100 { | ||
29 | compatible = "test-sub-device"; | ||
30 | reg = <0x100>; | ||
31 | }; | ||
32 | }; | ||
33 | }; | ||
34 | }; | ||
35 | }; | ||