diff options
Diffstat (limited to 'drivers/irqchip')
-rw-r--r-- | drivers/irqchip/irq-crossbar.c | 20 |
1 files changed, 18 insertions, 2 deletions
diff --git a/drivers/irqchip/irq-crossbar.c b/drivers/irqchip/irq-crossbar.c index 83f803bfab76..85c2985d8bcb 100644 --- a/drivers/irqchip/irq-crossbar.c +++ b/drivers/irqchip/irq-crossbar.c | |||
@@ -86,8 +86,13 @@ static inline int allocate_free_irq(int cb_no) | |||
86 | 86 | ||
87 | static inline bool needs_crossbar_write(irq_hw_number_t hw) | 87 | static inline bool needs_crossbar_write(irq_hw_number_t hw) |
88 | { | 88 | { |
89 | if (hw > GIC_IRQ_START) | 89 | int cb_no; |
90 | return true; | 90 | |
91 | if (hw > GIC_IRQ_START) { | ||
92 | cb_no = cb->irq_map[hw - GIC_IRQ_START]; | ||
93 | if (cb_no != IRQ_RESERVED && cb_no != IRQ_SKIP) | ||
94 | return true; | ||
95 | } | ||
91 | 96 | ||
92 | return false; | 97 | return false; |
93 | } | 98 | } |
@@ -130,8 +135,19 @@ static int crossbar_domain_xlate(struct irq_domain *d, | |||
130 | { | 135 | { |
131 | int ret; | 136 | int ret; |
132 | int req_num = intspec[1]; | 137 | int req_num = intspec[1]; |
138 | int direct_map_num; | ||
133 | 139 | ||
134 | if (req_num >= cb->max_crossbar_sources) { | 140 | if (req_num >= cb->max_crossbar_sources) { |
141 | direct_map_num = req_num - cb->max_crossbar_sources; | ||
142 | if (direct_map_num < cb->int_max) { | ||
143 | ret = cb->irq_map[direct_map_num]; | ||
144 | if (ret == IRQ_RESERVED || ret == IRQ_SKIP) { | ||
145 | /* We use the interrupt num as h/w irq num */ | ||
146 | ret = direct_map_num; | ||
147 | goto found; | ||
148 | } | ||
149 | } | ||
150 | |||
135 | pr_err("%s: requested crossbar number %d > max %d\n", | 151 | pr_err("%s: requested crossbar number %d > max %d\n", |
136 | __func__, req_num, cb->max_crossbar_sources); | 152 | __func__, req_num, cb->max_crossbar_sources); |
137 | return -EINVAL; | 153 | return -EINVAL; |