Commit 87c7662bea584d5e495e97a59c20b9abaac4eee8
Exists in
master
and in
13 other branches
Merge tag 'dt-for-linus' of git://git.secretlab.ca/git/linux
Pull devicetree bug fixes from Grant Likely: "These are some important bug fixes that need to get into v3.15. This branch contains a pair of important bug fixes for the DT code: - Fix some incorrect binding property names before they enter common usage - Fix bug where some platform devices will be unable to get their interrupt number when they depend on an interrupt controller that is not available at device creation time. This is a problem causing mainline to fail on a number of ARM platforms" * tag 'dt-for-linus' of git://git.secretlab.ca/git/linux: of/irq: do irq resolution in platform_get_irq of: selftest: add deferred probe interrupt test dt: Fix binding typos in clock-names and interrupt-names
Showing 14 changed files Side-by-side Diff
- Documentation/devicetree/bindings/net/socfpga-dwmac.txt
- Documentation/devicetree/bindings/net/stmmac.txt
- Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt
- Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
- arch/arm/boot/dts/am33xx.dtsi
- arch/arm/boot/dts/am4372.dtsi
- arch/arm/boot/dts/stih415-pinctrl.dtsi
- arch/arm/boot/dts/stih416-pinctrl.dtsi
- drivers/base/platform.c
- drivers/of/irq.c
- drivers/of/platform.c
- drivers/of/selftest.c
- drivers/of/testcase-data/tests-interrupts.dtsi
- include/linux/of_irq.h
Documentation/devicetree/bindings/net/socfpga-dwmac.txt
Documentation/devicetree/bindings/net/stmmac.txt
... | ... | @@ -33,7 +33,7 @@ |
33 | 33 | - max-frame-size: See ethernet.txt file in the same directory |
34 | 34 | - clocks: If present, the first clock should be the GMAC main clock, |
35 | 35 | further clocks may be specified in derived bindings. |
36 | -- clocks-names: One name for each entry in the clocks property, the | |
36 | +- clock-names: One name for each entry in the clocks property, the | |
37 | 37 | first one should be "stmmaceth". |
38 | 38 | |
39 | 39 | Examples: |
Documentation/devicetree/bindings/pinctrl/pinctrl-st.txt
... | ... | @@ -83,7 +83,7 @@ |
83 | 83 | reg = <0xfe61f080 0x4>; |
84 | 84 | reg-names = "irqmux"; |
85 | 85 | interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>; |
86 | - interrupts-names = "irqmux"; | |
86 | + interrupt-names = "irqmux"; | |
87 | 87 | ranges = <0 0xfe610000 0x5000>; |
88 | 88 | |
89 | 89 | PIO0: gpio@fe610000 { |
... | ... | @@ -165,7 +165,7 @@ |
165 | 165 | interrupt-parent = <&PIO3>; |
166 | 166 | #interrupt-cells = <2>; |
167 | 167 | interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; /* Interrupt line via PIO3-3 */ |
168 | - interrupts-names = "card-detect"; | |
168 | + interrupt-names = "card-detect"; | |
169 | 169 | pinctrl-names = "default"; |
170 | 170 | pinctrl-0 = <&pinctrl_mmc>; |
171 | 171 | }; |
Documentation/devicetree/bindings/sound/davinci-mcasp-audio.txt
arch/arm/boot/dts/am33xx.dtsi
... | ... | @@ -802,7 +802,7 @@ |
802 | 802 | <0x46000000 0x400000>; |
803 | 803 | reg-names = "mpu", "dat"; |
804 | 804 | interrupts = <80>, <81>; |
805 | - interrupts-names = "tx", "rx"; | |
805 | + interrupt-names = "tx", "rx"; | |
806 | 806 | status = "disabled"; |
807 | 807 | dmas = <&edma 8>, |
808 | 808 | <&edma 9>; |
... | ... | @@ -816,7 +816,7 @@ |
816 | 816 | <0x46400000 0x400000>; |
817 | 817 | reg-names = "mpu", "dat"; |
818 | 818 | interrupts = <82>, <83>; |
819 | - interrupts-names = "tx", "rx"; | |
819 | + interrupt-names = "tx", "rx"; | |
820 | 820 | status = "disabled"; |
821 | 821 | dmas = <&edma 10>, |
822 | 822 | <&edma 11>; |
arch/arm/boot/dts/am4372.dtsi
... | ... | @@ -691,7 +691,7 @@ |
691 | 691 | <0x46000000 0x400000>; |
692 | 692 | reg-names = "mpu", "dat"; |
693 | 693 | interrupts = <80>, <81>; |
694 | - interrupts-names = "tx", "rx"; | |
694 | + interrupt-names = "tx", "rx"; | |
695 | 695 | status = "disabled"; |
696 | 696 | dmas = <&edma 8>, |
697 | 697 | <&edma 9>; |
... | ... | @@ -705,7 +705,7 @@ |
705 | 705 | <0x46400000 0x400000>; |
706 | 706 | reg-names = "mpu", "dat"; |
707 | 707 | interrupts = <82>, <83>; |
708 | - interrupts-names = "tx", "rx"; | |
708 | + interrupt-names = "tx", "rx"; | |
709 | 709 | status = "disabled"; |
710 | 710 | dmas = <&edma 10>, |
711 | 711 | <&edma 11>; |
arch/arm/boot/dts/stih415-pinctrl.dtsi
... | ... | @@ -49,7 +49,7 @@ |
49 | 49 | reg = <0xfe61f080 0x4>; |
50 | 50 | reg-names = "irqmux"; |
51 | 51 | interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>; |
52 | - interrupts-names = "irqmux"; | |
52 | + interrupt-names = "irqmux"; | |
53 | 53 | ranges = <0 0xfe610000 0x5000>; |
54 | 54 | |
55 | 55 | PIO0: gpio@fe610000 { |
... | ... | @@ -187,7 +187,7 @@ |
187 | 187 | reg = <0xfee0f080 0x4>; |
188 | 188 | reg-names = "irqmux"; |
189 | 189 | interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>; |
190 | - interrupts-names = "irqmux"; | |
190 | + interrupt-names = "irqmux"; | |
191 | 191 | ranges = <0 0xfee00000 0x8000>; |
192 | 192 | |
193 | 193 | PIO5: gpio@fee00000 { |
... | ... | @@ -282,7 +282,7 @@ |
282 | 282 | reg = <0xfe82f080 0x4>; |
283 | 283 | reg-names = "irqmux"; |
284 | 284 | interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>; |
285 | - interrupts-names = "irqmux"; | |
285 | + interrupt-names = "irqmux"; | |
286 | 286 | ranges = <0 0xfe820000 0x8000>; |
287 | 287 | |
288 | 288 | PIO13: gpio@fe820000 { |
... | ... | @@ -423,7 +423,7 @@ |
423 | 423 | reg = <0xfd6bf080 0x4>; |
424 | 424 | reg-names = "irqmux"; |
425 | 425 | interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; |
426 | - interrupts-names = "irqmux"; | |
426 | + interrupt-names = "irqmux"; | |
427 | 427 | ranges = <0 0xfd6b0000 0x3000>; |
428 | 428 | |
429 | 429 | PIO100: gpio@fd6b0000 { |
... | ... | @@ -460,7 +460,7 @@ |
460 | 460 | reg = <0xfd33f080 0x4>; |
461 | 461 | reg-names = "irqmux"; |
462 | 462 | interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; |
463 | - interrupts-names = "irqmux"; | |
463 | + interrupt-names = "irqmux"; | |
464 | 464 | ranges = <0 0xfd330000 0x5000>; |
465 | 465 | |
466 | 466 | PIO103: gpio@fd330000 { |
arch/arm/boot/dts/stih416-pinctrl.dtsi
... | ... | @@ -53,7 +53,7 @@ |
53 | 53 | reg = <0xfe61f080 0x4>; |
54 | 54 | reg-names = "irqmux"; |
55 | 55 | interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>; |
56 | - interrupts-names = "irqmux"; | |
56 | + interrupt-names = "irqmux"; | |
57 | 57 | ranges = <0 0xfe610000 0x6000>; |
58 | 58 | |
59 | 59 | PIO0: gpio@fe610000 { |
... | ... | @@ -201,7 +201,7 @@ |
201 | 201 | reg = <0xfee0f080 0x4>; |
202 | 202 | reg-names = "irqmux"; |
203 | 203 | interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>; |
204 | - interrupts-names = "irqmux"; | |
204 | + interrupt-names = "irqmux"; | |
205 | 205 | ranges = <0 0xfee00000 0x10000>; |
206 | 206 | |
207 | 207 | PIO5: gpio@fee00000 { |
... | ... | @@ -333,7 +333,7 @@ |
333 | 333 | reg = <0xfe82f080 0x4>; |
334 | 334 | reg-names = "irqmux"; |
335 | 335 | interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>; |
336 | - interrupts-names = "irqmux"; | |
336 | + interrupt-names = "irqmux"; | |
337 | 337 | ranges = <0 0xfe820000 0x6000>; |
338 | 338 | |
339 | 339 | PIO13: gpio@fe820000 { |
... | ... | @@ -461,7 +461,7 @@ |
461 | 461 | reg = <0xfd6bf080 0x4>; |
462 | 462 | reg-names = "irqmux"; |
463 | 463 | interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>; |
464 | - interrupts-names = "irqmux"; | |
464 | + interrupt-names = "irqmux"; | |
465 | 465 | ranges = <0 0xfd6b0000 0x3000>; |
466 | 466 | |
467 | 467 | PIO100: gpio@fd6b0000 { |
... | ... | @@ -498,7 +498,7 @@ |
498 | 498 | reg = <0xfd33f080 0x4>; |
499 | 499 | reg-names = "irqmux"; |
500 | 500 | interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>; |
501 | - interrupts-names = "irqmux"; | |
501 | + interrupt-names = "irqmux"; | |
502 | 502 | ranges = <0 0xfd330000 0x5000>; |
503 | 503 | |
504 | 504 | PIO103: gpio@fd330000 { |
drivers/base/platform.c
... | ... | @@ -13,6 +13,7 @@ |
13 | 13 | #include <linux/string.h> |
14 | 14 | #include <linux/platform_device.h> |
15 | 15 | #include <linux/of_device.h> |
16 | +#include <linux/of_irq.h> | |
16 | 17 | #include <linux/module.h> |
17 | 18 | #include <linux/init.h> |
18 | 19 | #include <linux/dma-mapping.h> |
... | ... | @@ -87,7 +88,11 @@ |
87 | 88 | return -ENXIO; |
88 | 89 | return dev->archdata.irqs[num]; |
89 | 90 | #else |
90 | - struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num); | |
91 | + struct resource *r; | |
92 | + if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node) | |
93 | + return of_irq_get(dev->dev.of_node, num); | |
94 | + | |
95 | + r = platform_get_resource(dev, IORESOURCE_IRQ, num); | |
91 | 96 | |
92 | 97 | return r ? r->start : -ENXIO; |
93 | 98 | #endif |
drivers/of/irq.c
... | ... | @@ -364,7 +364,7 @@ |
364 | 364 | |
365 | 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 | 368 | * to the resource. |
369 | 369 | */ |
370 | 370 | of_property_read_string_index(dev, "interrupt-names", index, |
... | ... | @@ -378,6 +378,32 @@ |
378 | 378 | return irq; |
379 | 379 | } |
380 | 380 | EXPORT_SYMBOL_GPL(of_irq_to_resource); |
381 | + | |
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 | +} | |
381 | 407 | |
382 | 408 | /** |
383 | 409 | * of_irq_count - Count the number of IRQs a node uses |
drivers/of/platform.c
... | ... | @@ -168,7 +168,9 @@ |
168 | 168 | rc = of_address_to_resource(np, i, res); |
169 | 169 | WARN_ON(rc); |
170 | 170 | } |
171 | - WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq); | |
171 | + if (of_irq_to_resource_table(np, res, num_irq) != num_irq) | |
172 | + pr_debug("not all legacy IRQ resources mapped for %s\n", | |
173 | + np->name); | |
172 | 174 | } |
173 | 175 | |
174 | 176 | dev->dev.of_node = of_node_get(np); |
drivers/of/selftest.c
... | ... | @@ -10,6 +10,7 @@ |
10 | 10 | #include <linux/module.h> |
11 | 11 | #include <linux/of.h> |
12 | 12 | #include <linux/of_irq.h> |
13 | +#include <linux/of_platform.h> | |
13 | 14 | #include <linux/list.h> |
14 | 15 | #include <linux/mutex.h> |
15 | 16 | #include <linux/slab.h> |
... | ... | @@ -427,6 +428,36 @@ |
427 | 428 | } |
428 | 429 | } |
429 | 430 | |
431 | +static void __init of_selftest_platform_populate(void) | |
432 | +{ | |
433 | + int irq; | |
434 | + struct device_node *np; | |
435 | + struct platform_device *pdev; | |
436 | + | |
437 | + np = of_find_node_by_path("/testcase-data"); | |
438 | + of_platform_populate(np, of_default_bus_match_table, NULL, NULL); | |
439 | + | |
440 | + /* Test that a missing irq domain returns -EPROBE_DEFER */ | |
441 | + np = of_find_node_by_path("/testcase-data/testcase-device1"); | |
442 | + pdev = of_find_device_by_node(np); | |
443 | + if (!pdev) | |
444 | + selftest(0, "device 1 creation failed\n"); | |
445 | + irq = platform_get_irq(pdev, 0); | |
446 | + if (irq != -EPROBE_DEFER) | |
447 | + selftest(0, "device deferred probe failed - %d\n", irq); | |
448 | + | |
449 | + /* Test that a parsing failure does not return -EPROBE_DEFER */ | |
450 | + np = of_find_node_by_path("/testcase-data/testcase-device2"); | |
451 | + pdev = of_find_device_by_node(np); | |
452 | + if (!pdev) | |
453 | + selftest(0, "device 2 creation failed\n"); | |
454 | + irq = platform_get_irq(pdev, 0); | |
455 | + if (irq >= 0 || irq == -EPROBE_DEFER) | |
456 | + selftest(0, "device parsing error failed - %d\n", irq); | |
457 | + | |
458 | + selftest(1, "passed"); | |
459 | +} | |
460 | + | |
430 | 461 | static int __init of_selftest(void) |
431 | 462 | { |
432 | 463 | struct device_node *np; |
... | ... | @@ -445,6 +476,7 @@ |
445 | 476 | of_selftest_parse_interrupts(); |
446 | 477 | of_selftest_parse_interrupts_extended(); |
447 | 478 | of_selftest_match_node(); |
479 | + of_selftest_platform_populate(); | |
448 | 480 | pr_info("end of selftest - %i passed, %i failed\n", |
449 | 481 | selftest_results.passed, selftest_results.failed); |
450 | 482 | return 0; |
drivers/of/testcase-data/tests-interrupts.dtsi
... | ... | @@ -54,6 +54,19 @@ |
54 | 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 | }; |
include/linux/of_irq.h
... | ... | @@ -44,8 +44,13 @@ |
44 | 44 | |
45 | 45 | #ifdef CONFIG_OF_IRQ |
46 | 46 | extern int of_irq_count(struct device_node *dev); |
47 | +extern int of_irq_get(struct device_node *dev, int index); | |
47 | 48 | #else |
48 | 49 | static inline int of_irq_count(struct device_node *dev) |
50 | +{ | |
51 | + return 0; | |
52 | +} | |
53 | +static inline int of_irq_get(struct device_node *dev, int index) | |
49 | 54 | { |
50 | 55 | return 0; |
51 | 56 | } |