ARC linux uses 2 distribution modes for common interrupts: round robin mode (IDU_M_DISTRI_RR) and a simple destination mode (IDU_M_DISTRI_DEST). The first one is used when more than 1 cores may handle a common interrupt and the second one is used when only 1 core may handle a common interrupt. However idu_irq_set_affinity() always sets IDU_M_DISTRI_RR for all affinity values. But there is no sense in setting of such mode if only 1 core must handle a common interrupt.
Unified · Split
| @@ -181,6 +181,8 @@ idu_irq_set_affinity(struct irq_data *data, const struct cpumask *cpumask, · 180 unmodified lines | |||
| 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, · 1 unmodified line | |||
| 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 | ||