Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux

MIPS: BCM63xx: Allow setting affinity for IPIC

Wire up the set_affinity call for the internal PIC if booting on
a cpu supporting it.
Affinity is kept to boot cpu as default.

Signed-off-by: Jonas Gorski <jogo@openwrt.org>
Cc: linux-mips@linux-mips.org
Cc: John Crispin <blogic@openwrt.org>
Cc: Maxime Bizon <mbizon@freebox.fr>
Cc: Florian Fainelli <florian@openwrt.org>
Cc: Kevin Cernekee <cernekee@gmail.com>
Cc: Gregory Fong <gregory.0xf0@gmail.com>
Patchwork: https://patchwork.linux-mips.org/patch/7323/
Signed-off-by: Ralf Baechle <ralf@linux-mips.org>

authored by

Jonas Gorski and committed by
Ralf Baechle
b37f0f69 553e25b3

+40 -6
+40 -6
arch/mips/bcm63xx/irq.c
··· 32 32 static unsigned int ext_irq_start, ext_irq_end; 33 33 static unsigned int ext_irq_cfg_reg1, ext_irq_cfg_reg2; 34 34 static void (*internal_irq_mask)(struct irq_data *d); 35 - static void (*internal_irq_unmask)(struct irq_data *d); 35 + static void (*internal_irq_unmask)(struct irq_data *d, const struct cpumask *m); 36 36 37 37 38 38 static inline u32 get_ext_irq_perf_reg(int irq) ··· 49 49 do_IRQ(intbit - ext_irq_start + IRQ_EXTERNAL_BASE); 50 50 else 51 51 do_IRQ(intbit + IRQ_INTERNAL_BASE); 52 + } 53 + 54 + static inline int enable_irq_for_cpu(int cpu, struct irq_data *d, 55 + const struct cpumask *m) 56 + { 57 + bool enable = cpu_online(cpu); 58 + 59 + #ifdef CONFIG_SMP 60 + if (m) 61 + enable &= cpu_isset(cpu, *m); 62 + else if (irqd_affinity_was_set(d)) 63 + enable &= cpu_isset(cpu, *d->affinity); 64 + #endif 65 + return enable; 52 66 } 53 67 54 68 /* ··· 131 117 spin_unlock_irqrestore(&ipic_lock, flags); \ 132 118 } \ 133 119 \ 134 - static void __internal_irq_unmask_##width(struct irq_data *d) \ 120 + static void __internal_irq_unmask_##width(struct irq_data *d, \ 121 + const struct cpumask *m) \ 135 122 { \ 136 123 u32 val; \ 137 124 unsigned irq = d->irq - IRQ_INTERNAL_BASE; \ ··· 147 132 break; \ 148 133 \ 149 134 val = bcm_readl(irq_mask_addr[cpu] + reg * sizeof(u32));\ 150 - if (cpu_online(cpu)) \ 135 + if (enable_irq_for_cpu(cpu, d, m)) \ 151 136 val |= (1 << bit); \ 152 137 else \ 153 138 val &= ~(1 << bit); \ ··· 204 189 205 190 static void bcm63xx_internal_irq_unmask(struct irq_data *d) 206 191 { 207 - internal_irq_unmask(d); 192 + internal_irq_unmask(d, NULL); 208 193 } 209 194 210 195 /* ··· 252 237 spin_unlock_irqrestore(&epic_lock, flags); 253 238 254 239 if (is_ext_irq_cascaded) 255 - internal_irq_unmask(irq_get_irq_data(irq + ext_irq_start)); 240 + internal_irq_unmask(irq_get_irq_data(irq + ext_irq_start), 241 + NULL); 256 242 } 257 243 258 244 static void bcm63xx_external_irq_clear(struct irq_data *d) ··· 371 355 372 356 return IRQ_SET_MASK_OK_NOCOPY; 373 357 } 358 + 359 + #ifdef CONFIG_SMP 360 + static int bcm63xx_internal_set_affinity(struct irq_data *data, 361 + const struct cpumask *dest, 362 + bool force) 363 + { 364 + if (!irqd_irq_disabled(data)) 365 + internal_irq_unmask(data, dest); 366 + 367 + return 0; 368 + } 369 + #endif 374 370 375 371 static struct irq_chip bcm63xx_internal_irq_chip = { 376 372 .name = "bcm63xx_ipic", ··· 551 523 552 524 setup_irq(MIPS_CPU_IRQ_BASE + 2, &cpu_ip2_cascade_action); 553 525 #ifdef CONFIG_SMP 554 - if (is_ext_irq_cascaded) 526 + if (is_ext_irq_cascaded) { 555 527 setup_irq(MIPS_CPU_IRQ_BASE + 3, &cpu_ip3_cascade_action); 528 + bcm63xx_internal_irq_chip.irq_set_affinity = 529 + bcm63xx_internal_set_affinity; 530 + 531 + cpumask_clear(irq_default_affinity); 532 + cpumask_set_cpu(smp_processor_id(), irq_default_affinity); 533 + } 556 534 #endif 557 535 }