diff options
author | Helge Deller <deller@gmx.de> | 2022-03-27 15:46:26 +0200 |
---|---|---|
committer | Helge Deller <deller@gmx.de> | 2022-03-29 21:37:12 +0200 |
commit | 939fc856676c266c3bc347c1c1661872a3725c0f (patch) | |
tree | 8cd07730ca7845cde5300a282df06c21eb5ff625 /drivers/parisc/gsc.c | |
parent | 08a491b2e4b1c4c618ee82d3f4b0ff3b20c5acf5 (diff) | |
download | linux-939fc856676c266c3bc347c1c1661872a3725c0f.tar.gz linux-939fc856676c266c3bc347c1c1661872a3725c0f.tar.bz2 linux-939fc856676c266c3bc347c1c1661872a3725c0f.zip |
parisc: Fix CPU affinity for Lasi, WAX and Dino chips
Add the missing logic to allow Lasi, WAX and Dino to set the
CPU affinity. This fixes IRQ migration to other CPUs when a
CPU is shutdown which currently holds the IRQs for one of those
chips.
Signed-off-by: Helge Deller <deller@gmx.de>
Diffstat (limited to 'drivers/parisc/gsc.c')
-rw-r--r-- | drivers/parisc/gsc.c | 31 |
1 files changed, 31 insertions, 0 deletions
diff --git a/drivers/parisc/gsc.c b/drivers/parisc/gsc.c index ed9371acf37e..ec175ae99873 100644 --- a/drivers/parisc/gsc.c +++ b/drivers/parisc/gsc.c @@ -135,10 +135,41 @@ static void gsc_asic_unmask_irq(struct irq_data *d) */ } +#ifdef CONFIG_SMP +static int gsc_set_affinity_irq(struct irq_data *d, const struct cpumask *dest, + bool force) +{ + struct gsc_asic *gsc_dev = irq_data_get_irq_chip_data(d); + struct cpumask tmask; + int cpu_irq; + + if (!cpumask_and(&tmask, dest, cpu_online_mask)) + return -EINVAL; + + cpu_irq = cpu_check_affinity(d, &tmask); + if (cpu_irq < 0) + return cpu_irq; + + gsc_dev->gsc_irq.txn_addr = txn_affinity_addr(d->irq, cpu_irq); + gsc_dev->eim = ((u32) gsc_dev->gsc_irq.txn_addr) | gsc_dev->gsc_irq.txn_data; + + /* switch IRQ's for devices below LASI/WAX to other CPU */ + gsc_writel(gsc_dev->eim, gsc_dev->hpa + OFFSET_IAR); + + irq_data_update_effective_affinity(d, &tmask); + + return IRQ_SET_MASK_OK; +} +#endif + + static struct irq_chip gsc_asic_interrupt_type = { .name = "GSC-ASIC", .irq_unmask = gsc_asic_unmask_irq, .irq_mask = gsc_asic_mask_irq, +#ifdef CONFIG_SMP + .irq_set_affinity = gsc_set_affinity_irq, +#endif }; int gsc_assign_irq(struct irq_chip *type, void *data) |