Commit fd5984d7 authored by Linus Torvalds's avatar Linus Torvalds
Browse files

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
parents ad6ede80 9eabc99a
Loading
Loading
Loading
Loading
+2 −0
Original line number Diff line number Diff line
@@ -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
+26 −1
Original line number Diff line number Diff line
@@ -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,6 +3901,14 @@ int mp_irqdomain_map(struct irq_domain *domain, unsigned int virq,
			info->polarity = 1;
		}
		info->node = NUMA_NO_NODE;

		/*
		 * 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,
@@ -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)
{
+1 −1
Original line number Diff line number Diff line
@@ -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
+2 −0
Original line number Diff line number Diff line
@@ -68,6 +68,8 @@ static struct irqaction irq0 = {

void __init setup_default_timer_irq(void)
{
	if (!nr_legacy_irqs())
		return;
	setup_irq(0, &irq0);
}

+1 −1
Original line number Diff line number Diff line
@@ -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);
}

Loading