diff options
author | Sonic Zhang <sonic.zhang@analog.com> | 2009-12-28 07:29:57 +0000 |
---|---|---|
committer | Mike Frysinger <vapier@gentoo.org> | 2010-03-09 00:30:47 -0500 |
commit | 0325f25a919ed09d11b16ec8eccf95618dc36601 (patch) | |
tree | 4b2fba1389d1257088bbb598354b3cbc66f0178f /arch | |
parent | 69e1d8a61d5aa9e03676dc21fdfb750c5a97bb34 (diff) | |
download | op-kernel-dev-0325f25a919ed09d11b16ec8eccf95618dc36601.zip op-kernel-dev-0325f25a919ed09d11b16ec8eccf95618dc36601.tar.gz |
Blackfin: SMP: add support for IRQ affinity
Now that the Blackfin IRQ controller supports this, drivers get the normal
functionality of controlling which CPU to bind IRQs to.
Signed-off-by: Sonic Zhang <sonic.zhang@analog.com>
Signed-off-by: Mike Frysinger <vapier@gentoo.org>
Diffstat (limited to 'arch')
-rw-r--r-- | arch/blackfin/mach-common/ints-priority.c | 38 |
1 files changed, 34 insertions, 4 deletions
diff --git a/arch/blackfin/mach-common/ints-priority.c b/arch/blackfin/mach-common/ints-priority.c index 5202a60..a5d2434 100644 --- a/arch/blackfin/mach-common/ints-priority.c +++ b/arch/blackfin/mach-common/ints-priority.c @@ -173,7 +173,12 @@ static void bfin_internal_mask_irq(unsigned int irq) local_irq_restore_hw(flags); } +#ifdef CONFIG_SMP +static void bfin_internal_unmask_irq_affinity(unsigned int irq, + const struct cpumask *affinity) +#else static void bfin_internal_unmask_irq(unsigned int irq) +#endif { unsigned long flags; @@ -186,16 +191,38 @@ static void bfin_internal_unmask_irq(unsigned int irq) local_irq_save_hw(flags); mask_bank = SIC_SYSIRQ(irq) / 32; mask_bit = SIC_SYSIRQ(irq) % 32; - bfin_write_SIC_IMASK(mask_bank, bfin_read_SIC_IMASK(mask_bank) | - (1 << mask_bit)); #ifdef CONFIG_SMP - bfin_write_SICB_IMASK(mask_bank, bfin_read_SICB_IMASK(mask_bank) | - (1 << mask_bit)); + if (cpumask_test_cpu(0, affinity)) +#endif + bfin_write_SIC_IMASK(mask_bank, + bfin_read_SIC_IMASK(mask_bank) | + (1 << mask_bit)); +#ifdef CONFIG_SMP + if (cpumask_test_cpu(1, affinity)) + bfin_write_SICB_IMASK(mask_bank, + bfin_read_SICB_IMASK(mask_bank) | + (1 << mask_bit)); #endif #endif local_irq_restore_hw(flags); } +#ifdef CONFIG_SMP +static void bfin_internal_unmask_irq(unsigned int irq) +{ + struct irq_desc *desc = irq_to_desc(irq); + bfin_internal_unmask_irq_affinity(irq, desc->affinity); +} + +static int bfin_internal_set_affinity(unsigned int irq, const struct cpumask *mask) +{ + bfin_internal_mask_irq(irq); + bfin_internal_unmask_irq_affinity(irq, mask); + + return 0; +} +#endif + #ifdef CONFIG_PM int bfin_internal_set_wake(unsigned int irq, unsigned int state) { @@ -271,6 +298,9 @@ static struct irq_chip bfin_internal_irqchip = { .mask_ack = bfin_internal_mask_irq, .disable = bfin_internal_mask_irq, .enable = bfin_internal_unmask_irq, +#ifdef CONFIG_SMP + .set_affinity = bfin_internal_set_affinity, +#endif #ifdef CONFIG_PM .set_wake = bfin_internal_set_wake, #endif |