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
34253425 return nr_irqs_gsi;
34263426 }
34273427
3428+unsigned int arch_dynirq_lower_bound(unsigned int from)
3429+{
3430+ return from < nr_irqs_gsi ? nr_irqs_gsi : from;
3431+}
3432+
34283433 int __init arch_probe_nr_irqs(void)
34293434 {
34303435 int nr;
drivers/irqchip/irq-armada-370-xp.c+20−34
@@ -41,6 +41,7 @@ · 40 unmodified lines
4141 #define ARMADA_370_XP_INT_SET_ENABLE_OFFS (0x30)
4242 #define ARMADA_370_XP_INT_CLEAR_ENABLE_OFFS (0x34)
4343 #define ARMADA_370_XP_INT_SOURCE_CTL(irq) (0x100 + irq*4)
44+#define ARMADA_370_XP_INT_SOURCE_CPU_MASK 0xF
4445
4546 #define ARMADA_370_XP_CPU_INTACK_OFFS (0x44)
4647 #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
132133 struct msi_desc *desc)
133134 {
134135 struct msi_msg msg;
135− irq_hw_number_t hwirq;
136− int virq;
136+ int virq, hwirq;
137137
138138 hwirq = armada_370_xp_alloc_msi();
139139 if (hwirq < 0)
@@ -159,8 +159,19 @@ static void armada_370_xp_teardown_msi_irq(struct msi_chip *chip, · 19 unmodified lines
159159 unsigned int irq)
160160 {
161161 struct irq_data *d = irq_get_irq_data(irq);
162+ unsigned long hwirq = d->hwirq;
163+
162164 irq_dispose_mapping(irq);
163− armada_370_xp_free_msi(d->hwirq);
165+ armada_370_xp_free_msi(hwirq);
166+}
167+
168+static 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;
164175 }
165176
166177 static 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
201212
202213 msi_chip->setup_irq = armada_370_xp_setup_msi_irq;
203214 msi_chip->teardown_irq = armada_370_xp_teardown_msi_irq;
215+ msi_chip->check_device = armada_370_xp_check_msi_device;
204216 msi_chip->of_node = node;
205217
206218 armada_370_xp_msi_domain =
@@ -244,35 +256,18 @@ static DEFINE_RAW_SPINLOCK(irq_controller_lock); · 37 unmodified lines
244256 static int armada_xp_set_affinity(struct irq_data *d,
245257 const struct cpumask *mask_val, bool force)
246258 {
247− unsigned long reg;
248− unsigned long new_mask = 0;
249− unsigned long online_mask = 0;
250− unsigned long count = 0;
251259 irq_hw_number_t hwirq = irqd_to_hwirq(d);
260+ unsigned long reg, mask;
252261 int cpu;
253262
254− for_each_cpu(cpu, mask_val) {
255− new_mask |= 1 << cpu_logical_map(cpu);
256− count++;
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);
263+ /* Select a single core from the affinity mask which is online */
264+ cpu = cpumask_any_and(mask_val, cpu_online_mask);
265+ mask = 1UL << cpu_logical_map(cpu);
269266
270267 raw_spin_lock(&irq_controller_lock);
271−
272268 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;
274270 writel(reg, main_int_base + ARMADA_370_XP_INT_SOURCE_CTL(hwirq));
275−
276271 raw_spin_unlock(&irq_controller_lock);
277272
278273 return 0;
@@ -494,15 +489,6 @@ static int __init armada_370_xp_mpic_of_init(struct device_node *node, · 215 unmodified lines
494489
495490 #ifdef CONFIG_SMP
496491 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−
506492 #endif
507493
508494 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
107107 int i, size, max, reserved = 0, entry;
108108 const __be32 *irqsr;
109109
110− cb = kzalloc(sizeof(struct cb_device *), GFP_KERNEL);
110+ cb = kzalloc(sizeof(*cb), GFP_KERNEL);
111111
112112 if (!cb)
113113 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
210210 /**
211211 * irq_set_affinity - Set the irq affinity of a given irq
212212 * @irq: Interrupt to set affinity
213− * @mask: cpumask
213+ * @cpumask: cpumask
214214 *
215215 * Fails if cpumask does not contain an online CPU
216216 */
@@ -223,7 +223,7 @@ irq_set_affinity(unsigned int irq, const struct cpumask *cpumask) · 6 unmodified lines
223223 /**
224224 * irq_force_affinity - Force the irq affinity of a given irq
225225 * @irq: Interrupt to set affinity
226− * @mask: cpumask
226+ * @cpumask: cpumask
227227 *
228228 * Same as irq_set_affinity, but without checking the mask against
229229 * 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
603603 return d ? irqd_get_trigger_type(d) : 0;
604604 }
605605
606+unsigned int arch_dynirq_lower_bound(unsigned int from);
607+
606608 int __irq_alloc_descs(int irq, unsigned int from, unsigned int cnt, int node,
607609 struct module *owner);
608610
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
363363 if (from > irq)
364364 return -EINVAL;
365365 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);
366373 }
367374
368375 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
779779 {
780780 return 0;
781781 }
782+
783+unsigned 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