History

Merge branch 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip

Pull irq fixes from Thomas Gleixner: "This udpate delivers: - A fix for dynamic interrupt allocation on x86 which is required to exclude the GSI interrupts from the dynamic allocatable range. This was detected with the newfangled tablet SoCs which have GPIOs and therefor allocate a range of interrupts. The MSI allocations already excluded the GSI range, so we never noticed before. - The last missing set_irq_affinity() repair, which was delayed due to testing issues - A few bug fixes for the armada SoC interrupt controller - A memory allocation fix for the TI crossbar interrupt controller - A trivial kernel-doc warning fix" * 'irq-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: irqchip: irq-crossbar: Not allocating enough memory irqchip: armanda: Sanitize set_irq_affinity() genirq: x86: Ensure that dynamic irq allocation does not conflict linux/interrupt.h: fix new kernel-doc warnings irqchip: armada-370-xp: Fix releasing of MSIs irqchip: armada-370-xp: implement the ->check_device() msi_chip operation irqchip: armada-370-xp: fix invalid cast of signed value into unsigned variable

Linus Torvalds committed 12 years ago

Commit 0384dca2 parents 98facf0 0a1f83a7 files · +42 −37Browse files

Unified · Split

7 files
  1. arch/x86/kernel/apic/io_apic.c +5 −0
  2. drivers/irqchip/irq-armada-370-xp.c +20 −34
  3. drivers/irqchip/irq-crossbar.c +1 −1
  4. include/linux/interrupt.h +2 −2
  5. include/linux/irq.h +2 −0
  6. kernel/irq/irqdesc.c +7 −0
  7. kernel/softirq.c +5 −0
arch/x86/kernel/apic/io_apic.c+5−0
@@ -3425,6 +3425,11 @@ int get_nr_irqs_gsi(void) · 3424 unmodified lines
3425 return nr_irqs_gsi;3425 return nr_irqs_gsi;
3426}3426}
3427 3427
3428unsigned int arch_dynirq_lower_bound(unsigned int from)
3429{
3430 return from < nr_irqs_gsi ? nr_irqs_gsi : from;
3431}
3432
3428int __init arch_probe_nr_irqs(void)3433int __init arch_probe_nr_irqs(void)
3429{3434{
3430 int nr;3435 int nr;
drivers/irqchip/irq-armada-370-xp.c+20−34
@@ -41,6 +41,7 @@ · 40 unmodified lines
41#define ARMADA_370_XP_INT_SET_ENABLE_OFFS (0x30)41#define ARMADA_370_XP_INT_SET_ENABLE_OFFS (0x30)
42#define ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS (0x34)42#define ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS (0x34)
43#define ARMADA_370_XP_INT_SOURCE_CTL(irq) (0x100 + irq*4)43#define ARMADA_370_XP_INT_SOURCE_CTL(irq) (0x100 + irq*4)
44#define ARMADA_370_XP_INT_SOURCE_CPU_MASK 0xF
44 45
45#define ARMADA_370_XP_CPU_INTACK_OFFS (0x44)46#define ARMADA_370_XP_CPU_INTACK_OFFS (0x44)
46#define ARMADA_375_PPI_CAUSE (0x10)47#define ARMADA_375_PPI_CAUSE (0x10)
@@ -132,8 +133,7 @@ static int armada_370_xp_setup_msi_irq(struct msi_chip *chip, · 85 unmodified lines
132 struct msi_desc *desc)133 struct msi_desc *desc)
133{134{
134 struct msi_msg msg;135 struct msi_msg msg;
135 irq_hw_number_t hwirq;136 int virq, hwirq;
136 int virq;
137 137
138 hwirq = armada_370_xp_alloc_msi();138 hwirq = armada_370_xp_alloc_msi();
139 if (hwirq < 0)139 if (hwirq < 0)
@@ -159,8 +159,19 @@ static void armada_370_xp_teardown_msi_irq(struct msi_chip *chip, · 19 unmodified lines
159 unsigned int irq)159 unsigned int irq)
160{160{
161 struct irq_data *d = irq_get_irq_data(irq);161 struct irq_data *d = irq_get_irq_data(irq);
162 unsigned long hwirq = d->hwirq;
163
162 irq_dispose_mapping(irq);164 irq_dispose_mapping(irq);
163 armada_370_xp_free_msi(d->hwirq);165 armada_370_xp_free_msi(hwirq);
166}
167
168static int armada_370_xp_check_msi_device(struct msi_chip *chip, struct pci_dev *dev,
169 int nvec, int type)
170{
171 /* We support MSI, but not MSI-X */
172 if (type == PCI_CAP_ID_MSI)
173 return 0;
174 return -EINVAL;
164}175}
165 176
166static struct irq_chip armada_370_xp_msi_irq_chip = {177static struct irq_chip armada_370_xp_msi_irq_chip = {
@@ -201,6 +212,7 @@ static int armada_370_xp_msi_init(struct device_node *node, · 34 unmodified lines
201 212
202 msi_chip->setup_irq = armada_370_xp_setup_msi_irq;213 msi_chip->setup_irq = armada_370_xp_setup_msi_irq;
203 msi_chip->teardown_irq = armada_370_xp_teardown_msi_irq;214 msi_chip->teardown_irq = armada_370_xp_teardown_msi_irq;
215 msi_chip->check_device = armada_370_xp_check_msi_device;
204 msi_chip->of_node = node;216 msi_chip->of_node = node;
205 217
206 armada_370_xp_msi_domain =218 armada_370_xp_msi_domain =
@@ -244,35 +256,18 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock); · 37 unmodified lines
244static int armada_xp_set_affinity(struct irq_data *d,256static int armada_xp_set_affinity(struct irq_data *d,
245 const struct cpumask *mask_val, bool force)257 const struct cpumask *mask_val, bool force)
246{258{
247 unsigned long reg;
248 unsigned long new_mask = 0;
249 unsigned long online_mask = 0;
250 unsigned long count = 0;
251 irq_hw_number_t hwirq = irqd_to_hwirq(d);259 irq_hw_number_t hwirq = irqd_to_hwirq(d);
260 unsigned long reg, mask;
252 int cpu;261 int cpu;
253 262
254 for_each_cpu(cpu, mask_val) {263 /* Select a single core from the affinity mask which is online */
255 new_mask |= 1 << cpu_logical_map(cpu);264 cpu = cpumask_any_and(mask_val, cpu_online_mask);
256 count++;265 mask = 1UL << cpu_logical_map(cpu);
257 }
258
259 /*
260 * Forbid mutlicore interrupt affinity
261 * This is required since the MPIC HW doesn't limit
262 * several CPUs from acknowledging the same interrupt.
263 */
264 if (count > 1)
265 return -EINVAL;
266
267 for_each_cpu(cpu, cpu_online_mask)
268 online_mask |= 1 << cpu_logical_map(cpu);
269 266
270 raw_spin_lock(&irq_controller_lock);267 raw_spin_lock(&irq_controller_lock);
271
272 reg = readl(main_int_base + ARMADA_370_XP_INT_SOURCE_CTL(hwirq));268 reg = readl(main_int_base + ARMADA_370_XP_INT_SOURCE_CTL(hwirq));
273 reg = (reg & (~online_mask)) | new_mask;269 reg = (reg & (~ARMADA_370_XP_INT_SOURCE_CPU_MASK)) | mask;
274 writel(reg, main_int_base + ARMADA_370_XP_INT_SOURCE_CTL(hwirq));270 writel(reg, main_int_base + ARMADA_370_XP_INT_SOURCE_CTL(hwirq));
275
276 raw_spin_unlock(&irq_controller_lock);271 raw_spin_unlock(&irq_controller_lock);
277 272
278 return 0;273 return 0;
@@ -494,15 +489,6 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, · 215 unmodified lines
494 489
495#ifdef CONFIG_SMP490#ifdef CONFIG_SMP
496 armada_xp_mpic_smp_cpu_init();491 armada_xp_mpic_smp_cpu_init();
497
498 /*
499 * Set the default affinity from all CPUs to the boot cpu.
500 * This is required since the MPIC doesn't limit several CPUs
501 * from acknowledging the same interrupt.
502 */
503 cpumask_clear(irq_default_affinity);
504 cpumask_set_cpu(smp_processor_id(), irq_default_affinity);
505
506#endif492#endif
507 493
508 armada_370_xp_msi_init(node, main_int_res.start);494 armada_370_xp_msi_init(node, main_int_res.start);
drivers/irqchip/irq-crossbar.c+1−1
@@ -107,7 +107,7 @@ static int __init crossbar_of_init(struct device_node *node) · 106 unmodified lines
107 int i, size, max, reserved = 0, entry;107 int i, size, max, reserved = 0, entry;
108 const __be32 *irqsr;108 const __be32 *irqsr;
109 109
110 cb = kzalloc(sizeof(struct cb_device *), GFP_KERNEL);110 cb = kzalloc(sizeof(*cb), GFP_KERNEL);
111 111
112 if (!cb)112 if (!cb)
113 return -ENOMEM;113 return -ENOMEM;
include/linux/interrupt.h+2−2
@@ -210,7 +210,7 @@ extern int __irq_set_affinity(unsigned int irq, const struct cpumask *cpumask, · 209 unmodified lines
210/**210/**
211 * irq_set_affinity - Set the irq affinity of a given irq211 * irq_set_affinity - Set the irq affinity of a given irq
212 * @irq: Interrupt to set affinity212 * @irq: Interrupt to set affinity
213 * @mask: cpumask213 * @cpumask: cpumask
214 *214 *
215 * Fails if cpumask does not contain an online CPU215 * Fails if cpumask does not contain an online CPU
216 */216 */
@@ -223,7 +223,7 @@ irq_set_affinity(unsigned int irq, const struct cpumask *cpumask) · 6 unmodified lines
223/**223/**
224 * irq_force_affinity - Force the irq affinity of a given irq224 * irq_force_affinity - Force the irq affinity of a given irq
225 * @irq: Interrupt to set affinity225 * @irq: Interrupt to set affinity
226 * @mask: cpumask226 * @cpumask: cpumask
227 *227 *
228 * Same as irq_set_affinity, but without checking the mask against228 * Same as irq_set_affinity, but without checking the mask against
229 * online cpus.229 * online cpus.
include/linux/irq.h+2−0
@@ -603,6 +603,8 @@ static inline u32 irq_get_trigger_type(unsigned int irq) · 602 unmodified lines
603 return d ? irqd_get_trigger_type(d) : 0;603 return d ? irqd_get_trigger_type(d) : 0;
604}604}
605 605
606unsigned int arch_dynirq_lower_bound(unsigned int from);
607
606int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,608int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
607 struct module *owner);609 struct module *owner);
608 610
kernel/irq/irqdesc.c+7−0
@@ -363,6 +363,13 @@ __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node, · 362 unmodified lines
363 if (from > irq)363 if (from > irq)
364 return -EINVAL;364 return -EINVAL;
365 from = irq;365 from = irq;
366 } else {
367 /*
368 * For interrupts which are freely allocated the
369 * architecture can force a lower bound to the @from
370 * argument. x86 uses this to exclude the GSI space.
371 */
372 from = arch_dynirq_lower_bound(from);
366 }373 }
367 374
368 mutex_lock(&sparse_irq_lock);375 mutex_lock(&sparse_irq_lock);
kernel/softirq.c+5−0
@@ -779,3 +779,8 @@ int __init __weak arch_early_irq_init(void) · 778 unmodified lines
779{779{
780 return 0;780 return 0;
781}781}
782
783unsigned int __weak arch_dynirq_lower_bound(unsigned int from)
784{
785 return from;
786}

Keyboard shortcuts

General

Show keyboard shortcuts
?
Focus the current search
/

Issues and pull requests

Open filters
f

Issues, pull requests and Inbox

Select next item
j↓
Select previous item
k↑
Open selected item
Enter
Dismiss filters or clear selection
Esc

Repository code

Go to file
t