Discussion:
[PATCH v3 10/27] PCI/MSI: Remove useless bus->msi assignment
Yijing Wang
2014-10-15 03:06:58 UTC
Permalink
Now msi chip is saved in pci_sys_data in arm,
we could clean the bus->msi assignment in
pci core.

Signed-off-by: Yijing Wang <***@huawei.com>
CC: Thierry Reding <***@gmail.com>
CC: 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 efa48dc..98bf4c3 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -682,7 +682,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
Yijing Wang
2014-10-15 03:06:55 UTC
Permalink
Save msi chip in pci_sys_data instead of assign
msi chip to every pci bus in .add_bus().

Signed-off-by: Yijing Wang <***@huawei.com>
---
drivers/pci/host/pcie-rcar.c | 13 +++----------
1 files changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 61158e0..c999c7e 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -380,20 +380,10 @@ static int rcar_pcie_setup(int nr, struct pci_sys_data *sys)
return 1;
}

-static void rcar_pcie_add_bus(struct pci_bus *bus)
-{
- if (IS_ENABLED(CONFIG_PCI_MSI)) {
- struct rcar_pcie *pcie = sys_to_pcie(bus->sysdata);
-
- bus->msi = &pcie->msi.chip;
- }
-}
-
struct hw_pci rcar_pci = {
.setup = rcar_pcie_setup,
.map_irq = of_irq_parse_and_map_pci,
.ops = &rcar_pcie_ops,
- .add_bus = rcar_pcie_add_bus,
};

static void rcar_pcie_enable(struct rcar_pcie *pcie)
@@ -402,6 +392,9 @@ static void rcar_pcie_enable(struct rcar_pcie *pcie)

rcar_pci.nr_controllers = 1;
rcar_pci.private_data = (void **)&pcie;
+#ifdef CONFIG_PCI_MSI
+ rcar_pci.msi_chip = &pcie->msi.chip;
+#endif

pci_common_init_dev(&pdev->dev, &rcar_pci);
#ifdef CONFIG_PCI_DOMAINS
--
1.7.1
Yijing Wang
2014-10-15 03:06:57 UTC
Permalink
MSI chip will be saved in pci_sys_data, now we can
clean up pcibios_add_bus() and pcibios_remove_bus()
in arm, and use pci_find_msi_chip() to get msi chip
in core MSI code.

Signed-off-by: Yijing Wang <***@huawei.com>
---
arch/arm/include/asm/mach/pci.h | 4 ----
arch/arm/kernel/bios32.c | 16 ----------------
drivers/pci/msi.c | 11 +++--------
3 files changed, 3 insertions(+), 28 deletions(-)

diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 59b0d87..230b2c9 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -39,8 +39,6 @@ struct hw_pci {
resource_size_t start,
resource_size_t size,
resource_size_t align);
- void (*add_bus)(struct pci_bus *bus);
- void (*remove_bus)(struct pci_bus *bus);
};

/*
@@ -71,8 +69,6 @@ struct pci_sys_data {
resource_size_t start,
resource_size_t size,
resource_size_t align);
- void (*add_bus)(struct pci_bus *bus);
- void (*remove_bus)(struct pci_bus *bus);
void *private_data; /* platform controller private data */
};

diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index a19038d..b1b872e 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -360,20 +360,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)
}
EXPORT_SYMBOL(pcibios_fixup_bus);

-void pcibios_add_bus(struct pci_bus *bus)
-{
- struct pci_sys_data *sys = bus->sysdata;
- if (sys->add_bus)
- sys->add_bus(bus);
-}
-
-void pcibios_remove_bus(struct pci_bus *bus)
-{
- struct pci_sys_data *sys = bus->sysdata;
- if (sys->remove_bus)
- sys->remove_bus(bus);
-}
-
/*
* Swizzle the device pin each time we cross a bridge. If a platform does
* not provide a swizzle function, we perform the standard PCI swizzling.
@@ -478,8 +464,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
sys->swizzle = hw->swizzle;
sys->map_irq = hw->map_irq;
sys->align_resource = hw->align_resource;
- sys->add_bus = hw->add_bus;
- sys->remove_bus = hw->remove_bus;
INIT_LIST_HEAD(&sys->resources);

if (hw->private_data)
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index f11108c..56e54ad 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -32,12 +32,10 @@ int pci_msi_ignore_mask;

int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
- struct msi_chip *chip = dev->bus->msi;
+ struct msi_chip *chip;
int err;

- if (!chip)
- chip = pci_msi_chip(dev->bus);
-
+ chip = pci_msi_chip(dev->bus);
if (!chip || !chip->setup_irq)
return -EINVAL;

@@ -51,10 +49,7 @@ int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
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 = pci_msi_chip(entry->dev->bus);
+ struct msi_chip *chip = pci_msi_chip(entry->dev->bus);

if (!chip || !chip->teardown_irq)
return;
--
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-ia64" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Bjorn Helgaas
2014-10-23 05:38:58 UTC
Permalink
Post by Yijing Wang
MSI chip will be saved in pci_sys_data, now we can
clean up pcibios_add_bus() and pcibios_remove_bus()
in arm, and use pci_find_msi_chip() to get msi chip
in core MSI code.
---
arch/arm/include/asm/mach/pci.h | 4 ----
arch/arm/kernel/bios32.c | 16 ----------------
drivers/pci/msi.c | 11 +++--------
3 files changed, 3 insertions(+), 28 deletions(-)
diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 59b0d87..230b2c9 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -39,8 +39,6 @@ struct hw_pci {
resource_size_t start,
resource_size_t size,
resource_size_t align);
- void (*add_bus)(struct pci_bus *bus);
- void (*remove_bus)(struct pci_bus *bus);
};
/*
@@ -71,8 +69,6 @@ struct pci_sys_data {
resource_size_t start,
resource_size_t size,
resource_size_t align);
- void (*add_bus)(struct pci_bus *bus);
- void (*remove_bus)(struct pci_bus *bus);
void *private_data; /* platform controller private data */
};
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index a19038d..b1b872e 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -360,20 +360,6 @@ void pcibios_fixup_bus(struct pci_bus *bus)
}
EXPORT_SYMBOL(pcibios_fixup_bus);
-void pcibios_add_bus(struct pci_bus *bus)
-{
- struct pci_sys_data *sys = bus->sysdata;
- if (sys->add_bus)
- sys->add_bus(bus);
-}
-
-void pcibios_remove_bus(struct pci_bus *bus)
-{
- struct pci_sys_data *sys = bus->sysdata;
- if (sys->remove_bus)
- sys->remove_bus(bus);
-}
-
/*
* Swizzle the device pin each time we cross a bridge. If a platform does
* not provide a swizzle function, we perform the standard PCI swizzling.
@@ -478,8 +464,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
sys->swizzle = hw->swizzle;
sys->map_irq = hw->map_irq;
sys->align_resource = hw->align_resource;
- sys->add_bus = hw->add_bus;
- sys->remove_bus = hw->remove_bus;
INIT_LIST_HEAD(&sys->resources);
if (hw->private_data)
What do the core changes below have to do with the ARM changes above?
They should be a separate patch unless they can't be separated.
Post by Yijing Wang
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index f11108c..56e54ad 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -32,12 +32,10 @@ int pci_msi_ignore_mask;
int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
- struct msi_chip *chip = dev->bus->msi;
+ struct msi_chip *chip;
int err;
- if (!chip)
- chip = pci_msi_chip(dev->bus);
-
+ chip = pci_msi_chip(dev->bus);
if (!chip || !chip->setup_irq)
return -EINVAL;
@@ -51,10 +49,7 @@ int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
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 = pci_msi_chip(entry->dev->bus);
+ struct msi_chip *chip = pci_msi_chip(entry->dev->bus);
if (!chip || !chip->teardown_irq)
return;
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
More majordomo info at http://vger.kernel.org/majordomo-info.html
Yijing Wang
2014-10-23 06:39:35 UTC
Permalink
Post by Bjorn Helgaas
Post by Yijing Wang
/*
* Swizzle the device pin each time we cross a bridge. If a platform does
* not provide a swizzle function, we perform the standard PCI swizzling.
@@ -478,8 +464,6 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
sys->swizzle = hw->swizzle;
sys->map_irq = hw->map_irq;
sys->align_resource = hw->align_resource;
- sys->add_bus = hw->add_bus;
- sys->remove_bus = hw->remove_bus;
INIT_LIST_HEAD(&sys->resources);
if (hw->private_data)
What do the core changes below have to do with the ARM changes above?
They should be a separate patch unless they can't be separated.
Hm, it's not the thing have to do, because the changes below is only used by arm arch, so I put it here
together. It's ok to split the core changes out to another one.
Post by Bjorn Helgaas
Post by Yijing Wang
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index f11108c..56e54ad 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -32,12 +32,10 @@ int pci_msi_ignore_mask;
int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
- struct msi_chip *chip = dev->bus->msi;
+ struct msi_chip *chip;
int err;
- if (!chip)
- chip = pci_msi_chip(dev->bus);
-
+ chip = pci_msi_chip(dev->bus);
if (!chip || !chip->setup_irq)
return -EINVAL;
@@ -51,10 +49,7 @@ int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
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 = pci_msi_chip(entry->dev->bus);
+ struct msi_chip *chip = pci_msi_chip(entry->dev->bus);
if (!chip || !chip->teardown_irq)
return;
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
More majordomo info at http://vger.kernel.org/majordomo-info.html
.
--
Thanks!
Yijing
Yijing Wang
2014-10-15 03:06:54 UTC
Permalink
Save msi chip in pci_sys_data instead of assign
msi chip to every pci bus in .add_bus().

Signed-off-by: Yijing Wang <***@huawei.com>
---
drivers/pci/host/pcie-designware.c | 15 ++++-----------
1 files changed, 4 insertions(+), 11 deletions(-)

diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index dfed00a..56fa8ab 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -498,6 +498,10 @@ int __init dw_pcie_host_init(struct pcie_port *pp)
val |= PORT_LOGIC_SPEED_CHANGE;
dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);

+#ifdef CONFIG_PCI_MSI
+ dw_pcie_msi_chip.dev = pp->dev;
+ dw_pci.msi_chip = &dw_pcie_msi_chip;
+#endif
dw_pci.nr_controllers = 1;
dw_pci.private_data = (void **)&pp;

@@ -747,21 +751,10 @@ static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
return irq;
}

-static void dw_pcie_add_bus(struct pci_bus *bus)
-{
- if (IS_ENABLED(CONFIG_PCI_MSI)) {
- struct pcie_port *pp = sys_to_pcie(bus->sysdata);
-
- dw_pcie_msi_chip.dev = pp->dev;
- bus->msi = &dw_pcie_msi_chip;
- }
-}
-
static struct hw_pci dw_pci = {
.setup = dw_pcie_setup,
.scan = dw_pcie_scan_bus,
.map_irq = dw_pcie_map_irq,
- .add_bus = dw_pcie_add_bus,
};

void dw_pcie_setup_rc(struct pcie_port *pp)
--
1.7.1
Yijing Wang
2014-10-15 03:06:56 UTC
Permalink
Save msi chip in pci_sys_data instead of assign
msi chip to every pci bus in .add_bus().

Signed-off-by: Yijing Wang <***@huawei.com>
---
drivers/pci/host/pci-mvebu.c | 10 +++-------
1 files changed, 3 insertions(+), 7 deletions(-)

diff --git a/drivers/pci/host/pci-mvebu.c b/drivers/pci/host/pci-mvebu.c
index b1315e1..f8e9c6c 100644
--- a/drivers/pci/host/pci-mvebu.c
+++ b/drivers/pci/host/pci-mvebu.c
@@ -774,12 +774,6 @@ static struct pci_bus *mvebu_pcie_scan_bus(int nr, struct pci_sys_data *sys)
return bus;
}

-static void mvebu_pcie_add_bus(struct pci_bus *bus)
-{
- struct mvebu_pcie *pcie = sys_to_pcie(bus->sysdata);
- bus->msi = pcie->msi;
-}
-
static resource_size_t mvebu_pcie_align_resource(struct pci_dev *dev,
const struct resource *res,
resource_size_t start,
@@ -816,6 +810,9 @@ static void mvebu_pcie_enable(struct mvebu_pcie *pcie)

memset(&hw, 0, sizeof(hw));

+#ifdef CONFIG_PCI_MSI
+ hw.msi_chip = pcie->msi;
+#endif
hw.nr_controllers = 1;
hw.private_data = (void **)&pcie;
hw.setup = mvebu_pcie_setup;
@@ -823,7 +820,6 @@ static void mvebu_pcie_enable(struct mvebu_pcie *pcie)
hw.map_irq = of_irq_parse_and_map_pci;
hw.ops = &mvebu_pcie_ops;
hw.align_resource = mvebu_pcie_align_resource;
- hw.add_bus = mvebu_pcie_add_bus;

pci_common_init(&hw);
}
--
1.7.1
Yijing Wang
2014-10-15 03:06:53 UTC
Permalink
Save msi chip in pci_sys_data instead of assign
msi chip to every pci bus in .add_bus().

Signed-off-by: Yijing Wang <***@huawei.com>
---
drivers/pci/host/pci-tegra.c | 13 +++----------
1 files changed, 3 insertions(+), 10 deletions(-)

diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 3d43874..5af0525 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -694,15 +694,6 @@ static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
return irq;
}

-static void tegra_pcie_add_bus(struct pci_bus *bus)
-{
- if (IS_ENABLED(CONFIG_PCI_MSI)) {
- struct tegra_pcie *pcie = sys_to_pcie(bus->sysdata);
-
- bus->msi = &pcie->msi.chip;
- }
-}
-
static struct pci_bus *tegra_pcie_scan_bus(int nr, struct pci_sys_data *sys)
{
struct tegra_pcie *pcie = sys_to_pcie(sys);
@@ -1881,11 +1872,13 @@ static int tegra_pcie_enable(struct tegra_pcie *pcie)

memset(&hw, 0, sizeof(hw));

+#ifdef CONFIG_PCI_MSI
+ hw.msi_chip = &pcie->msi.chip;
+#endif
hw.nr_controllers = 1;
hw.private_data = (void **)&pcie;
hw.setup = tegra_pcie_setup;
hw.map_irq = tegra_pcie_map_irq;
- hw.add_bus = tegra_pcie_add_bus;
hw.scan = tegra_pcie_scan_bus;
hw.ops = &tegra_pcie_ops;
--
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Bjorn Helgaas
2014-10-23 05:18:31 UTC
Permalink
Post by Yijing Wang
Save msi chip in pci_sys_data instead of assign
msi chip to every pci bus in .add_bus().
---
drivers/pci/host/pci-tegra.c | 13 +++----------
1 files changed, 3 insertions(+), 10 deletions(-)
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 3d43874..5af0525 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -694,15 +694,6 @@ static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
return irq;
}
-static void tegra_pcie_add_bus(struct pci_bus *bus)
-{
- if (IS_ENABLED(CONFIG_PCI_MSI)) {
- struct tegra_pcie *pcie = sys_to_pcie(bus->sysdata);
-
- bus->msi = &pcie->msi.chip;
- }
-}
-
static struct pci_bus *tegra_pcie_scan_bus(int nr, struct pci_sys_data *sys)
{
struct tegra_pcie *pcie = sys_to_pcie(sys);
@@ -1881,11 +1872,13 @@ static int tegra_pcie_enable(struct tegra_pcie *pcie)
memset(&hw, 0, sizeof(hw));
+#ifdef CONFIG_PCI_MSI
+ hw.msi_chip = &pcie->msi.chip;
+#endif
Why did you use "#ifdef CONFIG_PCI_MSI" instead of the
"IS_ENABLED(CONFIG_PCI_MSI)" used previously?

It's true that CONFIG_PCI_MSI will never be a tristate symbol, so we don't
really *need* the extra smarts of IS_ENABLED(), but I'm fairly sympathetic
to James' argument [1] that we should just use IS_ENABLED() all the time
because it's simpler overall.

If you want to change the #ifdef to IS_ENABLED(), that should be a separate
patch from your msi_chip change, and we can debate the merits of that by
itself.

[1] http://lkml.iu.edu//hypermail/linux/kernel/1204.3/00081.html
Post by Yijing Wang
hw.nr_controllers = 1;
hw.private_data = (void **)&pcie;
hw.setup = tegra_pcie_setup;
hw.map_irq = tegra_pcie_map_irq;
- hw.add_bus = tegra_pcie_add_bus;
hw.scan = tegra_pcie_scan_bus;
hw.ops = &tegra_pcie_ops;
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Yijing Wang
2014-10-23 06:23:26 UTC
Permalink
Post by Bjorn Helgaas
Post by Yijing Wang
Save msi chip in pci_sys_data instead of assign
msi chip to every pci bus in .add_bus().
---
drivers/pci/host/pci-tegra.c | 13 +++----------
1 files changed, 3 insertions(+), 10 deletions(-)
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 3d43874..5af0525 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -694,15 +694,6 @@ static int tegra_pcie_map_irq(const struct pci_dev *pdev, u8 slot, u8 pin)
return irq;
}
-static void tegra_pcie_add_bus(struct pci_bus *bus)
-{
- if (IS_ENABLED(CONFIG_PCI_MSI)) {
- struct tegra_pcie *pcie = sys_to_pcie(bus->sysdata);
-
- bus->msi = &pcie->msi.chip;
- }
-}
-
static struct pci_bus *tegra_pcie_scan_bus(int nr, struct pci_sys_data *sys)
{
struct tegra_pcie *pcie = sys_to_pcie(sys);
@@ -1881,11 +1872,13 @@ static int tegra_pcie_enable(struct tegra_pcie *pcie)
memset(&hw, 0, sizeof(hw));
+#ifdef CONFIG_PCI_MSI
+ hw.msi_chip = &pcie->msi.chip;
+#endif
Why did you use "#ifdef CONFIG_PCI_MSI" instead of the
"IS_ENABLED(CONFIG_PCI_MSI)" used previously?
Just personal habit. :)
Post by Bjorn Helgaas
It's true that CONFIG_PCI_MSI will never be a tristate symbol, so we don't
really *need* the extra smarts of IS_ENABLED(), but I'm fairly sympathetic
to James' argument [1] that we should just use IS_ENABLED() all the time
because it's simpler overall.
If you want to change the #ifdef to IS_ENABLED(), that should be a separate
patch from your msi_chip change, and we can debate the merits of that by
itself.
[1] http://lkml.iu.edu//hypermail/linux/kernel/1204.3/00081.html
Hi Bjorn, thanks for your guidance. I will use IS_ENABLED() instead of #ifdef for simplification
in a separate patch.
Post by Bjorn Helgaas
Post by Yijing Wang
hw.nr_controllers = 1;
hw.private_data = (void **)&pcie;
hw.setup = tegra_pcie_setup;
hw.map_irq = tegra_pcie_map_irq;
- hw.add_bus = tegra_pcie_add_bus;
hw.scan = tegra_pcie_scan_bus;
hw.ops = &tegra_pcie_ops;
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
.
--
Thanks!
Yijing

--
To unsubscribe from this list: send the line "unsubscribe linux-ia64" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Yijing Wang
2014-10-15 03:07:02 UTC
Permalink
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 <***@huawei.com>
---
drivers/iommu/irq_remapping.c | 11 ++++++++---
1 files changed, 8 insertions(+), 3 deletions(-)

diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 33c4395..48d57e9 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -139,8 +139,8 @@ error:
return ret;
}

-static int irq_remapping_setup_msi_irqs(struct pci_dev *dev,
- int nvec, int type)
+static int irq_remapping_setup_msi_irqs(struct msi_chip *chip,
+ struct pci_dev *dev, int nvec, int type)
{
if (type == PCI_CAP_ID_MSI)
return do_setup_msi_irqs(dev, nvec);
@@ -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)
{
/*
@@ -165,9 +170,9 @@ 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;
}

static __init int setup_nointremap(char *str)
--
1.7.1
Yijing Wang
2014-10-15 03:06:51 UTC
Permalink
Now only s390/MSI use default_msi_mask_irq() and
default_msix_mask_irq(), replace them with the common
msi mask irq functions __msi_mask_irq() and __msix_mask_irq().
Remove default_msi_mask_irq() and default_msix_mask_irq().

Signed-off-by: Yijing Wang <***@huawei.com>
---
arch/s390/pci/pci.c | 4 ++--
include/linux/msi.h | 2 --
2 files changed, 2 insertions(+), 4 deletions(-)

diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 2fa7b14..552b990 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -448,9 +448,9 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
/* Release MSI interrupts */
list_for_each_entry(msi, &pdev->msi_list, list) {
if (msi->msi_attrib.is_msix)
- default_msix_mask_irq(msi, 1);
+ __msix_mask_irq(msi, 1);
else
- default_msi_mask_irq(msi, 1, 1);
+ __msi_mask_irq(msi, 1, 1);
irq_set_msi_desc(msi->irq, NULL);
irq_free_desc(msi->irq);
msi->msg.address_lo = 0;
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 9ac1e3b..175aa21 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -65,8 +65,6 @@ 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);
-#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
Yijing Wang
2014-10-15 03:07:10 UTC
Permalink
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 <***@huawei.com>
---
Hi Sebastian,
I dropped the Acked-by , because this version has a
lot changes compared to last. So, I guess you may want to check it again.
---
arch/s390/include/asm/pci.h | 9 +++++++++
arch/s390/pci/pci.c | 12 ++++++++++--
2 files changed, 19 insertions(+), 2 deletions(-)

diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index c030900..4d41f08 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -88,6 +88,8 @@ struct zpci_dev {
u32 uid; /* user defined id */
u8 util_str[CLP_UTIL_STR_LEN]; /* utility string */

+ struct msi_chip *msi_chip;
+
/* IRQ stuff */
u64 msi_addr; /* MSI address */
struct airq_iv *aibv; /* adapter interrupt bit vector */
@@ -121,6 +123,13 @@ struct zpci_dev {
struct dentry *debugfs_perf;
};

+static inline struct msi_chip *pci_msi_chip(struct pci_bus *bus)
+{
+ struct zpci_dev *zpci = bus->sysdata;
+
+ return zpci->msi_chip;
+}
+
static inline bool zdev_enabled(struct zpci_dev *zdev)
{
return (zdev->fh & (1UL << 31)) ? true : false;
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 552b990..bf6732f 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -358,7 +358,8 @@ static void zpci_irq_handler(struct airq_struct *airq)
}
}

-int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+static int zpci_setup_msi_irqs(struct msi_chip *chip,
+ struct pci_dev *pdev, int nvec, int type)
{
struct zpci_dev *zdev = get_zdev(pdev);
unsigned int hwirq, msi_vecs;
@@ -434,7 +435,8 @@ out:
return rc;
}

-void arch_teardown_msi_irqs(struct pci_dev *pdev)
+static void zpci_teardown_msi_irqs(struct msi_chip *chip,
+ struct pci_dev *pdev)
{
struct zpci_dev *zdev = get_zdev(pdev);
struct msi_desc *msi;
@@ -464,6 +466,11 @@ 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,
+};
+
static void zpci_map_resources(struct zpci_dev *zdev)
{
struct pci_dev *pdev = zdev->pdev;
@@ -749,6 +756,7 @@ static int zpci_scan_bus(struct zpci_dev *zdev)
if (ret)
return ret;

+ zdev->msi_chip = &zpci_msi_chip;
zdev->bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops,
zdev, &resources);
if (!zdev->bus) {
--
1.7.1
Sebastian Ott
2014-10-16 12:13:20 UTC
Permalink
Post by Yijing Wang
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.
---
Hi Sebastian,
I dropped the Acked-by , because this version has a
lot changes compared to last. So, I guess you may want to check it again.
I did and I agree with that one too.

Regards,
Sebastian
Post by Yijing Wang
---
arch/s390/include/asm/pci.h | 9 +++++++++
arch/s390/pci/pci.c | 12 ++++++++++--
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index c030900..4d41f08 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -88,6 +88,8 @@ struct zpci_dev {
u32 uid; /* user defined id */
u8 util_str[CLP_UTIL_STR_LEN]; /* utility string */
+ struct msi_chip *msi_chip;
+
/* IRQ stuff */
u64 msi_addr; /* MSI address */
struct airq_iv *aibv; /* adapter interrupt bit vector */
@@ -121,6 +123,13 @@ struct zpci_dev {
struct dentry *debugfs_perf;
};
+static inline struct msi_chip *pci_msi_chip(struct pci_bus *bus)
+{
+ struct zpci_dev *zpci = bus->sysdata;
+
+ return zpci->msi_chip;
+}
+
static inline bool zdev_enabled(struct zpci_dev *zdev)
{
return (zdev->fh & (1UL << 31)) ? true : false;
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 552b990..bf6732f 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -358,7 +358,8 @@ static void zpci_irq_handler(struct airq_struct *airq)
}
}
-int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+static int zpci_setup_msi_irqs(struct msi_chip *chip,
+ struct pci_dev *pdev, int nvec, int type)
{
struct zpci_dev *zdev = get_zdev(pdev);
unsigned int hwirq, msi_vecs;
return rc;
}
-void arch_teardown_msi_irqs(struct pci_dev *pdev)
+static void zpci_teardown_msi_irqs(struct msi_chip *chip,
+ struct pci_dev *pdev)
{
struct zpci_dev *zdev = get_zdev(pdev);
struct msi_desc *msi;
@@ -464,6 +466,11 @@ 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,
+};
+
static void zpci_map_resources(struct zpci_dev *zdev)
{
struct pci_dev *pdev = zdev->pdev;
@@ -749,6 +756,7 @@ static int zpci_scan_bus(struct zpci_dev *zdev)
if (ret)
return ret;
+ zdev->msi_chip = &zpci_msi_chip;
zdev->bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops,
zdev, &resources);
if (!zdev->bus) {
--
1.7.1
Yijing Wang
2014-10-17 01:04:06 UTC
Permalink
Post by Sebastian Ott
Post by Yijing Wang
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.
---
Hi Sebastian,
I dropped the Acked-by , because this version has a
lot changes compared to last. So, I guess you may want to check it again.
I did and I agree with that one too.
Thanks very much!

Thanks!
Yijing.
Post by Sebastian Ott
Regards,
Sebastian
Post by Yijing Wang
---
arch/s390/include/asm/pci.h | 9 +++++++++
arch/s390/pci/pci.c | 12 ++++++++++--
2 files changed, 19 insertions(+), 2 deletions(-)
diff --git a/arch/s390/include/asm/pci.h b/arch/s390/include/asm/pci.h
index c030900..4d41f08 100644
--- a/arch/s390/include/asm/pci.h
+++ b/arch/s390/include/asm/pci.h
@@ -88,6 +88,8 @@ struct zpci_dev {
u32 uid; /* user defined id */
u8 util_str[CLP_UTIL_STR_LEN]; /* utility string */
+ struct msi_chip *msi_chip;
+
/* IRQ stuff */
u64 msi_addr; /* MSI address */
struct airq_iv *aibv; /* adapter interrupt bit vector */
@@ -121,6 +123,13 @@ struct zpci_dev {
struct dentry *debugfs_perf;
};
+static inline struct msi_chip *pci_msi_chip(struct pci_bus *bus)
+{
+ struct zpci_dev *zpci = bus->sysdata;
+
+ return zpci->msi_chip;
+}
+
static inline bool zdev_enabled(struct zpci_dev *zdev)
{
return (zdev->fh & (1UL << 31)) ? true : false;
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 552b990..bf6732f 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -358,7 +358,8 @@ static void zpci_irq_handler(struct airq_struct *airq)
}
}
-int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+static int zpci_setup_msi_irqs(struct msi_chip *chip,
+ struct pci_dev *pdev, int nvec, int type)
{
struct zpci_dev *zdev = get_zdev(pdev);
unsigned int hwirq, msi_vecs;
return rc;
}
-void arch_teardown_msi_irqs(struct pci_dev *pdev)
+static void zpci_teardown_msi_irqs(struct msi_chip *chip,
+ struct pci_dev *pdev)
{
struct zpci_dev *zdev = get_zdev(pdev);
struct msi_desc *msi;
@@ -464,6 +466,11 @@ 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,
+};
+
static void zpci_map_resources(struct zpci_dev *zdev)
{
struct pci_dev *pdev = zdev->pdev;
@@ -749,6 +756,7 @@ static int zpci_scan_bus(struct zpci_dev *zdev)
if (ret)
return ret;
+ zdev->msi_chip = &zpci_msi_chip;
zdev->bus = pci_scan_root_bus(NULL, ZPCI_BUS_NR, &pci_root_ops,
zdev, &resources);
if (!zdev->bus) {
--
1.7.1
.
--
Thanks!
Yijing
Yijing Wang
2014-10-15 03:07:15 UTC
Permalink
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 <***@huawei.com>
---
Hi Lucas,
I dropped the reviewed-by, because this version has a lot changes
compared to last one, I guess you may want to check it again.
---
drivers/iommu/irq_remapping.c | 2 +-
drivers/pci/msi.c | 103 +++++++++++++++--------------------------
include/linux/msi.h | 14 ------
include/linux/pci.h | 8 ---
4 files changed, 39 insertions(+), 88 deletions(-)

diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 48d57e9..77160a5 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 5cbd774..b9fefe9 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -28,54 +28,31 @@ int pci_msi_ignore_mask;
#define msix_table_size(flags) ((flags & PCI_MSIX_FLAGS_QSIZE) + 1)


-/* Arch hooks */
-
-int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
-{
- struct msi_chip *chip;
- int err;
-
- chip = pci_msi_chip(dev->bus);
- if (!chip || !chip->setup_irq)
- return -EINVAL;
-
- err = chip->setup_irq(chip, 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 = pci_msi_chip(entry->dev->bus);
-
- if (!chip || !chip->teardown_irq)
- return;
-
- chip->teardown_irq(chip, 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 = pci_msi_chip(dev->bus);
- if (chip && chip->setup_irqs)
+ if (!chip)
+ return -EINVAL;
+
+ if (chip->setup_irqs)
return chip->setup_irqs(chip, 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(chip, dev, entry);
if (ret < 0)
return ret;
if (ret > 0)
@@ -85,13 +62,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 = pci_msi_chip(dev->bus);
+ if (!chip)
+ return;
+
+ if (chip->teardown_irqs)
+ return chip->teardown_irqs(chip, dev);
+
+ if (!chip->teardown_irq)
+ return;

list_for_each_entry(entry, &dev->msi_list, list) {
int i, nvec;
@@ -102,20 +86,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(chip, entry->irq + i);
}
}

-void __weak arch_teardown_msi_irqs(struct pci_dev *dev)
-{
- struct msi_chip *chip = pci_msi_chip(dev->bus);
-
- if (chip && chip->teardown_irqs)
- return chip->teardown_irqs(chip, dev);
-
- return default_teardown_msi_irqs(dev);
-}
-
static void default_restore_msi_irq(struct pci_dev *dev, int irq)
{
struct msi_desc *entry;
@@ -134,10 +108,18 @@ static void default_restore_msi_irq(struct pci_dev *dev, int irq)
__write_msi_msg(entry, &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 = pci_msi_chip(dev->bus);
+ 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 = pci_msi_chip(dev->bus);
if (chip && chip->restore_irqs)
return chip->restore_irqs(chip, dev);

@@ -250,15 +232,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);
@@ -376,7 +349,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) {
@@ -435,7 +408,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),
@@ -458,7 +431,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);
}
@@ -628,7 +601,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);
@@ -743,7 +716,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 eb5ae36..65b0927 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -52,20 +52,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;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 7a48b40..b28cc03 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1433,14 +1433,6 @@ static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }

#include <asm/pci.h>

-/* Just avoid compile error, will be clean up later */
-#ifdef CONFIG_PCI_MSI
-
-#ifndef pci_msi_chip
-#define pci_msi_chip(bus) NULL
-#endif
-
-#endif

/* these helpers provide future and backwards compatibility
* for accessing popular PCI BAR info */
--
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe linux-ia64" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Yijing Wang
2014-10-15 03:07:14 UTC
Permalink
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 <***@huawei.com>
---
arch/tile/include/asm/pci.h | 10 ++++++++++
arch/tile/kernel/pci_gx.c | 13 +++++++++++--
2 files changed, 21 insertions(+), 2 deletions(-)

diff --git a/arch/tile/include/asm/pci.h b/arch/tile/include/asm/pci.h
index dfedd7a..d27d9ec 100644
--- a/arch/tile/include/asm/pci.h
+++ b/arch/tile/include/asm/pci.h
@@ -152,6 +152,7 @@ struct pci_controller {
int pio_io_index; /* PIO region index for I/O space access */
#endif

+ struct msi_chip *msi_chip;
/*
* Mem-Map regions for all the memory controllers so that Linux can
* map all of its physical memory space to the PCI bus.
@@ -179,6 +180,15 @@ struct pci_controller {
int irq_intx_table[4];
};

+extern struct msi_chip tilegx_msi;
+
+static inline struct msi_chip *pci_msi_chip(struct pci_bus *bus)
+{
+ struct pci_controller *controller = bus->sysdata;
+
+ return controller->msi_chip;
+}
+
extern struct pci_controller pci_controllers[TILEGX_NUM_TRIO * TILEGX_TRIO_PCIES];
extern gxio_trio_context_t trio_contexts[TILEGX_NUM_TRIO];
extern int num_trio_shims;
diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c
index e39f9c5..ba66517 100644
--- a/arch/tile/kernel/pci_gx.c
+++ b/arch/tile/kernel/pci_gx.c
@@ -887,6 +887,7 @@ int __init pcibios_init(void)
controller->mem_offset);
pci_add_resource(&resources, &controller->io_space);
controller->first_busno = next_busno;
+ controller->msi_chip = &tilegx_msi;
bus = pci_scan_root_bus(NULL, next_busno, controller->ops,
controller, &resources);
controller->root_bus = bus;
@@ -1485,7 +1486,8 @@ 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 msi_chip *chip,
+ struct pci_dev *pdev, struct msi_desc *desc)
{
struct pci_controller *controller;
gxio_trio_context_t *trio_context;
@@ -1604,7 +1606,12 @@ is_64_failure:
return ret;
}

-void arch_teardown_msi_irq(unsigned int irq)
+static void tile_teardown_msi_irq(struct msi_chip *chip, unsigned int irq)
{
irq_free_hwirq(irq);
}
+
+struct msi_chip tilegx_msi = {
+ .setup_irq = tile_setup_msi_irq,
+ .teardown_irq = tile_teardown_msi_irq,
+};
--
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Yijing Wang
2014-10-15 03:07:12 UTC
Permalink
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 <***@huawei.com>
---
arch/ia64/include/asm/pci.h | 10 ++++++++++
arch/ia64/kernel/msi_ia64.c | 14 ++++++++++----
arch/ia64/pci/pci.c | 1 +
3 files changed, 21 insertions(+), 4 deletions(-)

diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index 52af5ed..907dcba 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -94,6 +94,7 @@ struct pci_controller {
int segment;
int node; /* nearest node with memory or NUMA_NO_NODE for global allocation */

+ struct msi_chip *msi_chip;
void *platform_data;
};

@@ -101,6 +102,15 @@ struct pci_controller {
#define PCI_CONTROLLER(busdev) ((struct pci_controller *) busdev->sysdata)
#define pci_domain_nr(busdev) (PCI_CONTROLLER(busdev)->segment)

+extern struct msi_chip chip;
+
+static inline struct msi_chip *pci_msi_chip(struct pci_bus *bus)
+{
+ struct pci_controller *ctrl = bus->sysdata;
+
+ return ctrl->msi_chip;
+}
+
extern struct pci_ops pci_root_ops;

static inline int pci_proc_domain(struct pci_bus *bus)
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index 8c3730c..401fc98 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -112,15 +112,16 @@ 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 msi_chip *chip,
+ 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(struct msi_chip *chip, unsigned int irq)
{
if (platform_teardown_msi_irq)
return platform_teardown_msi_irq(irq);
@@ -128,6 +129,11 @@ void arch_teardown_msi_irq(unsigned int irq)
return ia64_teardown_msi_irq(irq);
}

+struct msi_chip chip = {
+ .setup_irq = arch_ia64_setup_msi_irq,
+ .teardown_irq = arch_ia64_teardown_msi_irq,
+};
+
#ifdef CONFIG_INTEL_IOMMU
#ifdef CONFIG_SMP
static int dmar_msi_set_affinity(struct irq_data *data,
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 291a582..299b67d 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -437,6 +437,7 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)

controller->companion = device;
controller->node = acpi_get_node(device->handle);
+ controller->msi_chip = &chip;

info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
--
1.7.1
Bjorn Helgaas
2014-10-22 23:53:45 UTC
Permalink
Post by Yijing Wang
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.
This needs slightly more detail. You're using the MSI chip framework
"instead of arch MSI functions". Well, there are still arch-specific
functions, i.e., arch_ia64_setup_msi_irq() and
arch_ia64_teardown_msi_irq().

We used to have arch_setup_msi_irq() which had a weak default
implementation, and a strong arch-specific implementation here, and you're
replacing that model with the new "msi-ops" model. I don't know how you
want to write that, but it's not that you're getting rid of the
arch-specific code; you're keeping arch-specific code but structuring it
differently.
Post by Yijing Wang
---
arch/ia64/include/asm/pci.h | 10 ++++++++++
arch/ia64/kernel/msi_ia64.c | 14 ++++++++++----
arch/ia64/pci/pci.c | 1 +
3 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index 52af5ed..907dcba 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -94,6 +94,7 @@ struct pci_controller {
int segment;
int node; /* nearest node with memory or NUMA_NO_NODE for global allocation */
+ struct msi_chip *msi_chip;
void *platform_data;
};
@@ -101,6 +102,15 @@ struct pci_controller {
#define PCI_CONTROLLER(busdev) ((struct pci_controller *) busdev->sysdata)
#define pci_domain_nr(busdev) (PCI_CONTROLLER(busdev)->segment)
+extern struct msi_chip chip;
Please make this name more descriptive. "chip" is way too generic for a
global name.
Post by Yijing Wang
+static inline struct msi_chip *pci_msi_chip(struct pci_bus *bus)
+{
+ struct pci_controller *ctrl = bus->sysdata;
+
+ return ctrl->msi_chip;
+}
+
extern struct pci_ops pci_root_ops;
static inline int pci_proc_domain(struct pci_bus *bus)
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index 8c3730c..401fc98 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -112,15 +112,16 @@ 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 msi_chip *chip,
+ 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);
Please don't make gratuitous changes ("pdev" -> "dev") at the same time,
especially since the rest of the file still uses "pdev".
Post by Yijing Wang
}
-void arch_teardown_msi_irq(unsigned int irq)
+static void arch_ia64_teardown_msi_irq(struct msi_chip *chip, unsigned int irq)
{
if (platform_teardown_msi_irq)
return platform_teardown_msi_irq(irq);
@@ -128,6 +129,11 @@ void arch_teardown_msi_irq(unsigned int irq)
return ia64_teardown_msi_irq(irq);
}
+struct msi_chip chip = {
+ .setup_irq = arch_ia64_setup_msi_irq,
+ .teardown_irq = arch_ia64_teardown_msi_irq,
+};
+
#ifdef CONFIG_INTEL_IOMMU
#ifdef CONFIG_SMP
static int dmar_msi_set_affinity(struct irq_data *data,
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 291a582..299b67d 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -437,6 +437,7 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
controller->companion = device;
controller->node = acpi_get_node(device->handle);
+ controller->msi_chip = &chip;
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
Yijing Wang
2014-10-23 01:17:19 UTC
Permalink
Post by Bjorn Helgaas
Post by Yijing Wang
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.
This needs slightly more detail. You're using the MSI chip framework
"instead of arch MSI functions". Well, there are still arch-specific
functions, i.e., arch_ia64_setup_msi_irq() and
arch_ia64_teardown_msi_irq().
We used to have arch_setup_msi_irq() which had a weak default
implementation, and a strong arch-specific implementation here, and you're
replacing that model with the new "msi-ops" model. I don't know how you
want to write that, but it's not that you're getting rid of the
arch-specific code; you're keeping arch-specific code but structuring it
differently.
Hm, I will rename the msi-ops functions.
Post by Bjorn Helgaas
Post by Yijing Wang
---
arch/ia64/include/asm/pci.h | 10 ++++++++++
arch/ia64/kernel/msi_ia64.c | 14 ++++++++++----
arch/ia64/pci/pci.c | 1 +
3 files changed, 21 insertions(+), 4 deletions(-)
diff --git a/arch/ia64/include/asm/pci.h b/arch/ia64/include/asm/pci.h
index 52af5ed..907dcba 100644
--- a/arch/ia64/include/asm/pci.h
+++ b/arch/ia64/include/asm/pci.h
@@ -94,6 +94,7 @@ struct pci_controller {
int segment;
int node; /* nearest node with memory or NUMA_NO_NODE for global allocation */
+ struct msi_chip *msi_chip;
void *platform_data;
};
@@ -101,6 +102,15 @@ struct pci_controller {
#define PCI_CONTROLLER(busdev) ((struct pci_controller *) busdev->sysdata)
#define pci_domain_nr(busdev) (PCI_CONTROLLER(busdev)->segment)
+extern struct msi_chip chip;
Please make this name more descriptive. "chip" is way too generic for a
global name.
OK, what about rename it to ia64_msi_chip, and rename the original static irq_chip ia64_msi_chip to
static irq_chip msi_chip like in x86.
Post by Bjorn Helgaas
Post by Yijing Wang
+static inline struct msi_chip *pci_msi_chip(struct pci_bus *bus)
+{
+ struct pci_controller *ctrl = bus->sysdata;
+
+ return ctrl->msi_chip;
+}
+
extern struct pci_ops pci_root_ops;
static inline int pci_proc_domain(struct pci_bus *bus)
diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index 8c3730c..401fc98 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -112,15 +112,16 @@ 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 msi_chip *chip,
+ 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);
Please don't make gratuitous changes ("pdev" -> "dev") at the same time,
especially since the rest of the file still uses "pdev".
OK.
Post by Bjorn Helgaas
Post by Yijing Wang
}
-void arch_teardown_msi_irq(unsigned int irq)
+static void arch_ia64_teardown_msi_irq(struct msi_chip *chip, unsigned int irq)
{
if (platform_teardown_msi_irq)
return platform_teardown_msi_irq(irq);
@@ -128,6 +129,11 @@ void arch_teardown_msi_irq(unsigned int irq)
return ia64_teardown_msi_irq(irq);
}
+struct msi_chip chip = {
+ .setup_irq = arch_ia64_setup_msi_irq,
+ .teardown_irq = arch_ia64_teardown_msi_irq,
+};
+
#ifdef CONFIG_INTEL_IOMMU
#ifdef CONFIG_SMP
static int dmar_msi_set_affinity(struct irq_data *data,
diff --git a/arch/ia64/pci/pci.c b/arch/ia64/pci/pci.c
index 291a582..299b67d 100644
--- a/arch/ia64/pci/pci.c
+++ b/arch/ia64/pci/pci.c
@@ -437,6 +437,7 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)
controller->companion = device;
controller->node = acpi_get_node(device->handle);
+ controller->msi_chip = &chip;
info = kzalloc(sizeof(*info), GFP_KERNEL);
if (!info) {
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
.
--
Thanks!
Yijing
Yijing Wang
2014-10-15 03:07:13 UTC
Permalink
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 <***@huawei.com>
---
arch/sparc/kernel/pci.c | 14 ++++++++++++--
arch/sparc/kernel/pci_impl.h | 12 ++++++++++++
2 files changed, 24 insertions(+), 2 deletions(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index b36365f..a46a148 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -656,6 +656,9 @@ struct pci_bus *pci_scan_one_pbm(struct pci_pbm_info *pbm,

printk("PCI: Scanning PBM %s\n", node->full_name);

+#ifdef CONFIG_PCI_MSI
+ pbm->msi_chip = &sparc_msi_chip;
+#endif
pci_add_resource_offset(&resources, &pbm->io_space,
pbm->io_space.start);
pci_add_resource_offset(&resources, &pbm->mem_space,
@@ -905,7 +908,8 @@ 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)
+static int sparc_setup_msi_irq(struct msi_chip *chip,
+ struct pci_dev *pdev, struct msi_desc *desc)
{
struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;
unsigned int irq;
@@ -916,7 +920,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)
+static void sparc_teardown_msi_irq(struct msi_chip *chip, unsigned int irq)
{
struct msi_desc *entry = irq_get_msi_desc(irq);
struct pci_dev *pdev = entry->dev;
@@ -925,6 +929,12 @@ void arch_teardown_msi_irq(unsigned int irq)
if (pbm->teardown_msi_irq)
pbm->teardown_msi_irq(irq, pdev);
}
+
+struct msi_chip sparc_msi_chip = {
+ .setup_irq = sparc_setup_msi_irq,
+ .teardown_irq = sparc_teardown_msi_irq,
+};
+
#endif /* !(CONFIG_PCI_MSI) */

static void ali_sound_dma_hack(struct pci_dev *pdev, int set_bit)
diff --git a/arch/sparc/kernel/pci_impl.h b/arch/sparc/kernel/pci_impl.h
index 75803c7..073bb4e 100644
--- a/arch/sparc/kernel/pci_impl.h
+++ b/arch/sparc/kernel/pci_impl.h
@@ -55,6 +55,8 @@ struct sparc64_msiq_cookie {
struct pci_pbm_info *pbm;
unsigned long msiqid;
};
+
+extern struct msi_chip sparc_msi_chip;
#endif

struct pci_pbm_info {
@@ -132,6 +134,7 @@ struct pci_pbm_info {
void *msi_queues;
unsigned long *msi_bitmap;
unsigned int *msi_irq_table;
+ struct msi_chip *msi_chip;
int (*setup_msi_irq)(unsigned int *irq_p, struct pci_dev *pdev,
struct msi_desc *entry);
void (*teardown_msi_irq)(unsigned int irq, struct pci_dev *pdev);
@@ -153,6 +156,15 @@ struct pci_pbm_info {
int numa_node;
};

+#ifdef CONFIG_PCI_MSI
+static inline struct msi_chip *pci_msi_chip(struct pci_bus *bus)
+{
+ struct pci_pbm_info *pbm = bus->sysdata;
+
+ return pbm->msi_chip;
+}
+#endif
+
extern struct pci_pbm_info *pci_pbm_root;

extern int pci_num_pbms;
--
1.7.1
David Miller
2014-10-15 02:36:41 UTC
Permalink
From: Yijing Wang <wangyijing-hv44wF8Li93QT0dZR+***@public.gmane.org>
Date: Wed, 15 Oct 2014 11:07:13 +0800
Post by Yijing Wang
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.
Acked-by: David S. Miller <davem-fT/PcQaiUtIeIZ0/***@public.gmane.org>
Yijing Wang
2014-10-15 03:06:49 UTC
Permalink
Currently, pcie-designware, pcie-rcar and 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. And chip_data is an opaque pointer, how to use
it is arch dependent. It should not be placed in MSI core.

Signed-off-by: Yijing Wang <***@huawei.com>
Reviewed-by: Thierry Reding <***@nvidia.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 2f7c92c..ecb92a5 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
Yijing Wang
2014-10-15 03:07:00 UTC
Permalink
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 <***@huawei.com>
---
arch/x86/include/asm/pci.h | 13 +++++++++++++
arch/x86/kernel/apic/io_apic.c | 19 +++++++++++++++++++
arch/x86/pci/acpi.c | 1 +
arch/x86/pci/common.c | 3 +++
4 files changed, 36 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 0892ea0..f41b58a 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -20,6 +20,9 @@ struct pci_sysdata {
#ifdef CONFIG_X86_64
void *iommu; /* IOMMU private data */
#endif
+#ifdef CONFIG_PCI_MSI
+ struct msi_chip *msi_chip;
+#endif
};

extern int pci_routeirq;
@@ -41,6 +44,15 @@ static inline int pci_proc_domain(struct pci_bus *bus)
}
#endif

+#ifdef CONFIG_PCI_MSI
+static inline struct msi_chip *pci_msi_chip(struct pci_bus *bus)
+{
+ struct pci_sysdata *sd = bus->sysdata;
+
+ return sd->msi_chip;
+}
+#endif
+
/* Can be used to override the logic in pci_scan_bus for skipping
already-configured bus numbers - to be used for buggy BIOSes
or architectures with incomplete PCI setup by the loader */
@@ -101,6 +113,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 29290f5..ec79b38 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3227,11 +3227,30 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
return 0;
}

+static int __native_setup_msi_irqs(struct msi_chip *chip,
+ struct pci_dev *dev, int nvec, int type)
+{
+ return native_setup_msi_irqs(dev, nvec, type);
+}
+
void native_teardown_msi_irq(unsigned int irq)
{
irq_free_hwirq(irq);
}

+static void __native_teardown_msi_irq(struct msi_chip *chip,
+ unsigned int irq)
+{
+ native_teardown_msi_irq(irq);
+}
+
+static struct msi_chip native_msi_chip = {
+ .setup_irqs = __native_setup_msi_irqs,
+ .teardown_irq = __native_teardown_msi_irq,
+};
+
+struct msi_chip *x86_msi_chip = &native_msi_chip;
+
#ifdef CONFIG_DMAR_TABLE
static int
dmar_msi_set_affinity(struct irq_data *data, const struct cpumask *mask,
diff --git a/arch/x86/pci/acpi.c b/arch/x86/pci/acpi.c
index cfd1b13..6341d6d 100644
--- a/arch/x86/pci/acpi.c
+++ b/arch/x86/pci/acpi.c
@@ -508,6 +508,7 @@ struct pci_bus *pci_acpi_scan_root(struct acpi_pci_root *root)

sd = &info->sd;
sd->domain = domain;
+ sd->msi_chip = x86_msi_chip;
sd->node = node;
sd->companion = device;

diff --git a/arch/x86/pci/common.c b/arch/x86/pci/common.c
index 7b20bcc..0b2319a 100644
--- a/arch/x86/pci/common.c
+++ b/arch/x86/pci/common.c
@@ -468,6 +468,9 @@ void pcibios_scan_root(int busnum)
return;
}
sd->node = x86_pci_root_bus_node(busnum);
+#ifdef CONFIG_PCI_MSI
+ sd->msi_chip = x86_msi_chip;
+#endif
x86_pci_root_bus_resources(busnum, &resources);
printk(KERN_DEBUG "PCI: Probing PCI hardware (bus %02x)\n", busnum);
bus = pci_scan_root_bus(NULL, busnum, &pci_root_ops, sd, &resources);
--
1.7.1
Yijing Wang
2014-10-15 03:06:59 UTC
Permalink
Now there are a lot of __weak arch functions in MSI code.
These functions make MSI driver complex. Thierry introduced
MSI chip framework to configure MSI/MSI-X irq in arm. Use
MSI chip framework to refactor all other platform MSI
code to eliminate weak arch MSI functions. This patch add
.restore_irqs(), .teardown_irqs() and .setup_irqs() to make it
become more common.

Signed-off-by: Yijing Wang <***@huawei.com>
Reviewed-by: Lucas Stach <***@pengutronix.de>
---
drivers/pci/msi.c | 15 +++++++++++++++
include/linux/msi.h | 4 ++++
2 files changed, 19 insertions(+), 0 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 56e54ad..5cbd774 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -61,6 +61,11 @@ int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
struct msi_desc *entry;
int ret;
+ struct msi_chip *chip;
+
+ chip = pci_msi_chip(dev->bus);
+ if (chip && chip->setup_irqs)
+ return chip->setup_irqs(chip, dev, nvec, type);

/*
* If an architecture wants to support multiple MSI, it needs to
@@ -103,6 +108,11 @@ void default_teardown_msi_irqs(struct pci_dev *dev)

void __weak arch_teardown_msi_irqs(struct pci_dev *dev)
{
+ struct msi_chip *chip = pci_msi_chip(dev->bus);
+
+ if (chip && chip->teardown_irqs)
+ return chip->teardown_irqs(chip, dev);
+
return default_teardown_msi_irqs(dev);
}

@@ -126,6 +136,11 @@ static void default_restore_msi_irq(struct pci_dev *dev, int irq)

void __weak arch_restore_msi_irqs(struct pci_dev *dev)
{
+ struct msi_chip *chip = pci_msi_chip(dev->bus);
+
+ if (chip && chip->restore_irqs)
+ return chip->restore_irqs(chip, dev);
+
return default_restore_msi_irqs(dev);
}

diff --git a/include/linux/msi.h b/include/linux/msi.h
index 175aa21..eb5ae36 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -74,7 +74,11 @@ struct msi_chip {

int (*setup_irq)(struct msi_chip *chip, struct pci_dev *dev,
struct msi_desc *desc);
+ int (*setup_irqs)(struct msi_chip *chip, struct pci_dev *dev,
+ int nvec, int type);
void (*teardown_irq)(struct msi_chip *chip, unsigned int irq);
+ void (*teardown_irqs)(struct msi_chip *chip, struct pci_dev *dev);
+ void (*restore_irqs)(struct msi_chip *chip, struct pci_dev *dev);
};

#endif /* LINUX_MSI_H */
--
1.7.1
Yijing Wang
2014-10-15 03:07:11 UTC
Permalink
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 <***@huawei.com>
---
arch/arm/mach-iop13xx/include/mach/pci.h | 4 ++++
arch/arm/mach-iop13xx/iq81340mc.c | 3 +++
arch/arm/mach-iop13xx/iq81340sc.c | 5 ++++-
arch/arm/mach-iop13xx/msi.c | 11 +++++++++--
4 files changed, 20 insertions(+), 3 deletions(-)

diff --git a/arch/arm/mach-iop13xx/include/mach/pci.h b/arch/arm/mach-iop13xx/include/mach/pci.h
index 59f42b5..c87ac3a 100644
--- a/arch/arm/mach-iop13xx/include/mach/pci.h
+++ b/arch/arm/mach-iop13xx/include/mach/pci.h
@@ -11,6 +11,10 @@ void iop13xx_atu_select(struct hw_pci *plat_pci);
void iop13xx_pci_init(void);
void iop13xx_map_pci_memory(void);

+#ifdef CONFIG_PCI_MSI
+extern struct msi_chip iop13xx_msi_chip;
+#endif
+
#define IOP_PCI_STATUS_ERROR (PCI_STATUS_PARITY | \
PCI_STATUS_SIG_TARGET_ABORT | \
PCI_STATUS_REC_TARGET_ABORT | \
diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c
index 9cd07d3..1f499b6 100644
--- a/arch/arm/mach-iop13xx/iq81340mc.c
+++ b/arch/arm/mach-iop13xx/iq81340mc.c
@@ -59,6 +59,9 @@ static struct hw_pci iq81340mc_pci __initdata = {
.map_irq = iq81340mc_pcix_map_irq,
.scan = iop13xx_scan_bus,
.preinit = iop13xx_pci_init,
+#ifdef CONFIG_PCI_MSI
+ .msi_chip = &iop13xx_msi_chip,
+#endif
};

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..8bdfdc5 100644
--- a/arch/arm/mach-iop13xx/iq81340sc.c
+++ b/arch/arm/mach-iop13xx/iq81340sc.c
@@ -60,7 +60,10 @@ static struct hw_pci iq81340sc_pci __initdata = {
.setup = iop13xx_pci_setup,
.scan = iop13xx_scan_bus,
.map_irq = iq81340sc_atux_map_irq,
- .preinit = iop13xx_pci_init
+ .preinit = iop13xx_pci_init,
+#ifdef CONFIG_PCI_MSI
+ .msi_chip = &iop13xx_msi_chip,
+#endif
};

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..3135a63 100644
--- a/arch/arm/mach-iop13xx/msi.c
+++ b/arch/arm/mach-iop13xx/msi.c
@@ -132,7 +132,8 @@ 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 msi_chip *chip,
+ 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 +160,13 @@ 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(struct msi_chip *chip,
+ unsigned int irq)
{
irq_free_desc(irq);
}
+
+struct msi_chip iop13xx_chip = {
+ .setup_irq = iop13xx_setup_msi_irq,
+ .teardown_irq = iop13xx_teardown_msi_irq,
+};
--
1.7.1

--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Yijing Wang
2014-10-15 03:07:01 UTC
Permalink
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 <***@huawei.com>
Acked-by: David Vrabel <***@citrix.com>
CC: Konrad Rzeszutek Wilk <***@oracle.com>
---
arch/x86/pci/xen.c | 58 +++++++++++++++++++++++++++++++++++-----------------
1 files changed, 39 insertions(+), 19 deletions(-)

diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index e5b8b78..75067ca 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -157,7 +157,8 @@ static int acpi_register_gsi_xen(struct device *dev, u32 gsi,
struct xen_pci_frontend_ops *xen_pci_frontend;
EXPORT_SYMBOL_GPL(xen_pci_frontend);

-static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int xen_setup_msi_irqs(struct msi_chip *chip,
+ struct pci_dev *dev, int nvec, int type)
{
int irq, ret, i;
struct msi_desc *msidesc;
@@ -219,7 +220,8 @@ static void xen_msi_compose_msg(struct pci_dev *pdev, unsigned int pirq,
msg->data = XEN_PIRQ_MSI_DATA;
}

-static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int xen_hvm_setup_msi_irqs(struct msi_chip *chip,
+ struct pci_dev *dev, int nvec, int type)
{
int irq, pirq;
struct msi_desc *msidesc;
@@ -267,7 +269,8 @@ error:
#ifdef CONFIG_XEN_DOM0
static bool __read_mostly pci_seg_supported = true;

-static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int xen_initdom_setup_msi_irqs(struct msi_chip *chip,
+ struct pci_dev *dev, int nvec, int type)
{
int ret = 0;
struct msi_desc *msidesc;
@@ -349,7 +352,8 @@ out:
return ret;
}

-static void xen_initdom_restore_msi_irqs(struct pci_dev *dev)
+static void xen_initdom_restore_msi_irqs(struct msi_chip *chip,
+ struct pci_dev *dev)
{
int ret = 0;

@@ -376,7 +380,13 @@ static void xen_initdom_restore_msi_irqs(struct pci_dev *dev)
}
#endif

-static void xen_teardown_msi_irqs(struct pci_dev *dev)
+static void xen_teardown_msi_irq(struct msi_chip *chip, unsigned int irq)
+{
+ xen_destroy_irq(irq);
+}
+
+static void xen_teardown_msi_irqs(struct msi_chip *chip,
+ struct pci_dev *dev)
{
struct msi_desc *msidesc;

@@ -386,14 +396,22 @@ static void xen_teardown_msi_irqs(struct pci_dev *dev)
else
xen_pci_frontend_disable_msi(dev);

- /* Free the IRQ's and the msidesc using the generic code. */
- default_teardown_msi_irqs(dev);
-}
+ 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(chip, msidesc->irq + i);
+ }

-static void xen_teardown_msi_irq(unsigned int irq)
-{
- xen_destroy_irq(irq);
}
+
+struct msi_chip xen_msi_chip;
+
#endif

int __init pci_xen_init(void)
@@ -414,9 +432,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;
pci_msi_ignore_mask = 1;
#endif
return 0;
@@ -436,8 +454,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;
}
@@ -494,9 +513,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;
pci_msi_ignore_mask = 1;
#endif
xen_setup_acpi_sci();
--
1.7.1
Yijing Wang
2014-10-15 03:06:50 UTC
Permalink
Commit 0e4ccb1505a9 ("PCI: Add x86_msi.msi_mask_irq() and msix_mask_irq()")
introduced two __weak arch functions arch_msix_mask_irq() and
arch_msi_mask_irq() to work around a bug when running xen in x86.
These two functions made msi code more complex. This patch reverts
the commit and introduces a global flag to control msi mask action to
avoid the bug. The patch is also preparation for using MSI chip framework
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 will be removed in the later patch.

Signed-off-by: Yijing Wang <wangyijing-hv44wF8Li93QT0dZR+***@public.gmane.org>
CC: David Vrabel <david.vrabel-Sxgqhf6Nn4DQT0dZR+***@public.gmane.org>
CC: Konrad Rzeszutek Wilk <konrad.wilk-QHcLZuEGTsvQT0dZR+***@public.gmane.org>
---
Hi David and Konrad,
I dropped the Acked-by and tested-by, because this version has a
lot changes compared to last. So, I guess you may want to check it again.
---
arch/x86/include/asm/x86_init.h | 3 ---
arch/x86/kernel/x86_init.c | 10 ----------
arch/x86/pci/xen.c | 14 ++------------
drivers/pci/msi.c | 29 ++++++++++++-----------------
include/linux/msi.h | 8 ++++++--
5 files changed, 20 insertions(+), 44 deletions(-)

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/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 093f5f4..e5b8b78 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -394,14 +394,6 @@ 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)
-{
- return 0;
-}
#endif

int __init pci_xen_init(void)
@@ -425,8 +417,7 @@ 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;
+ pci_msi_ignore_mask = 1;
#endif
return 0;
}
@@ -506,8 +497,7 @@ 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;
+ pci_msi_ignore_mask = 1;
#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 ecb92a5..22e413c 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -23,6 +23,7 @@
#include "pci.h"

static int pci_msi_enable = 1;
+int pci_msi_ignore_mask;

#define msix_table_size(flags) ((flags & PCI_MSIX_FLAGS_QSIZE) + 1)

@@ -162,11 +163,11 @@ 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;

- if (!desc->msi_attrib.maskbit)
+ if (pci_msi_ignore_mask || !desc->msi_attrib.maskbit)
return 0;

mask_bits &= ~mask;
@@ -176,14 +177,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,11 +189,15 @@ 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 +
PCI_MSIX_ENTRY_VECTOR_CTRL;
+
+ if (pci_msi_ignore_mask)
+ return 0;
+
mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT;
if (flag)
mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
@@ -206,14 +206,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)
@@ -866,7 +861,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;
@@ -964,7 +959,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 44f4746..9ac1e3b 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -10,6 +10,8 @@ struct msi_msg {
u32 data; /* 16 bits of msi message data */
};

+extern int pci_msi_ignore_mask;
+
/* Helper functions */
struct irq_data;
struct msi_desc;
@@ -21,6 +23,8 @@ void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void read_msi_msg(unsigned int irq, struct msi_msg *msg);
void get_cached_msi_msg(unsigned int irq, 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 {
@@ -61,8 +65,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
Bjorn Helgaas
2014-10-23 04:25:35 UTC
Permalink
Post by Yijing Wang
Commit 0e4ccb1505a9 ("PCI: Add x86_msi.msi_mask_irq() and msix_mask_irq()")
introduced two __weak arch functions arch_msix_mask_irq() and
arch_msi_mask_irq() to work around a bug when running xen in x86.
These two functions made msi code more complex. This patch reverts
the commit and introduces a global flag to control msi mask action to
avoid the bug. The patch is also preparation for using MSI chip framework
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 will be removed in the later patch.
This patch is basically a revert of 0e4ccb1505a9 intermingled with the
addition of the new pci_msi_ignore_mask technique.

Can you please split this into two patches:

- Add the pci_msi_ignore_mask stuff (alongside the existing way)
- Revert 0e4ccb1505a9

I think that will make it easier to see what's going on.
Post by Yijing Wang
---
Hi David and Konrad,
I dropped the Acked-by and tested-by, because this version has a
lot changes compared to last. So, I guess you may want to check it again.
---
arch/x86/include/asm/x86_init.h | 3 ---
arch/x86/kernel/x86_init.c | 10 ----------
arch/x86/pci/xen.c | 14 ++------------
drivers/pci/msi.c | 29 ++++++++++++-----------------
include/linux/msi.h | 8 ++++++--
5 files changed, 20 insertions(+), 44 deletions(-)
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/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 093f5f4..e5b8b78 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -394,14 +394,6 @@ 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)
-{
- return 0;
-}
#endif
int __init pci_xen_init(void)
@@ -425,8 +417,7 @@ 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;
+ pci_msi_ignore_mask = 1;
#endif
return 0;
}
@@ -506,8 +497,7 @@ 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;
+ pci_msi_ignore_mask = 1;
#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 ecb92a5..22e413c 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -23,6 +23,7 @@
#include "pci.h"
static int pci_msi_enable = 1;
+int pci_msi_ignore_mask;
#define msix_table_size(flags) ((flags & PCI_MSIX_FLAGS_QSIZE) + 1)
@@ -162,11 +163,11 @@ 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;
- if (!desc->msi_attrib.maskbit)
+ if (pci_msi_ignore_mask || !desc->msi_attrib.maskbit)
return 0;
mask_bits &= ~mask;
@@ -176,14 +177,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,11 +189,15 @@ 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 +
PCI_MSIX_ENTRY_VECTOR_CTRL;
+
+ if (pci_msi_ignore_mask)
+ return 0;
+
mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT;
if (flag)
mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
@@ -206,14 +206,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)
@@ -866,7 +861,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;
@@ -964,7 +959,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 44f4746..9ac1e3b 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -10,6 +10,8 @@ struct msi_msg {
u32 data; /* 16 bits of msi message data */
};
+extern int pci_msi_ignore_mask;
+
/* Helper functions */
struct irq_data;
struct msi_desc;
@@ -21,6 +23,8 @@ void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void read_msi_msg(unsigned int irq, struct msi_msg *msg);
void get_cached_msi_msg(unsigned int irq, 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 {
@@ -61,8 +65,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
--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Yijing Wang
2014-10-23 04:44:24 UTC
Permalink
Post by Bjorn Helgaas
Post by Yijing Wang
Commit 0e4ccb1505a9 ("PCI: Add x86_msi.msi_mask_irq() and msix_mask_irq()")
introduced two __weak arch functions arch_msix_mask_irq() and
arch_msi_mask_irq() to work around a bug when running xen in x86.
These two functions made msi code more complex. This patch reverts
the commit and introduces a global flag to control msi mask action to
avoid the bug. The patch is also preparation for using MSI chip framework
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 will be removed in the later patch.
This patch is basically a revert of 0e4ccb1505a9 intermingled with the
addition of the new pci_msi_ignore_mask technique.
- Add the pci_msi_ignore_mask stuff (alongside the existing way)
- Revert 0e4ccb1505a9
I think that will make it easier to see what's going on.
OK, I will do it, thanks.

Thanks!
Yijing.
Post by Bjorn Helgaas
Post by Yijing Wang
---
Hi David and Konrad,
I dropped the Acked-by and tested-by, because this version has a
lot changes compared to last. So, I guess you may want to check it again.
---
arch/x86/include/asm/x86_init.h | 3 ---
arch/x86/kernel/x86_init.c | 10 ----------
arch/x86/pci/xen.c | 14 ++------------
drivers/pci/msi.c | 29 ++++++++++++-----------------
include/linux/msi.h | 8 ++++++--
5 files changed, 20 insertions(+), 44 deletions(-)
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/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 093f5f4..e5b8b78 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -394,14 +394,6 @@ 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)
-{
- return 0;
-}
#endif
int __init pci_xen_init(void)
@@ -425,8 +417,7 @@ 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;
+ pci_msi_ignore_mask = 1;
#endif
return 0;
}
@@ -506,8 +497,7 @@ 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;
+ pci_msi_ignore_mask = 1;
#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 ecb92a5..22e413c 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -23,6 +23,7 @@
#include "pci.h"
static int pci_msi_enable = 1;
+int pci_msi_ignore_mask;
#define msix_table_size(flags) ((flags & PCI_MSIX_FLAGS_QSIZE) + 1)
@@ -162,11 +163,11 @@ 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;
- if (!desc->msi_attrib.maskbit)
+ if (pci_msi_ignore_mask || !desc->msi_attrib.maskbit)
return 0;
mask_bits &= ~mask;
@@ -176,14 +177,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,11 +189,15 @@ 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 +
PCI_MSIX_ENTRY_VECTOR_CTRL;
+
+ if (pci_msi_ignore_mask)
+ return 0;
+
mask_bits &= ~PCI_MSIX_ENTRY_CTRL_MASKBIT;
if (flag)
mask_bits |= PCI_MSIX_ENTRY_CTRL_MASKBIT;
@@ -206,14 +206,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)
@@ -866,7 +861,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;
@@ -964,7 +959,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 44f4746..9ac1e3b 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -10,6 +10,8 @@ struct msi_msg {
u32 data; /* 16 bits of msi message data */
};
+extern int pci_msi_ignore_mask;
+
/* Helper functions */
struct irq_data;
struct msi_desc;
@@ -21,6 +23,8 @@ void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void read_msi_msg(unsigned int irq, struct msi_msg *msg);
void get_cached_msi_msg(unsigned int irq, 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 {
@@ -61,8 +65,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
.
--
Thanks!
Yijing
Yijing Wang
2014-10-15 03:07:09 UTC
Permalink
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-hv44wF8Li93QT0dZR+***@public.gmane.org>
---
Hi Michael,
I dropped the Acked-by , because this version has a
lot changes compared to last. So, I guess you may want to check it again.
---
arch/powerpc/include/asm/pci-bridge.h | 15 +++++++++++++++
arch/powerpc/kernel/msi.c | 12 ++++++++++--
arch/powerpc/kernel/pci-common.c | 3 +++
3 files changed, 28 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/include/asm/pci-bridge.h b/arch/powerpc/include/asm/pci-bridge.h
index 4ca90a3..233553e 100644
--- a/arch/powerpc/include/asm/pci-bridge.h
+++ b/arch/powerpc/include/asm/pci-bridge.h
@@ -32,6 +32,10 @@ struct pci_controller {
int self_busno;
struct resource busn;

+#ifdef CONFIG_PCI_MSI
+ struct msi_chip *msi_chip;
+#endif
+
void __iomem *io_base_virt;
#ifdef CONFIG_PPC64
void *io_base_alloc;
@@ -94,6 +98,17 @@ struct pci_controller {
void *private_data;
};

+#ifdef CONFIG_PCI_MSI
+extern struct msi_chip ppc_msi_chip;
+
+static inline struct msi_chip *pci_msi_chip(struct pci_bus *bus)
+{
+ struct pci_controller *hose = bus->sysdata;
+
+ return hose->msi_chip;
+}
+#endif
+
/* These are used for config access before all the PCI probing
has been done. */
extern int early_read_config_byte(struct pci_controller *hose, int bus,
diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c
index 71bd161..f38b67c 100644
--- a/arch/powerpc/kernel/msi.c
+++ b/arch/powerpc/kernel/msi.c
@@ -13,7 +13,8 @@

#include <asm/machdep.h>

-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int ppc_setup_msi_irqs(struct msi_chip *chip,
+ 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 +28,13 @@ 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 msi_chip *chip,
+ struct pci_dev *dev)
{
ppc_md.teardown_msi_irqs(dev);
}
+
+struct msi_chip ppc_msi_chip = {
+ .setup_irqs = ppc_setup_msi_irqs,
+ .teardown_irqs = ppc_teardown_msi_irqs,
+};
diff --git a/arch/powerpc/kernel/pci-common.c b/arch/powerpc/kernel/pci-common.c
index b2814e2..9f18b42 100644
--- a/arch/powerpc/kernel/pci-common.c
+++ b/arch/powerpc/kernel/pci-common.c
@@ -1594,6 +1594,9 @@ void pcibios_scan_phb(struct pci_controller *hose)
/* Wire up PHB bus resources */
pcibios_setup_phb_resources(hose, &resources);

+#ifdef CONFIG_PCI_MSI
+ hose->msi_chip = &ppc_msi_chip;
+#endif
hose->busn.start = hose->first_busno;
hose->busn.end = hose->last_busno;
hose->busn.flags = IORESOURCE_BUS;
--
1.7.1
Michael Ellerman
2014-10-17 07:23:20 UTC
Permalink
Post by Yijing Wang
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.
---
Hi Michael,
I dropped the Acked-by , because this version has a
lot changes compared to last. So, I guess you may want to check it again.
OK thanks.

Still looks OK and boots on one of my test systems that uses MSI.

Acked-by: Michael Ellerman <mpe-Gsx/***@public.gmane.org> (for powerpc)


cheers
Yijing Wang
2014-10-17 07:42:06 UTC
Permalink
Post by Michael Ellerman
Post by Yijing Wang
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.
---
Hi Michael,
I dropped the Acked-by , because this version has a
lot changes compared to last. So, I guess you may want to check it again.
OK thanks.
Still looks OK and boots on one of my test systems that uses MSI.
Good!
Thanks very much!

Thanks!
Yijing.
Post by Michael Ellerman
cheers
.
--
Thanks!
Yijing
Yijing Wang
2014-10-15 03:07:06 UTC
Permalink
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-hv44wF8Li93QT0dZR+***@public.gmane.org>
Cc: Thomas Gleixner <tglx-***@public.gmane.org>
---
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
Yijing Wang
2014-10-15 03:07:05 UTC
Permalink
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-hv44wF8Li93QT0dZR+***@public.gmane.org>
---
arch/mips/include/asm/octeon/pci-octeon.h | 4 +++
arch/mips/pci/msi-octeon.c | 31 ++++++++++++++++------------
arch/mips/pci/pci-octeon.c | 3 ++
3 files changed, 25 insertions(+), 13 deletions(-)

diff --git a/arch/mips/include/asm/octeon/pci-octeon.h b/arch/mips/include/asm/octeon/pci-octeon.h
index 64ba56a..27ffe42 100644
--- a/arch/mips/include/asm/octeon/pci-octeon.h
+++ b/arch/mips/include/asm/octeon/pci-octeon.h
@@ -66,4 +66,8 @@ enum octeon_dma_bar_type {
*/
extern enum octeon_dma_bar_type octeon_dma_bar_type;

+#ifdef CONFIG_PCI_MSI
+extern struct msi_chip octeon_msi_chip;
+#endif
+
#endif
diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c
index 63bbe07..fd4d698 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",
- 1 << request_private_bits);
+ pr_err("%s: Unable to find %d free interrupts, trying just one",
+ __func__, 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("%s: Unable to find a free MSI interrupt", __func__);
}

/* 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("%s: Invalid octeon_dma_bar_type", __func__);
}
msg.data = irq - OCTEON_IRQ_MSI_BIT0;

@@ -182,7 +182,8 @@ 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 msi_chip *chip, struct pci_dev *dev,
+ int nvec, int type)
{
struct msi_desc *entry;
int ret;
@@ -201,7 +202,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 +211,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(struct msi_chip *chip, unsigned int irq)
{
int number_irqs;
u64 bitmask;
@@ -226,8 +226,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("%s: Attempted to teardown illegal "
+ "MSI interrupt (%d)", __func__, irq);

irq -= OCTEON_IRQ_MSI_BIT0;
index = irq / 64;
@@ -249,8 +249,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("%s: Attempted to teardown MSI "
+ "interrupt (%d) not in use", __func__, irq);

/* Checks are done, update the in use bitmask */
spin_lock(&msi_free_irq_bitmask_lock);
@@ -259,6 +259,11 @@ void arch_teardown_msi_irq(unsigned int irq)
spin_unlock(&msi_free_irq_bitmask_lock);
}

+struct msi_chip octeon_msi_chip = {
+ .setup_irqs = octeon_setup_msi_irqs,
+ .teardown_irq = octeon_teardown_msi_irq,
+};
+
static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock);

static u64 msi_rcv_reg[4];
diff --git a/arch/mips/pci/pci-octeon.c b/arch/mips/pci/pci-octeon.c
index 59cccd9..aefaa8a 100644
--- a/arch/mips/pci/pci-octeon.c
+++ b/arch/mips/pci/pci-octeon.c
@@ -356,6 +356,9 @@ static struct pci_controller octeon_pci_controller = {
.io_resource = &octeon_pci_io_resource,
.io_offset = 0,
.io_map_base = OCTEON_PCI_IOSPACE_BASE,
+#ifdef CONFIG_PCI_MSI
+ .msi_chip = &octeon_msi_chip,
+#endif
};
--
1.7.1
Yijing Wang
2014-10-15 03:06:52 UTC
Permalink
Saving msi chip in pci_sys_data can make pci bus and
devices don't need to know msi chip detail, it also
make pci enumeration code be decoupled from msi chip.
In fact, all pci devices under the same pci hostbridge
share same msi chip. So msi chip should be seen as one
of resources or attributes to be initialized in pci host
bridge driver. Currently, pci hostbridge drivers create
pci_host_bridge in pci_create_root_bus(), and pass arch
specific pci sysdata to core pci scan functions. So pci
arch sysdata is good place to save msi chip.

Signed-off-by: Yijing Wang <***@huawei.com>
---
arch/arm/include/asm/mach/pci.h | 6 ++++++
arch/arm/include/asm/pci.h | 9 +++++++++
arch/arm/kernel/bios32.c | 3 +++
drivers/pci/msi.c | 6 ++++++
include/linux/pci.h | 9 +++++++++
5 files changed, 33 insertions(+), 0 deletions(-)

diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 7fc4278..59b0d87 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -22,6 +22,9 @@ struct hw_pci {
#ifdef CONFIG_PCI_DOMAINS
int domain;
#endif
+#ifdef CONFIG_PCI_MSI
+ struct msi_chip *msi_chip;
+#endif
struct pci_ops *ops;
int nr_controllers;
void **private_data;
@@ -47,6 +50,9 @@ struct pci_sys_data {
#ifdef CONFIG_PCI_DOMAINS
int domain;
#endif
+#ifdef CONFIG_PCI_MSI
+ struct msi_chip *msi_chip;
+#endif
struct list_head node;
int busnr; /* primary bus number */
u64 mem_offset; /* bus->cpu memory mapping offset */
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index 7e95d85..b562c09 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -31,6 +31,15 @@ static inline int pci_proc_domain(struct pci_bus *bus)
}
#endif /* CONFIG_PCI_DOMAINS */

+#ifdef CONFIG_PCI_MSI
+static inline struct msi_chip *pci_msi_chip(struct pci_bus *bus)
+{
+ struct pci_sys_data *root = bus->sysdata;
+
+ return root->msi_chip;
+}
+#endif
+
/*
* The PCI address space does equal the physical memory address space.
* The networking and block device layers use this boolean for bounce
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 17a26c1..a19038d 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -471,6 +471,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
#ifdef CONFIG_PCI_DOMAINS
sys->domain = hw->domain;
#endif
+#ifdef CONFIG_PCI_MSI
+ sys->msi_chip = hw->msi_chip;
+#endif
sys->busnr = busnr;
sys->swizzle = hw->swizzle;
sys->map_irq = hw->map_irq;
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 22e413c..f11108c 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -35,6 +35,9 @@ 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 = pci_msi_chip(dev->bus);
+
if (!chip || !chip->setup_irq)
return -EINVAL;

@@ -50,6 +53,9 @@ 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 = pci_msi_chip(entry->dev->bus);
+
if (!chip || !chip->teardown_irq)
return;

diff --git a/include/linux/pci.h b/include/linux/pci.h
index 9cd2721..7a48b40 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1433,6 +1433,15 @@ static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }

#include <asm/pci.h>

+/* Just avoid compile error, will be clean up later */
+#ifdef CONFIG_PCI_MSI
+
+#ifndef pci_msi_chip
+#define pci_msi_chip(bus) NULL
+#endif
+
+#endif
+
/* these helpers provide future and backwards compatibility
* for accessing popular PCI BAR info */
#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
--
1.7.1
Lorenzo Pieralisi
2014-10-20 17:21:58 UTC
Permalink
Post by Yijing Wang
Saving msi chip in pci_sys_data can make pci bus and
devices don't need to know msi chip detail, it also
make pci enumeration code be decoupled from msi chip.
In fact, all pci devices under the same pci hostbridge
share same msi chip. So msi chip should be seen as one
of resources or attributes to be initialized in pci host
bridge driver. Currently, pci hostbridge drivers create
pci_host_bridge in pci_create_root_bus(), and pass arch
specific pci sysdata to core pci scan functions. So pci
arch sysdata is good place to save msi chip.
---
arch/arm/include/asm/mach/pci.h | 6 ++++++
arch/arm/include/asm/pci.h | 9 +++++++++
arch/arm/kernel/bios32.c | 3 +++
drivers/pci/msi.c | 6 ++++++
include/linux/pci.h | 9 +++++++++
5 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 7fc4278..59b0d87 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -22,6 +22,9 @@ struct hw_pci {
#ifdef CONFIG_PCI_DOMAINS
int domain;
#endif
+#ifdef CONFIG_PCI_MSI
+ struct msi_chip *msi_chip;
+#endif
struct pci_ops *ops;
int nr_controllers;
void **private_data;
@@ -47,6 +50,9 @@ struct pci_sys_data {
#ifdef CONFIG_PCI_DOMAINS
int domain;
#endif
+#ifdef CONFIG_PCI_MSI
+ struct msi_chip *msi_chip;
+#endif
This struct is defined for ARM only. We are trying to remove dependency on it
so that we can have a single driver for ARM32 and ARM64 systems without
pcibios dependency. Why can't we add this msi chip data to the host
bridge struct instead ? I understand it is all a matter of how to pass
the pointer to pci_scan_root_bus(), where the bridge is created.
We could initialize the msi chip on the bridge through the bus pointer
returned by the pci_scan_root_bus() function.

Thanks,
Lorenzo
Post by Yijing Wang
struct list_head node;
int busnr; /* primary bus number */
u64 mem_offset; /* bus->cpu memory mapping offset */
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index 7e95d85..b562c09 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -31,6 +31,15 @@ static inline int pci_proc_domain(struct pci_bus *bus)
}
#endif /* CONFIG_PCI_DOMAINS */
+#ifdef CONFIG_PCI_MSI
+static inline struct msi_chip *pci_msi_chip(struct pci_bus *bus)
+{
+ struct pci_sys_data *root = bus->sysdata;
+
+ return root->msi_chip;
+}
+#endif
+
/*
* The PCI address space does equal the physical memory address space.
* The networking and block device layers use this boolean for bounce
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 17a26c1..a19038d 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -471,6 +471,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
#ifdef CONFIG_PCI_DOMAINS
sys->domain = hw->domain;
#endif
+#ifdef CONFIG_PCI_MSI
+ sys->msi_chip = hw->msi_chip;
+#endif
sys->busnr = busnr;
sys->swizzle = hw->swizzle;
sys->map_irq = hw->map_irq;
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 22e413c..f11108c 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -35,6 +35,9 @@ 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 = pci_msi_chip(dev->bus);
+
if (!chip || !chip->setup_irq)
return -EINVAL;
@@ -50,6 +53,9 @@ 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 = pci_msi_chip(entry->dev->bus);
+
if (!chip || !chip->teardown_irq)
return;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 9cd2721..7a48b40 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1433,6 +1433,15 @@ static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
#include <asm/pci.h>
+/* Just avoid compile error, will be clean up later */
+#ifdef CONFIG_PCI_MSI
+
+#ifndef pci_msi_chip
+#define pci_msi_chip(bus) NULL
+#endif
+
+#endif
+
/* these helpers provide future and backwards compatibility
* for accessing popular PCI BAR info */
#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
--
To unsubscribe from this list: send the line "unsubscribe linux-ia64" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Yijing Wang
2014-10-21 01:32:04 UTC
Permalink
Post by Lorenzo Pieralisi
Post by Yijing Wang
Saving msi chip in pci_sys_data can make pci bus and
devices don't need to know msi chip detail, it also
make pci enumeration code be decoupled from msi chip.
In fact, all pci devices under the same pci hostbridge
share same msi chip. So msi chip should be seen as one
of resources or attributes to be initialized in pci host
bridge driver. Currently, pci hostbridge drivers create
pci_host_bridge in pci_create_root_bus(), and pass arch
specific pci sysdata to core pci scan functions. So pci
arch sysdata is good place to save msi chip.
---
arch/arm/include/asm/mach/pci.h | 6 ++++++
arch/arm/include/asm/pci.h | 9 +++++++++
arch/arm/kernel/bios32.c | 3 +++
drivers/pci/msi.c | 6 ++++++
include/linux/pci.h | 9 +++++++++
5 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 7fc4278..59b0d87 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -22,6 +22,9 @@ struct hw_pci {
#ifdef CONFIG_PCI_DOMAINS
int domain;
#endif
+#ifdef CONFIG_PCI_MSI
+ struct msi_chip *msi_chip;
+#endif
struct pci_ops *ops;
int nr_controllers;
void **private_data;
@@ -47,6 +50,9 @@ struct pci_sys_data {
#ifdef CONFIG_PCI_DOMAINS
int domain;
#endif
+#ifdef CONFIG_PCI_MSI
+ struct msi_chip *msi_chip;
+#endif
This struct is defined for ARM only. We are trying to remove dependency on it
so that we can have a single driver for ARM32 and ARM64 systems without
pcibios dependency. Why can't we add this msi chip data to the host
bridge struct instead ? I understand it is all a matter of how to pass
the pointer to pci_scan_root_bus(), where the bridge is created.
We could initialize the msi chip on the bridge through the bus pointer
returned by the pci_scan_root_bus() function.
As mentioned in Patch 0, I will refactor generic pci hostbridge in another series,
We need not only save msi_chip into pci_host_bridge, and other common info, like domain_nr,
resources.

Thanks!
Yijing.
Post by Lorenzo Pieralisi
Thanks,
Lorenzo
Post by Yijing Wang
struct list_head node;
int busnr; /* primary bus number */
u64 mem_offset; /* bus->cpu memory mapping offset */
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index 7e95d85..b562c09 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -31,6 +31,15 @@ static inline int pci_proc_domain(struct pci_bus *bus)
}
#endif /* CONFIG_PCI_DOMAINS */
+#ifdef CONFIG_PCI_MSI
+static inline struct msi_chip *pci_msi_chip(struct pci_bus *bus)
+{
+ struct pci_sys_data *root = bus->sysdata;
+
+ return root->msi_chip;
+}
+#endif
+
/*
* The PCI address space does equal the physical memory address space.
* The networking and block device layers use this boolean for bounce
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 17a26c1..a19038d 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -471,6 +471,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
#ifdef CONFIG_PCI_DOMAINS
sys->domain = hw->domain;
#endif
+#ifdef CONFIG_PCI_MSI
+ sys->msi_chip = hw->msi_chip;
+#endif
sys->busnr = busnr;
sys->swizzle = hw->swizzle;
sys->map_irq = hw->map_irq;
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 22e413c..f11108c 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -35,6 +35,9 @@ 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 = pci_msi_chip(dev->bus);
+
if (!chip || !chip->setup_irq)
return -EINVAL;
@@ -50,6 +53,9 @@ 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 = pci_msi_chip(entry->dev->bus);
+
if (!chip || !chip->teardown_irq)
return;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 9cd2721..7a48b40 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1433,6 +1433,15 @@ static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
#include <asm/pci.h>
+/* Just avoid compile error, will be clean up later */
+#ifdef CONFIG_PCI_MSI
+
+#ifndef pci_msi_chip
+#define pci_msi_chip(bus) NULL
+#endif
+
+#endif
+
/* these helpers provide future and backwards compatibility
* for accessing popular PCI BAR info */
#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-kernel" in
More majordomo info at http://vger.kernel.org/majordomo-info.html
Please read the FAQ at http://www.tux.org/lkml/
.
--
Thanks!
Yijing

--
To unsubscribe from this list: send the line "unsubscribe linux-ia64" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Bjorn Helgaas
2014-10-23 05:35:55 UTC
Permalink
Post by Yijing Wang
Saving msi chip in pci_sys_data can make pci bus and
devices don't need to know msi chip detail, it also
make pci enumeration code be decoupled from msi chip.
In fact, all pci devices under the same pci hostbridge
share same msi chip. So msi chip should be seen as one
of resources or attributes to be initialized in pci host
bridge driver. Currently, pci hostbridge drivers create
pci_host_bridge in pci_create_root_bus(), and pass arch
specific pci sysdata to core pci scan functions. So pci
arch sysdata is good place to save msi chip.
---
arch/arm/include/asm/mach/pci.h | 6 ++++++
arch/arm/include/asm/pci.h | 9 +++++++++
arch/arm/kernel/bios32.c | 3 +++
drivers/pci/msi.c | 6 ++++++
include/linux/pci.h | 9 +++++++++
5 files changed, 33 insertions(+), 0 deletions(-)
diff --git a/arch/arm/include/asm/mach/pci.h b/arch/arm/include/asm/mach/pci.h
index 7fc4278..59b0d87 100644
--- a/arch/arm/include/asm/mach/pci.h
+++ b/arch/arm/include/asm/mach/pci.h
@@ -22,6 +22,9 @@ struct hw_pci {
#ifdef CONFIG_PCI_DOMAINS
int domain;
#endif
+#ifdef CONFIG_PCI_MSI
+ struct msi_chip *msi_chip;
+#endif
struct pci_ops *ops;
int nr_controllers;
void **private_data;
@@ -47,6 +50,9 @@ struct pci_sys_data {
#ifdef CONFIG_PCI_DOMAINS
int domain;
#endif
+#ifdef CONFIG_PCI_MSI
+ struct msi_chip *msi_chip;
+#endif
struct list_head node;
int busnr; /* primary bus number */
u64 mem_offset; /* bus->cpu memory mapping offset */
diff --git a/arch/arm/include/asm/pci.h b/arch/arm/include/asm/pci.h
index 7e95d85..b562c09 100644
--- a/arch/arm/include/asm/pci.h
+++ b/arch/arm/include/asm/pci.h
@@ -31,6 +31,15 @@ static inline int pci_proc_domain(struct pci_bus *bus)
}
#endif /* CONFIG_PCI_DOMAINS */
+#ifdef CONFIG_PCI_MSI
+static inline struct msi_chip *pci_msi_chip(struct pci_bus *bus)
+{
+ struct pci_sys_data *root = bus->sysdata;
+
+ return root->msi_chip;
+}
+#endif
+
/*
* The PCI address space does equal the physical memory address space.
* The networking and block device layers use this boolean for bounce
diff --git a/arch/arm/kernel/bios32.c b/arch/arm/kernel/bios32.c
index 17a26c1..a19038d 100644
--- a/arch/arm/kernel/bios32.c
+++ b/arch/arm/kernel/bios32.c
@@ -471,6 +471,9 @@ static void pcibios_init_hw(struct device *parent, struct hw_pci *hw,
#ifdef CONFIG_PCI_DOMAINS
sys->domain = hw->domain;
#endif
+#ifdef CONFIG_PCI_MSI
+ sys->msi_chip = hw->msi_chip;
+#endif
sys->busnr = busnr;
sys->swizzle = hw->swizzle;
sys->map_irq = hw->map_irq;
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 22e413c..f11108c 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -35,6 +35,9 @@ 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 = pci_msi_chip(dev->bus);
+
if (!chip || !chip->setup_irq)
return -EINVAL;
@@ -50,6 +53,9 @@ 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 = pci_msi_chip(entry->dev->bus);
+
if (!chip || !chip->teardown_irq)
return;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 9cd2721..7a48b40 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1433,6 +1433,15 @@ static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
#include <asm/pci.h>
+/* Just avoid compile error, will be clean up later */
+#ifdef CONFIG_PCI_MSI
+
+#ifndef pci_msi_chip
+#define pci_msi_chip(bus) NULL
+#endif
+#endif
I don't like the mixture of ARM changes and PCI core changes in the same
patch. Can you split this into a core patch that does something like this:

struct msi_chip * __weak pcibios_msi_controller(struct pci_bus *bus)
{
return NULL;
}

struct msi_chip *pci_msi_controller(struct pci_bus *bus)
{
msi_chip *controller = bus->msi;

if (controller)
return controller;
return pcibios_msi_controller(bus);
}

followed by an ARM patch that puts the msi_chip pointer in struct hw_pci
and implements pcibios_msi_controller()?

I know you're trying to *remove* weak functions, and this adds one, but
this section of the series is more about getting rid of the ARM
pcibios_add_bus() because all it was used for was setting the bus->msi
pointer.

Eventually we might have a way to stash an MSI controller pointer in the
generic pci_host_bridge struct, and then the pcibios_msi_controller()
interface could go away.
Post by Yijing Wang
+
/* these helpers provide future and backwards compatibility
* for accessing popular PCI BAR info */
#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
--
1.7.1
Yijing Wang
2014-10-23 06:32:24 UTC
Permalink
Post by Bjorn Helgaas
Post by Yijing Wang
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 22e413c..f11108c 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -35,6 +35,9 @@ 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 = pci_msi_chip(dev->bus);
+
if (!chip || !chip->setup_irq)
return -EINVAL;
@@ -50,6 +53,9 @@ 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 = pci_msi_chip(entry->dev->bus);
+
if (!chip || !chip->teardown_irq)
return;
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 9cd2721..7a48b40 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -1433,6 +1433,15 @@ static inline int pci_get_new_domain_nr(void) { return -ENOSYS; }
#include <asm/pci.h>
+/* Just avoid compile error, will be clean up later */
+#ifdef CONFIG_PCI_MSI
+
+#ifndef pci_msi_chip
+#define pci_msi_chip(bus) NULL
+#endif
+#endif
I don't like the mixture of ARM changes and PCI core changes in the same
struct msi_chip * __weak pcibios_msi_controller(struct pci_bus *bus)
{
return NULL;
}
struct msi_chip *pci_msi_controller(struct pci_bus *bus)
{
msi_chip *controller = bus->msi;
if (controller)
return controller;
return pcibios_msi_controller(bus);
}
followed by an ARM patch that puts the msi_chip pointer in struct hw_pci
and implements pcibios_msi_controller()?
OK, I will split it in half.
Post by Bjorn Helgaas
I know you're trying to *remove* weak functions, and this adds one, but
this section of the series is more about getting rid of the ARM
pcibios_add_bus() because all it was used for was setting the bus->msi
pointer.
Yes, agree.
Post by Bjorn Helgaas
Eventually we might have a way to stash an MSI controller pointer in the
generic pci_host_bridge struct, and then the pcibios_msi_controller()
interface could go away.
Yep, I am doing the work to make a generic pci_host_bridge, and try to rip it out from
pci_create_root_bus, that's also a large changes across many archs.
Post by Bjorn Helgaas
Post by Yijing Wang
+
/* these helpers provide future and backwards compatibility
* for accessing popular PCI BAR info */
#define pci_resource_start(dev, bar) ((dev)->resource[(bar)].start)
--
1.7.1
.
--
Thanks!
Yijing
Yijing Wang
2014-10-15 03:07:03 UTC
Permalink
Now we can clean up MSI weak arch functions in x86.

Signed-off-by: Yijing Wang <wangyijing-hv44wF8Li93QT0dZR+***@public.gmane.org>
---
arch/x86/include/asm/pci.h | 5 +----
arch/x86/include/asm/x86_init.h | 4 ----
arch/x86/kernel/apic/io_apic.c | 21 +++++----------------
arch/x86/kernel/x86_init.c | 24 ------------------------
4 files changed, 6 insertions(+), 48 deletions(-)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index f41b58a..3a5cf19 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -108,14 +108,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);
+void native_teardown_msi_irq(struct msi_chip *chip, unsigned int irq);
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 ec79b38..11d353f 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3200,7 +3200,8 @@ 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 msi_chip *chip,
+ struct pci_dev *dev, int nvec, int type)
{
struct msi_desc *msidesc;
unsigned int irq;
@@ -3227,26 +3228,14 @@ int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
return 0;
}

-static int __native_setup_msi_irqs(struct msi_chip *chip,
- struct pci_dev *dev, int nvec, int type)
-{
- return native_setup_msi_irqs(dev, nvec, type);
-}
-
-void native_teardown_msi_irq(unsigned int irq)
+void native_teardown_msi_irq(struct msi_chip *chip, unsigned int irq)
{
irq_free_hwirq(irq);
}

-static void __native_teardown_msi_irq(struct msi_chip *chip,
- unsigned int irq)
-{
- native_teardown_msi_irq(irq);
-}
-
static struct msi_chip native_msi_chip = {
- .setup_irqs = __native_setup_msi_irqs,
- .teardown_irq = __native_teardown_msi_irq,
+ .setup_irqs = native_setup_msi_irqs,
+ .teardown_irq = native_teardown_msi_irq,
};

struct msi_chip *x86_msi_chip = &native_msi_chip;
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 = {
--
1.7.1
Yijing Wang
2014-10-15 03:07:08 UTC
Permalink
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 <***@huawei.com>
---
arch/mips/pci/pci-xlr.c | 17 +++++++++++++++--
1 files changed, 15 insertions(+), 2 deletions(-)

diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c
index 0dde803..0e611de 100644
--- a/arch/mips/pci/pci-xlr.c
+++ b/arch/mips/pci/pci-xlr.c
@@ -149,6 +149,8 @@ static struct resource nlm_pci_io_resource = {
.flags = IORESOURCE_IO,
};

+static struct msi_chip xlr_msi_chip;
+
struct pci_controller nlm_pci_controller = {
.index = 0,
.pci_ops = &nlm_pci_ops,
@@ -156,6 +158,9 @@ struct pci_controller nlm_pci_controller = {
.mem_offset = 0x00000000UL,
.io_resource = &nlm_pci_io_resource,
.io_offset = 0x00000000UL,
+#ifdef CONFIG_PCI_MSI
+ .msi_chip = &xlr_msi_chip,
+#endif
};

/*
@@ -214,11 +219,13 @@ static int get_irq_vector(const struct pci_dev *dev)
}

#ifdef CONFIG_PCI_MSI
-void arch_teardown_msi_irq(unsigned int irq)
+static void xlr_teardown_msi_irq(struct msi_chip *chip,
+ unsigned int irq)
{
}

-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+static int xlr_setup_msi_irq(struct msi_chip *chip,
+ struct pci_dev *dev, struct msi_desc *desc)
{
struct msi_msg msg;
struct pci_dev *lnk;
@@ -263,6 +270,12 @@ 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,
+};
+
#endif

/* Extra ACK needed for XLR on chip PCI controller */
--
1.7.1
Yijing Wang
2014-10-15 03:07:07 UTC
Permalink
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 <***@huawei.com>
---
arch/mips/include/asm/netlogic/xlp-hal/pcibus.h | 1 +
arch/mips/pci/msi-xlp.c | 11 +++++++++--
arch/mips/pci/pci-xlp.c | 3 +++
3 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/mips/include/asm/netlogic/xlp-hal/pcibus.h b/arch/mips/include/asm/netlogic/xlp-hal/pcibus.h
index 91540f4..90646ad 100644
--- a/arch/mips/include/asm/netlogic/xlp-hal/pcibus.h
+++ b/arch/mips/include/asm/netlogic/xlp-hal/pcibus.h
@@ -103,6 +103,7 @@

#ifdef CONFIG_PCI_MSI
void xlp_init_node_msi_irqs(int node, int link);
+extern struct msi_chip xlp_chip;
#else
static inline void xlp_init_node_msi_irqs(int node, int link) {}
#endif
diff --git a/arch/mips/pci/msi-xlp.c b/arch/mips/pci/msi-xlp.c
index e469dc7..cca2257 100644
--- a/arch/mips/pci/msi-xlp.c
+++ b/arch/mips/pci/msi-xlp.c
@@ -245,7 +245,8 @@ static struct irq_chip xlp_msix_chip = {
.irq_unmask = unmask_msi_irq,
};

-void arch_teardown_msi_irq(unsigned int irq)
+static void xlp_teardown_msi_irq(struct msi_chip *chip,
+ unsigned int irq)
{
}

@@ -450,7 +451,8 @@ 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 msi_chip *chip,
+ struct pci_dev *dev, struct msi_desc *desc)
{
struct pci_dev *lnkdev;
uint64_t lnkbase;
@@ -472,6 +474,11 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
return xlp_setup_msi(lnkbase, node, link, desc);
}

+struct msi_chip xlp_chip = {
+ .setup_irq = xlp_setup_msi_irq,
+ .teardown_irq = xlp_teardown_msi_irq,
+};
+
void __init xlp_init_node_msi_irqs(int node, int link)
{
struct nlm_soc_info *nodep;
diff --git a/arch/mips/pci/pci-xlp.c b/arch/mips/pci/pci-xlp.c
index 7babf01..5d7b6a0 100644
--- a/arch/mips/pci/pci-xlp.c
+++ b/arch/mips/pci/pci-xlp.c
@@ -174,6 +174,9 @@ struct pci_controller nlm_pci_controller = {
.mem_offset = 0x00000000UL,
.io_resource = &nlm_pci_io_resource,
.io_offset = 0x00000000UL,
+#ifdef CONFIG_PCI_MSI
+ .msi_chip = &xlp_chip,
+#endif
};

struct pci_dev *xlp_get_pcie_link(const struct pci_dev *dev)
--
1.7.1
Yijing Wang
2014-10-15 03:07:04 UTC
Permalink
Save msi chip in pci sysdata, add arch pci_find_msi_chip()
to extract out msi chip.

Signed-off-by: Yijing Wang <***@huawei.com>
---
arch/mips/include/asm/pci.h | 14 ++++++++++++++
1 files changed, 14 insertions(+), 0 deletions(-)

diff --git a/arch/mips/include/asm/pci.h b/arch/mips/include/asm/pci.h
index 974b0e3..287661b 100644
--- a/arch/mips/include/asm/pci.h
+++ b/arch/mips/include/asm/pci.h
@@ -43,6 +43,9 @@ struct pci_controller {

int iommu;

+#ifdef CONFIG_PCI_MSI
+ struct msi_chip *msi_chip;
+#endif
/* Optional access methods for reading/writing the bus number
of the PCI controller */
int (*get_busno)(void);
@@ -54,6 +57,17 @@ struct pci_controller {
*/
extern void register_pci_controller(struct pci_controller *hose);

+#ifdef CONFIG_PCI_MSI
+
+static inline struct msi_chip *pci_msi_chip(struct pci_bus *bus)
+{
+ struct pci_controller *control = (struct pci_controller *)bus->sysdata;
+
+ return control->msi_chip;
+}
+
+#endif
+
/*
* board supplied pci irq fixup routine
*/
--
1.7.1
Bjorn Helgaas
2014-10-23 05:41:21 UTC
Permalink
Post by Yijing Wang
Now msi chip is saved in pci_sys_data in arm,
we could clean the bus->msi assignment in
pci core.
---
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 efa48dc..98bf4c3 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -682,7 +682,6 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
child->parent = parent;
child->ops = parent->ops;
- child->msi = parent->msi;
This needs an explanation of why ARM was the only arch to depend on this.
Post by Yijing Wang
child->sysdata = parent->sysdata;
child->bus_flags = parent->bus_flags;
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
More majordomo info at http://vger.kernel.org/majordomo-info.html
Yijing Wang
2014-10-23 06:40:50 UTC
Permalink
Post by Bjorn Helgaas
Post by Yijing Wang
Now msi chip is saved in pci_sys_data in arm,
we could clean the bus->msi assignment in
pci core.
---
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 efa48dc..98bf4c3 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -682,7 +682,6 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,
child->parent = parent;
child->ops = parent->ops;
- child->msi = parent->msi;
This needs an explanation of why ARM was the only arch to depend on this.
OK, will add explanation in next version.
Post by Bjorn Helgaas
Post by Yijing Wang
child->sysdata = parent->sysdata;
child->bus_flags = parent->bus_flags;
--
1.7.1
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
More majordomo info at http://vger.kernel.org/majordomo-info.html
.
--
Thanks!
Yijing

--
To unsubscribe from this list: send the line "unsubscribe sparclinux" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Bjorn Helgaas
2014-10-23 05:43:26 UTC
Permalink
Now there are a lot of weak arch functions in MSI code.
Thierry Reding Introduced MSI chip framework to configure MSI/MSI-X in arm,
that's a better solution than overriding lots of existing weak arch functionsin.
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 related platforms are warmly welcomed!
https://github.com/YijingWang/msi-chip-v3.git master
1. For patch "x86/xen/MSI: Eliminate...", introduce a new global flag "pci_msi_ignore_mask"
to control the msi mask instead of replacing the irqchip->mask with nop function,
the latter method has problem pointed out by Konrad Rzeszutek Wilk.
2. Save msi chip in arch pci sysdata instead of associating msi chip to pci bus.
Because pci devices under same host share the same msi chip, so I think associate
msi chip to pci host/pci sysdata is better than to bother every pci bus/devices.
A better solution suggested by Liviu is to rip out pci_host_bridge from pci_create_root_bus(),
then we can save some pci host common attributes like domain_nr, msi_chip, resources,
into the generic pci_host_bridge. Because this changes to pci host bridge is also
a large series, so I think we should go step by step, I will try to post it in another
series later.
4. Clean up arm pcibios_add_bus() and pcibios_remove_bus() which were used to associate
msi chip to pci bus.
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.
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.
This is a lot of stuff, and it's not all related, so putting it all
together in one series makes it hard for me to deal with it.
MSI: Remove the redundant irq_set_chip_data()
This doesn't seem related to eliminating weak functions.
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()
These two seem to go together.
arm/MSI: Save MSI chip in pci_sys_data
PCI: tegra: Save msi chip in pci_sys_data
PCI: designware: Save msi chip in pci_sys_data
PCI: rcar: Save msi chip in pci_sys_data
PCI: mvebu: Save msi chip in pci_sys_data
arm/PCI: Clean unused pcibios_add_bus() and pcibios_remove_bus()
PCI/MSI: Remove useless bus->msi assignment
These seem to go together (it'd be nice if they were all capitalized the
same).

I don't like the "msi_chip" name because the "chip" part doesn't convey
much information, other than telling us that apparently some sort of
semiconductor integrated circuit is involved. I sort of assumed that
much :)

Something like "msi_controller" would be more descriptive since we're
talking about an interrupt controller that accepts writes from a device and
turns them into CPU interrupts, e.g., a LAPIC.
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/MSI: Save msi chip in pci sysdata
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/include/asm/mach/pci.h | 10 +-
arch/arm/include/asm/pci.h | 9 ++
arch/arm/kernel/bios32.c | 19 +---
arch/arm/mach-iop13xx/include/mach/pci.h | 4 +
arch/arm/mach-iop13xx/iq81340mc.c | 3 +
arch/arm/mach-iop13xx/iq81340sc.c | 5 +-
arch/arm/mach-iop13xx/msi.c | 11 ++-
arch/ia64/include/asm/pci.h | 10 ++
arch/ia64/kernel/msi_ia64.c | 14 ++-
arch/ia64/pci/pci.c | 1 +
arch/mips/include/asm/netlogic/xlp-hal/pcibus.h | 1 +
arch/mips/include/asm/octeon/pci-octeon.h | 4 +
arch/mips/include/asm/pci.h | 14 +++
arch/mips/pci/msi-octeon.c | 31 +++---
arch/mips/pci/msi-xlp.c | 15 ++-
arch/mips/pci/pci-octeon.c | 3 +
arch/mips/pci/pci-xlp.c | 3 +
arch/mips/pci/pci-xlr.c | 17 +++-
arch/powerpc/include/asm/pci-bridge.h | 15 +++
arch/powerpc/kernel/msi.c | 12 ++-
arch/powerpc/kernel/pci-common.c | 3 +
arch/s390/include/asm/pci.h | 9 ++
arch/s390/pci/pci.c | 16 ++-
arch/sparc/kernel/pci.c | 14 ++-
arch/sparc/kernel/pci_impl.h | 12 ++
arch/tile/include/asm/pci.h | 10 ++
arch/tile/kernel/pci_gx.c | 13 ++-
arch/x86/include/asm/pci.h | 18 +++-
arch/x86/include/asm/x86_init.h | 7 --
arch/x86/kernel/apic/io_apic.c | 12 ++-
arch/x86/kernel/x86_init.c | 34 ------
arch/x86/pci/acpi.c | 1 +
arch/x86/pci/common.c | 3 +
arch/x86/pci/xen.c | 72 +++++++------
drivers/iommu/irq_remapping.c | 13 ++-
drivers/pci/host/pci-mvebu.c | 10 +--
drivers/pci/host/pci-tegra.c | 13 +--
drivers/pci/host/pcie-designware.c | 15 +--
drivers/pci/host/pcie-rcar.c | 13 +--
drivers/pci/msi.c | 133 ++++++++++-------------
drivers/pci/probe.c | 1 -
include/linux/msi.h | 24 ++---
include/linux/pci.h | 1 +
43 files changed, 379 insertions(+), 269 deletions(-)
Huh. I was hoping this was going to simplify things, and maybe it does
somehow, but it's unfortunate that it adds 110 lines of code overall. Does
that seem right to you? Why does it add code?

Who do you want to apply this? I can take it if that makes the most sense,
but I'd like acks from the architecture folks for their pieces, and
especially one from Thomas for the overall direction and the x86 parts.

If you want me to take this, can you refresh it to be based on v3.18-rc1?
I tried to apply it on v3.18-rc1, but [15/27] didn't apply because of
conflicts in arch/x86/kernel/apic/io_apic.c.

I'll look at these more tomorrow, I'm getting bleary-eyed tonight.

Bjorn
Yijing Wang
2014-10-23 07:45:32 UTC
Permalink
Post by Bjorn Helgaas
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.
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.
This is a lot of stuff, and it's not all related, so putting it all
together in one series makes it hard for me to deal with it.
MSI: Remove the redundant irq_set_chip_data()
OK, will post it out separately.
Post by Bjorn Helgaas
This doesn't seem related to eliminating weak functions.
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()
Will update your comments and post these together.
Post by Bjorn Helgaas
These two seem to go together.
arm/MSI: Save MSI chip in pci_sys_data
PCI: tegra: Save msi chip in pci_sys_data
PCI: designware: Save msi chip in pci_sys_data
PCI: rcar: Save msi chip in pci_sys_data
PCI: mvebu: Save msi chip in pci_sys_data
arm/PCI: Clean unused pcibios_add_bus() and pcibios_remove_bus()
PCI/MSI: Remove useless bus->msi assignment
These seem to go together (it'd be nice if they were all capitalized the
same).
OK, will update the titles and post together.
Post by Bjorn Helgaas
I don't like the "msi_chip" name because the "chip" part doesn't convey
much information, other than telling us that apparently some sort of
semiconductor integrated circuit is involved. I sort of assumed that
much :)
I think so, msi_chip easily make me confuse with x86 irq_chip msi_chip.
Post by Bjorn Helgaas
Something like "msi_controller" would be more descriptive since we're
talking about an interrupt controller that accepts writes from a device and
turns them into CPU interrupts, e.g., a LAPIC.
Hm, it's a better one, arm also use "msi-controller" to represent the msi related
object in DTS file.
Post by Bjorn Helgaas
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/MSI: Save msi chip in pci sysdata
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/include/asm/mach/pci.h | 10 +-
arch/arm/include/asm/pci.h | 9 ++
arch/arm/kernel/bios32.c | 19 +---
arch/arm/mach-iop13xx/include/mach/pci.h | 4 +
arch/arm/mach-iop13xx/iq81340mc.c | 3 +
arch/arm/mach-iop13xx/iq81340sc.c | 5 +-
arch/arm/mach-iop13xx/msi.c | 11 ++-
arch/ia64/include/asm/pci.h | 10 ++
arch/ia64/kernel/msi_ia64.c | 14 ++-
arch/ia64/pci/pci.c | 1 +
arch/mips/include/asm/netlogic/xlp-hal/pcibus.h | 1 +
arch/mips/include/asm/octeon/pci-octeon.h | 4 +
arch/mips/include/asm/pci.h | 14 +++
arch/mips/pci/msi-octeon.c | 31 +++---
arch/mips/pci/msi-xlp.c | 15 ++-
arch/mips/pci/pci-octeon.c | 3 +
arch/mips/pci/pci-xlp.c | 3 +
arch/mips/pci/pci-xlr.c | 17 +++-
arch/powerpc/include/asm/pci-bridge.h | 15 +++
arch/powerpc/kernel/msi.c | 12 ++-
arch/powerpc/kernel/pci-common.c | 3 +
arch/s390/include/asm/pci.h | 9 ++
arch/s390/pci/pci.c | 16 ++-
arch/sparc/kernel/pci.c | 14 ++-
arch/sparc/kernel/pci_impl.h | 12 ++
arch/tile/include/asm/pci.h | 10 ++
arch/tile/kernel/pci_gx.c | 13 ++-
arch/x86/include/asm/pci.h | 18 +++-
arch/x86/include/asm/x86_init.h | 7 --
arch/x86/kernel/apic/io_apic.c | 12 ++-
arch/x86/kernel/x86_init.c | 34 ------
arch/x86/pci/acpi.c | 1 +
arch/x86/pci/common.c | 3 +
arch/x86/pci/xen.c | 72 +++++++------
drivers/iommu/irq_remapping.c | 13 ++-
drivers/pci/host/pci-mvebu.c | 10 +--
drivers/pci/host/pci-tegra.c | 13 +--
drivers/pci/host/pcie-designware.c | 15 +--
drivers/pci/host/pcie-rcar.c | 13 +--
drivers/pci/msi.c | 133 ++++++++++-------------
drivers/pci/probe.c | 1 -
include/linux/msi.h | 24 ++---
include/linux/pci.h | 1 +
43 files changed, 379 insertions(+), 269 deletions(-)
Huh. I was hoping this was going to simplify things, and maybe it does
somehow, but it's unfortunate that it adds 110 lines of code overall. Does
that seem right to you? Why does it add code?
I filter out these patches which add code.

[PATCH v3 04/27] arm/MSI: Save MSI chip in pci_sys_data
5 files changed, 33 insertions(+), 0 deletions(-)
Insertions code mainly to introduce arch specific pci_msi_chip() to extract msi_chip from pci_sys_data, and temporary #ifdef

[PATCH v3 11/27] PCI/MSI: Refactor struct msi_chip to make it become more common
2 files changed, 19 insertions(+), 0 deletions(-)
Insertions here is to add msi ops like restore, teardown to msi_chip.

[PATCH v3 12/27] x86/MSI: Use MSI chip framework to configure MSI/MSI-X irq
4 files changed, 36 insertions(+), 0 deletions(-)
Arch specific pci_msi_chip() and declaration of msi_chip in x86, also some temporary code to compile ok.

[PATCH v3 13/27] x86/xen/MSI: Use MSI chip framework to configure MSI/MSI-X irq
1 files changed, 39 insertions(+), 19 deletions(-)
To avoid call default_teardown_msi_irq(), copy the default_teardown_msi_irq() code in this file.

[PATCH v3 16/27] Mips/MSI: Save msi chip in pci sysdata
1 files changed, 14 insertions(+), 0 deletions(-)
Arch specific pci_msi_chip() and some #ifdef code

[PATCH v3 17/27] MIPS/Octeon/MSI: Use MSI chip framework to configure MSI/MSI-X irq
3 files changed, 25 insertions(+), 13 deletions(-)

Archs Use msi chip framework to configure MSI/MSI-x
3 files changed, 13 insertions(+), 2 deletions(-)
1 files changed, 15 insertions(+), 2 deletions(-)
3 files changed, 28 insertions(+), 2 deletions(-)
2 files changed, 19 insertions(+), 2 deletions(-)
4 files changed, 20 insertions(+), 3 deletions(-)
3 files changed, 21 insertions(+), 4 deletions(-)
2 files changed, 24 insertions(+), 2 deletions(-)
2 files changed, 21 insertions(+), 2 deletions(-)

So the most adding code is to introduce arch specific pci_msi_chip(), this one will be removed after we make
pci_host_bridge generic and save msi_chip in it. There are also lots of #ifdef in arm code for msi_chip.
Post by Bjorn Helgaas
Who do you want to apply this? I can take it if that makes the most sense,
I hope you can apply this.
Post by Bjorn Helgaas
but I'd like acks from the architecture folks for their pieces, and
especially one from Thomas for the overall direction and the x86 parts.
OK.
Post by Bjorn Helgaas
If you want me to take this, can you refresh it to be based on v3.18-rc1?
I tried to apply it on v3.18-rc1, but [15/27] didn't apply because of
conflicts in arch/x86/kernel/apic/io_apic.c.
OK.
Post by Bjorn Helgaas
I'll look at these more tomorrow, I'm getting bleary-eyed tonight.
Thanks for your review and comments very much!

Thanks!
Yijing.
Post by Bjorn Helgaas
Bjorn
.
--
Thanks!
Yijing

--
To unsubscribe from this list: send the line "unsubscribe linux-ia64" in
the body of a message to ***@vger.kernel.org
More majordomo info at http://vger.kernel.org/majordomo-info.html
Loading...