aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/of
diff options
context:
space:
mode:
authorRob Herring <robh@kernel.org>2014-05-13 19:34:35 -0400
committerRob Herring <robh@kernel.org>2014-05-13 19:34:35 -0400
commiteafd370dfe487facfdef499057f4eac9aa0b4bf5 (patch)
tree0925a67cd658cdf4811f49b4cd2073f663166bd0 /drivers/of
parentc3fc952d2fbe3ec78defd70cf73d5d76d27092ec (diff)
parentfb2caa50fbacd21719a90dd66b617ce3cb4fd6d7 (diff)
Merge branch 'dt-bus-name' into for-next
Diffstat (limited to 'drivers/of')
-rw-r--r--drivers/of/address.c22
-rw-r--r--drivers/of/irq.c28
-rw-r--r--drivers/of/platform.c20
-rw-r--r--drivers/of/selftest.c46
-rw-r--r--drivers/of/testcase-data/testcases.dtsi1
-rw-r--r--drivers/of/testcase-data/tests-interrupts.dtsi13
-rw-r--r--drivers/of/testcase-data/tests-platform.dtsi35
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}
565EXPORT_SYMBOL(of_translate_dma_address); 564EXPORT_SYMBOL(of_translate_dma_address);
566 565
567bool 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}
584EXPORT_SYMBOL(of_can_translate_address);
585
586const __be32 *of_get_address(struct device_node *dev, int index, u64 *size, 566const __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)
380EXPORT_SYMBOL_GPL(of_irq_to_resource); 380EXPORT_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 */
391int 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
431static 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
430static int __init of_selftest(void) 475static 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};