summaryrefslogtreecommitdiff
path: root/target/linux/mvebu/patches-3.10/0072-PCI-Introduce-new-MSI-chip-infrastructure.patch
diff options
context:
space:
mode:
Diffstat (limited to 'target/linux/mvebu/patches-3.10/0072-PCI-Introduce-new-MSI-chip-infrastructure.patch')
-rw-r--r--target/linux/mvebu/patches-3.10/0072-PCI-Introduce-new-MSI-chip-infrastructure.patch108
1 files changed, 108 insertions, 0 deletions
diff --git a/target/linux/mvebu/patches-3.10/0072-PCI-Introduce-new-MSI-chip-infrastructure.patch b/target/linux/mvebu/patches-3.10/0072-PCI-Introduce-new-MSI-chip-infrastructure.patch
new file mode 100644
index 0000000..291a3b3
--- /dev/null
+++ b/target/linux/mvebu/patches-3.10/0072-PCI-Introduce-new-MSI-chip-infrastructure.patch
@@ -0,0 +1,108 @@
+From 9c6ddccbbfaf789beccc6a1d87abe9bc60dc570f Mon Sep 17 00:00:00 2001
+From: Thierry Reding <thierry.reding@avionic-design.de>
+Date: Thu, 6 Jun 2013 18:20:29 +0200
+Subject: [PATCH 072/203] PCI: Introduce new MSI chip infrastructure
+
+The new struct msi_chip is used to associated an MSI controller with a
+PCI bus. It is automatically handed down from the root to its children
+during bus enumeration.
+
+This patch provides default (weak) implementations for the architecture-
+specific MSI functions (arch_setup_msi_irq(), arch_teardown_msi_irq()
+and arch_msi_check_device()) which check if a PCI device's bus has an
+attached MSI chip and forward the call appropriately.
+
+Signed-off-by: Thierry Reding <thierry.reding@avionic-design.de>
+Signed-off-by: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
+Acked-by: Bjorn Helgaas <bhelgaas@google.com>
+Tested-by: Daniel Price <daniel.price@gmail.com>
+Tested-by: Thierry Reding <thierry.reding@gmail.com>
+---
+ drivers/pci/msi.c | 27 +++++++++++++++++++++++++--
+ drivers/pci/probe.c | 1 +
+ include/linux/msi.h | 11 +++++++++++
+ include/linux/pci.h | 1 +
+ 4 files changed, 38 insertions(+), 2 deletions(-)
+
+--- a/drivers/pci/msi.c
++++ b/drivers/pci/msi.c
+@@ -32,16 +32,39 @@ static int pci_msi_enable = 1;
+
+ int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+ {
+- return -EINVAL;
++ 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;
+ }
+
+ void __weak arch_teardown_msi_irq(unsigned int irq)
+ {
++ struct msi_chip *chip = irq_get_chip_data(irq);
++
++ 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)
+ {
+- return 0;
++ struct msi_chip *chip = dev->bus->msi;
++
++ if (!chip || !chip->check_device)
++ return 0;
++
++ return chip->check_device(chip, dev, nvec, type);
+ }
+
+ int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+--- a/drivers/pci/probe.c
++++ b/drivers/pci/probe.c
+@@ -634,6 +634,7 @@ static struct pci_bus *pci_alloc_child_b
+
+ child->parent = parent;
+ child->ops = parent->ops;
++ child->msi = parent->msi;
+ child->sysdata = parent->sysdata;
+ child->bus_flags = parent->bus_flags;
+
+--- a/include/linux/msi.h
++++ b/include/linux/msi.h
+@@ -64,4 +64,15 @@ void arch_restore_msi_irqs(struct pci_de
+ void default_teardown_msi_irqs(struct pci_dev *dev);
+ void default_restore_msi_irqs(struct pci_dev *dev, int irq);
+
++struct msi_chip {
++ struct module *owner;
++ struct device *dev;
++
++ int (*setup_irq)(struct msi_chip *chip, struct pci_dev *dev,
++ struct msi_desc *desc);
++ void (*teardown_irq)(struct msi_chip *chip, unsigned int irq);
++ int (*check_device)(struct msi_chip *chip, struct pci_dev *dev,
++ int nvec, int type);
++};
++
+ #endif /* LINUX_MSI_H */
+--- a/include/linux/pci.h
++++ b/include/linux/pci.h
+@@ -432,6 +432,7 @@ struct pci_bus {
+ struct resource busn_res; /* bus numbers routed to this bus */
+
+ struct pci_ops *ops; /* configuration access functions */
++ struct msi_chip *msi; /* MSI controller */
+ void *sysdata; /* hook for sys-specific extension */
+ struct proc_dir_entry *procdir; /* directory entry in /proc/bus/pci */
+