mirror of
https://github.com/torvalds/linux.git
synced 2024-11-28 07:01:32 +00:00
Devicetree bug fixes for 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. -----BEGIN PGP SIGNATURE----- Version: GnuPG v1 iQIcBAABAgAGBQJTXr8WAAoJEMWQL496c2LNhzgP/RhhIS9ySzJkdPEMksnBaQbN JKG+wBwlzvtJSPw2xX5EpWweOd1PDqHxLjjWu7q5WIrQQyOGRAELkYg1H+5ksFo1 obCAFOjTC7VXPGc+BX0dLN6Eq4UHP8k3Ui8zlMSZQNt+gBvYo1gX2ulR8sQgS8rF xw+8iNDA2GIFusQbci35yOAhp6yo/ble3KIeR5dFKeMpiVSh9rqdLS+H9HgnG5Sw G2LUrAeRY2yQbow3c1001HiKrJieZZSTCq8oiZDgJZY5+Qk8zamyj2xxgMoJUA8Q 2Kcb3379vNvDgjYX61NiwyrhIbJEiao8IXq6WMDNbmH3+FUwogrnh/A/g5POtX0N JV5tGkc/2lfm5oBCFSzcw661XjLysPsm3nPLhnxRL/dlBVkl0IZzTVYPTqUtoKlK NfwKFUDgg+QVmhFQT0BDCyOGAcRsz4rNEPPB6M12OmEKgxGpetfUaFdBcJqSNaxf Ac6AAZCXrkLlRNOVhK333ILPxv1JRC++JAeRKNwHr9e6j2aJjUgilSuzpHJ5Lkyo sj6kp+n1n+giYlgc9GjM7b33tm8XEd4rbcgwCWwaypEsl4FIwPs9xMys7md8SOCE AAnVPVUvLGC9O2GhldeQlOgtGWzILW3zJXb2mrMIIGyLBGBx1qr3VJIZpxoddTc0 UtIJn0X37mKY/R4/hWs4 =B2JT -----END PGP SIGNATURE----- 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
This commit is contained in:
commit
87c7662bea
@ -23,5 +23,5 @@ gmac0: ethernet@ff700000 {
|
||||
interrupt-names = "macirq";
|
||||
mac-address = [00 00 00 00 00 00];/* Filled in by U-Boot */
|
||||
clocks = <&emac_0_clk>;
|
||||
clocks-names = "stmmaceth";
|
||||
clock-names = "stmmaceth";
|
||||
};
|
||||
|
@ -33,7 +33,7 @@ Optional properties:
|
||||
- max-frame-size: See ethernet.txt file in the same directory
|
||||
- clocks: If present, the first clock should be the GMAC main clock,
|
||||
further clocks may be specified in derived bindings.
|
||||
- clocks-names: One name for each entry in the clocks property, the
|
||||
- clock-names: One name for each entry in the clocks property, the
|
||||
first one should be "stmmaceth".
|
||||
|
||||
Examples:
|
||||
|
@ -83,7 +83,7 @@ Example:
|
||||
reg = <0xfe61f080 0x4>;
|
||||
reg-names = "irqmux";
|
||||
interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-names = "irqmux";
|
||||
interrupt-names = "irqmux";
|
||||
ranges = <0 0xfe610000 0x5000>;
|
||||
|
||||
PIO0: gpio@fe610000 {
|
||||
@ -165,7 +165,7 @@ sdhci0:sdhci@fe810000{
|
||||
interrupt-parent = <&PIO3>;
|
||||
#interrupt-cells = <2>;
|
||||
interrupts = <3 IRQ_TYPE_LEVEL_HIGH>; /* Interrupt line via PIO3-3 */
|
||||
interrupts-names = "card-detect";
|
||||
interrupt-names = "card-detect";
|
||||
pinctrl-names = "default";
|
||||
pinctrl-0 = <&pinctrl_mmc>;
|
||||
};
|
||||
|
@ -47,7 +47,7 @@ mcasp0: mcasp0@1d00000 {
|
||||
reg = <0x100000 0x3000>;
|
||||
reg-names "mpu";
|
||||
interrupts = <82>, <83>;
|
||||
interrupts-names = "tx", "rx";
|
||||
interrupt-names = "tx", "rx";
|
||||
op-mode = <0>; /* MCASP_IIS_MODE */
|
||||
tdm-slots = <2>;
|
||||
serial-dir = <
|
||||
|
@ -802,7 +802,7 @@
|
||||
<0x46000000 0x400000>;
|
||||
reg-names = "mpu", "dat";
|
||||
interrupts = <80>, <81>;
|
||||
interrupts-names = "tx", "rx";
|
||||
interrupt-names = "tx", "rx";
|
||||
status = "disabled";
|
||||
dmas = <&edma 8>,
|
||||
<&edma 9>;
|
||||
@ -816,7 +816,7 @@
|
||||
<0x46400000 0x400000>;
|
||||
reg-names = "mpu", "dat";
|
||||
interrupts = <82>, <83>;
|
||||
interrupts-names = "tx", "rx";
|
||||
interrupt-names = "tx", "rx";
|
||||
status = "disabled";
|
||||
dmas = <&edma 10>,
|
||||
<&edma 11>;
|
||||
|
@ -691,7 +691,7 @@
|
||||
<0x46000000 0x400000>;
|
||||
reg-names = "mpu", "dat";
|
||||
interrupts = <80>, <81>;
|
||||
interrupts-names = "tx", "rx";
|
||||
interrupt-names = "tx", "rx";
|
||||
status = "disabled";
|
||||
dmas = <&edma 8>,
|
||||
<&edma 9>;
|
||||
@ -705,7 +705,7 @@
|
||||
<0x46400000 0x400000>;
|
||||
reg-names = "mpu", "dat";
|
||||
interrupts = <82>, <83>;
|
||||
interrupts-names = "tx", "rx";
|
||||
interrupt-names = "tx", "rx";
|
||||
status = "disabled";
|
||||
dmas = <&edma 10>,
|
||||
<&edma 11>;
|
||||
|
@ -49,7 +49,7 @@
|
||||
reg = <0xfe61f080 0x4>;
|
||||
reg-names = "irqmux";
|
||||
interrupts = <GIC_SPI 180 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-names = "irqmux";
|
||||
interrupt-names = "irqmux";
|
||||
ranges = <0 0xfe610000 0x5000>;
|
||||
|
||||
PIO0: gpio@fe610000 {
|
||||
@ -187,7 +187,7 @@
|
||||
reg = <0xfee0f080 0x4>;
|
||||
reg-names = "irqmux";
|
||||
interrupts = <GIC_SPI 181 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-names = "irqmux";
|
||||
interrupt-names = "irqmux";
|
||||
ranges = <0 0xfee00000 0x8000>;
|
||||
|
||||
PIO5: gpio@fee00000 {
|
||||
@ -282,7 +282,7 @@
|
||||
reg = <0xfe82f080 0x4>;
|
||||
reg-names = "irqmux";
|
||||
interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-names = "irqmux";
|
||||
interrupt-names = "irqmux";
|
||||
ranges = <0 0xfe820000 0x8000>;
|
||||
|
||||
PIO13: gpio@fe820000 {
|
||||
@ -423,7 +423,7 @@
|
||||
reg = <0xfd6bf080 0x4>;
|
||||
reg-names = "irqmux";
|
||||
interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-names = "irqmux";
|
||||
interrupt-names = "irqmux";
|
||||
ranges = <0 0xfd6b0000 0x3000>;
|
||||
|
||||
PIO100: gpio@fd6b0000 {
|
||||
@ -460,7 +460,7 @@
|
||||
reg = <0xfd33f080 0x4>;
|
||||
reg-names = "irqmux";
|
||||
interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-names = "irqmux";
|
||||
interrupt-names = "irqmux";
|
||||
ranges = <0 0xfd330000 0x5000>;
|
||||
|
||||
PIO103: gpio@fd330000 {
|
||||
|
@ -53,7 +53,7 @@
|
||||
reg = <0xfe61f080 0x4>;
|
||||
reg-names = "irqmux";
|
||||
interrupts = <GIC_SPI 182 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-names = "irqmux";
|
||||
interrupt-names = "irqmux";
|
||||
ranges = <0 0xfe610000 0x6000>;
|
||||
|
||||
PIO0: gpio@fe610000 {
|
||||
@ -201,7 +201,7 @@
|
||||
reg = <0xfee0f080 0x4>;
|
||||
reg-names = "irqmux";
|
||||
interrupts = <GIC_SPI 183 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-names = "irqmux";
|
||||
interrupt-names = "irqmux";
|
||||
ranges = <0 0xfee00000 0x10000>;
|
||||
|
||||
PIO5: gpio@fee00000 {
|
||||
@ -333,7 +333,7 @@
|
||||
reg = <0xfe82f080 0x4>;
|
||||
reg-names = "irqmux";
|
||||
interrupts = <GIC_SPI 184 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-names = "irqmux";
|
||||
interrupt-names = "irqmux";
|
||||
ranges = <0 0xfe820000 0x6000>;
|
||||
|
||||
PIO13: gpio@fe820000 {
|
||||
@ -461,7 +461,7 @@
|
||||
reg = <0xfd6bf080 0x4>;
|
||||
reg-names = "irqmux";
|
||||
interrupts = <GIC_SPI 113 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-names = "irqmux";
|
||||
interrupt-names = "irqmux";
|
||||
ranges = <0 0xfd6b0000 0x3000>;
|
||||
|
||||
PIO100: gpio@fd6b0000 {
|
||||
@ -498,7 +498,7 @@
|
||||
reg = <0xfd33f080 0x4>;
|
||||
reg-names = "irqmux";
|
||||
interrupts = <GIC_SPI 114 IRQ_TYPE_LEVEL_HIGH>;
|
||||
interrupts-names = "irqmux";
|
||||
interrupt-names = "irqmux";
|
||||
ranges = <0 0xfd330000 0x5000>;
|
||||
|
||||
PIO103: gpio@fd330000 {
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include <linux/string.h>
|
||||
#include <linux/platform_device.h>
|
||||
#include <linux/of_device.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/module.h>
|
||||
#include <linux/init.h>
|
||||
#include <linux/dma-mapping.h>
|
||||
@ -87,7 +88,11 @@ int platform_get_irq(struct platform_device *dev, unsigned int num)
|
||||
return -ENXIO;
|
||||
return dev->archdata.irqs[num];
|
||||
#else
|
||||
struct resource *r = platform_get_resource(dev, IORESOURCE_IRQ, num);
|
||||
struct resource *r;
|
||||
if (IS_ENABLED(CONFIG_OF_IRQ) && dev->dev.of_node)
|
||||
return of_irq_get(dev->dev.of_node, num);
|
||||
|
||||
r = platform_get_resource(dev, IORESOURCE_IRQ, num);
|
||||
|
||||
return r ? r->start : -ENXIO;
|
||||
#endif
|
||||
|
@ -364,7 +364,7 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
|
||||
|
||||
memset(r, 0, sizeof(*r));
|
||||
/*
|
||||
* Get optional "interrupts-names" property to add a name
|
||||
* Get optional "interrupt-names" property to add a name
|
||||
* to the resource.
|
||||
*/
|
||||
of_property_read_string_index(dev, "interrupt-names", index,
|
||||
@ -379,6 +379,32 @@ int of_irq_to_resource(struct device_node *dev, int index, struct resource *r)
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(of_irq_to_resource);
|
||||
|
||||
/**
|
||||
* of_irq_get - Decode a node's IRQ and return it as a Linux irq number
|
||||
* @dev: pointer to device tree node
|
||||
* @index: zero-based index of the irq
|
||||
*
|
||||
* Returns Linux irq number on success, or -EPROBE_DEFER if the irq domain
|
||||
* is not yet created.
|
||||
*
|
||||
*/
|
||||
int of_irq_get(struct device_node *dev, int index)
|
||||
{
|
||||
int rc;
|
||||
struct of_phandle_args oirq;
|
||||
struct irq_domain *domain;
|
||||
|
||||
rc = of_irq_parse_one(dev, index, &oirq);
|
||||
if (rc)
|
||||
return rc;
|
||||
|
||||
domain = irq_find_host(oirq.np);
|
||||
if (!domain)
|
||||
return -EPROBE_DEFER;
|
||||
|
||||
return irq_create_of_mapping(&oirq);
|
||||
}
|
||||
|
||||
/**
|
||||
* of_irq_count - Count the number of IRQs a node uses
|
||||
* @dev: pointer to device tree node
|
||||
|
@ -168,7 +168,9 @@ struct platform_device *of_device_alloc(struct device_node *np,
|
||||
rc = of_address_to_resource(np, i, res);
|
||||
WARN_ON(rc);
|
||||
}
|
||||
WARN_ON(of_irq_to_resource_table(np, res, num_irq) != num_irq);
|
||||
if (of_irq_to_resource_table(np, res, num_irq) != num_irq)
|
||||
pr_debug("not all legacy IRQ resources mapped for %s\n",
|
||||
np->name);
|
||||
}
|
||||
|
||||
dev->dev.of_node = of_node_get(np);
|
||||
|
@ -10,6 +10,7 @@
|
||||
#include <linux/module.h>
|
||||
#include <linux/of.h>
|
||||
#include <linux/of_irq.h>
|
||||
#include <linux/of_platform.h>
|
||||
#include <linux/list.h>
|
||||
#include <linux/mutex.h>
|
||||
#include <linux/slab.h>
|
||||
@ -427,6 +428,36 @@ static void __init of_selftest_match_node(void)
|
||||
}
|
||||
}
|
||||
|
||||
static void __init of_selftest_platform_populate(void)
|
||||
{
|
||||
int irq;
|
||||
struct device_node *np;
|
||||
struct platform_device *pdev;
|
||||
|
||||
np = of_find_node_by_path("/testcase-data");
|
||||
of_platform_populate(np, of_default_bus_match_table, NULL, NULL);
|
||||
|
||||
/* Test that a missing irq domain returns -EPROBE_DEFER */
|
||||
np = of_find_node_by_path("/testcase-data/testcase-device1");
|
||||
pdev = of_find_device_by_node(np);
|
||||
if (!pdev)
|
||||
selftest(0, "device 1 creation failed\n");
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq != -EPROBE_DEFER)
|
||||
selftest(0, "device deferred probe failed - %d\n", irq);
|
||||
|
||||
/* Test that a parsing failure does not return -EPROBE_DEFER */
|
||||
np = of_find_node_by_path("/testcase-data/testcase-device2");
|
||||
pdev = of_find_device_by_node(np);
|
||||
if (!pdev)
|
||||
selftest(0, "device 2 creation failed\n");
|
||||
irq = platform_get_irq(pdev, 0);
|
||||
if (irq >= 0 || irq == -EPROBE_DEFER)
|
||||
selftest(0, "device parsing error failed - %d\n", irq);
|
||||
|
||||
selftest(1, "passed");
|
||||
}
|
||||
|
||||
static int __init of_selftest(void)
|
||||
{
|
||||
struct device_node *np;
|
||||
@ -445,6 +476,7 @@ static int __init of_selftest(void)
|
||||
of_selftest_parse_interrupts();
|
||||
of_selftest_parse_interrupts_extended();
|
||||
of_selftest_match_node();
|
||||
of_selftest_platform_populate();
|
||||
pr_info("end of selftest - %i passed, %i failed\n",
|
||||
selftest_results.passed, selftest_results.failed);
|
||||
return 0;
|
||||
|
@ -54,5 +54,18 @@
|
||||
<&test_intmap1 1 2>;
|
||||
};
|
||||
};
|
||||
|
||||
testcase-device1 {
|
||||
compatible = "testcase-device";
|
||||
interrupt-parent = <&test_intc0>;
|
||||
interrupts = <1>;
|
||||
};
|
||||
|
||||
testcase-device2 {
|
||||
compatible = "testcase-device";
|
||||
interrupt-parent = <&test_intc2>;
|
||||
interrupts = <1>; /* invalid specifier - too short */
|
||||
};
|
||||
};
|
||||
|
||||
};
|
||||
|
@ -44,11 +44,16 @@ extern void of_irq_init(const struct of_device_id *matches);
|
||||
|
||||
#ifdef CONFIG_OF_IRQ
|
||||
extern int of_irq_count(struct device_node *dev);
|
||||
extern int of_irq_get(struct device_node *dev, int index);
|
||||
#else
|
||||
static inline int of_irq_count(struct device_node *dev)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
static inline int of_irq_get(struct device_node *dev, int index)
|
||||
{
|
||||
return 0;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(CONFIG_OF)
|
||||
|
Loading…
Reference in New Issue
Block a user