forked from luck/tmp_suning_uos_patched
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
This commit is contained in:
commit
fd5984d7c8
|
@ -227,6 +227,8 @@ static inline void io_apic_modify(unsigned int apic, unsigned int reg, unsigned
|
|||
|
||||
extern void io_apic_eoi(unsigned int apic, unsigned int vector);
|
||||
|
||||
extern bool mp_should_keep_irq(struct device *dev);
|
||||
|
||||
#else /* !CONFIG_X86_IO_APIC */
|
||||
|
||||
#define io_apic_assign_pci_irqs 0
|
||||
|
|
|
@ -1070,6 +1070,11 @@ static int mp_map_pin_to_irq(u32 gsi, int idx, int ioapic, int pin,
|
|||
}
|
||||
|
||||
if (flags & IOAPIC_MAP_ALLOC) {
|
||||
/* special handling for legacy IRQs */
|
||||
if (irq < nr_legacy_irqs() && info->count == 1 &&
|
||||
mp_irqdomain_map(domain, irq, pin) != 0)
|
||||
irq = -1;
|
||||
|
||||
if (irq > 0)
|
||||
info->count++;
|
||||
else if (info->count == 0)
|
||||
|
@ -3896,7 +3901,15 @@ int mp_irqdomain_map(struct irq_domain *domain, unsigned int virq,
|
|||
info->polarity = 1;
|
||||
}
|
||||
info->node = NUMA_NO_NODE;
|
||||
info->set = 1;
|
||||
|
||||
/*
|
||||
* setup_IO_APIC_irqs() programs all legacy IRQs with default
|
||||
* trigger and polarity attributes. Don't set the flag for that
|
||||
* case so the first legacy IRQ user could reprogram the pin
|
||||
* with real trigger and polarity attributes.
|
||||
*/
|
||||
if (virq >= nr_legacy_irqs() || info->count)
|
||||
info->set = 1;
|
||||
}
|
||||
set_io_apic_irq_attr(&attr, ioapic, hwirq, info->trigger,
|
||||
info->polarity);
|
||||
|
@ -3946,6 +3959,18 @@ int mp_set_gsi_attr(u32 gsi, int trigger, int polarity, int node)
|
|||
return ret;
|
||||
}
|
||||
|
||||
bool mp_should_keep_irq(struct device *dev)
|
||||
{
|
||||
if (dev->power.is_prepared)
|
||||
return true;
|
||||
#ifdef CONFIG_PM_RUNTIME
|
||||
if (dev->power.runtime_status == RPM_SUSPENDING)
|
||||
return true;
|
||||
#endif
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/* Enable IOAPIC early just for system timer */
|
||||
void __init pre_init_apic_IRQ0(void)
|
||||
{
|
||||
|
|
|
@ -203,7 +203,7 @@ void __init native_init_IRQ(void)
|
|||
set_intr_gate(i, interrupt[i - FIRST_EXTERNAL_VECTOR]);
|
||||
}
|
||||
|
||||
if (!acpi_ioapic && !of_ioapic)
|
||||
if (!acpi_ioapic && !of_ioapic && nr_legacy_irqs())
|
||||
setup_irq(2, &irq2);
|
||||
|
||||
#ifdef CONFIG_X86_32
|
||||
|
|
|
@ -68,6 +68,8 @@ static struct irqaction irq0 = {
|
|||
|
||||
void __init setup_default_timer_irq(void)
|
||||
{
|
||||
if (!nr_legacy_irqs())
|
||||
return;
|
||||
setup_irq(0, &irq0);
|
||||
}
|
||||
|
||||
|
|
|
@ -229,7 +229,7 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
|
|||
|
||||
static void intel_mid_pci_irq_disable(struct pci_dev *dev)
|
||||
{
|
||||
if (!dev->dev.power.is_prepared && dev->irq > 0)
|
||||
if (!mp_should_keep_irq(&dev->dev) && dev->irq > 0)
|
||||
mp_unmap_irq(dev->irq);
|
||||
}
|
||||
|
||||
|
|
|
@ -1256,7 +1256,7 @@ static int pirq_enable_irq(struct pci_dev *dev)
|
|||
|
||||
static void pirq_disable_irq(struct pci_dev *dev)
|
||||
{
|
||||
if (io_apic_assign_pci_irqs && !dev->dev.power.is_prepared &&
|
||||
if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) &&
|
||||
dev->irq) {
|
||||
mp_unmap_irq(dev->irq);
|
||||
dev->irq = 0;
|
||||
|
|
|
@ -484,6 +484,10 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
|
|||
/* Keep IOAPIC pin configuration when suspending */
|
||||
if (dev->dev.power.is_prepared)
|
||||
return;
|
||||
#ifdef CONFIG_PM_RUNTIME
|
||||
if (dev->dev.power.runtime_status == RPM_SUSPENDING)
|
||||
return;
|
||||
#endif
|
||||
|
||||
entry = acpi_pci_irq_lookup(dev, pin);
|
||||
if (!entry)
|
||||
|
|
Loading…
Reference in New Issue
Block a user