.. | .. |
---|
| 1 | +// SPDX-License-Identifier: GPL-2.0-or-later |
---|
1 | 2 | /* |
---|
2 | 3 | * Interrupt management for most GSC and related devices. |
---|
3 | 4 | * |
---|
.. | .. |
---|
6 | 7 | * (c) Copyright 1999 Matthew Wilcox |
---|
7 | 8 | * (c) Copyright 2000 Helge Deller |
---|
8 | 9 | * (c) Copyright 2001 Matthew Wilcox for Hewlett-Packard |
---|
9 | | - * |
---|
10 | | - * This program is free software; you can redistribute it and/or modify |
---|
11 | | - * it under the terms of the GNU General Public License as published by |
---|
12 | | - * the Free Software Foundation; either version 2 of the License, or |
---|
13 | | - * (at your option) any later version. |
---|
14 | 10 | */ |
---|
15 | 11 | |
---|
16 | 12 | #include <linux/bitops.h> |
---|
.. | .. |
---|
139 | 135 | */ |
---|
140 | 136 | } |
---|
141 | 137 | |
---|
| 138 | +#ifdef CONFIG_SMP |
---|
| 139 | +static int gsc_set_affinity_irq(struct irq_data *d, const struct cpumask *dest, |
---|
| 140 | + bool force) |
---|
| 141 | +{ |
---|
| 142 | + struct gsc_asic *gsc_dev = irq_data_get_irq_chip_data(d); |
---|
| 143 | + struct cpumask tmask; |
---|
| 144 | + int cpu_irq; |
---|
| 145 | + |
---|
| 146 | + if (!cpumask_and(&tmask, dest, cpu_online_mask)) |
---|
| 147 | + return -EINVAL; |
---|
| 148 | + |
---|
| 149 | + cpu_irq = cpu_check_affinity(d, &tmask); |
---|
| 150 | + if (cpu_irq < 0) |
---|
| 151 | + return cpu_irq; |
---|
| 152 | + |
---|
| 153 | + gsc_dev->gsc_irq.txn_addr = txn_affinity_addr(d->irq, cpu_irq); |
---|
| 154 | + gsc_dev->eim = ((u32) gsc_dev->gsc_irq.txn_addr) | gsc_dev->gsc_irq.txn_data; |
---|
| 155 | + |
---|
| 156 | + /* switch IRQ's for devices below LASI/WAX to other CPU */ |
---|
| 157 | + gsc_writel(gsc_dev->eim, gsc_dev->hpa + OFFSET_IAR); |
---|
| 158 | + |
---|
| 159 | + irq_data_update_effective_affinity(d, &tmask); |
---|
| 160 | + |
---|
| 161 | + return IRQ_SET_MASK_OK; |
---|
| 162 | +} |
---|
| 163 | +#endif |
---|
| 164 | + |
---|
| 165 | + |
---|
142 | 166 | static struct irq_chip gsc_asic_interrupt_type = { |
---|
143 | 167 | .name = "GSC-ASIC", |
---|
144 | 168 | .irq_unmask = gsc_asic_unmask_irq, |
---|
145 | 169 | .irq_mask = gsc_asic_mask_irq, |
---|
| 170 | +#ifdef CONFIG_SMP |
---|
| 171 | + .irq_set_affinity = gsc_set_affinity_irq, |
---|
| 172 | +#endif |
---|
146 | 173 | }; |
---|
147 | 174 | |
---|
148 | 175 | int gsc_assign_irq(struct irq_chip *type, void *data) |
---|