aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/irqchip
diff options
context:
space:
mode:
authorNishanth Menon <nm@ti.com>2014-06-26 03:10:20 -0400
committerJason Cooper <jason@lakedaemon.net>2014-06-30 15:11:17 -0400
commit6f16fc878a51572a998655e5ef1c396cb269648d (patch)
treee97ef38d5c8a50c26dc9eefb8648700f81cf27b4 /drivers/irqchip
parent1d50d2ce6337724d30055bdbe082236cc86e6785 (diff)
irqchip: crossbar: Check for premapped crossbar before allocating
If irq_of_parse_and_map is executed twice, the same crossbar is mapped to two different GIC interrupts. This is completely undesirable. Instead, check if the requested crossbar event is pre-allocated and provide that GIC mapping back to caller if already allocated. Signed-off-by: Nishanth Menon <nm@ti.com> Signed-off-by: Sricharan R <r.sricharan@ti.com> Acked-by: Santosh Shilimkar <santosh.shilimkar@ti.com> Link: https://lkml.kernel.org/r/1403766634-18543-3-git-send-email-r.sricharan@ti.com Signed-off-by: Jason Cooper <jason@lakedaemon.net>
Diffstat (limited to 'drivers/irqchip')
-rw-r--r--drivers/irqchip/irq-crossbar.c16
1 files changed, 16 insertions, 0 deletions
diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c
index 20105bcdf408..51d4b878e5d6 100644
--- a/drivers/irqchip/irq-crossbar.c
+++ b/drivers/irqchip/irq-crossbar.c
@@ -51,6 +51,17 @@ static inline void crossbar_writeb(int irq_no, int cb_no)
51 writeb(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]); 51 writeb(cb_no, cb->crossbar_base + cb->register_offsets[irq_no]);
52} 52}
53 53
54static inline int get_prev_map_irq(int cb_no)
55{
56 int i;
57
58 for (i = 0; i < cb->int_max; i++)
59 if (cb->irq_map[i] == cb_no)
60 return i;
61
62 return -ENODEV;
63}
64
54static inline int allocate_free_irq(int cb_no) 65static inline int allocate_free_irq(int cb_no)
55{ 66{
56 int i; 67 int i;
@@ -88,11 +99,16 @@ static int crossbar_domain_xlate(struct irq_domain *d,
88{ 99{
89 unsigned long ret; 100 unsigned long ret;
90 101
102 ret = get_prev_map_irq(intspec[1]);
103 if (!IS_ERR_VALUE(ret))
104 goto found;
105
91 ret = allocate_free_irq(intspec[1]); 106 ret = allocate_free_irq(intspec[1]);
92 107
93 if (IS_ERR_VALUE(ret)) 108 if (IS_ERR_VALUE(ret))
94 return ret; 109 return ret;
95 110
111found:
96 *out_hwirq = ret + GIC_IRQ_START; 112 *out_hwirq = ret + GIC_IRQ_START;
97 return 0; 113 return 0;
98} 114}