Commit fd5984d7c8e8e249aca0c515817ab1e7dee1502c
Exists in
ti-lsk-linux-4.1.y
and in
10 other branches
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
Showing 7 changed files Side-by-side Diff
arch/x86/include/asm/io_apic.h
arch/x86/kernel/apic/io_apic.c
... | ... | @@ -1070,6 +1070,11 @@ |
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) |
... | ... | @@ -3896,7 +3901,15 @@ |
3896 | 3901 | info->polarity = 1; |
3897 | 3902 | } |
3898 | 3903 | 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; | |
3900 | 3913 | } |
3901 | 3914 | set_io_apic_irq_attr(&attr, ioapic, hwirq, info->trigger, |
3902 | 3915 | info->polarity); |
... | ... | @@ -3944,6 +3957,18 @@ |
3944 | 3957 | mutex_unlock(&ioapic_mutex); |
3945 | 3958 | |
3946 | 3959 | return ret; |
3960 | +} | |
3961 | + | |
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; | |
3947 | 3972 | } |
3948 | 3973 | |
3949 | 3974 | /* Enable IOAPIC early just for system timer */ |
arch/x86/kernel/irqinit.c
arch/x86/kernel/time.c
arch/x86/pci/intel_mid_pci.c
arch/x86/pci/irq.c
... | ... | @@ -1256,7 +1256,7 @@ |
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; |
drivers/acpi/pci_irq.c
... | ... | @@ -484,6 +484,10 @@ |
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) |