PCI, x86: Implement pcibios_alloc_irq() and pcibios_free_irq()

To support IOAPIC hotplug, we need to allocate PCI IRQ resources on demand
and free them when not used anymore.

Implement pcibios_alloc_irq() and pcibios_free_irq() to dynamically
allocate and free PCI IRQs.

Remove mp_should_keep_irq(), which is no longer used.

[bhelgaas: changelog]
Signed-off-by: Jiang Liu <jiang.liu@linux.intel.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
Acked-by: Thomas Gleixner <tglx@linutronix.de>
This commit is contained in:
Jiang Liu 2015-06-10 16:54:59 +08:00 committed by Bjorn Helgaas
parent 890e484758
commit 991de2e590
5 changed files with 16 additions and 37 deletions

View file

@ -93,8 +93,6 @@ extern raw_spinlock_t pci_config_lock;
extern int (*pcibios_enable_irq)(struct pci_dev *dev);
extern void (*pcibios_disable_irq)(struct pci_dev *dev);
extern bool mp_should_keep_irq(struct device *dev);
struct pci_raw_ops {
int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn,
int reg, int len, u32 *val);

View file

@ -673,24 +673,22 @@ int pcibios_add_device(struct pci_dev *dev)
return 0;
}
int pcibios_enable_device(struct pci_dev *dev, int mask)
int pcibios_alloc_irq(struct pci_dev *dev)
{
int err;
if ((err = pci_enable_resources(dev, mask)) < 0)
return err;
if (!pci_dev_msi_enabled(dev))
return pcibios_enable_irq(dev);
return 0;
return pcibios_enable_irq(dev);
}
void pcibios_disable_device (struct pci_dev *dev)
void pcibios_free_irq(struct pci_dev *dev)
{
if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq)
if (pcibios_disable_irq)
pcibios_disable_irq(dev);
}
int pcibios_enable_device(struct pci_dev *dev, int mask)
{
return pci_enable_resources(dev, mask);
}
int pci_ext_cfg_avail(void)
{
if (raw_pci_ext_ops)

View file

@ -234,10 +234,13 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
static void intel_mid_pci_irq_disable(struct pci_dev *dev)
{
if (!mp_should_keep_irq(&dev->dev) && dev->irq_managed &&
dev->irq > 0) {
if (dev->irq_managed && dev->irq > 0) {
mp_unmap_irq(dev->irq);
dev->irq_managed = 0;
/*
* Don't reset dev->irq here, otherwise
* intel_mid_pci_irq_enable() will fail on next call.
*/
}
}

View file

@ -1257,22 +1257,9 @@ static int pirq_enable_irq(struct pci_dev *dev)
return 0;
}
bool mp_should_keep_irq(struct device *dev)
{
if (dev->power.is_prepared)
return true;
#ifdef CONFIG_PM
if (dev->power.runtime_status == RPM_SUSPENDING)
return true;
#endif
return false;
}
static void pirq_disable_irq(struct pci_dev *dev)
{
if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) &&
dev->irq_managed && dev->irq) {
if (io_apic_assign_pci_irqs && dev->irq_managed && dev->irq) {
mp_unmap_irq(dev->irq);
dev->irq = 0;
dev->irq_managed = 0;

View file

@ -484,14 +484,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
if (!pin || !dev->irq_managed || dev->irq <= 0)
return;
/* Keep IOAPIC pin configuration when suspending */
if (dev->dev.power.is_prepared)
return;
#ifdef CONFIG_PM
if (dev->dev.power.runtime_status == RPM_SUSPENDING)
return;
#endif
entry = acpi_pci_irq_lookup(dev, pin);
if (!entry)
return;
@ -512,5 +504,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
if (gsi >= 0) {
acpi_unregister_gsi(gsi);
dev->irq_managed = 0;
dev->irq = 0;
}
}