diff options
Diffstat (limited to 'arch/arc/kernel/mcip.c')
-rw-r--r-- | arch/arc/kernel/mcip.c | 32 |
1 files changed, 20 insertions, 12 deletions
diff --git a/arch/arc/kernel/mcip.c b/arch/arc/kernel/mcip.c index c424d5abc318..f39142acc89e 100644 --- a/arch/arc/kernel/mcip.c +++ b/arch/arc/kernel/mcip.c | |||
@@ -181,6 +181,8 @@ idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask, | |||
181 | { | 181 | { |
182 | unsigned long flags; | 182 | unsigned long flags; |
183 | cpumask_t online; | 183 | cpumask_t online; |
184 | unsigned int destination_bits; | ||
185 | unsigned int distribution_mode; | ||
184 | 186 | ||
185 | /* errout if no online cpu per @cpumask */ | 187 | /* errout if no online cpu per @cpumask */ |
186 | if (!cpumask_and(&online, cpumask, cpu_online_mask)) | 188 | if (!cpumask_and(&online, cpumask, cpu_online_mask)) |
@@ -188,8 +190,15 @@ idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask, | |||
188 | 190 | ||
189 | raw_spin_lock_irqsave(&mcip_lock, flags); | 191 | raw_spin_lock_irqsave(&mcip_lock, flags); |
190 | 192 | ||
191 | idu_set_dest(data->hwirq, cpumask_bits(&online)[0]); | 193 | destination_bits = cpumask_bits(&online)[0]; |
192 | idu_set_mode(data->hwirq, IDU_M_TRIG_LEVEL, IDU_M_DISTRI_RR); | 194 | idu_set_dest(data->hwirq, destination_bits); |
195 | |||
196 | if (ffs(destination_bits) == fls(destination_bits)) | ||
197 | distribution_mode = IDU_M_DISTRI_DEST; | ||
198 | else | ||
199 | distribution_mode = IDU_M_DISTRI_RR; | ||
200 | |||
201 | idu_set_mode(data->hwirq, IDU_M_TRIG_LEVEL, distribution_mode); | ||
193 | 202 | ||
194 | raw_spin_unlock_irqrestore(&mcip_lock, flags); | 203 | raw_spin_unlock_irqrestore(&mcip_lock, flags); |
195 | 204 | ||
@@ -207,16 +216,15 @@ static struct irq_chip idu_irq_chip = { | |||
207 | 216 | ||
208 | }; | 217 | }; |
209 | 218 | ||
210 | static int idu_first_irq; | 219 | static irq_hw_number_t idu_first_hwirq; |
211 | 220 | ||
212 | static void idu_cascade_isr(struct irq_desc *desc) | 221 | static void idu_cascade_isr(struct irq_desc *desc) |
213 | { | 222 | { |
214 | struct irq_domain *domain = irq_desc_get_handler_data(desc); | 223 | struct irq_domain *idu_domain = irq_desc_get_handler_data(desc); |
215 | unsigned int core_irq = irq_desc_get_irq(desc); | 224 | irq_hw_number_t core_hwirq = irqd_to_hwirq(irq_desc_get_irq_data(desc)); |
216 | unsigned int idu_irq; | 225 | irq_hw_number_t idu_hwirq = core_hwirq - idu_first_hwirq; |
217 | 226 | ||
218 | idu_irq = core_irq - idu_first_irq; | 227 | generic_handle_irq(irq_find_mapping(idu_domain, idu_hwirq)); |
219 | generic_handle_irq(irq_find_mapping(domain, idu_irq)); | ||
220 | } | 228 | } |
221 | 229 | ||
222 | static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hwirq) | 230 | static int idu_irq_map(struct irq_domain *d, unsigned int virq, irq_hw_number_t hwirq) |
@@ -282,7 +290,7 @@ idu_of_init(struct device_node *intc, struct device_node *parent) | |||
282 | struct irq_domain *domain; | 290 | struct irq_domain *domain; |
283 | /* Read IDU BCR to confirm nr_irqs */ | 291 | /* Read IDU BCR to confirm nr_irqs */ |
284 | int nr_irqs = of_irq_count(intc); | 292 | int nr_irqs = of_irq_count(intc); |
285 | int i, irq; | 293 | int i, virq; |
286 | struct mcip_bcr mp; | 294 | struct mcip_bcr mp; |
287 | 295 | ||
288 | READ_BCR(ARC_REG_MCIP_BCR, mp); | 296 | READ_BCR(ARC_REG_MCIP_BCR, mp); |
@@ -303,11 +311,11 @@ idu_of_init(struct device_node *intc, struct device_node *parent) | |||
303 | * however we need it to get the parent virq and set IDU handler | 311 | * however we need it to get the parent virq and set IDU handler |
304 | * as first level isr | 312 | * as first level isr |
305 | */ | 313 | */ |
306 | irq = irq_of_parse_and_map(intc, i); | 314 | virq = irq_of_parse_and_map(intc, i); |
307 | if (!i) | 315 | if (!i) |
308 | idu_first_irq = irq; | 316 | idu_first_hwirq = irqd_to_hwirq(irq_get_irq_data(virq)); |
309 | 317 | ||
310 | irq_set_chained_handler_and_data(irq, idu_cascade_isr, domain); | 318 | irq_set_chained_handler_and_data(virq, idu_cascade_isr, domain); |
311 | } | 319 | } |
312 | 320 | ||
313 | __mcip_cmd(CMD_IDU_ENABLE, 0); | 321 | __mcip_cmd(CMD_IDU_ENABLE, 0); |