History

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

Pull x86 fixes from Peter Anvin: "One patch to avoid assigning interrupts we don't actually have on non-PC platforms, and two patches that addresses bugs in the new IOAPIC assignment code" * 'x86-urgent-for-linus' of git://git.kernel.org/pub/scm/linux/kernel/git/tip/tip: x86, irq, PCI: Keep IRQ assignment for runtime power management x86: irq: Fix bug in setting IOAPIC pin attributes x86: Fix non-PC platform kernel crash on boot due to NULL dereference

Linus Torvalds committed 12 years ago

Commit fd5984d2 parents ad6ede8 9eabc997 files · +37 −4Browse files

Unified · Split

7 files
  1. arch/x86/include/asm/io_apic.h +2 −0
  2. arch/x86/kernel/apic/io_apic.c +26 −1
  3. arch/x86/kernel/irqinit.c +1 −1
  4. arch/x86/kernel/time.c +2 −0
  5. arch/x86/pci/intel_mid_pci.c +1 −1
  6. arch/x86/pci/irq.c +1 −1
  7. drivers/acpi/pci_irq.c +4 −0
arch/x86/include/asm/io_apic.h+2−0
@@ -227,6 +227,8 @@ static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned · 226 unmodified lines
227227
228228 extern void io_apic_eoi(unsigned int apic, unsigned int vector);
229229
230+extern bool mp_should_keep_irq(struct device *dev);
231+
230232 #else /* !CONFIG_X86_IO_APIC */
231233
232234 #define io_apic_assign_pci_irqs 0
arch/x86/kernel/apic/io_apic.c+26−1
@@ -1070,6 +1070,11 @@ static int mp_map_pin_to_irq(u32 gsi, int idx, int ioapic, int pin, · 1069 unmodified lines
10701070 }
10711071
10721072 if (flags & IOAPIC_MAP_ALLOC) {
1073+ /* special handling for legacy IRQs */
1074+ if (irq < nr_legacy_irqs() && info->count == 1 &&
1075+ mp_irqdomain_map(domain, irq, pin) != 0)
1076+ irq = -1;
1077+
10731078 if (irq > 0)
10741079 info->count++;
10751080 else if (info->count == 0)
@@ -3896,7 +3901,15 @@ int mp_irqdomain_map(struct irq_domain *domain, unsigned int virq, · 2820 unmodified lines
38963901 info->polarity = 1;
38973902 }
38983903 info->node = NUMA_NO_NODE;
3899− info->set = 1;
3904+
3905+ /*
3906+ * setup_IO_APIC_irqs() programs all legacy IRQs with default
3907+ * trigger and polarity attributes. Don't set the flag for that
3908+ * case so the first legacy IRQ user could reprogram the pin
3909+ * with real trigger and polarity attributes.
3910+ */
3911+ if (virq >= nr_legacy_irqs() || info->count)
3912+ info->set = 1;
39003913 }
39013914 set_io_apic_irq_attr(&attr, ioapic, hwirq, info->trigger,
39023915 info->polarity);
@@ -3946,6 +3959,18 @@ int mp_set_gsi_attr(u32 gsi, int trigger, int polarity, int node) · 43 unmodified lines
39463959 return ret;
39473960 }
39483961
3962+bool mp_should_keep_irq(struct device *dev)
3963+{
3964+ if (dev->power.is_prepared)
3965+ return true;
3966+#ifdef CONFIG_PM_RUNTIME
3967+ if (dev->power.runtime_status == RPM_SUSPENDING)
3968+ return true;
3969+#endif
3970+
3971+ return false;
3972+}
3973+
39493974 /* Enable IOAPIC early just for system timer */
39503975 void __init pre_init_apic_IRQ0(void)
39513976 {
arch/x86/kernel/irqinit.c+1−1
@@ -203,7 +203,7 @@ void __init native_init_IRQ(void) · 202 unmodified lines
203203 set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]);
204204 }
205205
206− if (!acpi_ioapic && !of_ioapic)
206+ if (!acpi_ioapic && !of_ioapic && nr_legacy_irqs())
207207 setup_irq(2, &irq2);
208208
209209 #ifdef CONFIG_X86_32
arch/x86/kernel/time.c+2−0
@@ -68,6 +68,8 @@ static struct irqaction irq0 = { · 67 unmodified lines
6868
6969 void __init setup_default_timer_irq(void)
7070 {
71+ if (!nr_legacy_irqs())
72+ return;
7173 setup_irq(0, &irq0);
7274 }
7375
arch/x86/pci/intel_mid_pci.c+1−1
@@ -229,7 +229,7 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev) · 228 unmodified lines
229229
230230 static void intel_mid_pci_irq_disable(struct pci_dev *dev)
231231 {
232− if (!dev->dev.power.is_prepared && dev->irq > 0)
232+ if (!mp_should_keep_irq(&dev->dev) && dev->irq > 0)
233233 mp_unmap_irq(dev->irq);
234234 }
235235
arch/x86/pci/irq.c+1−1
@@ -1256,7 +1256,7 @@ static int pirq_enable_irq(struct pci_dev *dev) · 1255 unmodified lines
12561256
12571257 static void pirq_disable_irq(struct pci_dev *dev)
12581258 {
1259− if (io_apic_assign_pci_irqs && !dev->dev.power.is_prepared &&
1259+ if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) &&
12601260 dev->irq) {
12611261 mp_unmap_irq(dev->irq);
12621262 dev->irq = 0;
drivers/acpi/pci_irq.c+4−0
@@ -484,6 +484,10 @@ void acpi_pci_irq_disable(struct pci_dev *dev) · 483 unmodified lines
484484 /* Keep IOAPIC pin configuration when suspending */
485485 if (dev->dev.power.is_prepared)
486486 return;
487+#ifdef CONFIG_PM_RUNTIME
488+ if (dev->dev.power.runtime_status == RPM_SUSPENDING)
489+ return;
490+#endif
487491
488492 entry = acpi_pci_irq_lookup(dev, pin);
489493 if (!entry)

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