.. | .. |
---|
10 | 10 | |
---|
11 | 11 | #include <linux/acpi.h> |
---|
12 | 12 | #include <linux/init.h> |
---|
| 13 | +#include <linux/of_device.h> |
---|
13 | 14 | #include <linux/of_irq.h> |
---|
14 | 15 | #include <linux/irqchip.h> |
---|
| 16 | +#include <linux/platform_device.h> |
---|
15 | 17 | |
---|
16 | 18 | /* |
---|
17 | 19 | * This special of_device_id is the sentinel at the end of the |
---|
.. | .. |
---|
20 | 22 | * special section. |
---|
21 | 23 | */ |
---|
22 | 24 | static const struct of_device_id |
---|
23 | | -irqchip_of_match_end __used __section(__irqchip_of_table_end); |
---|
| 25 | +irqchip_of_match_end __used __section("__irqchip_of_table_end"); |
---|
24 | 26 | |
---|
25 | 27 | extern struct of_device_id __irqchip_of_table[]; |
---|
26 | 28 | |
---|
.. | .. |
---|
29 | 31 | of_irq_init(__irqchip_of_table); |
---|
30 | 32 | acpi_probe_device_table(irqchip); |
---|
31 | 33 | } |
---|
| 34 | + |
---|
| 35 | +int platform_irqchip_probe(struct platform_device *pdev) |
---|
| 36 | +{ |
---|
| 37 | + struct device_node *np = pdev->dev.of_node; |
---|
| 38 | + struct device_node *par_np = of_irq_find_parent(np); |
---|
| 39 | + of_irq_init_cb_t irq_init_cb = of_device_get_match_data(&pdev->dev); |
---|
| 40 | + |
---|
| 41 | + if (!irq_init_cb) { |
---|
| 42 | + of_node_put(par_np); |
---|
| 43 | + return -EINVAL; |
---|
| 44 | + } |
---|
| 45 | + |
---|
| 46 | + if (par_np == np) |
---|
| 47 | + par_np = NULL; |
---|
| 48 | + |
---|
| 49 | + /* |
---|
| 50 | + * If there's a parent interrupt controller and none of the parent irq |
---|
| 51 | + * domains have been registered, that means the parent interrupt |
---|
| 52 | + * controller has not been initialized yet. it's not time for this |
---|
| 53 | + * interrupt controller to initialize. So, defer probe of this |
---|
| 54 | + * interrupt controller. The actual initialization callback of this |
---|
| 55 | + * interrupt controller can check for specific domains as necessary. |
---|
| 56 | + */ |
---|
| 57 | + if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) { |
---|
| 58 | + of_node_put(par_np); |
---|
| 59 | + return -EPROBE_DEFER; |
---|
| 60 | + } |
---|
| 61 | + |
---|
| 62 | + return irq_init_cb(np, par_np); |
---|
| 63 | +} |
---|
| 64 | +EXPORT_SYMBOL_GPL(platform_irqchip_probe); |
---|