summaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorStephen Warren <swarren@nvidia.com>2013-08-13 12:07:26 -0600
committerStephen Warren <swarren@nvidia.com>2013-08-13 12:07:26 -0600
commit734a0f6bb93d6f2c27a2b2976e9da1e31905facd (patch)
tree9bfd05c893da5c37318f5ca0147898f1d9f1fe09 /drivers/pci
parente9f624499cc84a625648ccfbd550b74d17d52fb2 (diff)
parent6a4324ebf5cf412d55fd1ea259d4dd29fb8f90e8 (diff)
downloadlinux-734a0f6bb93d6f2c27a2b2976e9da1e31905facd.tar.bz2
Merge tag 'msi-3.12-2' into for-3.12/soc
pci msi changes for v3.12 (round 2) - fix build breakage for s390 allyesconfig due to !HAVE_GENERIC_HARDIRQS
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/Kconfig4
-rw-r--r--drivers/pci/msi.c85
-rw-r--r--drivers/pci/probe.c1
3 files changed, 63 insertions, 27 deletions
diff --git a/drivers/pci/Kconfig b/drivers/pci/Kconfig
index 81944fb73116..b6a99f7a9b20 100644
--- a/drivers/pci/Kconfig
+++ b/drivers/pci/Kconfig
@@ -1,13 +1,9 @@
#
# PCI configuration
#
-config ARCH_SUPPORTS_MSI
- bool
-
config PCI_MSI
bool "Message Signaled Interrupts (MSI and MSI-X)"
depends on PCI
- depends on ARCH_SUPPORTS_MSI
help
This allows device drivers to enable MSI (Message Signaled
Interrupts). Message Signaled Interrupts enable a device to
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index aca7578b05e5..b35f93c232cf 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -30,20 +30,60 @@ static int pci_msi_enable = 1;
/* Arch hooks */
-#ifndef arch_msi_check_device
-int arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
+#if defined(CONFIG_GENERIC_HARDIRQS)
+int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
+ struct msi_chip *chip = dev->bus->msi;
+ int err;
+
+ if (!chip || !chip->setup_irq)
+ return -EINVAL;
+
+ err = chip->setup_irq(chip, dev, desc);
+ if (err < 0)
+ return err;
+
+ irq_set_chip_data(desc->irq, chip);
+
return 0;
}
-#endif
-#ifndef arch_setup_msi_irqs
-# define arch_setup_msi_irqs default_setup_msi_irqs
-# define HAVE_DEFAULT_MSI_SETUP_IRQS
-#endif
+void __weak arch_teardown_msi_irq(unsigned int irq)
+{
+ struct msi_chip *chip = irq_get_chip_data(irq);
-#ifdef HAVE_DEFAULT_MSI_SETUP_IRQS
-int default_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+ if (!chip || !chip->teardown_irq)
+ return;
+
+ chip->teardown_irq(chip, irq);
+}
+
+int __weak arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
+{
+ struct msi_chip *chip = dev->bus->msi;
+
+ if (!chip || !chip->check_device)
+ return 0;
+
+ return chip->check_device(chip, dev, nvec, type);
+}
+#else
+int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+{
+ return -ENOSYS;
+}
+
+void __weak arch_teardown_msi_irq(unsigned int irq)
+{
+}
+
+int __weak arch_msi_check_device(struct pci_dev *dev, int nvec, int type)
+{
+ return 0;
+}
+#endif /* CONFIG_GENERIC_HARDIRQS */
+
+int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
struct msi_desc *entry;
int ret;
@@ -65,14 +105,11 @@ int default_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
return 0;
}
-#endif
-
-#ifndef arch_teardown_msi_irqs
-# define arch_teardown_msi_irqs default_teardown_msi_irqs
-# define HAVE_DEFAULT_MSI_TEARDOWN_IRQS
-#endif
-#ifdef HAVE_DEFAULT_MSI_TEARDOWN_IRQS
+/*
+ * We have a default implementation available as a separate non-weak
+ * function, as it is used by the Xen x86 PCI code
+ */
void default_teardown_msi_irqs(struct pci_dev *dev)
{
struct msi_desc *entry;
@@ -89,14 +126,12 @@ void default_teardown_msi_irqs(struct pci_dev *dev)
arch_teardown_msi_irq(entry->irq + i);
}
}
-#endif
-#ifndef arch_restore_msi_irqs
-# define arch_restore_msi_irqs default_restore_msi_irqs
-# define HAVE_DEFAULT_MSI_RESTORE_IRQS
-#endif
+void __weak arch_teardown_msi_irqs(struct pci_dev *dev)
+{
+ return default_teardown_msi_irqs(dev);
+}
-#ifdef HAVE_DEFAULT_MSI_RESTORE_IRQS
void default_restore_msi_irqs(struct pci_dev *dev, int irq)
{
struct msi_desc *entry;
@@ -114,7 +149,11 @@ void default_restore_msi_irqs(struct pci_dev *dev, int irq)
if (entry)
write_msi_msg(irq, &entry->msg);
}
-#endif
+
+void __weak arch_restore_msi_irqs(struct pci_dev *dev, int irq)
+{
+ return default_restore_msi_irqs(dev, irq);
+}
static void msi_set_enable(struct pci_dev *dev, int enable)
{
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index 46ada5c098eb..b8eaa8167849 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -666,6 +666,7 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
child->parent = parent;
child->ops = parent->ops;
+ child->msi = parent->msi;
child->sysdata = parent->sysdata;
child->bus_flags = parent->bus_flags;