1f6e916b8SThomas Petazzoni /* 2f6e916b8SThomas Petazzoni * Copyright (C) 2012 Thomas Petazzoni 3f6e916b8SThomas Petazzoni * 4f6e916b8SThomas Petazzoni * Thomas Petazzoni <thomas.petazzoni@free-electrons.com> 5f6e916b8SThomas Petazzoni * 6f6e916b8SThomas Petazzoni * This file is licensed under the terms of the GNU General Public 7f6e916b8SThomas Petazzoni * License version 2. This program is licensed "as is" without any 8f6e916b8SThomas Petazzoni * warranty of any kind, whether express or implied. 9f6e916b8SThomas Petazzoni */ 10f6e916b8SThomas Petazzoni 1146e589a3SMarc Zyngier #include <linux/acpi.h> 12f6e916b8SThomas Petazzoni #include <linux/init.h> 13ee076750SRob Herring #include <linux/of.h> 14f6e916b8SThomas Petazzoni #include <linux/of_irq.h> 15559ba4b1SStephen Boyd #include <linux/irqchip.h> 16f8410e62SSaravana Kannan #include <linux/platform_device.h> 17f6e916b8SThomas Petazzoni 18f6e916b8SThomas Petazzoni /* 19f6e916b8SThomas Petazzoni * This special of_device_id is the sentinel at the end of the 20f6e916b8SThomas Petazzoni * of_device_id[] array of all irqchips. It is automatically placed at 21f6e916b8SThomas Petazzoni * the end of the array by the linker, thanks to being part of a 22f6e916b8SThomas Petazzoni * special section. 23f6e916b8SThomas Petazzoni */ 24f6e916b8SThomas Petazzoni static const struct of_device_id 2533def849SJoe Perches irqchip_of_match_end __used __section("__irqchip_of_table_end"); 26f6e916b8SThomas Petazzoni 27735e0da7SRob Herring extern struct of_device_id __irqchip_of_table[]; 28f6e916b8SThomas Petazzoni irqchip_init(void)29f6e916b8SThomas Petazzonivoid __init irqchip_init(void) 30f6e916b8SThomas Petazzoni { 31735e0da7SRob Herring of_irq_init(__irqchip_of_table); 3246e589a3SMarc Zyngier acpi_probe_device_table(irqchip); 33f6e916b8SThomas Petazzoni } 34f8410e62SSaravana Kannan platform_irqchip_probe(struct platform_device * pdev)35f8410e62SSaravana Kannanint platform_irqchip_probe(struct platform_device *pdev) 36f8410e62SSaravana Kannan { 37f8410e62SSaravana Kannan struct device_node *np = pdev->dev.of_node; 38*61ecbceaSJoe Hattori struct device_node *par_np __free(device_node) = of_irq_find_parent(np); 39f8410e62SSaravana Kannan of_irq_init_cb_t irq_init_cb = of_device_get_match_data(&pdev->dev); 40f8410e62SSaravana Kannan 416caa5a2bSMiaoqian Lin if (!irq_init_cb) { 42f8410e62SSaravana Kannan return -EINVAL; 436caa5a2bSMiaoqian Lin } 44f8410e62SSaravana Kannan 45f8410e62SSaravana Kannan if (par_np == np) 46f8410e62SSaravana Kannan par_np = NULL; 47f8410e62SSaravana Kannan 48f8410e62SSaravana Kannan /* 49f8410e62SSaravana Kannan * If there's a parent interrupt controller and none of the parent irq 50f8410e62SSaravana Kannan * domains have been registered, that means the parent interrupt 51f8410e62SSaravana Kannan * controller has not been initialized yet. it's not time for this 52f8410e62SSaravana Kannan * interrupt controller to initialize. So, defer probe of this 53f8410e62SSaravana Kannan * interrupt controller. The actual initialization callback of this 54f8410e62SSaravana Kannan * interrupt controller can check for specific domains as necessary. 55f8410e62SSaravana Kannan */ 566caa5a2bSMiaoqian Lin if (par_np && !irq_find_matching_host(par_np, DOMAIN_BUS_ANY)) { 57f8410e62SSaravana Kannan return -EPROBE_DEFER; 586caa5a2bSMiaoqian Lin } 59f8410e62SSaravana Kannan 60f8410e62SSaravana Kannan return irq_init_cb(np, par_np); 61f8410e62SSaravana Kannan } 62f8410e62SSaravana Kannan EXPORT_SYMBOL_GPL(platform_irqchip_probe); 63