Commit a9f8094a authored by Linus Torvalds's avatar Linus Torvalds

Merge tag 'pci-v4.5-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci

Pull PCI fixes from Bjorn Helgaas:
 "Enumeration:
    Revert x86 pcibios_alloc_irq() to fix regression (Bjorn Helgaas)

  Marvell MVEBU host bridge driver:
    Restrict build to 32-bit ARM (Thierry Reding)"

* tag 'pci-v4.5-fixes-3' of git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci:
  PCI: mvebu: Restrict build to 32-bit ARM
  Revert "PCI, x86: Implement pcibios_alloc_irq() and pcibios_free_irq()"
  Revert "PCI: Add helpers to manage pci_dev->irq and pci_dev->irq_managed"
  Revert "x86/PCI: Don't alloc pcibios-irq when MSI is enabled"
parents b9ea44bf 61d9e854
...@@ -93,6 +93,8 @@ extern raw_spinlock_t pci_config_lock; ...@@ -93,6 +93,8 @@ extern raw_spinlock_t pci_config_lock;
extern int (*pcibios_enable_irq)(struct pci_dev *dev); extern int (*pcibios_enable_irq)(struct pci_dev *dev);
extern void (*pcibios_disable_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 { struct pci_raw_ops {
int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn, int (*read)(unsigned int domain, unsigned int bus, unsigned int devfn,
int reg, int len, u32 *val); int reg, int len, u32 *val);
......
...@@ -711,28 +711,22 @@ int pcibios_add_device(struct pci_dev *dev) ...@@ -711,28 +711,22 @@ int pcibios_add_device(struct pci_dev *dev)
return 0; return 0;
} }
int pcibios_alloc_irq(struct pci_dev *dev) int pcibios_enable_device(struct pci_dev *dev, int mask)
{ {
/* int err;
* If the PCI device was already claimed by core code and has
* MSI enabled, probing of the pcibios IRQ will overwrite
* dev->irq. So bail out if MSI is already enabled.
*/
if (pci_dev_msi_enabled(dev))
return -EBUSY;
return pcibios_enable_irq(dev); if ((err = pci_enable_resources(dev, mask)) < 0)
} return err;
void pcibios_free_irq(struct pci_dev *dev) if (!pci_dev_msi_enabled(dev))
{ return pcibios_enable_irq(dev);
if (pcibios_disable_irq) return 0;
pcibios_disable_irq(dev);
} }
int pcibios_enable_device(struct pci_dev *dev, int mask) void pcibios_disable_device (struct pci_dev *dev)
{ {
return pci_enable_resources(dev, mask); if (!pci_dev_msi_enabled(dev) && pcibios_disable_irq)
pcibios_disable_irq(dev);
} }
int pci_ext_cfg_avail(void) int pci_ext_cfg_avail(void)
......
...@@ -215,7 +215,7 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev) ...@@ -215,7 +215,7 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
int polarity; int polarity;
int ret; int ret;
if (pci_has_managed_irq(dev)) if (dev->irq_managed && dev->irq > 0)
return 0; return 0;
switch (intel_mid_identify_cpu()) { switch (intel_mid_identify_cpu()) {
...@@ -256,13 +256,10 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev) ...@@ -256,13 +256,10 @@ static int intel_mid_pci_irq_enable(struct pci_dev *dev)
static void intel_mid_pci_irq_disable(struct pci_dev *dev) static void intel_mid_pci_irq_disable(struct pci_dev *dev)
{ {
if (pci_has_managed_irq(dev)) { if (!mp_should_keep_irq(&dev->dev) && dev->irq_managed &&
dev->irq > 0) {
mp_unmap_irq(dev->irq); mp_unmap_irq(dev->irq);
dev->irq_managed = 0; dev->irq_managed = 0;
/*
* Don't reset dev->irq here, otherwise
* intel_mid_pci_irq_enable() will fail on next call.
*/
} }
} }
......
...@@ -1202,7 +1202,7 @@ static int pirq_enable_irq(struct pci_dev *dev) ...@@ -1202,7 +1202,7 @@ static int pirq_enable_irq(struct pci_dev *dev)
struct pci_dev *temp_dev; struct pci_dev *temp_dev;
int irq; int irq;
if (pci_has_managed_irq(dev)) if (dev->irq_managed && dev->irq > 0)
return 0; return 0;
irq = IO_APIC_get_PCI_irq_vector(dev->bus->number, irq = IO_APIC_get_PCI_irq_vector(dev->bus->number,
...@@ -1230,7 +1230,8 @@ static int pirq_enable_irq(struct pci_dev *dev) ...@@ -1230,7 +1230,8 @@ static int pirq_enable_irq(struct pci_dev *dev)
} }
dev = temp_dev; dev = temp_dev;
if (irq >= 0) { if (irq >= 0) {
pci_set_managed_irq(dev, irq); dev->irq_managed = 1;
dev->irq = irq;
dev_info(&dev->dev, "PCI->APIC IRQ transform: " dev_info(&dev->dev, "PCI->APIC IRQ transform: "
"INT %c -> IRQ %d\n", 'A' + pin - 1, irq); "INT %c -> IRQ %d\n", 'A' + pin - 1, irq);
return 0; return 0;
...@@ -1256,10 +1257,24 @@ static int pirq_enable_irq(struct pci_dev *dev) ...@@ -1256,10 +1257,24 @@ static int pirq_enable_irq(struct pci_dev *dev)
return 0; 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) static void pirq_disable_irq(struct pci_dev *dev)
{ {
if (io_apic_assign_pci_irqs && pci_has_managed_irq(dev)) { if (io_apic_assign_pci_irqs && !mp_should_keep_irq(&dev->dev) &&
dev->irq_managed && dev->irq) {
mp_unmap_irq(dev->irq); mp_unmap_irq(dev->irq);
pci_reset_managed_irq(dev); dev->irq = 0;
dev->irq_managed = 0;
} }
} }
...@@ -406,7 +406,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev) ...@@ -406,7 +406,7 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
return 0; return 0;
} }
if (pci_has_managed_irq(dev)) if (dev->irq_managed && dev->irq > 0)
return 0; return 0;
entry = acpi_pci_irq_lookup(dev, pin); entry = acpi_pci_irq_lookup(dev, pin);
...@@ -451,7 +451,8 @@ int acpi_pci_irq_enable(struct pci_dev *dev) ...@@ -451,7 +451,8 @@ int acpi_pci_irq_enable(struct pci_dev *dev)
kfree(entry); kfree(entry);
return rc; return rc;
} }
pci_set_managed_irq(dev, rc); dev->irq = rc;
dev->irq_managed = 1;
if (link) if (link)
snprintf(link_desc, sizeof(link_desc), " -> Link[%s]", link); snprintf(link_desc, sizeof(link_desc), " -> Link[%s]", link);
...@@ -474,9 +475,17 @@ void acpi_pci_irq_disable(struct pci_dev *dev) ...@@ -474,9 +475,17 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
u8 pin; u8 pin;
pin = dev->pin; pin = dev->pin;
if (!pin || !pci_has_managed_irq(dev)) if (!pin || !dev->irq_managed || dev->irq <= 0)
return; 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); entry = acpi_pci_irq_lookup(dev, pin);
if (!entry) if (!entry)
return; return;
...@@ -496,6 +505,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev) ...@@ -496,6 +505,6 @@ void acpi_pci_irq_disable(struct pci_dev *dev)
dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin)); dev_dbg(&dev->dev, "PCI INT %c disabled\n", pin_name(pin));
if (gsi >= 0) { if (gsi >= 0) {
acpi_unregister_gsi(gsi); acpi_unregister_gsi(gsi);
pci_reset_managed_irq(dev); dev->irq_managed = 0;
} }
} }
...@@ -14,6 +14,7 @@ config PCI_DRA7XX ...@@ -14,6 +14,7 @@ config PCI_DRA7XX
config PCI_MVEBU config PCI_MVEBU
bool "Marvell EBU PCIe controller" bool "Marvell EBU PCIe controller"
depends on ARCH_MVEBU || ARCH_DOVE depends on ARCH_MVEBU || ARCH_DOVE
depends on ARM
depends on OF depends on OF
config PCIE_DW config PCIE_DW
......
...@@ -988,23 +988,6 @@ static inline int pci_is_managed(struct pci_dev *pdev) ...@@ -988,23 +988,6 @@ static inline int pci_is_managed(struct pci_dev *pdev)
return pdev->is_managed; return pdev->is_managed;
} }
static inline void pci_set_managed_irq(struct pci_dev *pdev, unsigned int irq)
{
pdev->irq = irq;
pdev->irq_managed = 1;
}
static inline void pci_reset_managed_irq(struct pci_dev *pdev)
{
pdev->irq = 0;
pdev->irq_managed = 0;
}
static inline bool pci_has_managed_irq(struct pci_dev *pdev)
{
return pdev->irq_managed && pdev->irq > 0;
}
void pci_disable_device(struct pci_dev *dev); void pci_disable_device(struct pci_dev *dev);
extern unsigned int pcibios_max_latency; extern unsigned int pcibios_max_latency;
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment