* [PATCH v2 02/22] PCI/MSI: Remove useless bus->msi assignment
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Currently, PCI drivers will initialize bus->msi in
pcibios_add_bus(). pcibios_add_bus() will be called
in every pci bus initialization. So the bus->msi
assignment in pci_alloc_child_bus() is useless.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
CC: Thierry Reding <thierry.reding@gmail.com>
CC: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
drivers/pci/probe.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)
diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index e3cf8a2..8296576 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -677,7 +677,6 @@ 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;
--
1.7.1
^ permalink raw reply related
* [PATCH v2 10/22] Irq_remapping/MSI: Use MSI chip framework to configure MSI/MSI-X irq
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
---
drivers/iommu/irq_remapping.c | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 33c4395..7929590 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -148,6 +148,11 @@ static int irq_remapping_setup_msi_irqs(struct pci_dev *dev,
return do_setup_msix_irqs(dev, nvec);
}
+static struct msi_chip remap_msi_chip = {
+ .setup_irqs = irq_remapping_setup_msi_irqs,
+ .teardown_irq = native_teardown_msi_irq,
+};
+
static void eoi_ioapic_pin_remapped(int apic, int pin, int vector)
{
/*
@@ -168,6 +173,7 @@ static void __init irq_remapping_modify_x86_ops(void)
x86_msi.setup_msi_irqs = irq_remapping_setup_msi_irqs;
x86_msi.setup_hpet_msi = setup_hpet_msi_remapped;
x86_msi.compose_msi_msg = compose_remapped_msi_msg;
+ x86_msi_chip = &remap_msi_chip;
}
static __init int setup_nointremap(char *str)
--
1.7.1
^ permalink raw reply related
* [PATCH v2 09/22] x86/xen/MSI: Use MSI chip framework to configure MSI/MSI-X irq
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.
Tested-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Acked-by: David Vrabel <david.vrabel@citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
CC: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
arch/x86/pci/xen.c | 46 ++++++++++++++++++++++++++++++----------------
1 files changed, 30 insertions(+), 16 deletions(-)
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 84c2fce..e669ee4 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -376,6 +376,11 @@ static void xen_initdom_restore_msi_irqs(struct pci_dev *dev)
}
#endif
+static void xen_teardown_msi_irq(unsigned int irq)
+{
+ xen_destroy_irq(irq);
+}
+
static void xen_teardown_msi_irqs(struct pci_dev *dev)
{
struct msi_desc *msidesc;
@@ -385,19 +390,26 @@ static void xen_teardown_msi_irqs(struct pci_dev *dev)
xen_pci_frontend_disable_msix(dev);
else
xen_pci_frontend_disable_msi(dev);
-
- /* Free the IRQ's and the msidesc using the generic code. */
- default_teardown_msi_irqs(dev);
-}
-
-static void xen_teardown_msi_irq(unsigned int irq)
-{
- xen_destroy_irq(irq);
+
+ list_for_each_entry(msidesc, &dev->msi_list, list) {
+ int i, nvec;
+ if (msidesc->irq == 0)
+ continue;
+ if (msidesc->nvec_used)
+ nvec = msidesc->nvec_used;
+ else
+ nvec = 1 << msidesc->msi_attrib.multiple;
+ for (i = 0; i < nvec; i++)
+ xen_teardown_msi_irq(msidesc->irq + i);
+ }
}
void xen_nop_msi_mask(struct irq_data *data)
{
}
+
+struct msi_chip xen_msi_chip;
+
#endif
int __init pci_xen_init(void)
@@ -418,9 +430,9 @@ int __init pci_xen_init(void)
#endif
#ifdef CONFIG_PCI_MSI
- x86_msi.setup_msi_irqs = xen_setup_msi_irqs;
- x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
- x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs;
+ xen_msi_chip.setup_irqs = xen_setup_msi_irqs;
+ xen_msi_chip.teardown_irqs = xen_teardown_msi_irqs;
+ x86_msi_chip = &xen_msi_chip;
msi_chip.irq_mask = xen_nop_msi_mask;
msi_chip.irq_unmask = xen_nop_msi_mask;
#endif
@@ -441,8 +453,9 @@ int __init pci_xen_hvm_init(void)
#endif
#ifdef CONFIG_PCI_MSI
- x86_msi.setup_msi_irqs = xen_hvm_setup_msi_irqs;
- x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
+ xen_msi_chip.setup_irqs = xen_hvm_setup_msi_irqs;
+ xen_msi_chip.teardown_irq = xen_teardown_msi_irq;
+ x86_msi_chip = &xen_msi_chip;
#endif
return 0;
}
@@ -499,9 +512,10 @@ int __init pci_xen_initial_domain(void)
int irq;
#ifdef CONFIG_PCI_MSI
- x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs;
- x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
- x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs;
+ xen_msi_chip.setup_irqs = xen_initdom_setup_msi_irqs;
+ xen_msi_chip.teardown_irq = xen_teardown_msi_irq;
+ xen_msi_chip.restore_irqs = xen_initdom_restore_msi_irqs;
+ x86_msi_chip = &xen_msi_chip;
msi_chip.irq_mask = xen_nop_msi_mask;
msi_chip.irq_unmask = xen_nop_msi_mask;
#endif
--
1.7.1
^ permalink raw reply related
* [PATCH v2 01/22] PCI/MSI: Clean up struct msi_chip argument
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Msi_chip functions setup_irq/teardown_irq rarely use msi_chip
argument. We can look up msi_chip pointer by the device pointer
or irq number, so clean up msi_chip argument.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
CC: Thierry Reding <thierry.reding@gmail.com>
CC: Thomas Petazzoni <thomas.petazzoni@free-electrons.com>
---
drivers/irqchip/irq-armada-370-xp.c | 8 +++-----
drivers/pci/host/pci-tegra.c | 8 +++++---
drivers/pci/host/pcie-designware.c | 4 ++--
drivers/pci/host/pcie-rcar.c | 8 +++++---
drivers/pci/msi.c | 4 ++--
include/linux/msi.h | 5 ++---
6 files changed, 19 insertions(+), 18 deletions(-)
diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index df60eab..3909d06 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -129,9 +129,8 @@ static void armada_370_xp_free_msi(int hwirq)
mutex_unlock(&msi_used_lock);
}
-static int armada_370_xp_setup_msi_irq(struct msi_chip *chip,
- struct pci_dev *pdev,
- struct msi_desc *desc)
+static int armada_370_xp_setup_msi_irq(struct pci_dev *pdev,
+ struct msi_desc *desc)
{
struct msi_msg msg;
int virq, hwirq;
@@ -160,8 +159,7 @@ static int armada_370_xp_setup_msi_irq(struct msi_chip *chip,
return 0;
}
-static void armada_370_xp_teardown_msi_irq(struct msi_chip *chip,
- unsigned int irq)
+static void armada_370_xp_teardown_msi_irq(unsigned int irq)
{
struct irq_data *d = irq_get_irq_data(irq);
unsigned long hwirq = d->hwirq;
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 0fb0fdb..edd4040 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -1157,9 +1157,10 @@ static irqreturn_t tegra_pcie_msi_irq(int irq, void *data)
return processed > 0 ? IRQ_HANDLED : IRQ_NONE;
}
-static int tegra_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
+static int tegra_msi_setup_irq(struct pci_dev *pdev,
struct msi_desc *desc)
{
+ struct msi_chip *chip = pdev->bus->msi;
struct tegra_msi *msi = to_tegra_msi(chip);
struct msi_msg msg;
unsigned int irq;
@@ -1185,10 +1186,11 @@ static int tegra_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
return 0;
}
-static void tegra_msi_teardown_irq(struct msi_chip *chip, unsigned int irq)
+static void tegra_msi_teardown_irq(unsigned int irq)
{
- struct tegra_msi *msi = to_tegra_msi(chip);
struct irq_data *d = irq_get_irq_data(irq);
+ struct msi_chip *chip = irq_get_chip_data(irq);
+ struct tegra_msi *msi = to_tegra_msi(chip);
tegra_msi_free(msi, d->hwirq);
}
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index fa2fa45..517f1e1 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -342,7 +342,7 @@ static void clear_irq(unsigned int irq)
msi->msi_attrib.multiple = 0;
}
-static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
+static int dw_msi_setup_irq(struct pci_dev *pdev,
struct msi_desc *desc)
{
int irq, pos, msgvec;
@@ -383,7 +383,7 @@ static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
return 0;
}
-static void dw_msi_teardown_irq(struct msi_chip *chip, unsigned int irq)
+static void dw_msi_teardown_irq(unsigned int irq)
{
clear_irq(irq);
}
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 4884ee5..647bc9f 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -615,9 +615,10 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
return IRQ_HANDLED;
}
-static int rcar_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
+static int rcar_msi_setup_irq(struct pci_dev *pdev,
struct msi_desc *desc)
{
+ struct msi_chip *chip = pdev->bus->msi;
struct rcar_msi *msi = to_rcar_msi(chip);
struct rcar_pcie *pcie = container_of(chip, struct rcar_pcie, msi.chip);
struct msi_msg msg;
@@ -645,10 +646,11 @@ static int rcar_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
return 0;
}
-static void rcar_msi_teardown_irq(struct msi_chip *chip, unsigned int irq)
+static void rcar_msi_teardown_irq(unsigned int irq)
{
- struct rcar_msi *msi = to_rcar_msi(chip);
struct irq_data *d = irq_get_irq_data(irq);
+ struct msi_chip *chip = irq_get_chip_data(irq);
+ struct rcar_msi *msi = to_rcar_msi(chip);
rcar_msi_free(msi, d->hwirq);
}
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index aae2fc8..51d7e62 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -37,7 +37,7 @@ int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
if (!chip || !chip->setup_irq)
return -EINVAL;
- err = chip->setup_irq(chip, dev, desc);
+ err = chip->setup_irq(dev, desc);
if (err < 0)
return err;
@@ -53,7 +53,7 @@ void __weak arch_teardown_msi_irq(unsigned int irq)
if (!chip || !chip->teardown_irq)
return;
- chip->teardown_irq(chip, irq);
+ chip->teardown_irq(irq);
}
int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 36c63cf..45ef8cb 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -68,9 +68,8 @@ struct msi_chip {
struct device_node *of_node;
struct list_head list;
- 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 (*setup_irq)(struct pci_dev *dev, struct msi_desc *desc);
+ void (*teardown_irq)(unsigned int irq);
};
#endif /* LINUX_MSI_H */
--
1.7.1
^ permalink raw reply related
* [PATCH v2 00/22] Use MSI chip framework to configure MSI/MSI-X in all platforms
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
This series is based Bjorn's pci/msi branch
git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci/msi
Currently, there are a lot of weak arch functions in MSI code.
Thierry Reding Introduced MSI chip framework to configure MSI/MSI-X in arm.
This series use MSI chip framework to refactor MSI code across all platforms
to eliminate weak arch functions. Then all MSI irqs will be managed in a
unified framework. Because this series changed a lot of ARCH MSI code,
so tests in the platforms which MSI code modified are warmly welcomed!
v1->v2:
Add a patch to make s390 MSI code build happy between patch "x86/xen/MSI: E.."
and "s390/MSI: Use MSI..". Fix several typo problems found by Lucas.
RFC->v1:
Updated "[patch 4/21] x86/xen/MSI: Eliminate...", export msi_chip instead
of #ifdef to fix MSI bug in xen running in x86.
Rename arch_get_match_msi_chip() to arch_find_msi_chip().
Drop use struct device as the msi_chip argument, we will do that
later in another patchset.
Yijing Wang (22):
PCI/MSI: Clean up struct msi_chip argument
PCI/MSI: Remove useless bus->msi assignment
MSI: Remove the redundant irq_set_chip_data()
x86/xen/MSI: Eliminate arch_msix_mask_irq() and arch_msi_mask_irq()
s390/MSI: Use __msi_mask_irq() instead of default_msi_mask_irq()
PCI/MSI: Introduce weak arch_find_msi_chip() to find MSI chip
PCI/MSI: Refactor struct msi_chip to make it become more common
x86/MSI: Use MSI chip framework to configure MSI/MSI-X irq
x86/xen/MSI: Use MSI chip framework to configure MSI/MSI-X irq
Irq_remapping/MSI: Use MSI chip framework to configure MSI/MSI-X irq
x86/MSI: Remove unused MSI weak arch functions
MIPS/Octeon/MSI: Use MSI chip framework to configure MSI/MSI-X irq
MIPS/Xlp: Remove the dead function destroy_irq() to fix build error
MIPS/Xlp/MSI: Use MSI chip framework to configure MSI/MSI-X irq
MIPS/Xlr/MSI: Use MSI chip framework to configure MSI/MSI-X irq
Powerpc/MSI: Use MSI chip framework to configure MSI/MSI-X irq
s390/MSI: Use MSI chip framework to configure MSI/MSI-X irq
arm/iop13xx/MSI: Use MSI chip framework to configure MSI/MSI-X irq
IA64/MSI: Use MSI chip framework to configure MSI/MSI-X irq
Sparc/MSI: Use MSI chip framework to configure MSI/MSI-X irq
tile/MSI: Use MSI chip framework to configure MSI/MSI-X irq
PCI/MSI: Clean up unused MSI arch functions
arch/arm/mach-iop13xx/include/mach/pci.h | 2 +
arch/arm/mach-iop13xx/iq81340mc.c | 1 +
arch/arm/mach-iop13xx/iq81340sc.c | 1 +
arch/arm/mach-iop13xx/msi.c | 9 ++-
arch/arm/mach-iop13xx/pci.c | 6 ++
arch/ia64/kernel/msi_ia64.c | 18 ++++-
arch/mips/pci/msi-octeon.c | 35 ++++++----
arch/mips/pci/msi-xlp.c | 18 ++++--
arch/mips/pci/pci-xlr.c | 15 ++++-
arch/powerpc/kernel/msi.c | 14 +++-
arch/s390/pci/pci.c | 18 ++++-
arch/sparc/kernel/pci.c | 14 +++-
arch/tile/kernel/pci_gx.c | 14 +++-
arch/x86/include/asm/apic.h | 4 +
arch/x86/include/asm/pci.h | 4 +-
arch/x86/include/asm/x86_init.h | 7 --
arch/x86/kernel/apic/io_apic.c | 16 ++++-
arch/x86/kernel/x86_init.c | 34 ---------
arch/x86/pci/xen.c | 60 +++++++++-------
drivers/iommu/irq_remapping.c | 9 ++-
drivers/irqchip/irq-armada-370-xp.c | 8 +--
drivers/pci/host/pci-tegra.c | 8 ++-
drivers/pci/host/pcie-designware.c | 4 +-
drivers/pci/host/pcie-rcar.c | 8 ++-
drivers/pci/msi.c | 114 ++++++++++++++----------------
drivers/pci/probe.c | 1 -
include/linux/msi.h | 26 ++-----
27 files changed, 266 insertions(+), 202 deletions(-)
^ permalink raw reply
* [PATCH v2 13/22] MIPS/Xlp: Remove the dead function destroy_irq() to fix build error
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Commit 465665f78a7 ("mips: Kill pointless destroy_irq()") removed
the destroy_irq(). So remove the leftover one in xlp_setup_msix()
to fix build error.
arch/mips/pci/msi-xlp.c: In function 'xlp_setup_msix':
arch/mips/pci/msi-xlp.c:447:3: error: implicit declaration of function 'destroy_irq'..
cc1: some warnings being treated as errors
make[1]: *** [arch/mips/pci/msi-xlp.o] Error 1
make: *** [arch/mips/pci/] Error 2
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Cc: Thomas Gleixner <tglx@linutronix.de>
---
arch/mips/pci/msi-xlp.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)
diff --git a/arch/mips/pci/msi-xlp.c b/arch/mips/pci/msi-xlp.c
index fa374fe..e469dc7 100644
--- a/arch/mips/pci/msi-xlp.c
+++ b/arch/mips/pci/msi-xlp.c
@@ -443,10 +443,8 @@ static int xlp_setup_msix(uint64_t lnkbase, int node, int link,
msg.data = 0xc00 | msixvec;
ret = irq_set_msi_desc(xirq, desc);
- if (ret < 0) {
- destroy_irq(xirq);
+ if (ret < 0)
return ret;
- }
write_msi_msg(xirq, &msg);
return 0;
--
1.7.1
^ permalink raw reply related
* [PATCH v2 11/22] x86/MSI: Remove unused MSI weak arch functions
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Now we can clean up MSI weak arch functions in x86.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
---
arch/x86/include/asm/pci.h | 3 ---
arch/x86/include/asm/x86_init.h | 4 ----
arch/x86/kernel/apic/io_apic.c | 2 +-
arch/x86/kernel/x86_init.c | 24 ------------------------
drivers/iommu/irq_remapping.c | 1 -
5 files changed, 1 insertions(+), 33 deletions(-)
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 878a06d..34f9676 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -96,14 +96,11 @@ extern void pci_iommu_alloc(void);
#ifdef CONFIG_PCI_MSI
/* implemented in arch/x86/kernel/apic/io_apic. */
struct msi_desc;
-int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
void native_teardown_msi_irq(unsigned int irq);
-void native_restore_msi_irqs(struct pci_dev *dev);
int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
unsigned int irq_base, unsigned int irq_offset);
extern struct msi_chip *x86_msi_chip;
#else
-#define native_setup_msi_irqs NULL
#define native_teardown_msi_irq NULL
#endif
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index f58a9c7..2514f67 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -174,13 +174,9 @@ struct pci_dev;
struct msi_msg;
struct x86_msi_ops {
- int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type);
void (*compose_msi_msg)(struct pci_dev *dev, unsigned int irq,
unsigned int dest, struct msi_msg *msg,
u8 hpet_id);
- void (*teardown_msi_irq)(unsigned int irq);
- void (*teardown_msi_irqs)(struct pci_dev *dev);
- void (*restore_msi_irqs)(struct pci_dev *dev);
int (*setup_hpet_msi)(unsigned int irq, unsigned int id);
};
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 882b95e..f998192 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3200,7 +3200,7 @@ int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
return 0;
}
-int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
struct msi_desc *msidesc;
unsigned int irq;
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 234b072..cc32568 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -110,34 +110,10 @@ EXPORT_SYMBOL_GPL(x86_platform);
#if defined(CONFIG_PCI_MSI)
struct x86_msi_ops x86_msi = {
- .setup_msi_irqs = native_setup_msi_irqs,
.compose_msi_msg = native_compose_msi_msg,
- .teardown_msi_irq = native_teardown_msi_irq,
- .teardown_msi_irqs = default_teardown_msi_irqs,
- .restore_msi_irqs = default_restore_msi_irqs,
.setup_hpet_msi = default_setup_hpet_msi,
};
-/* MSI arch specific hooks */
-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
-{
- return x86_msi.setup_msi_irqs(dev, nvec, type);
-}
-
-void arch_teardown_msi_irqs(struct pci_dev *dev)
-{
- x86_msi.teardown_msi_irqs(dev);
-}
-
-void arch_teardown_msi_irq(unsigned int irq)
-{
- x86_msi.teardown_msi_irq(irq);
-}
-
-void arch_restore_msi_irqs(struct pci_dev *dev)
-{
- x86_msi.restore_msi_irqs(dev);
-}
#endif
struct x86_io_apic_ops x86_io_apic_ops = {
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 7929590..99b1c0f 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -170,7 +170,6 @@ static void __init irq_remapping_modify_x86_ops(void)
x86_io_apic_ops.set_affinity = set_remapped_irq_affinity;
x86_io_apic_ops.setup_entry = setup_ioapic_remapped_entry;
x86_io_apic_ops.eoi_ioapic_pin = eoi_ioapic_pin_remapped;
- x86_msi.setup_msi_irqs = irq_remapping_setup_msi_irqs;
x86_msi.setup_hpet_msi = setup_hpet_msi_remapped;
x86_msi.compose_msi_msg = compose_remapped_msi_msg;
x86_msi_chip = &remap_msi_chip;
--
1.7.1
^ permalink raw reply related
* [PATCH v2 14/22] MIPS/Xlp/MSI: Use MSI chip framework to configure MSI/MSI-X irq
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
---
arch/mips/pci/msi-xlp.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/mips/pci/msi-xlp.c b/arch/mips/pci/msi-xlp.c
index e469dc7..6b791ef 100644
--- a/arch/mips/pci/msi-xlp.c
+++ b/arch/mips/pci/msi-xlp.c
@@ -245,7 +245,7 @@ static struct irq_chip xlp_msix_chip = {
.irq_unmask = unmask_msi_irq,
};
-void arch_teardown_msi_irq(unsigned int irq)
+void xlp_teardown_msi_irq(unsigned int irq)
{
}
@@ -450,7 +450,7 @@ static int xlp_setup_msix(uint64_t lnkbase, int node, int link,
return 0;
}
-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+static int xlp_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
struct pci_dev *lnkdev;
uint64_t lnkbase;
@@ -472,6 +472,16 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
return xlp_setup_msi(lnkbase, node, link, desc);
}
+static struct msi_chip xlp_chip = {
+ .setup_irq = xlp_setup_msi_irq,
+ .teardown_irq = xlp_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return &xlp_chip;
+}
+
void __init xlp_init_node_msi_irqs(int node, int link)
{
struct nlm_soc_info *nodep;
--
1.7.1
^ permalink raw reply related
* [PATCH v2 04/22] x86/xen/MSI: Eliminate arch_msix_mask_irq() and arch_msi_mask_irq()
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Commit 0e4ccb150 added two __weak arch functions arch_msix_mask_irq()
and arch_msi_mask_irq() to fix a bug found when running xen in x86.
Introduced these two funcntions make MSI code complex. And mask/unmask
is the irq actions related to interrupt controller, should not use
weak arch functions to override mask/unmask interfaces. This patch
reverted commit 0e4ccb150 and export struct irq_chip msi_chip, modify
msi_chip->irq_mask/irq_unmask() in xen init functions to fix this
bug for simplicity. Also this is preparation for using struct
msi_chip instead of weak arch MSI functions in all platforms.
Keep default_msi_mask_irq() and default_msix_mask_irq() in
linux/msi.h to make s390 MSI code compile happy, they wiil be removed
in the later patch.
Tested-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Acked-by: David Vrabel <david.vrabel@citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
CC: Konrad Rzeszutek Wilk <konrad.wilk@oracle.com>
---
arch/x86/include/asm/apic.h | 4 ++++
arch/x86/include/asm/x86_init.h | 3 ---
arch/x86/kernel/apic/io_apic.c | 2 +-
arch/x86/kernel/x86_init.c | 10 ----------
arch/x86/pci/xen.c | 16 ++++++----------
drivers/pci/msi.c | 22 ++++++----------------
include/linux/msi.h | 6 ++++--
7 files changed, 21 insertions(+), 42 deletions(-)
diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 465b309..47a5f94 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -43,6 +43,10 @@ static inline void generic_apic_probe(void)
}
#endif
+#ifdef CONFIG_PCI_MSI
+extern struct irq_chip msi_chip;
+#endif
+
#ifdef CONFIG_X86_LOCAL_APIC
extern unsigned int apic_verbosity;
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index e45e4da..f58a9c7 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -172,7 +172,6 @@ struct x86_platform_ops {
struct pci_dev;
struct msi_msg;
-struct msi_desc;
struct x86_msi_ops {
int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type);
@@ -183,8 +182,6 @@ struct x86_msi_ops {
void (*teardown_msi_irqs)(struct pci_dev *dev);
void (*restore_msi_irqs)(struct pci_dev *dev);
int (*setup_hpet_msi)(unsigned int irq, unsigned int id);
- u32 (*msi_mask_irq)(struct msi_desc *desc, u32 mask, u32 flag);
- u32 (*msix_mask_irq)(struct msi_desc *desc, u32 flag);
};
struct IO_APIC_route_entry;
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e877cfb..2a2ec28 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3161,7 +3161,7 @@ msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force)
* IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
* which implement the MSI or MSI-X Capability Structure.
*/
-static struct irq_chip msi_chip = {
+struct irq_chip msi_chip = {
.name = "PCI-MSI",
.irq_unmask = unmask_msi_irq,
.irq_mask = mask_msi_irq,
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index e48b674..234b072 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -116,8 +116,6 @@ struct x86_msi_ops x86_msi = {
.teardown_msi_irqs = default_teardown_msi_irqs,
.restore_msi_irqs = default_restore_msi_irqs,
.setup_hpet_msi = default_setup_hpet_msi,
- .msi_mask_irq = default_msi_mask_irq,
- .msix_mask_irq = default_msix_mask_irq,
};
/* MSI arch specific hooks */
@@ -140,14 +138,6 @@ void arch_restore_msi_irqs(struct pci_dev *dev)
{
x86_msi.restore_msi_irqs(dev);
}
-u32 arch_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
-{
- return x86_msi.msi_mask_irq(desc, mask, flag);
-}
-u32 arch_msix_mask_irq(struct msi_desc *desc, u32 flag)
-{
- return x86_msi.msix_mask_irq(desc, flag);
-}
#endif
struct x86_io_apic_ops x86_io_apic_ops = {
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index ad03739..84c2fce 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -394,13 +394,9 @@ static void xen_teardown_msi_irq(unsigned int irq)
{
xen_destroy_irq(irq);
}
-static u32 xen_nop_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
-{
- return 0;
-}
-static u32 xen_nop_msix_mask_irq(struct msi_desc *desc, u32 flag)
+
+void xen_nop_msi_mask(struct irq_data *data)
{
- return 0;
}
#endif
@@ -425,8 +421,8 @@ int __init pci_xen_init(void)
x86_msi.setup_msi_irqs = xen_setup_msi_irqs;
x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs;
- x86_msi.msi_mask_irq = xen_nop_msi_mask_irq;
- x86_msi.msix_mask_irq = xen_nop_msix_mask_irq;
+ msi_chip.irq_mask = xen_nop_msi_mask;
+ msi_chip.irq_unmask = xen_nop_msi_mask;
#endif
return 0;
}
@@ -506,8 +502,8 @@ int __init pci_xen_initial_domain(void)
x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs;
x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs;
- x86_msi.msi_mask_irq = xen_nop_msi_mask_irq;
- x86_msi.msix_mask_irq = xen_nop_msix_mask_irq;
+ msi_chip.irq_mask = xen_nop_msi_mask;
+ msi_chip.irq_unmask = xen_nop_msi_mask;
#endif
xen_setup_acpi_sci();
__acpi_register_gsi = acpi_register_gsi_xen;
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 50f67a3..5f8f3af 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -162,7 +162,7 @@ static inline __attribute_const__ u32 msi_mask(unsigned x)
* reliably as devices without an INTx disable bit will then generate a
* level IRQ which will never be cleared.
*/
-u32 default_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
+u32 __msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
{
u32 mask_bits = desc->masked;
@@ -176,14 +176,9 @@ u32 default_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
return mask_bits;
}
-__weak u32 arch_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
-{
- return default_msi_mask_irq(desc, mask, flag);
-}
-
static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
{
- desc->masked = arch_msi_mask_irq(desc, mask, flag);
+ desc->masked = __msi_mask_irq(desc, mask, flag);
}
/*
@@ -193,7 +188,7 @@ static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
* file. This saves a few milliseconds when initialising devices with lots
* of MSI-X interrupts.
*/
-u32 default_msix_mask_irq(struct msi_desc *desc, u32 flag)
+u32 __msix_mask_irq(struct msi_desc *desc, u32 flag)
{
u32 mask_bits = desc->masked;
unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
@@ -206,14 +201,9 @@ u32 default_msix_mask_irq(struct msi_desc *desc, u32 flag)
return mask_bits;
}
-__weak u32 arch_msix_mask_irq(struct msi_desc *desc, u32 flag)
-{
- return default_msix_mask_irq(desc, flag);
-}
-
static void msix_mask_irq(struct msi_desc *desc, u32 flag)
{
- desc->masked = arch_msix_mask_irq(desc, flag);
+ desc->masked = __msix_mask_irq(desc, flag);
}
static void msi_set_mask_bit(struct irq_data *data, u32 flag)
@@ -852,7 +842,7 @@ void pci_msi_shutdown(struct pci_dev *dev)
/* Return the device with MSI unmasked as initial states */
mask = msi_mask(desc->msi_attrib.multi_cap);
/* Keep cached state to be restored */
- arch_msi_mask_irq(desc, mask, ~mask);
+ __msi_mask_irq(desc, mask, ~mask);
/* Restore dev->irq to its default pin-assertion irq */
dev->irq = desc->msi_attrib.default_irq;
@@ -950,7 +940,7 @@ void pci_msix_shutdown(struct pci_dev *dev)
/* Return the device with MSI-X masked as initial states */
list_for_each_entry(entry, &dev->msi_list, list) {
/* Keep cached states to be restored */
- arch_msix_mask_irq(entry, 1);
+ __msix_mask_irq(entry, 1);
}
msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0);
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 45ef8cb..cc46a62 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -19,6 +19,8 @@ void read_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void write_msi_msg(unsigned int irq, struct msi_msg *msg);
+u32 __msix_mask_irq(struct msi_desc *desc, u32 flag);
+u32 __msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag);
struct msi_desc {
struct {
@@ -59,8 +61,8 @@ void arch_restore_msi_irqs(struct pci_dev *dev);
void default_teardown_msi_irqs(struct pci_dev *dev);
void default_restore_msi_irqs(struct pci_dev *dev);
-u32 default_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag);
-u32 default_msix_mask_irq(struct msi_desc *desc, u32 flag);
+#define default_msi_mask_irq __msi_mask_irq
+#define default_msix_mask_irq __msix_mask_irq
struct msi_chip {
struct module *owner;
--
1.7.1
^ permalink raw reply related
* [PATCH v2 03/22] MSI: Remove the redundant irq_set_chip_data()
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Currently, pcie-designware, pcie-rcar, pci-tegra drivers
use irq chip_data to save the msi_chip pointer. They
already call irq_set_chip_data() in their own MSI irq map
functions. So irq_set_chip_data() in arch_setup_msi_irq()
is useless.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
---
drivers/pci/msi.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 51d7e62..50f67a3 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -41,14 +41,13 @@ int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *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);
+ struct msi_desc *entry = irq_get_msi_desc(irq);
+ struct msi_chip *chip = entry->dev->bus->msi;
if (!chip || !chip->teardown_irq)
return;
--
1.7.1
^ permalink raw reply related
* [PATCH v2 16/22] Powerpc/MSI: Use MSI chip framework to configure MSI/MSI-X irq
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Acked-by: Michael Ellerman <mpe@ellerman.id.au>
---
arch/powerpc/kernel/msi.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c
index 71bd161..01781a4 100644
--- a/arch/powerpc/kernel/msi.c
+++ b/arch/powerpc/kernel/msi.c
@@ -13,7 +13,7 @@
#include <asm/machdep.h>
-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int ppc_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
if (!ppc_md.setup_msi_irqs || !ppc_md.teardown_msi_irqs) {
pr_debug("msi: Platform doesn't provide MSI callbacks.\n");
@@ -27,7 +27,17 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
return ppc_md.setup_msi_irqs(dev, nvec, type);
}
-void arch_teardown_msi_irqs(struct pci_dev *dev)
+static void ppc_teardown_msi_irqs(struct pci_dev *dev)
{
ppc_md.teardown_msi_irqs(dev);
}
+
+static struct msi_chip ppc_msi_chip = {
+ .setup_irqs = ppc_setup_msi_irqs,
+ .teardown_irqs = ppc_teardown_msi_irqs,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return &ppc_msi_chip;
+}
--
1.7.1
^ permalink raw reply related
* [PATCH v2 12/22] MIPS/Octeon/MSI: Use MSI chip framework to configure MSI/MSI-X irq
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
---
arch/mips/pci/msi-octeon.c | 35 ++++++++++++++++++++++-------------
1 files changed, 22 insertions(+), 13 deletions(-)
diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c
index 63bbe07..14f2d16 100644
--- a/arch/mips/pci/msi-octeon.c
+++ b/arch/mips/pci/msi-octeon.c
@@ -57,7 +57,7 @@ static int msi_irq_size;
*
* Returns 0 on success.
*/
-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+static int octeon_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
struct msi_msg msg;
u16 control;
@@ -132,12 +132,12 @@ msi_irq_allocated:
/* Make sure the search for available interrupts didn't fail */
if (irq >= 64) {
if (request_private_bits) {
- pr_err("arch_setup_msi_irq: Unable to find %d free interrupts, trying just one",
+ pr_err("octeon_setup_msi_irq: Unable to find %d free interrupts, trying just one",
1 << request_private_bits);
request_private_bits = 0;
goto try_only_one;
} else
- panic("arch_setup_msi_irq: Unable to find a free MSI interrupt");
+ panic("octeon_setup_msi_irq: Unable to find a free MSI interrupt");
}
/* MSI interrupts start at logical IRQ OCTEON_IRQ_MSI_BIT0 */
@@ -168,7 +168,7 @@ msi_irq_allocated:
msg.address_hi = (0 + CVMX_SLI_PCIE_MSI_RCV) >> 32;
break;
default:
- panic("arch_setup_msi_irq: Invalid octeon_dma_bar_type");
+ panic("octeon_setup_msi_irq: Invalid octeon_dma_bar_type");
}
msg.data = irq - OCTEON_IRQ_MSI_BIT0;
@@ -182,7 +182,7 @@ msi_irq_allocated:
return 0;
}
-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int octeon_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
struct msi_desc *entry;
int ret;
@@ -201,7 +201,7 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
return 1;
list_for_each_entry(entry, &dev->msi_list, list) {
- ret = arch_setup_msi_irq(dev, entry);
+ ret = octeon_setup_msi_irq(dev, entry);
if (ret < 0)
return ret;
if (ret > 0)
@@ -210,14 +210,13 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
return 0;
}
-
/**
* Called when a device no longer needs its MSI interrupts. All
* MSI interrupts for the device are freed.
*
* @irq: The devices first irq number. There may be multple in sequence.
*/
-void arch_teardown_msi_irq(unsigned int irq)
+static void octeon_teardown_msi_irq(unsigned int irq)
{
int number_irqs;
u64 bitmask;
@@ -226,8 +225,8 @@ void arch_teardown_msi_irq(unsigned int irq)
if ((irq < OCTEON_IRQ_MSI_BIT0)
|| (irq > msi_irq_size + OCTEON_IRQ_MSI_BIT0))
- panic("arch_teardown_msi_irq: Attempted to teardown illegal "
- "MSI interrupt (%d)", irq);
+ panic("octeon_teardown_msi_irq: Attempted to teardown illegal "
+ "MSI interrupt (%d)", irq);
irq -= OCTEON_IRQ_MSI_BIT0;
index = irq / 64;
@@ -240,7 +239,7 @@ void arch_teardown_msi_irq(unsigned int irq)
*/
number_irqs = 0;
while ((irq0 + number_irqs < 64) &&
- (msi_multiple_irq_bitmask[index]
+ (msi_multiple_irq_bitmask[index]
& (1ull << (irq0 + number_irqs))))
number_irqs++;
number_irqs++;
@@ -249,8 +248,8 @@ void arch_teardown_msi_irq(unsigned int irq)
/* Shift the mask to the correct bit location */
bitmask <<= irq0;
if ((msi_free_irq_bitmask[index] & bitmask) != bitmask)
- panic("arch_teardown_msi_irq: Attempted to teardown MSI "
- "interrupt (%d) not in use", irq);
+ panic("octeon_teardown_msi_irq: Attempted to teardown MSI "
+ "interrupt (%d) not in use", irq);
/* Checks are done, update the in use bitmask */
spin_lock(&msi_free_irq_bitmask_lock);
@@ -259,6 +258,16 @@ void arch_teardown_msi_irq(unsigned int irq)
spin_unlock(&msi_free_irq_bitmask_lock);
}
+static struct msi_chip octeon_msi_chip = {
+ .setup_irqs = octeon_setup_msi_irqs,
+ .teardown_irq = octeon_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return &octeon_msi_chip;
+}
+
static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock);
static u64 msi_rcv_reg[4];
--
1.7.1
^ permalink raw reply related
* [PATCH v2 18/22] arm/iop13xx/MSI: Use MSI chip framework to configure MSI/MSI-X irq
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
---
arch/arm/mach-iop13xx/include/mach/pci.h | 2 ++
arch/arm/mach-iop13xx/iq81340mc.c | 1 +
arch/arm/mach-iop13xx/iq81340sc.c | 1 +
arch/arm/mach-iop13xx/msi.c | 9 +++++++--
arch/arm/mach-iop13xx/pci.c | 6 ++++++
5 files changed, 17 insertions(+), 2 deletions(-)
diff --git a/arch/arm/mach-iop13xx/include/mach/pci.h b/arch/arm/mach-iop13xx/include/mach/pci.h
index 59f42b5..7a073cb 100644
--- a/arch/arm/mach-iop13xx/include/mach/pci.h
+++ b/arch/arm/mach-iop13xx/include/mach/pci.h
@@ -10,6 +10,8 @@ struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data *);
void iop13xx_atu_select(struct hw_pci *plat_pci);
void iop13xx_pci_init(void);
void iop13xx_map_pci_memory(void);
+void iop13xx_add_bus(struct pci_bus *bus);
+extern struct msi_chip iop13xx_msi_chip;
#define IOP_PCI_STATUS_ERROR (PCI_STATUS_PARITY | \
PCI_STATUS_SIG_TARGET_ABORT | \
diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c
index 9cd07d3..19d47cb 100644
--- a/arch/arm/mach-iop13xx/iq81340mc.c
+++ b/arch/arm/mach-iop13xx/iq81340mc.c
@@ -59,6 +59,7 @@ static struct hw_pci iq81340mc_pci __initdata = {
.map_irq = iq81340mc_pcix_map_irq,
.scan = iop13xx_scan_bus,
.preinit = iop13xx_pci_init,
+ .add_bus = iop13xx_add_bus;
};
static int __init iq81340mc_pci_init(void)
diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c
index b3ec11c..4d56993 100644
--- a/arch/arm/mach-iop13xx/iq81340sc.c
+++ b/arch/arm/mach-iop13xx/iq81340sc.c
@@ -61,6 +61,7 @@ static struct hw_pci iq81340sc_pci __initdata = {
.scan = iop13xx_scan_bus,
.map_irq = iq81340sc_atux_map_irq,
.preinit = iop13xx_pci_init
+ .add_bus = iop13xx_add_bus;
};
static int __init iq81340sc_pci_init(void)
diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c
index e7730cf..1a8cb2f 100644
--- a/arch/arm/mach-iop13xx/msi.c
+++ b/arch/arm/mach-iop13xx/msi.c
@@ -132,7 +132,7 @@ static struct irq_chip iop13xx_msi_chip = {
.irq_unmask = unmask_msi_irq,
};
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+static int iop13xx_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
int id, irq = irq_alloc_desc_from(IRQ_IOP13XX_MSI_0, -1);
struct msi_msg msg;
@@ -159,7 +159,12 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
return 0;
}
-void arch_teardown_msi_irq(unsigned int irq)
+static void iop13xx_teardown_msi_irq(unsigned int irq)
{
irq_free_desc(irq);
}
+
+struct msi_chip iop13xx_chip = {
+ .setup_irq = iop13xx_setup_msi_irq,
+ .teardown_irq = iop13xx_teardown_msi_irq,
+};
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
index 9082b84..f498800 100644
--- a/arch/arm/mach-iop13xx/pci.c
+++ b/arch/arm/mach-iop13xx/pci.c
@@ -962,6 +962,12 @@ void __init iop13xx_atu_select(struct hw_pci *plat_pci)
}
}
+void iop13xx_add_bus(struct pci_bus *bus)
+{
+ if (IS_ENABLED(CONFIG_PCI_MSI))
+ bus->msi = &iop13xx_msi_chip;
+}
+
void __init iop13xx_pci_init(void)
{
/* clear pre-existing south bridge errors */
--
1.7.1
^ permalink raw reply related
* [PATCH v2 15/22] MIPS/Xlr/MSI: Use MSI chip framework to configure MSI/MSI-X irq
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
---
arch/mips/pci/pci-xlr.c | 15 +++++++++++++--
1 files changed, 13 insertions(+), 2 deletions(-)
diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c
index 0dde803..7bd91cc 100644
--- a/arch/mips/pci/pci-xlr.c
+++ b/arch/mips/pci/pci-xlr.c
@@ -214,11 +214,11 @@ static int get_irq_vector(const struct pci_dev *dev)
}
#ifdef CONFIG_PCI_MSI
-void arch_teardown_msi_irq(unsigned int irq)
+void xlr_teardown_msi_irq(unsigned int irq)
{
}
-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+int xlr_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
struct msi_msg msg;
struct pci_dev *lnk;
@@ -263,6 +263,17 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
write_msi_msg(irq, &msg);
return 0;
}
+
+static struct msi_chip xlr_msi_chip = {
+ .setup_irq = xlr_setup_msi_irq,
+ .teardown_irq = xlr_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return &xlr_msi_chip;
+}
+
#endif
/* Extra ACK needed for XLR on chip PCI controller */
--
1.7.1
^ permalink raw reply related
* [PATCH v2 17/22] s390/MSI: Use MSI chip framework to configure MSI/MSI-X irq
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Acked-by: Sebastian Ott <sebott@linux.vnet.ibm.com>
---
arch/s390/pci/pci.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 552b990..da5316e 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -358,7 +358,7 @@ static void zpci_irq_handler(struct airq_struct *airq)
}
}
-int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+int zpci_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
{
struct zpci_dev *zdev = get_zdev(pdev);
unsigned int hwirq, msi_vecs;
@@ -434,7 +434,7 @@ out:
return rc;
}
-void arch_teardown_msi_irqs(struct pci_dev *pdev)
+static void zpci_teardown_msi_irqs(struct pci_dev *pdev)
{
struct zpci_dev *zdev = get_zdev(pdev);
struct msi_desc *msi;
@@ -464,6 +464,16 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
airq_iv_free_bit(zpci_aisb_iv, zdev->aisb);
}
+static struct msi_chip zpci_msi_chip = {
+ .setup_irqs = zpci_setup_msi_irqs,
+ .teardown_irqs = zpci_teardown_msi_irqs,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return &zpci_msi_chip;
+}
+
static void zpci_map_resources(struct zpci_dev *zdev)
{
struct pci_dev *pdev = zdev->pdev;
--
1.7.1
^ permalink raw reply related
* [PATCH v2 19/22] IA64/MSI: Use MSI chip framework to configure MSI/MSI-X irq
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
---
arch/ia64/kernel/msi_ia64.c | 18 ++++++++++++++----
1 files changed, 14 insertions(+), 4 deletions(-)
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index 4efe748..55ac859 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -112,15 +112,15 @@ static struct irq_chip ia64_msi_chip = {
};
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+static int arch_ia64_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
if (platform_setup_msi_irq)
- return platform_setup_msi_irq(pdev, desc);
+ return platform_setup_msi_irq(dev, desc);
- return ia64_setup_msi_irq(pdev, desc);
+ return ia64_setup_msi_irq(dev, desc);
}
-void arch_teardown_msi_irq(unsigned int irq)
+static void arch_ia64_teardown_msi_irq(unsigned int irq)
{
if (platform_teardown_msi_irq)
return platform_teardown_msi_irq(irq);
@@ -128,6 +128,16 @@ void arch_teardown_msi_irq(unsigned int irq)
return ia64_teardown_msi_irq(irq);
}
+static struct msi_chip chip = {
+ .setup_irq = arch_ia64_setup_msi_irq,
+ .teardown_irq = arch_ia64_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return &chip;
+}
+
#ifdef CONFIG_INTEL_IOMMU
#ifdef CONFIG_SMP
static int dmar_msi_set_affinity(struct irq_data *data,
--
1.7.1
^ permalink raw reply related
* [PATCH v2 20/22] Sparc/MSI: Use MSI chip framework to configure MSI/MSI-X irq
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
---
arch/sparc/kernel/pci.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index b36365f..2a89ee2 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -905,7 +905,7 @@ int pci_domain_nr(struct pci_bus *pbus)
EXPORT_SYMBOL(pci_domain_nr);
#ifdef CONFIG_PCI_MSI
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+int sparc_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
{
struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;
unsigned int irq;
@@ -916,7 +916,7 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
return pbm->setup_msi_irq(&irq, pdev, desc);
}
-void arch_teardown_msi_irq(unsigned int irq)
+void sparc_teardown_msi_irq(unsigned int irq)
{
struct msi_desc *entry = irq_get_msi_desc(irq);
struct pci_dev *pdev = entry->dev;
@@ -925,6 +925,16 @@ void arch_teardown_msi_irq(unsigned int irq)
if (pbm->teardown_msi_irq)
pbm->teardown_msi_irq(irq, pdev);
}
+
+static struct msi_chip sparc_msi_chip = {
+ .setup_irq = sparc_setup_msi_irq,
+ .teardown_irq = sparc_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return &sparc_msi_chip;
+}
#endif /* !(CONFIG_PCI_MSI) */
static void ali_sound_dma_hack(struct pci_dev *pdev, int set_bit)
--
1.7.1
^ permalink raw reply related
* [PATCH v2 22/22] PCI/MSI: Clean up unused MSI arch functions
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Now we use struct msi_chip in all platforms to configure
MSI/MSI-X. We can clean up the unused arch functions.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
Reviewed-by: Lucas Stach <l.stach@pengutronix.de>
---
drivers/iommu/irq_remapping.c | 2 +-
drivers/pci/msi.c | 100 +++++++++++++++-------------------------
include/linux/msi.h | 14 ------
3 files changed, 39 insertions(+), 77 deletions(-)
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 99b1c0f..6e645f0 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -92,7 +92,7 @@ error:
/*
* Restore altered MSI descriptor fields and prevent just destroyed
- * IRQs from tearing down again in default_teardown_msi_irqs()
+ * IRQs from tearing down again in teardown_msi_irqs()
*/
msidesc->irq = 0;
msidesc->nvec_used = 0;
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index d10edee..9fe427f 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -34,51 +34,31 @@ struct msi_chip * __weak arch_find_msi_chip(struct pci_dev *dev)
return dev->bus->msi;
}
-int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
-{
- struct msi_chip *chip = arch_find_msi_chip(dev);
- int err;
-
- if (!chip || !chip->setup_irq)
- return -EINVAL;
-
- err = chip->setup_irq(dev, desc);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-void __weak arch_teardown_msi_irq(unsigned int irq)
-{
- struct msi_desc *entry = irq_get_msi_desc(irq);
- struct msi_chip *chip = entry->dev->bus->msi;
-
- if (!chip || !chip->teardown_irq)
- return;
-
- chip->teardown_irq(irq);
-}
-
-int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+int setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
struct msi_desc *entry;
int ret;
struct msi_chip *chip;
chip = arch_find_msi_chip(dev);
- if (chip && chip->setup_irqs)
+ if (!chip)
+ return -EINVAL;
+
+ if (chip->setup_irqs)
return chip->setup_irqs(dev, nvec, type);
/*
* If an architecture wants to support multiple MSI, it needs to
- * override arch_setup_msi_irqs()
+ * implement chip->setup_irqs().
*/
if (type == PCI_CAP_ID_MSI && nvec > 1)
return 1;
+ if (!chip->setup_irq)
+ return -EINVAL;
+
list_for_each_entry(entry, &dev->msi_list, list) {
- ret = arch_setup_msi_irq(dev, entry);
+ ret = chip->setup_irq(dev, entry);
if (ret < 0)
return ret;
if (ret > 0)
@@ -88,13 +68,20 @@ int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
return 0;
}
-/*
- * 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)
+static void teardown_msi_irqs(struct pci_dev *dev)
{
struct msi_desc *entry;
+ struct msi_chip *chip;
+
+ chip = arch_find_msi_chip(dev);
+ if (!chip)
+ return;
+
+ if (chip->teardown_irqs)
+ return chip->teardown_irqs(dev);
+
+ if (!chip->teardown_irq)
+ return;
list_for_each_entry(entry, &dev->msi_list, list) {
int i, nvec;
@@ -105,20 +92,10 @@ void default_teardown_msi_irqs(struct pci_dev *dev)
else
nvec = 1 << entry->msi_attrib.multiple;
for (i = 0; i < nvec; i++)
- arch_teardown_msi_irq(entry->irq + i);
+ chip->teardown_irq(entry->irq + i);
}
}
-void __weak arch_teardown_msi_irqs(struct pci_dev *dev)
-{
- struct msi_chip *chip = arch_find_msi_chip(dev);
-
- if (chip && chip->teardown_irqs)
- return chip->teardown_irqs(dev);
-
- return default_teardown_msi_irqs(dev);
-}
-
static void default_restore_msi_irq(struct pci_dev *dev, int irq)
{
struct msi_desc *entry;
@@ -137,10 +114,18 @@ static void default_restore_msi_irq(struct pci_dev *dev, int irq)
write_msi_msg(irq, &entry->msg);
}
-void __weak arch_restore_msi_irqs(struct pci_dev *dev)
+static void default_restore_msi_irqs(struct pci_dev *dev)
{
- struct msi_chip *chip = arch_find_msi_chip(dev);
+ struct msi_desc *entry = NULL;
+
+ list_for_each_entry(entry, &dev->msi_list, list) {
+ default_restore_msi_irq(dev, entry->irq);
+ }
+}
+static void restore_msi_irqs(struct pci_dev *dev)
+{
+ struct msi_chip *chip = arch_find_msi_chip(dev);
if (chip && chip->restore_irqs)
return chip->restore_irqs(dev);
@@ -249,15 +234,6 @@ void unmask_msi_irq(struct irq_data *data)
msi_set_mask_bit(data, 0);
}
-void default_restore_msi_irqs(struct pci_dev *dev)
-{
- struct msi_desc *entry;
-
- list_for_each_entry(entry, &dev->msi_list, list) {
- default_restore_msi_irq(dev, entry->irq);
- }
-}
-
void read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
{
BUG_ON(entry->dev->current_state != PCI_D0);
@@ -361,7 +337,7 @@ static void free_msi_irqs(struct pci_dev *dev)
BUG_ON(irq_has_action(entry->irq + i));
}
- arch_teardown_msi_irqs(dev);
+ teardown_msi_irqs(dev);
list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
if (entry->msi_attrib.is_msix) {
@@ -420,7 +396,7 @@ static void __pci_restore_msi_state(struct pci_dev *dev)
pci_intx_for_msi(dev, 0);
msi_set_enable(dev, 0);
- arch_restore_msi_irqs(dev);
+ restore_msi_irqs(dev);
pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control);
msi_mask_irq(entry, msi_mask(entry->msi_attrib.multi_cap),
@@ -443,7 +419,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
msix_clear_and_set_ctrl(dev, 0,
PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL);
- arch_restore_msi_irqs(dev);
+ restore_msi_irqs(dev);
list_for_each_entry(entry, &dev->msi_list, list) {
msix_mask_irq(entry, entry->masked);
}
@@ -613,7 +589,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
list_add_tail(&entry->list, &dev->msi_list);
/* Configure MSI capability structure */
- ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI);
+ ret = setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI);
if (ret) {
msi_mask_irq(entry, mask, ~mask);
free_msi_irqs(dev);
@@ -728,7 +704,7 @@ static int msix_capability_init(struct pci_dev *dev,
if (ret)
return ret;
- ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX);
+ ret = setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX);
if (ret)
goto out_avail;
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 4cf1f31..920ad52 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -48,20 +48,6 @@ struct msi_desc {
struct msi_msg msg;
};
-/*
- * The arch hooks to setup up msi irqs. Those functions are
- * implemented as weak symbols so that they /can/ be overriden by
- * architecture specific code if needed.
- */
-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc);
-void arch_teardown_msi_irq(unsigned int irq);
-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
-void arch_teardown_msi_irqs(struct pci_dev *dev);
-void arch_restore_msi_irqs(struct pci_dev *dev);
-
-void default_teardown_msi_irqs(struct pci_dev *dev);
-void default_restore_msi_irqs(struct pci_dev *dev);
-
struct msi_chip {
struct module *owner;
struct device *dev;
--
1.7.1
^ permalink raw reply related
* [PATCH v2 21/22] tile/MSI: Use MSI chip framework to configure MSI/MSI-X irq
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
---
arch/tile/kernel/pci_gx.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c
index e39f9c5..4912b75 100644
--- a/arch/tile/kernel/pci_gx.c
+++ b/arch/tile/kernel/pci_gx.c
@@ -1485,7 +1485,7 @@ static struct irq_chip tilegx_msi_chip = {
/* TBD: support set_affinity. */
};
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+static int tile_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
{
struct pci_controller *controller;
gxio_trio_context_t *trio_context;
@@ -1604,7 +1604,17 @@ is_64_failure:
return ret;
}
-void arch_teardown_msi_irq(unsigned int irq)
+void tile_teardown_msi_irq(unsigned int irq)
{
irq_free_hwirq(irq);
}
+
+static struct msi_chip tile_msi_chip = {
+ .setup_irq = tile_setup_msi_irq,
+ .teardown_irq = tile_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return &tile_msi_chip;
+}
--
1.7.1
^ permalink raw reply related
* [PATCH v2 08/22] x86/MSI: Use MSI chip framework to configure MSI/MSI-X irq
From: Yijing Wang @ 2014-09-25 3:14 UTC (permalink / raw)
To: Bjorn Helgaas
Cc: linux-mips, linux-ia64, linux-pci, Bharat.Bhushan, Yijing Wang,
Thierry Reding, sparclinux, linux-arch, linux-s390, Russell King,
Joerg Roedel, x86, Sebastian Ott, xen-devel, arnab.basu,
Arnd Bergmann, Konrad Rzeszutek Wilk, Chris Metcalf,
Thomas Gleixner, linux-arm-kernel, Thomas Petazzoni, Xinwei Hu,
Tony Luck, Sergei Shtylyov, linux-kernel, Ralf Baechle, iommu,
David Vrabel, Wuyun, linuxppc-dev, David S. Miller, Lucas Stach
In-Reply-To: <1411614872-4009-1-git-send-email-wangyijing@huawei.com>
Use MSI chip framework instead of arch MSI functions to configure
MSI/MSI-X irq. So we can manage MSI/MSI-X irq in a unified framework.
Signed-off-by: Yijing Wang <wangyijing@huawei.com>
---
arch/x86/include/asm/pci.h | 1 +
arch/x86/kernel/apic/io_apic.c | 12 ++++++++++++
2 files changed, 13 insertions(+), 0 deletions(-)
diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 0892ea0..878a06d 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -101,6 +101,7 @@ void native_teardown_msi_irq(unsigned int irq);
void native_restore_msi_irqs(struct pci_dev *dev);
int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
unsigned int irq_base, unsigned int irq_offset);
+extern struct msi_chip *x86_msi_chip;
#else
#define native_setup_msi_irqs NULL
#define native_teardown_msi_irq NULL
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 2a2ec28..882b95e 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3337,6 +3337,18 @@ int default_setup_hpet_msi(unsigned int irq, unsigned int id)
}
#endif
+struct msi_chip apic_msi_chip = {
+ .setup_irqs = native_setup_msi_irqs,
+ .teardown_irq = native_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return x86_msi_chip;
+}
+
+struct msi_chip *x86_msi_chip = &apic_msi_chip;
+
#endif /* CONFIG_PCI_MSI */
/*
* Hypertransport interrupt support
--
1.7.1
^ permalink raw reply related
* Re: [2/5] powerpc/eeh: Add eeh_pe_state sysfs entry
From: Michael Ellerman @ 2014-09-25 4:09 UTC (permalink / raw)
To: Gavin Shan, linuxppc-dev; +Cc: Gavin Shan
In-Reply-To: <1408244549-10221-3-git-send-email-gwshan@linux.vnet.ibm.com>
On Sun, 2014-17-08 at 03:02:26 UTC, Gavin Shan wrote:
> The patch adds sysfs entry "eeh_pe_state". Reading on it returns
> the PE's state while writing to it clears the frozen state. It's
> used to check or clear the PE frozen state from userland for
> debugging purpose.
>
> diff --git a/arch/powerpc/kernel/eeh_sysfs.c b/arch/powerpc/kernel/eeh_sysfs.c
> index e2595ba..e69bcbb 100644
> --- a/arch/powerpc/kernel/eeh_sysfs.c
> +++ b/arch/powerpc/kernel/eeh_sysfs.c
> @@ -54,6 +54,63 @@ EEH_SHOW_ATTR(eeh_mode, mode, "0x%x");
> EEH_SHOW_ATTR(eeh_config_addr, config_addr, "0x%x");
> EEH_SHOW_ATTR(eeh_pe_config_addr, pe_config_addr, "0x%x");
>
> +static ssize_t eeh_pe_state_show(struct device *dev,
> + struct device_attribute *attr, char *buf)
> +{
> + struct pci_dev *pdev = to_pci_dev(dev);
> + struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev);
> + int state;
> +
> + if (!edev || !edev->pe)
> + return 0;
> +
> + state = eeh_ops->get_state(edev->pe, NULL);
> + return sprintf(buf, "PHB#%d-PE#%d: 0x%08x 0x%08x\n",
> + edev->pe->phb->global_number,
> + edev->pe->addr, state, edev->pe->state);
Shouldn't this only display the state, ie not the number and addr etc.
And why are there two states, state and edev->pe->state ?
> +static ssize_t eeh_pe_state_store(struct device *dev,
> + struct device_attribute *attr,
> + const char *buf, size_t count)
> +{
> + struct pci_dev *pdev = to_pci_dev(dev);
> + struct eeh_dev *edev = pci_dev_to_eeh_dev(pdev);
> + int ret;
> +
> + if (!edev || !edev->pe)
> + return 0;
Shouldn't that be an error?
> + /* Nothing to do if it's not frozen */
> + if (!(edev->pe->state & EEH_PE_ISOLATED))
> + return 0;
> +
> + /* Enable MMIO */
> + ret = eeh_pci_enable(edev->pe, EEH_OPT_THAW_MMIO);
> + if (ret) {
> + pr_warn("%s: Failure %d enabling MMIO for PHB#%d-PE#%d\n",
> + __func__, ret, edev->pe->phb->global_number,
> + edev->pe->addr);
> + return 0;
Error ?
> + }
> +
> + /* Enable DMA */
> + ret = eeh_pci_enable(edev->pe, EEH_OPT_THAW_DMA);
> + if (ret) {
> + pr_warn("%s: Failure %d enabling DMA for PHB#%d-PE#%d\n",
> + __func__, ret, edev->pe->phb->global_number,
> + edev->pe->addr);
> + return 0;
Error?
And should it roll back, ie. unthaw MMIO?
cheers
^ permalink raw reply
* [PATCH 1/3] powerpc/eeh: Dump PCI config space for all child devices
From: Gavin Shan @ 2014-09-25 4:13 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Gavin Shan
The PEs can be organized as nested. Current implementation doesn't
dump PCI config space for subordinate devices of child PEs. However,
the frozen PE could be caused by those subordinate devices of its
child PEs.
The patch dumps PCI config space for all subordinate devices of the
problematic PE.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
arch/powerpc/kernel/eeh.c | 35 ++++++++++++++++++++---------------
1 file changed, 20 insertions(+), 15 deletions(-)
diff --git a/arch/powerpc/kernel/eeh.c b/arch/powerpc/kernel/eeh.c
index 6c88d781..03d75cb 100644
--- a/arch/powerpc/kernel/eeh.c
+++ b/arch/powerpc/kernel/eeh.c
@@ -117,7 +117,7 @@ static DEFINE_MUTEX(eeh_dev_mutex);
* not dynamically alloced, so that it ends up in RMO where RTAS
* can access it.
*/
-#define EEH_PCI_REGS_LOG_LEN 4096
+#define EEH_PCI_REGS_LOG_LEN 8192
static unsigned char pci_regs_buf[EEH_PCI_REGS_LOG_LEN];
/*
@@ -148,16 +148,12 @@ static int __init eeh_setup(char *str)
}
__setup("eeh=", eeh_setup);
-/**
- * eeh_gather_pci_data - Copy assorted PCI config space registers to buff
- * @edev: device to report data for
- * @buf: point to buffer in which to log
- * @len: amount of room in buffer
- *
- * This routine captures assorted PCI configuration space data,
- * and puts them into a buffer for RTAS error logging.
+/*
+ * This routine captures assorted PCI configuration space data
+ * for the indicated PCI device, and puts them into a buffer
+ * for RTAS error logging.
*/
-static size_t eeh_gather_pci_data(struct eeh_dev *edev, char *buf, size_t len)
+static size_t eeh_dump_dev_log(struct eeh_dev *edev, char *buf, size_t len)
{
struct device_node *dn = eeh_dev_to_of_node(edev);
u32 cfg;
@@ -255,6 +251,19 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char *buf, size_t len)
return n;
}
+static void *eeh_dump_pe_log(void *data, void *flag)
+{
+ struct eeh_pe *pe = data;
+ struct eeh_dev *edev, *tmp;
+ size_t *plen = flag;
+
+ eeh_pe_for_each_dev(pe, edev, tmp)
+ *plen += eeh_dump_dev_log(edev, pci_regs_buf + *plen,
+ EEH_PCI_REGS_LOG_LEN - *plen);
+
+ return NULL;
+}
+
/**
* eeh_slot_error_detail - Generate combined log including driver log and error log
* @pe: EEH PE
@@ -268,7 +277,6 @@ static size_t eeh_gather_pci_data(struct eeh_dev *edev, char *buf, size_t len)
void eeh_slot_error_detail(struct eeh_pe *pe, int severity)
{
size_t loglen = 0;
- struct eeh_dev *edev, *tmp;
/*
* When the PHB is fenced or dead, it's pointless to collect
@@ -286,10 +294,7 @@ void eeh_slot_error_detail(struct eeh_pe *pe, int severity)
eeh_pe_restore_bars(pe);
pci_regs_buf[0] = 0;
- eeh_pe_for_each_dev(pe, edev, tmp) {
- loglen += eeh_gather_pci_data(edev, pci_regs_buf + loglen,
- EEH_PCI_REGS_LOG_LEN - loglen);
- }
+ eeh_pe_traverse(pe, eeh_dump_pe_log, &loglen);
}
eeh_ops->get_log(pe, severity, pci_regs_buf, loglen);
--
1.8.3.2
^ permalink raw reply related
* [PATCH 2/3] powerpc/powernv: Fetch frozen PE on top level
From: Gavin Shan @ 2014-09-25 4:13 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Gavin Shan
In-Reply-To: <1411618387-7920-1-git-send-email-gwshan@linux.vnet.ibm.com>
It should have been part of commit 1ad7a72c5 ("powerpc/eeh: Report
frozen parent PE prior to child PE"). There are 2 ways to report
EEH errors: proactively polling triggered by PCI config or IO
accesses, or interrupt driven event. We missed to report and handle
parent frozen PE prior to child frozen PE for the later case on
PowerNV platform.
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
arch/powerpc/platforms/powernv/eeh-ioda.c | 48 ++++++++++++++++++++++---------
1 file changed, 34 insertions(+), 14 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/eeh-ioda.c b/arch/powerpc/platforms/powernv/eeh-ioda.c
index f248586..57de63c 100644
--- a/arch/powerpc/platforms/powernv/eeh-ioda.c
+++ b/arch/powerpc/platforms/powernv/eeh-ioda.c
@@ -880,14 +880,12 @@ static int ioda_eeh_get_pe(struct pci_controller *hose,
* the master PE because slave PE is invisible
* to EEH core.
*/
- if (phb->get_pe_state) {
- pnv_pe = &phb->ioda.pe_array[pe_no];
- if (pnv_pe->flags & PNV_IODA_PE_SLAVE) {
- pnv_pe = pnv_pe->master;
- WARN_ON(!pnv_pe ||
- !(pnv_pe->flags & PNV_IODA_PE_MASTER));
- pe_no = pnv_pe->pe_number;
- }
+ pnv_pe = &phb->ioda.pe_array[pe_no];
+ if (pnv_pe->flags & PNV_IODA_PE_SLAVE) {
+ pnv_pe = pnv_pe->master;
+ WARN_ON(!pnv_pe ||
+ !(pnv_pe->flags & PNV_IODA_PE_MASTER));
+ pe_no = pnv_pe->pe_number;
}
/* Find the PE according to PE# */
@@ -898,15 +896,37 @@ static int ioda_eeh_get_pe(struct pci_controller *hose,
if (!dev_pe)
return -EEXIST;
- /*
- * At this point, we're sure the compound PE should
- * be put into frozen state.
- */
+ /* Freeze the (compound) PE */
*pe = dev_pe;
- if (phb->freeze_pe &&
- !(dev_pe->state & EEH_PE_ISOLATED))
+ if (!(dev_pe->state & EEH_PE_ISOLATED))
phb->freeze_pe(phb, pe_no);
+ /*
+ * At this point, we're sure the (compound) PE should
+ * have been frozen. However, we still need poke until
+ * hitting the frozen PE on top level.
+ */
+ dev_pe = dev_pe->parent;
+ while (dev_pe && !(dev_pe->type & EEH_PE_PHB)) {
+ int ret;
+ int active_flags = (EEH_STATE_MMIO_ACTIVE |
+ EEH_STATE_DMA_ACTIVE);
+
+ ret = eeh_ops->get_state(dev_pe, NULL);
+ if (ret <= 0 || (ret & active_flags) == active_flags) {
+ dev_pe = dev_pe->parent;
+ continue;
+ }
+
+ /* Frozen parent PE */
+ *pe = dev_pe;
+ if (!(dev_pe->state & EEH_PE_ISOLATED))
+ phb->freeze_pe(phb, dev_pe->addr);
+
+ /* Next one */
+ dev_pe = dev_pe->parent;
+ }
+
return 0;
}
--
1.8.3.2
^ permalink raw reply related
* [RFC PATCH] powerpc/powernv: Fix dma_ops for bypass window
From: Gavin Shan @ 2014-09-25 4:14 UTC (permalink / raw)
To: linuxppc-dev; +Cc: Gavin Shan
When using bypass window on IODA2, the incorrect DMA operations
"dma_iommu_ops" is used by devices. The device driver calls
dma_get_required_mask() to determine using 32-bits or bypass DMA
window. Unfortunately, the returned DMA mask always forces the
driver to use 32-bits DMA window. The problem was reported on
the device as follows:
0004:03:00.0 0107: 1000:0087 (rev 05)
0004:03:00.0 Serial Attached SCSI controller: LSI Logic / Symbios \
Logic SAS2308 PCI-Express Fusion-MPT SAS-2 (rev 05)
The patch fixes above issue by keeping things consistent: when
enabling bypass window, we switch to "dma_direct_ops". Instead,
switch to "pci_dma_ops" when disabling bypass window.
Reported-by: Murali N. Iyer <mniyer@us.ibm.com>
Signed-off-by: Gavin Shan <gwshan@linux.vnet.ibm.com>
---
arch/powerpc/platforms/powernv/pci-ioda.c | 76 +++++++++++++++++++------------
1 file changed, 46 insertions(+), 30 deletions(-)
diff --git a/arch/powerpc/platforms/powernv/pci-ioda.c b/arch/powerpc/platforms/powernv/pci-ioda.c
index 36b1a7a..60e44d9 100644
--- a/arch/powerpc/platforms/powernv/pci-ioda.c
+++ b/arch/powerpc/platforms/powernv/pci-ioda.c
@@ -883,13 +883,29 @@ static int pnv_pci_ioda_dma_set_mask(struct pnv_phb *phb,
set_dma_offset(&pdev->dev, pe->tce_bypass_base);
} else {
dev_info(&pdev->dev, "Using 32-bit DMA via iommu\n");
- set_dma_ops(&pdev->dev, &dma_iommu_ops);
+ set_dma_ops(&pdev->dev, get_pci_dma_ops());
set_iommu_table_base(&pdev->dev, &pe->tce32_table);
}
*pdev->dev.dma_mask = dma_mask;
return 0;
}
+static void pnv_ioda_setup_dev_dma(struct pnv_ioda_pe *pe,
+ struct pci_dev *pdev,
+ bool add_to_iommu_group)
+{
+ if (pe->tce_bypass_enabled) {
+ set_dma_ops(&pdev->dev, &dma_direct_ops);
+ set_dma_offset(&pdev->dev, pe->tce_bypass_base);
+ } else {
+ set_dma_ops(&pdev->dev, get_pci_dma_ops());
+ set_iommu_table_base(&pdev->dev, &pe->tce32_table);
+ }
+
+ if (add_to_iommu_group)
+ iommu_add_device(&pdev->dev);
+}
+
static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe,
struct pci_bus *bus,
bool add_to_iommu_group)
@@ -897,11 +913,7 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe,
struct pci_dev *dev;
list_for_each_entry(dev, &bus->devices, bus_list) {
- if (add_to_iommu_group)
- set_iommu_table_base_and_group(&dev->dev,
- &pe->tce32_table);
- else
- set_iommu_table_base(&dev->dev, &pe->tce32_table);
+ pnv_ioda_setup_dev_dma(pe, dev, add_to_iommu_group);
if (dev->subordinate)
pnv_ioda_setup_bus_dma(pe, dev->subordinate,
@@ -909,6 +921,15 @@ static void pnv_ioda_setup_bus_dma(struct pnv_ioda_pe *pe,
}
}
+static void pnv_ioda_setup_pe_dma(struct pnv_ioda_pe *pe,
+ bool add_to_iommu_group)
+{
+ if (pe->pdev)
+ pnv_ioda_setup_dev_dma(pe, pe->pdev, add_to_iommu_group);
+ else
+ pnv_ioda_setup_bus_dma(pe, pe->pbus, add_to_iommu_group);
+}
+
static void pnv_pci_ioda1_tce_invalidate(struct pnv_ioda_pe *pe,
struct iommu_table *tbl,
__be64 *startp, __be64 *endp, bool rm)
@@ -1080,11 +1101,7 @@ static void pnv_pci_ioda_setup_dma_pe(struct pnv_phb *phb,
iommu_init_table(tbl, phb->hose->node);
iommu_register_group(tbl, phb->hose->global_number, pe->pe_number);
- if (pe->pdev)
- set_iommu_table_base_and_group(&pe->pdev->dev, tbl);
- else
- pnv_ioda_setup_bus_dma(pe, pe->pbus, true);
-
+ pnv_ioda_setup_pe_dma(pe, true);
return;
fail:
/* XXX Failure: Try to fallback to 64-bit only ? */
@@ -1101,7 +1118,13 @@ static void pnv_pci_ioda2_set_bypass(struct iommu_table *tbl, bool enable)
uint16_t window_id = (pe->pe_number << 1 ) + 1;
int64_t rc;
+ /* Check if we really need do something */
+ if (pe->tce_bypass_enabled == enable)
+ return;
+
pe_info(pe, "%sabling 64-bit DMA bypass\n", enable ? "En" : "Dis");
+ pe->tce_bypass_enabled = enable;
+
if (enable) {
phys_addr_t top = memblock_end_of_DRAM();
@@ -1117,22 +1140,15 @@ static void pnv_pci_ioda2_set_bypass(struct iommu_table *tbl, bool enable)
window_id,
pe->tce_bypass_base,
0);
-
- /*
- * EEH needs the mapping between IOMMU table and group
- * of those VFIO/KVM pass-through devices. We can postpone
- * resetting DMA ops until the DMA mask is configured in
- * host side.
- */
- if (pe->pdev)
- set_iommu_table_base(&pe->pdev->dev, tbl);
- else
- pnv_ioda_setup_bus_dma(pe, pe->pbus, false);
}
- if (rc)
+ if (rc != OPAL_SUCCESS) {
pe_err(pe, "OPAL error %lld configuring bypass window\n", rc);
- else
- pe->tce_bypass_enabled = enable;
+ return;
+ }
+
+ /* Update base and operations */
+ pe->tce_bypass_enabled = enable;
+ pnv_ioda_setup_pe_dma(pe, false);
}
static void pnv_pci_ioda2_setup_bypass_pe(struct pnv_phb *phb,
@@ -1213,12 +1229,12 @@ static void pnv_pci_ioda2_setup_dma_pe(struct pnv_phb *phb,
iommu_init_table(tbl, phb->hose->node);
iommu_register_group(tbl, phb->hose->global_number, pe->pe_number);
- if (pe->pdev)
- set_iommu_table_base_and_group(&pe->pdev->dev, tbl);
- else
- pnv_ioda_setup_bus_dma(pe, pe->pbus, true);
+ /* If the bypass window fails to be created, we still
+ * can use 32-bits window.
+ */
+ pnv_ioda_setup_pe_dma(pe, true);
- /* Also create a bypass window */
+ /* Create bypass window */
pnv_pci_ioda2_setup_bypass_pe(phb, pe);
return;
fail:
--
1.8.3.2
^ permalink raw reply related
* Re: [1/4] powerpc/powernv: Sync header with firmware
From: Michael Ellerman @ 2014-09-25 4:27 UTC (permalink / raw)
To: Gavin Shan, linuxppc-dev; +Cc: qiudayu, Gavin Shan
In-Reply-To: <1409039779-392-2-git-send-email-gwshan@linux.vnet.ibm.com>
On Tue, 2014-26-08 at 07:56:16 UTC, Gavin Shan wrote:
> From: Mike Qiu <qiudayu@linux.vnet.ibm.com>
>
> The patch synchronizes firmware header file (opal.h) for PCI error
> injection.
>
> diff --git a/arch/powerpc/include/asm/opal.h b/arch/powerpc/include/asm/opal.h
> index 4593a93..9113653 100644
> --- a/arch/powerpc/include/asm/opal.h
> +++ b/arch/powerpc/include/asm/opal.h
> @@ -200,6 +201,33 @@ enum OpalPciErrorSeverity {
> OPAL_EEH_SEV_INF = 5
> };
>
> +enum OpalErrinjctType {
> + OpalErrinjctTypeIoaBusError = 0,
> + OpalErrinjctTypeIoaBusError64 = 1,
> +
> + /* IoaBusError & IoaBusError64 */
> + OpalEjtIoaLoadMemAddr = 0,
> + OpalEjtIoaLoadMemData = 1,
> + OpalEjtIoaLoadIoAddr = 2,
> + OpalEjtIoaLoadIoData = 3,
> + OpalEjtIoaLoadConfigAddr = 4,
> + OpalEjtIoaLoadConfigData = 5,
> + OpalEjtIoaStoreMemAddr = 6,
> + OpalEjtIoaStoreMemData = 7,
> + OpalEjtIoaStoreIoAddr = 8,
> + OpalEjtIoaStoreIoData = 9,
> + OpalEjtIoaStoreConfigAddr = 10,
> + OpalEjtIoaStoreConfigData = 11,
> + OpalEjtIoaDmaReadMemAddr = 12,
> + OpalEjtIoaDmaReadMemData = 13,
> + OpalEjtIoaDmaReadMemMaster = 14,
> + OpalEjtIoaDmaReadMemTarget = 15,
> + OpalEjtIoaDmaWriteMemAddr = 16,
> + OpalEjtIoaDmaWriteMemData = 17,
> + OpalEjtIoaDmaWriteMemMaster = 18,
> + OpalEjtIoaDmaWriteMemTarget = 19,
> +};
I realise these come from the skiboot source, but they're just too ugly.
Please use kernel style naming, like most of the rest of the file, eg:
OPAL_ERR_INJECT_IOA_BUS_ERR
Also this enum seems to contain two separate types, the first two values are
the "type", and the rest are "functions".
The only usage I see is:
/* Sanity check on error type */
if (type < OpalErrinjctTypeIoaBusError ||
type > OpalErrinjctTypeIoaBusError64 ||
function < OpalEjtIoaLoadMemAddr ||
function > OpalEjtIoaDmaWriteMemTarget) {
pr_warn("%s: Invalid error type %d-%d\n",
__func__, type, function);
return -ERANGE;
}
So we could also just do:
# define OPAL_ERR_INJECT_TYPE_MIN 0
# define OPAL_ERR_INJECT_TYPE_MAX 1
# define OPAL_ERR_INJECT_FUNC_MIN 0
# define OPAL_ERR_INJECT_FUNC_MAX 19
if (type < OPAL_ERR_INJECT_TYPE_MIN ||
type > OPAL_ERR_INJECT_TYPE_MAX ||
function < OPAL_ERR_INJECT_FUNC_MIN ||
function > OPAL_ERR_INJECT_FUNC_MIN)
{
pr_warn("%s: Invalid error type %d-%d\n", __func__, type, function);
return -ERANGE;
}
cheers
^ permalink raw reply
page: next (older) | prev (newer) | latest
- recent:[subjects (threaded)|topics (new)|topics (active)]
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox