Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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

+37 -4
+2
arch/x86/include/asm/io_apic.h
··· 227 227 228 228 extern void io_apic_eoi(unsigned int apic, unsigned int vector); 229 229 230 + extern bool mp_should_keep_irq(struct device *dev); 231 + 230 232 #else /* !CONFIG_X86_IO_APIC */ 231 233 232 234 #define io_apic_assign_pci_irqs 0
+26 -1
arch/x86/kernel/apic/io_apic.c
··· 1070 1070 } 1071 1071 1072 1072 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 + 1073 1078 if (irq > 0) 1074 1079 info->count++; 1075 1080 else if (info->count == 0) ··· 3901 3896 info->polarity = 1; 3902 3897 } 3903 3898 info->node = NUMA_NO_NODE; 3904 - info->set = 1; 3899 + 3900 + /* 3901 + * setup_IO_APIC_irqs() programs all legacy IRQs with default 3902 + * trigger and polarity attributes. Don't set the flag for that 3903 + * case so the first legacy IRQ user could reprogram the pin 3904 + * with real trigger and polarity attributes. 3905 + */ 3906 + if (virq >= nr_legacy_irqs() || info->count) 3907 + info->set = 1; 3905 3908 } 3906 3909 set_io_apic_irq_attr(&attr, ioapic, hwirq, info->trigger, 3907 3910 info->polarity); ··· 3957 3944 mutex_unlock(&ioapic_mutex); 3958 3945 3959 3946 return ret; 3947 + } 3948 + 3949 + bool mp_should_keep_irq(struct device *dev) 3950 + { 3951 + if (dev->power.is_prepared) 3952 + return true; 3953 + #ifdef CONFIG_PM_RUNTIME 3954 + if (dev->power.runtime_status == RPM_SUSPENDING) 3955 + return true; 3956 + #endif 3957 + 3958 + return false; 3960 3959 } 3961 3960 3962 3961 /* Enable IOAPIC early just for system timer */
+1 -1
arch/x86/kernel/irqinit.c
··· 203 203 set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]); 204 204 } 205 205 206 - if (!acpi_ioapic && !of_ioapic) 206 + if (!acpi_ioapic && !of_ioapic && nr_legacy_irqs()) 207 207 setup_irq(2, &irq2); 208 208 209 209 #ifdef CONFIG_X86_32
+2
arch/x86/kernel/time.c
··· 68 68 69 69 void __init setup_default_timer_irq(void) 70 70 { 71 + if (!nr_legacy_irqs()) 72 + return; 71 73 setup_irq(0, &irq0); 72 74 } 73 75
+1 -1
arch/x86/pci/intel_mid_pci.c
··· 229 229 230 230 static void intel_mid_pci_irq_disable(struct pci_dev *dev) 231 231 { 232 - if (!dev->dev.power.is_prepared && dev->irq > 0) 232 + if (!mp_should_keep_irq(&dev->dev) && dev->irq > 0) 233 233 mp_unmap_irq(dev->irq); 234 234 } 235 235
+1 -1
arch/x86/pci/irq.c
··· 1256 1256 1257 1257 static void pirq_disable_irq(struct pci_dev *dev) 1258 1258 { 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) && 1260 1260 dev->irq) { 1261 1261 mp_unmap_irq(dev->irq); 1262 1262 dev->irq = 0;
+4
drivers/acpi/pci_irq.c
··· 484 484 /* Keep IOAPIC pin configuration when suspending */ 485 485 if (dev->dev.power.is_prepared) 486 486 return; 487 + #ifdef CONFIG_PM_RUNTIME 488 + if (dev->dev.power.runtime_status == RPM_SUSPENDING) 489 + return; 490 + #endif 487 491 488 492 entry = acpi_pci_irq_lookup(dev, pin); 489 493 if (!entry)