aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/irqchip
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/irqchip')
-rw-r--r--drivers/irqchip/irq-crossbar.c20
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
87static inline bool needs_crossbar_write(irq_hw_number_t hw) 87static 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;