aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/irqchip
diff options
context:
space:
mode:
authorBoris BREZILLON <boris.brezillon@free-electrons.com>2014-07-10 14:25:39 -0400
committerJason Cooper <jason@lakedaemon.net>2014-07-17 09:38:51 -0400
commitb2f579b58e93ded5916fb69a28cfc86e0ab951a6 (patch)
treec5d6a7d037994d2f0d416e3bc3d7689bc87d8ef4 /drivers/irqchip
parentb1479ebb772003461f0458a0b3a68cb1c4036288 (diff)
irqchip: atmel-aic: Add irq fixup infrastructure
Add irq fixup infrastructure to handle IP blocks connected to shared irqs that are left in an unknown state when booting the kernel. In this case the IP block which has not masked its interrupt and has no driver loaded (either because it is not compiled or because it is not loaded yet) might generate spurious interrupts when another IP block request the shared irq. A good example of this case is the RTC block on which register configs are kept even after a shutdown (if a proper VDDcore is supplied), and thus might generate spurious interrupts when the platform is switched on. Signed-off-by: Boris BREZILLON <boris.brezillon@free-electrons.com> Link: https://lkml.kernel.org/r/1405016741-2407-2-git-send-email-boris.brezillon@free-electrons.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'drivers/irqchip')
-rw-r--r--drivers/irqchip/irq-atmel-aic-common.c19
-rw-r--r--drivers/irqchip/irq-atmel-aic-common.h2
2 files changed, 21 insertions, 0 deletions
diff --git a/drivers/irqchip/irq-atmel-aic-common.c b/drivers/irqchip/irq-atmel-aic-common.c
index 18b76fc03d53..4705bdbc6e7b 100644
--- a/drivers/irqchip/irq-atmel-aic-common.c
+++ b/drivers/irqchip/irq-atmel-aic-common.c
@@ -139,6 +139,25 @@ static void __init aic_common_ext_irq_of_init(struct irq_domain *domain)
139 } 139 }
140} 140}
141 141
142void __init aic_common_irq_fixup(const struct of_device_id *matches)
143{
144 struct device_node *root = of_find_node_by_path("/");
145 const struct of_device_id *match;
146
147 if (!root)
148 return;
149
150 match = of_match_node(matches, root);
151 of_node_put(root);
152
153 if (match) {
154 void (*fixup)(struct device_node *) = match->data;
155 fixup(root);
156 }
157
158 of_node_put(root);
159}
160
142struct irq_domain *__init aic_common_of_init(struct device_node *node, 161struct irq_domain *__init aic_common_of_init(struct device_node *node,
143 const struct irq_domain_ops *ops, 162 const struct irq_domain_ops *ops,
144 const char *name, int nirqs) 163 const char *name, int nirqs)
diff --git a/drivers/irqchip/irq-atmel-aic-common.h b/drivers/irqchip/irq-atmel-aic-common.h
index c178557ab7e8..aa0a42c36a7f 100644
--- a/drivers/irqchip/irq-atmel-aic-common.h
+++ b/drivers/irqchip/irq-atmel-aic-common.h
@@ -32,4 +32,6 @@ struct irq_domain *__init aic_common_of_init(struct device_node *node,
32 const struct irq_domain_ops *ops, 32 const struct irq_domain_ops *ops,
33 const char *name, int nirqs); 33 const char *name, int nirqs);
34 34
35void __init aic_common_irq_fixup(const struct of_device_id *matches);
36
35#endif /* __IRQ_ATMEL_AIC_COMMON_H */ 37#endif /* __IRQ_ATMEL_AIC_COMMON_H */