| .. | .. |
|---|
| 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 | + return -EINVAL; |
|---|
| 43 | + |
|---|
| 44 | + if (par_np == np) |
|---|
| 45 | + par_np = NULL; |
|---|
| 46 | + |
|---|
| 47 | + /* |
|---|
| 48 | + * If there's a parent interrupt controller and none of the parent irq |
|---|
| 49 | + * domains have been registered, that means the parent interrupt |
|---|
| 50 | + * controller has not been initialized yet. it's not time for this |
|---|
| 51 | + * interrupt controller to initialize. So, defer probe of this |
|---|
| 52 | + * interrupt controller. The actual initialization callback of this |
|---|
| 53 | + * interrupt controller can check for specific domains as necessary. |
|---|
| 54 | + */ |
|---|
| 55 | + if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) |
|---|
| 56 | + return -EPROBE_DEFER; |
|---|
| 57 | + |
|---|
| 58 | + return irq_init_cb(np, par_np); |
|---|
| 59 | +} |
|---|
| 60 | +EXPORT_SYMBOL_GPL(platform_irqchip_probe); |
|---|