Discussion:
[PATCH v2 07/22] PCI/MSI: Refactor struct msi_chip to make it become more common
Yijing Wang
2014-09-25 03:14:17 UTC
Permalink
Now there are a lot of __weak arch functions in MSI code.
These functions make MSI driver complex. Thierry Reding Introduced
a new MSI chip framework to configure MSI/MSI-X irq in ARM. Use
the new MSI chip framework to refactor all other platform MSI
arch code to eliminate weak arch MSI functions. This patch add
.restore_irq() 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 | 3 +++
2 files changed, 18 insertions(+), 0 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 3acbe65..d10edee 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -64,6 +64,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 = arch_find_msi_chip(dev);
+ if (chip && chip->setup_irqs)
+ return chip->setup_irqs(dev, nvec, type);

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

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

@@ -129,6 +139,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 = arch_find_msi_chip(dev);
+
+ if (chip && chip->restore_irqs)
+ return chip->restore_irqs(dev);
+
return default_restore_msi_irqs(dev);
}

diff --git a/include/linux/msi.h b/include/linux/msi.h
index 6fdc5c6..4cf1f31 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -69,7 +69,10 @@ struct msi_chip {
struct list_head list;

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

#endif /* LINUX_MSI_H */
--
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-09-25 03:14:15 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 cc46a62..6fdc5c6 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -61,8 +61,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

--
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-09-25 03:14:28 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 | 2 ++
arch/arm/mach-iop13xx/iq81340mc.c | 1 +
arch/arm/mach-iop13xx/iq81340sc.c | 1 +
arch/arm/mach-iop13xx/msi.c | 9 +++++++--
arch/arm/mach-iop13xx/pci.c | 6 ++++++
5 files changed, 17 insertions(+), 2 deletions(-)

diff --git a/arch/arm/mach-iop13xx/include/mach/pci.h b/arch/arm/mach-iop13xx/include/mach/pci.h
index 59f42b5..7a073cb 100644
--- a/arch/arm/mach-iop13xx/include/mach/pci.h
+++ b/arch/arm/mach-iop13xx/include/mach/pci.h
@@ -10,6 +10,8 @@ struct pci_bus *iop13xx_scan_bus(int nr, struct pci_sys_data *);
void iop13xx_atu_select(struct hw_pci *plat_pci);
void iop13xx_pci_init(void);
void iop13xx_map_pci_memory(void);
+void iop13xx_add_bus(struct pci_bus *bus);
+extern struct msi_chip iop13xx_msi_chip;

#define IOP_PCI_STATUS_ERROR (PCI_STATUS_PARITY | \
PCI_STATUS_SIG_TARGET_ABORT | \
diff --git a/arch/arm/mach-iop13xx/iq81340mc.c b/arch/arm/mach-iop13xx/iq81340mc.c
index 9cd07d3..19d47cb 100644
--- a/arch/arm/mach-iop13xx/iq81340mc.c
+++ b/arch/arm/mach-iop13xx/iq81340mc.c
@@ -59,6 +59,7 @@ static struct hw_pci iq81340mc_pci __initdata = {
.map_irq = iq81340mc_pcix_map_irq,
.scan = iop13xx_scan_bus,
.preinit = iop13xx_pci_init,
+ .add_bus = iop13xx_add_bus;
};

static int __init iq81340mc_pci_init(void)
diff --git a/arch/arm/mach-iop13xx/iq81340sc.c b/arch/arm/mach-iop13xx/iq81340sc.c
index b3ec11c..4d56993 100644
--- a/arch/arm/mach-iop13xx/iq81340sc.c
+++ b/arch/arm/mach-iop13xx/iq81340sc.c
@@ -61,6 +61,7 @@ static struct hw_pci iq81340sc_pci __initdata = {
.scan = iop13xx_scan_bus,
.map_irq = iq81340sc_atux_map_irq,
.preinit = iop13xx_pci_init
+ .add_bus = iop13xx_add_bus;
};

static int __init iq81340sc_pci_init(void)
diff --git a/arch/arm/mach-iop13xx/msi.c b/arch/arm/mach-iop13xx/msi.c
index e7730cf..1a8cb2f 100644
--- a/arch/arm/mach-iop13xx/msi.c
+++ b/arch/arm/mach-iop13xx/msi.c
@@ -132,7 +132,7 @@ static struct irq_chip iop13xx_msi_chip = {
.irq_unmask = unmask_msi_irq,
};

-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+static int iop13xx_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
int id, irq = irq_alloc_desc_from(IRQ_IOP13XX_MSI_0, -1);
struct msi_msg msg;
@@ -159,7 +159,12 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
return 0;
}

-void arch_teardown_msi_irq(unsigned int irq)
+static void iop13xx_teardown_msi_irq(unsigned int irq)
{
irq_free_desc(irq);
}
+
+struct msi_chip iop13xx_chip = {
+ .setup_irq = iop13xx_setup_msi_irq,
+ .teardown_irq = iop13xx_teardown_msi_irq,
+};
diff --git a/arch/arm/mach-iop13xx/pci.c b/arch/arm/mach-iop13xx/pci.c
index 9082b84..f498800 100644
--- a/arch/arm/mach-iop13xx/pci.c
+++ b/arch/arm/mach-iop13xx/pci.c
@@ -962,6 +962,12 @@ void __init iop13xx_atu_select(struct hw_pci *plat_pci)
}
}

+void iop13xx_add_bus(struct pci_bus *bus)
+{
+ if (IS_ENABLED(CONFIG_PCI_MSI))
+ bus->msi = &iop13xx_msi_chip;
+}
+
void __init iop13xx_pci_init(void)
{
/* clear pre-existing south bridge errors */
--
1.7.1
Yijing Wang
2014-09-25 03:14:32 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>
Reviewed-by: Lucas Stach <***@pengutronix.de>
---
drivers/iommu/irq_remapping.c | 2 +-
drivers/pci/msi.c | 100 +++++++++++++++-------------------------
include/linux/msi.h | 14 ------
3 files changed, 39 insertions(+), 77 deletions(-)

diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 99b1c0f..6e645f0 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -92,7 +92,7 @@ error:

/*
* Restore altered MSI descriptor fields and prevent just destroyed
- * IRQs from tearing down again in default_teardown_msi_irqs()
+ * IRQs from tearing down again in teardown_msi_irqs()
*/
msidesc->irq = 0;
msidesc->nvec_used = 0;
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index d10edee..9fe427f 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -34,51 +34,31 @@ struct msi_chip * __weak arch_find_msi_chip(struct pci_dev *dev)
return dev->bus->msi;
}

-int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
-{
- struct msi_chip *chip = arch_find_msi_chip(dev);
- int err;
-
- if (!chip || !chip->setup_irq)
- return -EINVAL;
-
- err = chip->setup_irq(dev, desc);
- if (err < 0)
- return err;
-
- return 0;
-}
-
-void __weak arch_teardown_msi_irq(unsigned int irq)
-{
- struct msi_desc *entry = irq_get_msi_desc(irq);
- struct msi_chip *chip = entry->dev->bus->msi;
-
- if (!chip || !chip->teardown_irq)
- return;
-
- chip->teardown_irq(irq);
-}
-
-int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+int setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
struct msi_desc *entry;
int ret;
struct msi_chip *chip;

chip = arch_find_msi_chip(dev);
- if (chip && chip->setup_irqs)
+ if (!chip)
+ return -EINVAL;
+
+ if (chip->setup_irqs)
return chip->setup_irqs(dev, nvec, type);

/*
* If an architecture wants to support multiple MSI, it needs to
- * override arch_setup_msi_irqs()
+ * implement chip->setup_irqs().
*/
if (type == PCI_CAP_ID_MSI && nvec > 1)
return 1;

+ if (!chip->setup_irq)
+ return -EINVAL;
+
list_for_each_entry(entry, &dev->msi_list, list) {
- ret = arch_setup_msi_irq(dev, entry);
+ ret = chip->setup_irq(dev, entry);
if (ret < 0)
return ret;
if (ret > 0)
@@ -88,13 +68,20 @@ int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
return 0;
}

-/*
- * We have a default implementation available as a separate non-weak
- * function, as it is used by the Xen x86 PCI code
- */
-void default_teardown_msi_irqs(struct pci_dev *dev)
+static void teardown_msi_irqs(struct pci_dev *dev)
{
struct msi_desc *entry;
+ struct msi_chip *chip;
+
+ chip = arch_find_msi_chip(dev);
+ if (!chip)
+ return;
+
+ if (chip->teardown_irqs)
+ return chip->teardown_irqs(dev);
+
+ if (!chip->teardown_irq)
+ return;

list_for_each_entry(entry, &dev->msi_list, list) {
int i, nvec;
@@ -105,20 +92,10 @@ void default_teardown_msi_irqs(struct pci_dev *dev)
else
nvec = 1 << entry->msi_attrib.multiple;
for (i = 0; i < nvec; i++)
- arch_teardown_msi_irq(entry->irq + i);
+ chip->teardown_irq(entry->irq + i);
}
}

-void __weak arch_teardown_msi_irqs(struct pci_dev *dev)
-{
- struct msi_chip *chip = arch_find_msi_chip(dev);
-
- if (chip && chip->teardown_irqs)
- return chip->teardown_irqs(dev);
-
- return default_teardown_msi_irqs(dev);
-}
-
static void default_restore_msi_irq(struct pci_dev *dev, int irq)
{
struct msi_desc *entry;
@@ -137,10 +114,18 @@ static void default_restore_msi_irq(struct pci_dev *dev, int irq)
write_msi_msg(irq, &entry->msg);
}

-void __weak arch_restore_msi_irqs(struct pci_dev *dev)
+static void default_restore_msi_irqs(struct pci_dev *dev)
{
- struct msi_chip *chip = arch_find_msi_chip(dev);
+ struct msi_desc *entry = NULL;
+
+ list_for_each_entry(entry, &dev->msi_list, list) {
+ default_restore_msi_irq(dev, entry->irq);
+ }
+}

+static void restore_msi_irqs(struct pci_dev *dev)
+{
+ struct msi_chip *chip = arch_find_msi_chip(dev);
if (chip && chip->restore_irqs)
return chip->restore_irqs(dev);

@@ -249,15 +234,6 @@ void unmask_msi_irq(struct irq_data *data)
msi_set_mask_bit(data, 0);
}

-void default_restore_msi_irqs(struct pci_dev *dev)
-{
- struct msi_desc *entry;
-
- list_for_each_entry(entry, &dev->msi_list, list) {
- default_restore_msi_irq(dev, entry->irq);
- }
-}
-
void read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
{
BUG_ON(entry->dev->current_state != PCI_D0);
@@ -361,7 +337,7 @@ static void free_msi_irqs(struct pci_dev *dev)
BUG_ON(irq_has_action(entry->irq + i));
}

- arch_teardown_msi_irqs(dev);
+ teardown_msi_irqs(dev);

list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
if (entry->msi_attrib.is_msix) {
@@ -420,7 +396,7 @@ static void __pci_restore_msi_state(struct pci_dev *dev)

pci_intx_for_msi(dev, 0);
msi_set_enable(dev, 0);
- arch_restore_msi_irqs(dev);
+ restore_msi_irqs(dev);

pci_read_config_word(dev, dev->msi_cap + PCI_MSI_FLAGS, &control);
msi_mask_irq(entry, msi_mask(entry->msi_attrib.multi_cap),
@@ -443,7 +419,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
msix_clear_and_set_ctrl(dev, 0,
PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL);

- arch_restore_msi_irqs(dev);
+ restore_msi_irqs(dev);
list_for_each_entry(entry, &dev->msi_list, list) {
msix_mask_irq(entry, entry->masked);
}
@@ -613,7 +589,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
list_add_tail(&entry->list, &dev->msi_list);

/* Configure MSI capability structure */
- ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI);
+ ret = setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI);
if (ret) {
msi_mask_irq(entry, mask, ~mask);
free_msi_irqs(dev);
@@ -728,7 +704,7 @@ static int msix_capability_init(struct pci_dev *dev,
if (ret)
return ret;

- ret = arch_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX);
+ ret = setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSIX);
if (ret)
goto out_avail;

diff --git a/include/linux/msi.h b/include/linux/msi.h
index 4cf1f31..920ad52 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -48,20 +48,6 @@ struct msi_desc {
struct msi_msg msg;
};

-/*
- * The arch hooks to setup up msi irqs. Those functions are
- * implemented as weak symbols so that they /can/ be overriden by
- * architecture specific code if needed.
- */
-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc);
-void arch_teardown_msi_irq(unsigned int irq);
-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
-void arch_teardown_msi_irqs(struct pci_dev *dev);
-void arch_restore_msi_irqs(struct pci_dev *dev);
-
-void default_teardown_msi_irqs(struct pci_dev *dev);
-void default_restore_msi_irqs(struct pci_dev *dev);
-
struct msi_chip {
struct module *owner;
struct device *dev;
--
1.7.1

--
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-09-25 03:14:31 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/kernel/pci_gx.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/tile/kernel/pci_gx.c b/arch/tile/kernel/pci_gx.c
index e39f9c5..4912b75 100644
--- a/arch/tile/kernel/pci_gx.c
+++ b/arch/tile/kernel/pci_gx.c
@@ -1485,7 +1485,7 @@ static struct irq_chip tilegx_msi_chip = {
/* TBD: support set_affinity. */
};

-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+static int tile_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
{
struct pci_controller *controller;
gxio_trio_context_t *trio_context;
@@ -1604,7 +1604,17 @@ is_64_failure:
return ret;
}

-void arch_teardown_msi_irq(unsigned int irq)
+void tile_teardown_msi_irq(unsigned int irq)
{
irq_free_hwirq(irq);
}
+
+static struct msi_chip tile_msi_chip = {
+ .setup_irq = tile_setup_msi_irq,
+ .teardown_irq = tile_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return &tile_msi_chip;
+}
--
1.7.1

--
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-09-25 03:14:29 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/kernel/msi_ia64.c | 18 ++++++++++++++----
1 files changed, 14 insertions(+), 4 deletions(-)

diff --git a/arch/ia64/kernel/msi_ia64.c b/arch/ia64/kernel/msi_ia64.c
index 4efe748..55ac859 100644
--- a/arch/ia64/kernel/msi_ia64.c
+++ b/arch/ia64/kernel/msi_ia64.c
@@ -112,15 +112,15 @@ static struct irq_chip ia64_msi_chip = {
};


-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+static int arch_ia64_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
if (platform_setup_msi_irq)
- return platform_setup_msi_irq(pdev, desc);
+ return platform_setup_msi_irq(dev, desc);

- return ia64_setup_msi_irq(pdev, desc);
+ return ia64_setup_msi_irq(dev, desc);
}

-void arch_teardown_msi_irq(unsigned int irq)
+static void arch_ia64_teardown_msi_irq(unsigned int irq)
{
if (platform_teardown_msi_irq)
return platform_teardown_msi_irq(irq);
@@ -128,6 +128,16 @@ void arch_teardown_msi_irq(unsigned int irq)
return ia64_teardown_msi_irq(irq);
}

+static struct msi_chip chip = {
+ .setup_irq = arch_ia64_setup_msi_irq,
+ .teardown_irq = arch_ia64_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return &chip;
+}
+
#ifdef CONFIG_INTEL_IOMMU
#ifdef CONFIG_SMP
static int dmar_msi_set_affinity(struct irq_data *data,
--
1.7.1

--
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-09-25 03:14:30 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 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index b36365f..2a89ee2 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -905,7 +905,7 @@ int pci_domain_nr(struct pci_bus *pbus)
EXPORT_SYMBOL(pci_domain_nr);

#ifdef CONFIG_PCI_MSI
-int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
+int sparc_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
{
struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;
unsigned int irq;
@@ -916,7 +916,7 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
return pbm->setup_msi_irq(&irq, pdev, desc);
}

-void arch_teardown_msi_irq(unsigned int irq)
+void sparc_teardown_msi_irq(unsigned int irq)
{
struct msi_desc *entry = irq_get_msi_desc(irq);
struct pci_dev *pdev = entry->dev;
@@ -925,6 +925,16 @@ void arch_teardown_msi_irq(unsigned int irq)
if (pbm->teardown_msi_irq)
pbm->teardown_msi_irq(irq, pdev);
}
+
+static struct msi_chip sparc_msi_chip = {
+ .setup_irq = sparc_setup_msi_irq,
+ .teardown_irq = sparc_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return &sparc_msi_chip;
+}
#endif /* !(CONFIG_PCI_MSI) */

static void ali_sound_dma_hack(struct pci_dev *pdev, int set_bit)
--
1.7.1

--
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-09-25 03:14:16 UTC
Permalink
Introduce weak arch_find_msi_chip() to find the match msi_chip.
Currently, MSI chip associates pci bus to msi_chip. Because in
ARM platform, there may be more than one MSI controller in system.
Associate pci bus to msi_chip help pci device to find the match
msi_chip and setup MSI/MSI-X irq correctly. But in other platform,
like in x86. we only need one MSI chip, because all device use
the same MSI address/data and irq etc. So it's no need to associate
pci bus to MSI chip, just use a arch function, arch_find_msi_chip()
to return the MSI chip for simplicity. The default weak
arch_find_msi_chip() used in ARM platform, find the MSI chip
by pci bus.

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

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 5f8f3af..3acbe65 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -29,9 +29,14 @@ static int pci_msi_enable = 1;

/* Arch hooks */

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

if (!chip || !chip->setup_irq)
--
1.7.1
Thierry Reding
2014-09-25 07:26:20 UTC
Permalink
Post by Yijing Wang
Introduce weak arch_find_msi_chip() to find the match msi_chip.
Currently, MSI chip associates pci bus to msi_chip. Because in
ARM platform, there may be more than one MSI controller in system.
Associate pci bus to msi_chip help pci device to find the match
msi_chip and setup MSI/MSI-X irq correctly. But in other platform,
like in x86. we only need one MSI chip, because all device use
the same MSI address/data and irq etc. So it's no need to associate
pci bus to MSI chip, just use a arch function, arch_find_msi_chip()
to return the MSI chip for simplicity. The default weak
arch_find_msi_chip() used in ARM platform, find the MSI chip
by pci bus.
Can't x86 simply set the bus' .msi field anyway? It would seem to be
easy to do and unifies the code rather than driving it further apart
using even more of the __weak functions.

Thierry
Yijing Wang
2014-09-26 02:10:23 UTC
Permalink
Post by Thierry Reding
Post by Yijing Wang
Introduce weak arch_find_msi_chip() to find the match msi_chip.
Currently, MSI chip associates pci bus to msi_chip. Because in
ARM platform, there may be more than one MSI controller in system.
Associate pci bus to msi_chip help pci device to find the match
msi_chip and setup MSI/MSI-X irq correctly. But in other platform,
like in x86. we only need one MSI chip, because all device use
the same MSI address/data and irq etc. So it's no need to associate
pci bus to MSI chip, just use a arch function, arch_find_msi_chip()
to return the MSI chip for simplicity. The default weak
arch_find_msi_chip() used in ARM platform, find the MSI chip
by pci bus.
Can't x86 simply set the bus' .msi field anyway? It would seem to be
easy to do and unifies the code rather than driving it further apart
using even more of the __weak functions.
As mentioned in the first reply, I will rework this one when we find a better solution.

Thanks!
Yijing.
Post by Thierry Reding
Thierry
--
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
Thomas Gleixner
2014-09-25 10:38:34 UTC
Permalink
Post by Yijing Wang
Introduce weak arch_find_msi_chip() to find the match msi_chip.
Currently, MSI chip associates pci bus to msi_chip. Because in
ARM platform, there may be more than one MSI controller in system.
Associate pci bus to msi_chip help pci device to find the match
msi_chip and setup MSI/MSI-X irq correctly. But in other platform,
like in x86. we only need one MSI chip, because all device use
the same MSI address/data and irq etc. So it's no need to associate
pci bus to MSI chip, just use a arch function, arch_find_msi_chip()
to return the MSI chip for simplicity. The default weak
arch_find_msi_chip() used in ARM platform, find the MSI chip
by pci bus.
This is really backwards. On one hand you try to get rid of the weak
arch functions zoo and then you invent new ones for no good
reason. Why can't x86 store the chip in the pci bus?

Looking deeper, I'm questioning the whole notion of different
msi_chips. Are this really different MSI controllers with a different
feature set or are this defacto multiple instances of the same
controller which just need a different data set?

Thanks,

tglx
Yijing Wang
2014-09-26 02:33:24 UTC
Permalink
Post by Thomas Gleixner
Post by Yijing Wang
Introduce weak arch_find_msi_chip() to find the match msi_chip.
Currently, MSI chip associates pci bus to msi_chip. Because in
ARM platform, there may be more than one MSI controller in system.
Associate pci bus to msi_chip help pci device to find the match
msi_chip and setup MSI/MSI-X irq correctly. But in other platform,
like in x86. we only need one MSI chip, because all device use
the same MSI address/data and irq etc. So it's no need to associate
pci bus to MSI chip, just use a arch function, arch_find_msi_chip()
to return the MSI chip for simplicity. The default weak
arch_find_msi_chip() used in ARM platform, find the MSI chip
by pci bus.
This is really backwards. On one hand you try to get rid of the weak
arch functions zoo and then you invent new ones for no good
reason. Why can't x86 store the chip in the pci bus?
Hi Thomas, I introduced this weak function , because I thought all platforms
except arm always have only one msi chip, and I hoped to provide a simplest
solution, less code changes. I consider several solutions to associate msi chip
and PCI device. In my reply to Thierry in first reply,
http://marc.info/?l=linux-pci&m=141169658208255&w=2
Could you give me some advices ?

Thanks!
Yijing.
Post by Thomas Gleixner
Looking deeper, I'm questioning the whole notion of different
msi_chips. Are this really different MSI controllers with a different
feature set or are this defacto multiple instances of the same
controller which just need a different data set?
Thanks,
tglx
.
--
Thanks!
Yijing
Yijing Wang
2014-09-26 02:44:26 UTC
Permalink
Post by Thomas Gleixner
Post by Yijing Wang
Introduce weak arch_find_msi_chip() to find the match msi_chip.
Currently, MSI chip associates pci bus to msi_chip. Because in
ARM platform, there may be more than one MSI controller in system.
Associate pci bus to msi_chip help pci device to find the match
msi_chip and setup MSI/MSI-X irq correctly. But in other platform,
like in x86. we only need one MSI chip, because all device use
the same MSI address/data and irq etc. So it's no need to associate
pci bus to MSI chip, just use a arch function, arch_find_msi_chip()
to return the MSI chip for simplicity. The default weak
arch_find_msi_chip() used in ARM platform, find the MSI chip
by pci bus.
This is really backwards. On one hand you try to get rid of the weak
arch functions zoo and then you invent new ones for no good
reason. Why can't x86 store the chip in the pci bus?
Looking deeper, I'm questioning the whole notion of different
msi_chips. Are this really different MSI controllers with a different
feature set or are this defacto multiple instances of the same
controller which just need a different data set?
MSI chip in this series is to setup MSI irq, including IRQ allocation, Map,
compose MSI msg ..., in different platform, many arch specific MSI irq details in it.
It's difficult to extract the common data and code.

I have a plan to rework MSI related irq_chips in kernel, PCI and Non-PCI, currently,
HPET, DMAR and PCI have their own irq_chip and MSI related functions, write_msi_msg(),
mask_msi_irq(), etc... I want to extract the common data set for that, so we can
remove lots of unnecessary MSI code.

Thanks!
Yijing.
Post by Thomas Gleixner
Thanks,
tglx
.
--
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
Thomas Gleixner
2014-09-26 10:38:26 UTC
Permalink
Post by Yijing Wang
Post by Thomas Gleixner
Post by Yijing Wang
Introduce weak arch_find_msi_chip() to find the match msi_chip.
Currently, MSI chip associates pci bus to msi_chip. Because in
ARM platform, there may be more than one MSI controller in system.
Associate pci bus to msi_chip help pci device to find the match
msi_chip and setup MSI/MSI-X irq correctly. But in other platform,
like in x86. we only need one MSI chip, because all device use
the same MSI address/data and irq etc. So it's no need to associate
pci bus to MSI chip, just use a arch function, arch_find_msi_chip()
to return the MSI chip for simplicity. The default weak
arch_find_msi_chip() used in ARM platform, find the MSI chip
by pci bus.
This is really backwards. On one hand you try to get rid of the weak
arch functions zoo and then you invent new ones for no good
reason. Why can't x86 store the chip in the pci bus?
Looking deeper, I'm questioning the whole notion of different
msi_chips. Are this really different MSI controllers with a different
feature set or are this defacto multiple instances of the same
controller which just need a different data set?
MSI chip in this series is to setup MSI irq, including IRQ allocation, Map,
compose MSI msg ..., in different platform, many arch specific MSI irq details in it.
It's difficult to extract the common data and code.
I have a plan to rework MSI related irq_chips in kernel, PCI and Non-PCI, currently,
HPET, DMAR and PCI have their own irq_chip and MSI related functions, write_msi_msg(),
mask_msi_irq(), etc... I want to extract the common data set for that, so we can
remove lots of unnecessary MSI code.
That makes sense. Can you please make sure that this does not conflict
with the ongoing work Jiang is doing in the x86 irq area with
hierarchical irqdomains to distangle layered levels like MSI from the
underlying vector/irqremap mechanics.

Thanks,

tglx
Yijing Wang
2014-09-28 02:35:09 UTC
Permalink
Post by Thomas Gleixner
Post by Yijing Wang
MSI chip in this series is to setup MSI irq, including IRQ allocation, Map,
compose MSI msg ..., in different platform, many arch specific MSI irq details in it.
It's difficult to extract the common data and code.
I have a plan to rework MSI related irq_chips in kernel, PCI and Non-PCI, currently,
HPET, DMAR and PCI have their own irq_chip and MSI related functions, write_msi_msg(),
mask_msi_irq(), etc... I want to extract the common data set for that, so we can
remove lots of unnecessary MSI code.
That makes sense. Can you please make sure that this does not conflict
with the ongoing work Jiang is doing in the x86 irq area with
hierarchical irqdomains to distangle layered levels like MSI from the
underlying vector/irqremap mechanics.
Yes, I'm reviewing Jiang hierarchical irqdomains series, I'm interested in that changes.

Thanks!
Yijing.
Post by Thomas Gleixner
Thanks,
tglx
.
--
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-09-25 03:14:23 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 <***@huawei.com>
Cc: Thomas Gleixner <***@linutronix.de>
---
arch/mips/pci/msi-xlp.c | 4 +---
1 files changed, 1 insertions(+), 3 deletions(-)

diff --git a/arch/mips/pci/msi-xlp.c b/arch/mips/pci/msi-xlp.c
index fa374fe..e469dc7 100644
--- a/arch/mips/pci/msi-xlp.c
+++ b/arch/mips/pci/msi-xlp.c
@@ -443,10 +443,8 @@ static int xlp_setup_msix(uint64_t lnkbase, int node, int link,
msg.data = 0xc00 | msixvec;

ret = irq_set_msi_desc(xirq, desc);
- if (ret < 0) {
- destroy_irq(xirq);
+ if (ret < 0)
return ret;
- }

write_msi_msg(xirq, &msg);
return 0;
--
1.7.1
Yijing Wang
2014-09-25 03:14:27 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: Sebastian Ott <***@linux.vnet.ibm.com>
---
arch/s390/pci/pci.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 552b990..da5316e 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -358,7 +358,7 @@ static void zpci_irq_handler(struct airq_struct *airq)
}
}

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

-void arch_teardown_msi_irqs(struct pci_dev *pdev)
+static void zpci_teardown_msi_irqs(struct pci_dev *pdev)
{
struct zpci_dev *zdev = get_zdev(pdev);
struct msi_desc *msi;
@@ -464,6 +464,16 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
airq_iv_free_bit(zpci_aisb_iv, zdev->aisb);
}

+static struct msi_chip zpci_msi_chip = {
+ .setup_irqs = zpci_setup_msi_irqs,
+ .teardown_irqs = zpci_teardown_msi_irqs,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return &zpci_msi_chip;
+}
+
static void zpci_map_resources(struct zpci_dev *zdev)
{
struct pci_dev *pdev = zdev->pdev;
--
1.7.1

--
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
Thierry Reding
2014-09-25 07:38:01 UTC
Permalink
On Thu, Sep 25, 2014 at 11:14:27AM +0800, Yijing Wang wrote:
[...]
Post by Yijing Wang
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
[...]
Post by Yijing Wang
@@ -358,7 +358,7 @@ static void zpci_irq_handler(struct airq_struct *airq)
}
}
-int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+int zpci_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
static?
Yijing Wang
2014-09-26 02:14:09 UTC
Permalink
Post by Thierry Reding
[...]
Post by Yijing Wang
diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
[...]
Post by Yijing Wang
@@ -358,7 +358,7 @@ static void zpci_irq_handler(struct airq_struct *airq)
}
}
-int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
+int zpci_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
static?
Yes, Will update.
--
Thanks!
Yijing
Yijing Wang
2014-09-25 03:14:19 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.

Tested-by: Konrad Rzeszutek Wilk <***@oracle.com>
Signed-off-by: Yijing Wang <***@huawei.com>
Acked-by: David Vrabel <***@citrix.com>
Reviewed-by: Konrad Rzeszutek Wilk <***@oracle.com>
CC: Konrad Rzeszutek Wilk <***@oracle.com>
---
arch/x86/pci/xen.c | 46 ++++++++++++++++++++++++++++++----------------
1 files changed, 30 insertions(+), 16 deletions(-)

diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index 84c2fce..e669ee4 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -376,6 +376,11 @@ static void xen_initdom_restore_msi_irqs(struct pci_dev *dev)
}
#endif

+static void xen_teardown_msi_irq(unsigned int irq)
+{
+ xen_destroy_irq(irq);
+}
+
static void xen_teardown_msi_irqs(struct pci_dev *dev)
{
struct msi_desc *msidesc;
@@ -385,19 +390,26 @@ static void xen_teardown_msi_irqs(struct pci_dev *dev)
xen_pci_frontend_disable_msix(dev);
else
xen_pci_frontend_disable_msi(dev);
-
- /* Free the IRQ's and the msidesc using the generic code. */
- default_teardown_msi_irqs(dev);
-}
-
-static void xen_teardown_msi_irq(unsigned int irq)
-{
- xen_destroy_irq(irq);
+
+ list_for_each_entry(msidesc, &dev->msi_list, list) {
+ int i, nvec;
+ if (msidesc->irq == 0)
+ continue;
+ if (msidesc->nvec_used)
+ nvec = msidesc->nvec_used;
+ else
+ nvec = 1 << msidesc->msi_attrib.multiple;
+ for (i = 0; i < nvec; i++)
+ xen_teardown_msi_irq(msidesc->irq + i);
+ }
}

void xen_nop_msi_mask(struct irq_data *data)
{
}
+
+struct msi_chip xen_msi_chip;
+
#endif

int __init pci_xen_init(void)
@@ -418,9 +430,9 @@ int __init pci_xen_init(void)
#endif

#ifdef CONFIG_PCI_MSI
- x86_msi.setup_msi_irqs = xen_setup_msi_irqs;
- x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
- x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs;
+ xen_msi_chip.setup_irqs = xen_setup_msi_irqs;
+ xen_msi_chip.teardown_irqs = xen_teardown_msi_irqs;
+ x86_msi_chip = &xen_msi_chip;
msi_chip.irq_mask = xen_nop_msi_mask;
msi_chip.irq_unmask = xen_nop_msi_mask;
#endif
@@ -441,8 +453,9 @@ int __init pci_xen_hvm_init(void)
#endif

#ifdef CONFIG_PCI_MSI
- x86_msi.setup_msi_irqs = xen_hvm_setup_msi_irqs;
- x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
+ xen_msi_chip.setup_irqs = xen_hvm_setup_msi_irqs;
+ xen_msi_chip.teardown_irq = xen_teardown_msi_irq;
+ x86_msi_chip = &xen_msi_chip;
#endif
return 0;
}
@@ -499,9 +512,10 @@ int __init pci_xen_initial_domain(void)
int irq;

#ifdef CONFIG_PCI_MSI
- x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs;
- x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
- x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs;
+ xen_msi_chip.setup_irqs = xen_initdom_setup_msi_irqs;
+ xen_msi_chip.teardown_irq = xen_teardown_msi_irq;
+ xen_msi_chip.restore_irqs = xen_initdom_restore_msi_irqs;
+ x86_msi_chip = &xen_msi_chip;
msi_chip.irq_mask = xen_nop_msi_mask;
msi_chip.irq_unmask = xen_nop_msi_mask;
#endif
--
1.7.1
Yijing Wang
2014-09-25 03:14:18 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 | 1 +
arch/x86/kernel/apic/io_apic.c | 12 ++++++++++++
2 files changed, 13 insertions(+), 0 deletions(-)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 0892ea0..878a06d 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -101,6 +101,7 @@ void native_teardown_msi_irq(unsigned int irq);
void native_restore_msi_irqs(struct pci_dev *dev);
int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
unsigned int irq_base, unsigned int irq_offset);
+extern struct msi_chip *x86_msi_chip;
#else
#define native_setup_msi_irqs NULL
#define native_teardown_msi_irq NULL
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 2a2ec28..882b95e 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3337,6 +3337,18 @@ int default_setup_hpet_msi(unsigned int irq, unsigned int id)
}
#endif

+struct msi_chip apic_msi_chip = {
+ .setup_irqs = native_setup_msi_irqs,
+ .teardown_irq = native_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return x86_msi_chip;
+}
+
+struct msi_chip *x86_msi_chip = &apic_msi_chip;
+
#endif /* CONFIG_PCI_MSI */
/*
* Hypertransport interrupt support
--
1.7.1

--
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-09-25 03:14:20 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 | 6 ++++++
1 files changed, 6 insertions(+), 0 deletions(-)

diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 33c4395..7929590 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -148,6 +148,11 @@ static int irq_remapping_setup_msi_irqs(struct pci_dev *dev,
return do_setup_msix_irqs(dev, nvec);
}

+static struct msi_chip remap_msi_chip = {
+ .setup_irqs = irq_remapping_setup_msi_irqs,
+ .teardown_irq = native_teardown_msi_irq,
+};
+
static void eoi_ioapic_pin_remapped(int apic, int pin, int vector)
{
/*
@@ -168,6 +173,7 @@ static void __init irq_remapping_modify_x86_ops(void)
x86_msi.setup_msi_irqs = irq_remapping_setup_msi_irqs;
x86_msi.setup_hpet_msi = setup_hpet_msi_remapped;
x86_msi.compose_msi_msg = compose_remapped_msi_msg;
+ x86_msi_chip = &remap_msi_chip;
}

static __init int setup_nointremap(char *str)
--
1.7.1
Yijing Wang
2014-09-25 03:14:25 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/pci/pci-xlr.c | 15 +++++++++++++--
1 files changed, 13 insertions(+), 2 deletions(-)

diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c
index 0dde803..7bd91cc 100644
--- a/arch/mips/pci/pci-xlr.c
+++ b/arch/mips/pci/pci-xlr.c
@@ -214,11 +214,11 @@ static int get_irq_vector(const struct pci_dev *dev)
}

#ifdef CONFIG_PCI_MSI
-void arch_teardown_msi_irq(unsigned int irq)
+void xlr_teardown_msi_irq(unsigned int irq)
{
}

-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+int xlr_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
struct msi_msg msg;
struct pci_dev *lnk;
@@ -263,6 +263,17 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
write_msi_msg(irq, &msg);
return 0;
}
+
+static struct msi_chip xlr_msi_chip = {
+ .setup_irq = xlr_setup_msi_irq,
+ .teardown_irq = xlr_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return &xlr_msi_chip;
+}
+
#endif

/* Extra ACK needed for XLR on chip PCI controller */
--
1.7.1
Thierry Reding
2014-09-25 07:37:01 UTC
Permalink
On Thu, Sep 25, 2014 at 11:14:25AM +0800, Yijing Wang wrote:
[...]
Post by Yijing Wang
diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c
[...]
Post by Yijing Wang
@@ -214,11 +214,11 @@ static int get_irq_vector(const struct pci_dev *dev)
}
#ifdef CONFIG_PCI_MSI
-void arch_teardown_msi_irq(unsigned int irq)
+void xlr_teardown_msi_irq(unsigned int irq)
{
}
-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+int xlr_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
Can both of these now be static?

Thierry
Yijing Wang
2014-09-26 02:13:42 UTC
Permalink
Post by Thierry Reding
[...]
Post by Yijing Wang
diff --git a/arch/mips/pci/pci-xlr.c b/arch/mips/pci/pci-xlr.c
[...]
Post by Yijing Wang
@@ -214,11 +214,11 @@ static int get_irq_vector(const struct pci_dev *dev)
}
#ifdef CONFIG_PCI_MSI
-void arch_teardown_msi_irq(unsigned int irq)
+void xlr_teardown_msi_irq(unsigned int irq)
{
}
-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+int xlr_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
Can both of these now be static?
Yes, Will update.
Post by Thierry Reding
Thierry
--
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-09-25 03:14:24 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/pci/msi-xlp.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/mips/pci/msi-xlp.c b/arch/mips/pci/msi-xlp.c
index e469dc7..6b791ef 100644
--- a/arch/mips/pci/msi-xlp.c
+++ b/arch/mips/pci/msi-xlp.c
@@ -245,7 +245,7 @@ static struct irq_chip xlp_msix_chip = {
.irq_unmask = unmask_msi_irq,
};

-void arch_teardown_msi_irq(unsigned int irq)
+void xlp_teardown_msi_irq(unsigned int irq)
{
}

@@ -450,7 +450,7 @@ static int xlp_setup_msix(uint64_t lnkbase, int node, int link,
return 0;
}

-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+static int xlp_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
struct pci_dev *lnkdev;
uint64_t lnkbase;
@@ -472,6 +472,16 @@ int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
return xlp_setup_msi(lnkbase, node, link, desc);
}

+static struct msi_chip xlp_chip = {
+ .setup_irq = xlp_setup_msi_irq,
+ .teardown_irq = xlp_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return &xlp_chip;
+}
+
void __init xlp_init_node_msi_irqs(int node, int link)
{
struct nlm_soc_info *nodep;
--
1.7.1
Thierry Reding
2014-09-25 07:36:09 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.
Nit: s/irq/IRQ/ in the above.
Post by Yijing Wang
---
arch/mips/pci/msi-xlp.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/mips/pci/msi-xlp.c b/arch/mips/pci/msi-xlp.c
index e469dc7..6b791ef 100644
--- a/arch/mips/pci/msi-xlp.c
+++ b/arch/mips/pci/msi-xlp.c
@@ -245,7 +245,7 @@ static struct irq_chip xlp_msix_chip = {
.irq_unmask = unmask_msi_irq,
};
-void arch_teardown_msi_irq(unsigned int irq)
+void xlp_teardown_msi_irq(unsigned int irq)
Should this not be static now as well?

Thierry
Yijing Wang
2014-09-26 02:13:21 UTC
Permalink
Post by Thierry Reding
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.
Nit: s/irq/IRQ/ in the above.
Post by Yijing Wang
---
arch/mips/pci/msi-xlp.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)
diff --git a/arch/mips/pci/msi-xlp.c b/arch/mips/pci/msi-xlp.c
index e469dc7..6b791ef 100644
--- a/arch/mips/pci/msi-xlp.c
+++ b/arch/mips/pci/msi-xlp.c
@@ -245,7 +245,7 @@ static struct irq_chip xlp_msix_chip = {
.irq_unmask = unmask_msi_irq,
};
-void arch_teardown_msi_irq(unsigned int irq)
+void xlp_teardown_msi_irq(unsigned int irq)
Should this not be static now as well?
Yes, Will update.
Post by Thierry Reding
Thierry
--
Thanks!
Yijing
Yijing Wang
2014-09-25 03:14:12 UTC
Permalink
Currently, PCI drivers will initialize bus->msi in
pcibios_add_bus(). pcibios_add_bus() will be called
in every pci bus initialization. So the bus->msi
assignment in pci_alloc_child_bus() is useless.

Signed-off-by: Yijing Wang <wangyijing-hv44wF8Li93QT0dZR+***@public.gmane.org>
CC: Thierry Reding <thierry.reding-***@public.gmane.org>
CC: Thomas Petazzoni <thomas.petazzoni-wi1+55ScJUtKEb57/***@public.gmane.org>
---
drivers/pci/probe.c | 1 -
1 files changed, 0 insertions(+), 1 deletions(-)

diff --git a/drivers/pci/probe.c b/drivers/pci/probe.c
index e3cf8a2..8296576 100644
--- a/drivers/pci/probe.c
+++ b/drivers/pci/probe.c
@@ -677,7 +677,6 @@ static struct pci_bus *pci_alloc_child_bus(struct pci_bus *parent,

child->parent = parent;
child->ops = parent->ops;
- child->msi = parent->msi;
child->sysdata = parent->sysdata;
child->bus_flags = parent->bus_flags;
--
1.7.1
Thierry Reding
2014-09-25 07:06:01 UTC
Permalink
Post by Yijing Wang
Currently, PCI drivers will initialize bus->msi in
pcibios_add_bus(). pcibios_add_bus() will be called
in every pci bus initialization. So the bus->msi
assignment in pci_alloc_child_bus() is useless.
I think this should be the other way around. The default should be to
inherit bus->msi from the parent. That way drivers don't typically have
to do it, yet they can still opt to override it if they need to.

For Tegra for example I think it would work if we assigned the MSI chip
to the root bus (in tegra_pcie_scan_bus()) and then have it propagated
to child busses in pci_alloc_child_bus() so that tegra_pcie_add_bus()
can be removed altogether.

Thierry
Yijing Wang
2014-09-26 01:55:07 UTC
Permalink
Post by Thierry Reding
Post by Yijing Wang
Currently, PCI drivers will initialize bus->msi in
pcibios_add_bus(). pcibios_add_bus() will be called
in every pci bus initialization. So the bus->msi
assignment in pci_alloc_child_bus() is useless.
I think this should be the other way around. The default should be to
inherit bus->msi from the parent. That way drivers don't typically have
to do it, yet they can still opt to override it if they need to.
For Tegra for example I think it would work if we assigned the MSI chip
to the root bus (in tegra_pcie_scan_bus()) and then have it propagated
to child busses in pci_alloc_child_bus() so that tegra_pcie_add_bus()
can be removed altogether.
Hi Thierry, thanks very much for your review and comments!

Because pcibios_add_bus() and "child->msi = parent->msi;" in pci_alloc_child_bus()
do the same thing. So I think we should use one and remove another. I like
the latter.

In addition, I consider several solutions to associate msi chip and PCI device.

1. Add a msi_chip member in PCI arch sysdata to store the msi_chip pointer. Because
all PCI devices under a PCI hostbridge always share the same msi chip, so every PCI device
can find the msi chip by pci_bus->sysdata, but in this solution, we also need to add
ARCH specific functions to extract msi chip from PCI arch sysdata, like pci_domain_nr().
Then we can remove .add_bus() like tegra_pcie_add_bus() and the msi assignment in pci_alloc_child_bus().

2. Remove .add_bus() functions, associate PCI root bus and msi chip after PCI root bus created,
as you mentioned above. In this solution we need to associate PCI root bus and msi chip in all PCI
hostbridge drivers, like in tegra_pcie_scan_bus().


3. Introduce a global msi chip list, currently, only in arm, there maybe more than one type MSI chip,
but in arm, we can find msi chip by PCI hostbridge platform device's of_node, Eg. use "msi-parent" property
to find it. Or msi chip is integrated into PCI hostbridge, we can find msi chip by compare msi_chip->dev and
PCI hostbridge's platform device's struct device *dev pointer. And because PCI hostbridge platform device pass
to pci_create_root_bus() as the parent device, so every PCI devices can first find the platform device, then
to find the msi chip, this solution looks a bit ugly, but we only associate pci hostbridge and msi chip, PCI child
buses and devices do not have to know the msi chip details.

4. Last, in this series, introduced weak arch function arch_find_msi_chip(), it's the simplest one, because all platforms
except arm, only one msi chip will exist in system.

What do you think about this ?

Thanks!
Yijing.
Post by Thierry Reding
Thierry
--
Thanks!
Yijing
Yijing Wang
2014-09-25 03:14:26 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: Michael Ellerman <***@ellerman.id.au>
---
arch/powerpc/kernel/msi.c | 14 ++++++++++++--
1 files changed, 12 insertions(+), 2 deletions(-)

diff --git a/arch/powerpc/kernel/msi.c b/arch/powerpc/kernel/msi.c
index 71bd161..01781a4 100644
--- a/arch/powerpc/kernel/msi.c
+++ b/arch/powerpc/kernel/msi.c
@@ -13,7 +13,7 @@

#include <asm/machdep.h>

-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int ppc_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
if (!ppc_md.setup_msi_irqs || !ppc_md.teardown_msi_irqs) {
pr_debug("msi: Platform doesn't provide MSI callbacks.\n");
@@ -27,7 +27,17 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
return ppc_md.setup_msi_irqs(dev, nvec, type);
}

-void arch_teardown_msi_irqs(struct pci_dev *dev)
+static void ppc_teardown_msi_irqs(struct pci_dev *dev)
{
ppc_md.teardown_msi_irqs(dev);
}
+
+static struct msi_chip ppc_msi_chip = {
+ .setup_irqs = ppc_setup_msi_irqs,
+ .teardown_irqs = ppc_teardown_msi_irqs,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return &ppc_msi_chip;
+}
--
1.7.1
Yijing Wang
2014-09-25 03:14:21 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 | 3 ---
arch/x86/include/asm/x86_init.h | 4 ----
arch/x86/kernel/apic/io_apic.c | 2 +-
arch/x86/kernel/x86_init.c | 24 ------------------------
drivers/iommu/irq_remapping.c | 1 -
5 files changed, 1 insertions(+), 33 deletions(-)

diff --git a/arch/x86/include/asm/pci.h b/arch/x86/include/asm/pci.h
index 878a06d..34f9676 100644
--- a/arch/x86/include/asm/pci.h
+++ b/arch/x86/include/asm/pci.h
@@ -96,14 +96,11 @@ extern void pci_iommu_alloc(void);
#ifdef CONFIG_PCI_MSI
/* implemented in arch/x86/kernel/apic/io_apic. */
struct msi_desc;
-int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type);
void native_teardown_msi_irq(unsigned int irq);
-void native_restore_msi_irqs(struct pci_dev *dev);
int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
unsigned int irq_base, unsigned int irq_offset);
extern struct msi_chip *x86_msi_chip;
#else
-#define native_setup_msi_irqs NULL
#define native_teardown_msi_irq NULL
#endif

diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index f58a9c7..2514f67 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -174,13 +174,9 @@ struct pci_dev;
struct msi_msg;

struct x86_msi_ops {
- int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type);
void (*compose_msi_msg)(struct pci_dev *dev, unsigned int irq,
unsigned int dest, struct msi_msg *msg,
u8 hpet_id);
- void (*teardown_msi_irq)(unsigned int irq);
- void (*teardown_msi_irqs)(struct pci_dev *dev);
- void (*restore_msi_irqs)(struct pci_dev *dev);
int (*setup_hpet_msi)(unsigned int irq, unsigned int id);
};

diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index 882b95e..f998192 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3200,7 +3200,7 @@ int setup_msi_irq(struct pci_dev *dev, struct msi_desc *msidesc,
return 0;
}

-int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int native_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
struct msi_desc *msidesc;
unsigned int irq;
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index 234b072..cc32568 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -110,34 +110,10 @@ EXPORT_SYMBOL_GPL(x86_platform);

#if defined(CONFIG_PCI_MSI)
struct x86_msi_ops x86_msi = {
- .setup_msi_irqs = native_setup_msi_irqs,
.compose_msi_msg = native_compose_msi_msg,
- .teardown_msi_irq = native_teardown_msi_irq,
- .teardown_msi_irqs = default_teardown_msi_irqs,
- .restore_msi_irqs = default_restore_msi_irqs,
.setup_hpet_msi = default_setup_hpet_msi,
};

-/* MSI arch specific hooks */
-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
-{
- return x86_msi.setup_msi_irqs(dev, nvec, type);
-}
-
-void arch_teardown_msi_irqs(struct pci_dev *dev)
-{
- x86_msi.teardown_msi_irqs(dev);
-}
-
-void arch_teardown_msi_irq(unsigned int irq)
-{
- x86_msi.teardown_msi_irq(irq);
-}
-
-void arch_restore_msi_irqs(struct pci_dev *dev)
-{
- x86_msi.restore_msi_irqs(dev);
-}
#endif

struct x86_io_apic_ops x86_io_apic_ops = {
diff --git a/drivers/iommu/irq_remapping.c b/drivers/iommu/irq_remapping.c
index 7929590..99b1c0f 100644
--- a/drivers/iommu/irq_remapping.c
+++ b/drivers/iommu/irq_remapping.c
@@ -170,7 +170,6 @@ static void __init irq_remapping_modify_x86_ops(void)
x86_io_apic_ops.set_affinity = set_remapped_irq_affinity;
x86_io_apic_ops.setup_entry = setup_ioapic_remapped_entry;
x86_io_apic_ops.eoi_ioapic_pin = eoi_ioapic_pin_remapped;
- x86_msi.setup_msi_irqs = irq_remapping_setup_msi_irqs;
x86_msi.setup_hpet_msi = setup_hpet_msi_remapped;
x86_msi.compose_msi_msg = compose_remapped_msi_msg;
x86_msi_chip = &remap_msi_chip;
--
1.7.1
Yijing Wang
2014-09-25 03:14:11 UTC
Permalink
Msi_chip functions setup_irq/teardown_irq rarely use msi_chip
argument. We can look up msi_chip pointer by the device pointer
or irq number, so clean up msi_chip argument.

Signed-off-by: Yijing Wang <wangyijing-hv44wF8Li93QT0dZR+***@public.gmane.org>
CC: Thierry Reding <thierry.reding-***@public.gmane.org>
CC: Thomas Petazzoni <thomas.petazzoni-wi1+55ScJUtKEb57/***@public.gmane.org>
---
drivers/irqchip/irq-armada-370-xp.c | 8 +++-----
drivers/pci/host/pci-tegra.c | 8 +++++---
drivers/pci/host/pcie-designware.c | 4 ++--
drivers/pci/host/pcie-rcar.c | 8 +++++---
drivers/pci/msi.c | 4 ++--
include/linux/msi.h | 5 ++---
6 files changed, 19 insertions(+), 18 deletions(-)

diff --git a/drivers/irqchip/irq-armada-370-xp.c b/drivers/irqchip/irq-armada-370-xp.c
index df60eab..3909d06 100644
--- a/drivers/irqchip/irq-armada-370-xp.c
+++ b/drivers/irqchip/irq-armada-370-xp.c
@@ -129,9 +129,8 @@ static void armada_370_xp_free_msi(int hwirq)
mutex_unlock(&msi_used_lock);
}

-static int armada_370_xp_setup_msi_irq(struct msi_chip *chip,
- struct pci_dev *pdev,
- struct msi_desc *desc)
+static int armada_370_xp_setup_msi_irq(struct pci_dev *pdev,
+ struct msi_desc *desc)
{
struct msi_msg msg;
int virq, hwirq;
@@ -160,8 +159,7 @@ static int armada_370_xp_setup_msi_irq(struct msi_chip *chip,
return 0;
}

-static void armada_370_xp_teardown_msi_irq(struct msi_chip *chip,
- unsigned int irq)
+static void armada_370_xp_teardown_msi_irq(unsigned int irq)
{
struct irq_data *d = irq_get_irq_data(irq);
unsigned long hwirq = d->hwirq;
diff --git a/drivers/pci/host/pci-tegra.c b/drivers/pci/host/pci-tegra.c
index 0fb0fdb..edd4040 100644
--- a/drivers/pci/host/pci-tegra.c
+++ b/drivers/pci/host/pci-tegra.c
@@ -1157,9 +1157,10 @@ static irqreturn_t tegra_pcie_msi_irq(int irq, void *data)
return processed > 0 ? IRQ_HANDLED : IRQ_NONE;
}

-static int tegra_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
+static int tegra_msi_setup_irq(struct pci_dev *pdev,
struct msi_desc *desc)
{
+ struct msi_chip *chip = pdev->bus->msi;
struct tegra_msi *msi = to_tegra_msi(chip);
struct msi_msg msg;
unsigned int irq;
@@ -1185,10 +1186,11 @@ static int tegra_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
return 0;
}

-static void tegra_msi_teardown_irq(struct msi_chip *chip, unsigned int irq)
+static void tegra_msi_teardown_irq(unsigned int irq)
{
- struct tegra_msi *msi = to_tegra_msi(chip);
struct irq_data *d = irq_get_irq_data(irq);
+ struct msi_chip *chip = irq_get_chip_data(irq);
+ struct tegra_msi *msi = to_tegra_msi(chip);

tegra_msi_free(msi, d->hwirq);
}
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index fa2fa45..517f1e1 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -342,7 +342,7 @@ static void clear_irq(unsigned int irq)
msi->msi_attrib.multiple = 0;
}

-static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
+static int dw_msi_setup_irq(struct pci_dev *pdev,
struct msi_desc *desc)
{
int irq, pos, msgvec;
@@ -383,7 +383,7 @@ static int dw_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
return 0;
}

-static void dw_msi_teardown_irq(struct msi_chip *chip, unsigned int irq)
+static void dw_msi_teardown_irq(unsigned int irq)
{
clear_irq(irq);
}
diff --git a/drivers/pci/host/pcie-rcar.c b/drivers/pci/host/pcie-rcar.c
index 4884ee5..647bc9f 100644
--- a/drivers/pci/host/pcie-rcar.c
+++ b/drivers/pci/host/pcie-rcar.c
@@ -615,9 +615,10 @@ static irqreturn_t rcar_pcie_msi_irq(int irq, void *data)
return IRQ_HANDLED;
}

-static int rcar_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
+static int rcar_msi_setup_irq(struct pci_dev *pdev,
struct msi_desc *desc)
{
+ struct msi_chip *chip = pdev->bus->msi;
struct rcar_msi *msi = to_rcar_msi(chip);
struct rcar_pcie *pcie = container_of(chip, struct rcar_pcie, msi.chip);
struct msi_msg msg;
@@ -645,10 +646,11 @@ static int rcar_msi_setup_irq(struct msi_chip *chip, struct pci_dev *pdev,
return 0;
}

-static void rcar_msi_teardown_irq(struct msi_chip *chip, unsigned int irq)
+static void rcar_msi_teardown_irq(unsigned int irq)
{
- struct rcar_msi *msi = to_rcar_msi(chip);
struct irq_data *d = irq_get_irq_data(irq);
+ struct msi_chip *chip = irq_get_chip_data(irq);
+ struct rcar_msi *msi = to_rcar_msi(chip);

rcar_msi_free(msi, d->hwirq);
}
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index aae2fc8..51d7e62 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -37,7 +37,7 @@ int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
if (!chip || !chip->setup_irq)
return -EINVAL;

- err = chip->setup_irq(chip, dev, desc);
+ err = chip->setup_irq(dev, desc);
if (err < 0)
return err;

@@ -53,7 +53,7 @@ void __weak arch_teardown_msi_irq(unsigned int irq)
if (!chip || !chip->teardown_irq)
return;

- chip->teardown_irq(chip, irq);
+ chip->teardown_irq(irq);
}

int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 36c63cf..45ef8cb 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -68,9 +68,8 @@ struct msi_chip {
struct device_node *of_node;
struct list_head list;

- int (*setup_irq)(struct msi_chip *chip, struct pci_dev *dev,
- struct msi_desc *desc);
- void (*teardown_irq)(struct msi_chip *chip, unsigned int irq);
+ int (*setup_irq)(struct pci_dev *dev, struct msi_desc *desc);
+ void (*teardown_irq)(unsigned int irq);
};

#endif /* LINUX_MSI_H */
--
1.7.1
Thierry Reding
2014-09-25 07:15:38 UTC
Permalink
Post by Yijing Wang
Msi_chip functions setup_irq/teardown_irq rarely use msi_chip
argument.
That's not true. Out of the four drivers that you modify two use the
parameter. And the two that don't probably should be using it too.

50% is not "rarely". =)
Post by Yijing Wang
We can look up msi_chip pointer by the device pointer
or irq number, so clean up msi_chip argument.
I don't like this particular change. The idea was to keep the API object
oriented so that drivers wouldn't have to know where to get the MSI chip
from. It also makes it more resilient against code reorganizations since
the core code is the only place that needs to know where to get the chip
from.

Thierry
Thomas Gleixner
2014-09-25 10:20:20 UTC
Permalink
Post by Thierry Reding
Post by Yijing Wang
Msi_chip functions setup_irq/teardown_irq rarely use msi_chip
argument.
That's not true. Out of the four drivers that you modify two use the
parameter. And the two that don't probably should be using it too.
50% is not "rarely". =)
Post by Yijing Wang
We can look up msi_chip pointer by the device pointer
or irq number, so clean up msi_chip argument.
I don't like this particular change. The idea was to keep the API object
oriented so that drivers wouldn't have to know where to get the MSI chip
from. It also makes it more resilient against code reorganizations since
the core code is the only place that needs to know where to get the chip
from.
Right. We have the same thing in the irq_chip callbacks. All of them
take "struct irq_data", because it's already available in the core
code and it gives easy access to all information (chip, chipdata ...)
which is necessary for the callback implementations.

Thanks,

tglx
Yijing Wang
2014-09-26 02:15:48 UTC
Permalink
Post by Thomas Gleixner
Post by Thierry Reding
Post by Yijing Wang
Msi_chip functions setup_irq/teardown_irq rarely use msi_chip
argument.
That's not true. Out of the four drivers that you modify two use the
parameter. And the two that don't probably should be using it too.
50% is not "rarely". =)
Post by Yijing Wang
We can look up msi_chip pointer by the device pointer
or irq number, so clean up msi_chip argument.
I don't like this particular change. The idea was to keep the API object
oriented so that drivers wouldn't have to know where to get the MSI chip
from. It also makes it more resilient against code reorganizations since
the core code is the only place that needs to know where to get the chip
from.
Right. We have the same thing in the irq_chip callbacks. All of them
take "struct irq_data", because it's already available in the core
code and it gives easy access to all information (chip, chipdata ...)
which is necessary for the callback implementations.
OK, I will drop this change, tglx, thanks for your review and comments!

Thanks!
Yijing.
Post by Thomas Gleixner
Thanks,
tglx
--
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
Yijing Wang
2014-09-26 01:58:54 UTC
Permalink
Post by Thierry Reding
Post by Yijing Wang
Msi_chip functions setup_irq/teardown_irq rarely use msi_chip
argument.
That's not true. Out of the four drivers that you modify two use the
parameter. And the two that don't probably should be using it too.
50% is not "rarely". =)
Post by Yijing Wang
We can look up msi_chip pointer by the device pointer
or irq number, so clean up msi_chip argument.
I don't like this particular change. The idea was to keep the API object
oriented so that drivers wouldn't have to know where to get the MSI chip
from. It also makes it more resilient against code reorganizations since
the core code is the only place that needs to know where to get the chip
from.
Hm, ok, Thomas also don't like this change, I will drop this one, thanks.

Thanks!
Yijing.
Post by Thierry Reding
Thierry
--
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-09-25 03:14:14 UTC
Permalink
Commit 0e4ccb150 added two __weak arch functions arch_msix_mask_irq()
and arch_msi_mask_irq() to fix a bug found when running xen in x86.
Introduced these two funcntions make MSI code complex. And mask/unmask
is the irq actions related to interrupt controller, should not use
weak arch functions to override mask/unmask interfaces. This patch
reverted commit 0e4ccb150 and export struct irq_chip msi_chip, modify
msi_chip->irq_mask/irq_unmask() in xen init functions to fix this
bug for simplicity. Also this is preparation for using struct
msi_chip instead of weak arch MSI functions in all platforms.
Keep default_msi_mask_irq() and default_msix_mask_irq() in
linux/msi.h to make s390 MSI code compile happy, they wiil be removed
in the later patch.

Tested-by: Konrad Rzeszutek Wilk <konrad.wilk-QHcLZuEGTsvQT0dZR+***@public.gmane.org>
Signed-off-by: Yijing Wang <wangyijing-hv44wF8Li93QT0dZR+***@public.gmane.org>
Acked-by: David Vrabel <david.vrabel-Sxgqhf6Nn4DQT0dZR+***@public.gmane.org>
Reviewed-by: Konrad Rzeszutek Wilk <konrad.wilk-QHcLZuEGTsvQT0dZR+***@public.gmane.org>
CC: Konrad Rzeszutek Wilk <konrad.wilk-QHcLZuEGTsvQT0dZR+***@public.gmane.org>
---
arch/x86/include/asm/apic.h | 4 ++++
arch/x86/include/asm/x86_init.h | 3 ---
arch/x86/kernel/apic/io_apic.c | 2 +-
arch/x86/kernel/x86_init.c | 10 ----------
arch/x86/pci/xen.c | 16 ++++++----------
drivers/pci/msi.c | 22 ++++++----------------
include/linux/msi.h | 6 ++++--
7 files changed, 21 insertions(+), 42 deletions(-)

diff --git a/arch/x86/include/asm/apic.h b/arch/x86/include/asm/apic.h
index 465b309..47a5f94 100644
--- a/arch/x86/include/asm/apic.h
+++ b/arch/x86/include/asm/apic.h
@@ -43,6 +43,10 @@ static inline void generic_apic_probe(void)
}
#endif

+#ifdef CONFIG_PCI_MSI
+extern struct irq_chip msi_chip;
+#endif
+
#ifdef CONFIG_X86_LOCAL_APIC

extern unsigned int apic_verbosity;
diff --git a/arch/x86/include/asm/x86_init.h b/arch/x86/include/asm/x86_init.h
index e45e4da..f58a9c7 100644
--- a/arch/x86/include/asm/x86_init.h
+++ b/arch/x86/include/asm/x86_init.h
@@ -172,7 +172,6 @@ struct x86_platform_ops {

struct pci_dev;
struct msi_msg;
-struct msi_desc;

struct x86_msi_ops {
int (*setup_msi_irqs)(struct pci_dev *dev, int nvec, int type);
@@ -183,8 +182,6 @@ struct x86_msi_ops {
void (*teardown_msi_irqs)(struct pci_dev *dev);
void (*restore_msi_irqs)(struct pci_dev *dev);
int (*setup_hpet_msi)(unsigned int irq, unsigned int id);
- u32 (*msi_mask_irq)(struct msi_desc *desc, u32 mask, u32 flag);
- u32 (*msix_mask_irq)(struct msi_desc *desc, u32 flag);
};

struct IO_APIC_route_entry;
diff --git a/arch/x86/kernel/apic/io_apic.c b/arch/x86/kernel/apic/io_apic.c
index e877cfb..2a2ec28 100644
--- a/arch/x86/kernel/apic/io_apic.c
+++ b/arch/x86/kernel/apic/io_apic.c
@@ -3161,7 +3161,7 @@ msi_set_affinity(struct irq_data *data, const struct cpumask *mask, bool force)
* IRQ Chip for MSI PCI/PCI-X/PCI-Express Devices,
* which implement the MSI or MSI-X Capability Structure.
*/
-static struct irq_chip msi_chip = {
+struct irq_chip msi_chip = {
.name = "PCI-MSI",
.irq_unmask = unmask_msi_irq,
.irq_mask = mask_msi_irq,
diff --git a/arch/x86/kernel/x86_init.c b/arch/x86/kernel/x86_init.c
index e48b674..234b072 100644
--- a/arch/x86/kernel/x86_init.c
+++ b/arch/x86/kernel/x86_init.c
@@ -116,8 +116,6 @@ struct x86_msi_ops x86_msi = {
.teardown_msi_irqs = default_teardown_msi_irqs,
.restore_msi_irqs = default_restore_msi_irqs,
.setup_hpet_msi = default_setup_hpet_msi,
- .msi_mask_irq = default_msi_mask_irq,
- .msix_mask_irq = default_msix_mask_irq,
};

/* MSI arch specific hooks */
@@ -140,14 +138,6 @@ void arch_restore_msi_irqs(struct pci_dev *dev)
{
x86_msi.restore_msi_irqs(dev);
}
-u32 arch_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
-{
- return x86_msi.msi_mask_irq(desc, mask, flag);
-}
-u32 arch_msix_mask_irq(struct msi_desc *desc, u32 flag)
-{
- return x86_msi.msix_mask_irq(desc, flag);
-}
#endif

struct x86_io_apic_ops x86_io_apic_ops = {
diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index ad03739..84c2fce 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -394,13 +394,9 @@ static void xen_teardown_msi_irq(unsigned int irq)
{
xen_destroy_irq(irq);
}
-static u32 xen_nop_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
-{
- return 0;
-}
-static u32 xen_nop_msix_mask_irq(struct msi_desc *desc, u32 flag)
+
+void xen_nop_msi_mask(struct irq_data *data)
{
- return 0;
}
#endif

@@ -425,8 +421,8 @@ int __init pci_xen_init(void)
x86_msi.setup_msi_irqs = xen_setup_msi_irqs;
x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
x86_msi.teardown_msi_irqs = xen_teardown_msi_irqs;
- x86_msi.msi_mask_irq = xen_nop_msi_mask_irq;
- x86_msi.msix_mask_irq = xen_nop_msix_mask_irq;
+ msi_chip.irq_mask = xen_nop_msi_mask;
+ msi_chip.irq_unmask = xen_nop_msi_mask;
#endif
return 0;
}
@@ -506,8 +502,8 @@ int __init pci_xen_initial_domain(void)
x86_msi.setup_msi_irqs = xen_initdom_setup_msi_irqs;
x86_msi.teardown_msi_irq = xen_teardown_msi_irq;
x86_msi.restore_msi_irqs = xen_initdom_restore_msi_irqs;
- x86_msi.msi_mask_irq = xen_nop_msi_mask_irq;
- x86_msi.msix_mask_irq = xen_nop_msix_mask_irq;
+ msi_chip.irq_mask = xen_nop_msi_mask;
+ msi_chip.irq_unmask = xen_nop_msi_mask;
#endif
xen_setup_acpi_sci();
__acpi_register_gsi = acpi_register_gsi_xen;
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 50f67a3..5f8f3af 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -162,7 +162,7 @@ static inline __attribute_const__ u32 msi_mask(unsigned x)
* reliably as devices without an INTx disable bit will then generate a
* level IRQ which will never be cleared.
*/
-u32 default_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
+u32 __msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
{
u32 mask_bits = desc->masked;

@@ -176,14 +176,9 @@ u32 default_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
return mask_bits;
}

-__weak u32 arch_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
-{
- return default_msi_mask_irq(desc, mask, flag);
-}
-
static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
{
- desc->masked = arch_msi_mask_irq(desc, mask, flag);
+ desc->masked = __msi_mask_irq(desc, mask, flag);
}

/*
@@ -193,7 +188,7 @@ static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
* file. This saves a few milliseconds when initialising devices with lots
* of MSI-X interrupts.
*/
-u32 default_msix_mask_irq(struct msi_desc *desc, u32 flag)
+u32 __msix_mask_irq(struct msi_desc *desc, u32 flag)
{
u32 mask_bits = desc->masked;
unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
@@ -206,14 +201,9 @@ u32 default_msix_mask_irq(struct msi_desc *desc, u32 flag)
return mask_bits;
}

-__weak u32 arch_msix_mask_irq(struct msi_desc *desc, u32 flag)
-{
- return default_msix_mask_irq(desc, flag);
-}
-
static void msix_mask_irq(struct msi_desc *desc, u32 flag)
{
- desc->masked = arch_msix_mask_irq(desc, flag);
+ desc->masked = __msix_mask_irq(desc, flag);
}

static void msi_set_mask_bit(struct irq_data *data, u32 flag)
@@ -852,7 +842,7 @@ void pci_msi_shutdown(struct pci_dev *dev)
/* Return the device with MSI unmasked as initial states */
mask = msi_mask(desc->msi_attrib.multi_cap);
/* Keep cached state to be restored */
- arch_msi_mask_irq(desc, mask, ~mask);
+ __msi_mask_irq(desc, mask, ~mask);

/* Restore dev->irq to its default pin-assertion irq */
dev->irq = desc->msi_attrib.default_irq;
@@ -950,7 +940,7 @@ void pci_msix_shutdown(struct pci_dev *dev)
/* Return the device with MSI-X masked as initial states */
list_for_each_entry(entry, &dev->msi_list, list) {
/* Keep cached states to be restored */
- arch_msix_mask_irq(entry, 1);
+ __msix_mask_irq(entry, 1);
}

msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0);
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 45ef8cb..cc46a62 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -19,6 +19,8 @@ void read_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void write_msi_msg(unsigned int irq, struct msi_msg *msg);
+u32 __msix_mask_irq(struct msi_desc *desc, u32 flag);
+u32 __msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag);

struct msi_desc {
struct {
@@ -59,8 +61,8 @@ void arch_restore_msi_irqs(struct pci_dev *dev);

void default_teardown_msi_irqs(struct pci_dev *dev);
void default_restore_msi_irqs(struct pci_dev *dev);
-u32 default_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag);
-u32 default_msix_mask_irq(struct msi_desc *desc, u32 flag);
+#define default_msi_mask_irq __msi_mask_irq
+#define default_msix_mask_irq __msix_mask_irq

struct msi_chip {
struct module *owner;
--
1.7.1
Konrad Rzeszutek Wilk
2014-09-25 14:33:46 UTC
Permalink
Post by Yijing Wang
Commit 0e4ccb150 added two __weak arch functions arch_msix_mask_irq()
and arch_msi_mask_irq() to fix a bug found when running xen in x86.
Introduced these two funcntions make MSI code complex. And mask/unmask
"These two functions made the MSI code more complex."
Post by Yijing Wang
is the irq actions related to interrupt controller, should not use
weak arch functions to override mask/unmask interfaces. This patch
I am bit baffled of what you are saying.
Post by Yijing Wang
reverted commit 0e4ccb150 and export struct irq_chip msi_chip, modify
msi_chip->irq_mask/irq_unmask() in xen init functions to fix this
bug for simplicity. Also this is preparation for using struct
msi_chip instead of weak arch MSI functions in all platforms.
Keep default_msi_mask_irq() and default_msix_mask_irq() in
linux/msi.h to make s390 MSI code compile happy, they wiil be removed
s/wiil/will.
Post by Yijing Wang
in the later patch.
I don't even remember testing it - I guess I did the earlier version.
Post by Yijing Wang
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 50f67a3..5f8f3af 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -162,7 +162,7 @@ static inline __attribute_const__ u32 msi_mask(unsigned x)
* reliably as devices without an INTx disable bit will then generate a
* level IRQ which will never be cleared.
*/
-u32 default_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
+u32 __msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
{
u32 mask_bits = desc->masked;
@@ -176,14 +176,9 @@ u32 default_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
return mask_bits;
}
-__weak u32 arch_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
-{
- return default_msi_mask_irq(desc, mask, flag);
-}
-
static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
{
- desc->masked = arch_msi_mask_irq(desc, mask, flag);
+ desc->masked = __msi_mask_irq(desc, mask, flag);
}
/*
@@ -193,7 +188,7 @@ static void msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
* file. This saves a few milliseconds when initialising devices with lots
* of MSI-X interrupts.
*/
-u32 default_msix_mask_irq(struct msi_desc *desc, u32 flag)
+u32 __msix_mask_irq(struct msi_desc *desc, u32 flag)
{
u32 mask_bits = desc->masked;
unsigned offset = desc->msi_attrib.entry_nr * PCI_MSIX_ENTRY_SIZE +
@@ -206,14 +201,9 @@ u32 default_msix_mask_irq(struct msi_desc *desc, u32 flag)
return mask_bits;
}
-__weak u32 arch_msix_mask_irq(struct msi_desc *desc, u32 flag)
-{
- return default_msix_mask_irq(desc, flag);
-}
-
static void msix_mask_irq(struct msi_desc *desc, u32 flag)
{
- desc->masked = arch_msix_mask_irq(desc, flag);
+ desc->masked = __msix_mask_irq(desc, flag);
}
static void msi_set_mask_bit(struct irq_data *data, u32 flag)
@@ -852,7 +842,7 @@ void pci_msi_shutdown(struct pci_dev *dev)
/* Return the device with MSI unmasked as initial states */
mask = msi_mask(desc->msi_attrib.multi_cap);
/* Keep cached state to be restored */
- arch_msi_mask_irq(desc, mask, ~mask);
+ __msi_mask_irq(desc, mask, ~mask);
If I am reading this right, it will call the old 'default_msi_mask_irq'
which is exactly what we don't want to do under Xen. We want to call
the NOP code.
Post by Yijing Wang
/* Restore dev->irq to its default pin-assertion irq */
dev->irq = desc->msi_attrib.default_irq;
@@ -950,7 +940,7 @@ void pci_msix_shutdown(struct pci_dev *dev)
/* Return the device with MSI-X masked as initial states */
list_for_each_entry(entry, &dev->msi_list, list) {
/* Keep cached states to be restored */
- arch_msix_mask_irq(entry, 1);
+ __msix_mask_irq(entry, 1);
Ditto here.

Looking more at this code I have to retract my Reviewed-by and Tested-by
on the whole series.

Is it possible to get a git tree for this please?
Post by Yijing Wang
}
msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0);
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 45ef8cb..cc46a62 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -19,6 +19,8 @@ void read_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void write_msi_msg(unsigned int irq, struct msi_msg *msg);
+u32 __msix_mask_irq(struct msi_desc *desc, u32 flag);
+u32 __msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag);
struct msi_desc {
struct {
@@ -59,8 +61,8 @@ void arch_restore_msi_irqs(struct pci_dev *dev);
void default_teardown_msi_irqs(struct pci_dev *dev);
void default_restore_msi_irqs(struct pci_dev *dev);
-u32 default_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag);
-u32 default_msix_mask_irq(struct msi_desc *desc, u32 flag);
+#define default_msi_mask_irq __msi_mask_irq
+#define default_msix_mask_irq __msix_mask_irq
struct msi_chip {
struct module *owner;
--
1.7.1
Yijing Wang
2014-09-26 03:12:30 UTC
Permalink
Post by Konrad Rzeszutek Wilk
Post by Yijing Wang
Commit 0e4ccb150 added two __weak arch functions arch_msix_mask_irq()
and arch_msi_mask_irq() to fix a bug found when running xen in x86.
Introduced these two funcntions make MSI code complex. And mask/unmask
"These two functions made the MSI code more complex."
OK, will update, thanks.
Post by Konrad Rzeszutek Wilk
Post by Yijing Wang
is the irq actions related to interrupt controller, should not use
weak arch functions to override mask/unmask interfaces. This patch
I am bit baffled of what you are saying.
Sorry for my poor English. The meaning is that I think override irq_chip
mask/unmask irq is better than introduced weak functions.
Post by Konrad Rzeszutek Wilk
Post by Yijing Wang
reverted commit 0e4ccb150 and export struct irq_chip msi_chip, modify
msi_chip->irq_mask/irq_unmask() in xen init functions to fix this
bug for simplicity. Also this is preparation for using struct
msi_chip instead of weak arch MSI functions in all platforms.
Keep default_msi_mask_irq() and default_msix_mask_irq() in
linux/msi.h to make s390 MSI code compile happy, they wiil be removed
s/wiil/will.
Will update, thanks.
Post by Konrad Rzeszutek Wilk
Post by Yijing Wang
in the later patch.
I don't even remember testing it - I guess I did the earlier version.
Yes, I added your tested-by because in last version, you help to test the whole series in xen.
And I didn't change something in xen part patches in this new version.
Post by Konrad Rzeszutek Wilk
Post by Yijing Wang
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 50f67a3..5f8f3af 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
...
Post by Konrad Rzeszutek Wilk
Post by Yijing Wang
static void msi_set_mask_bit(struct irq_data *data, u32 flag)
@@ -852,7 +842,7 @@ void pci_msi_shutdown(struct pci_dev *dev)
/* Return the device with MSI unmasked as initial states */
mask = msi_mask(desc->msi_attrib.multi_cap);
/* Keep cached state to be restored */
- arch_msi_mask_irq(desc, mask, ~mask);
+ __msi_mask_irq(desc, mask, ~mask);
If I am reading this right, it will call the old 'default_msi_mask_irq'
which is exactly what we don't want to do under Xen. We want to call
the NOP code.
Good catch. I missed this one, it will also be called in xen.
I need to rework this patch.
Post by Konrad Rzeszutek Wilk
Post by Yijing Wang
/* Restore dev->irq to its default pin-assertion irq */
dev->irq = desc->msi_attrib.default_irq;
@@ -950,7 +940,7 @@ void pci_msix_shutdown(struct pci_dev *dev)
/* Return the device with MSI-X masked as initial states */
list_for_each_entry(entry, &dev->msi_list, list) {
/* Keep cached states to be restored */
- arch_msix_mask_irq(entry, 1);
+ __msix_mask_irq(entry, 1);
Ditto here.
Looking more at this code I have to retract my Reviewed-by and Tested-by
on the whole series.
OK, because this patch still need some enhancement.
Post by Konrad Rzeszutek Wilk
Is it possible to get a git tree for this please?
I will provide a git tree as soon as possible.

Thanks!
Yijing.
Post by Konrad Rzeszutek Wilk
Post by Yijing Wang
}
msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_ENABLE, 0);
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 45ef8cb..cc46a62 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -19,6 +19,8 @@ void read_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void __write_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void write_msi_msg(unsigned int irq, struct msi_msg *msg);
+u32 __msix_mask_irq(struct msi_desc *desc, u32 flag);
+u32 __msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag);
struct msi_desc {
struct {
@@ -59,8 +61,8 @@ void arch_restore_msi_irqs(struct pci_dev *dev);
void default_teardown_msi_irqs(struct pci_dev *dev);
void default_restore_msi_irqs(struct pci_dev *dev);
-u32 default_msi_mask_irq(struct msi_desc *desc, u32 mask, u32 flag);
-u32 default_msix_mask_irq(struct msi_desc *desc, u32 flag);
+#define default_msi_mask_irq __msi_mask_irq
+#define default_msix_mask_irq __msix_mask_irq
struct msi_chip {
struct module *owner;
--
1.7.1
.
--
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-09-25 03:14:22 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/msi-octeon.c | 35 ++++++++++++++++++++++-------------
1 files changed, 22 insertions(+), 13 deletions(-)

diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c
index 63bbe07..14f2d16 100644
--- a/arch/mips/pci/msi-octeon.c
+++ b/arch/mips/pci/msi-octeon.c
@@ -57,7 +57,7 @@ static int msi_irq_size;
*
* Returns 0 on success.
*/
-int arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
+static int octeon_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
{
struct msi_msg msg;
u16 control;
@@ -132,12 +132,12 @@ msi_irq_allocated:
/* Make sure the search for available interrupts didn't fail */
if (irq >= 64) {
if (request_private_bits) {
- pr_err("arch_setup_msi_irq: Unable to find %d free interrupts, trying just one",
+ pr_err("octeon_setup_msi_irq: Unable to find %d free interrupts, trying just one",
1 << request_private_bits);
request_private_bits = 0;
goto try_only_one;
} else
- panic("arch_setup_msi_irq: Unable to find a free MSI interrupt");
+ panic("octeon_setup_msi_irq: Unable to find a free MSI interrupt");
}

/* MSI interrupts start at logical IRQ OCTEON_IRQ_MSI_BIT0 */
@@ -168,7 +168,7 @@ msi_irq_allocated:
msg.address_hi = (0 + CVMX_SLI_PCIE_MSI_RCV) >> 32;
break;
default:
- panic("arch_setup_msi_irq: Invalid octeon_dma_bar_type");
+ panic("octeon_setup_msi_irq: Invalid octeon_dma_bar_type");
}
msg.data = irq - OCTEON_IRQ_MSI_BIT0;

@@ -182,7 +182,7 @@ msi_irq_allocated:
return 0;
}

-int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
+static int octeon_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
{
struct msi_desc *entry;
int ret;
@@ -201,7 +201,7 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
return 1;

list_for_each_entry(entry, &dev->msi_list, list) {
- ret = arch_setup_msi_irq(dev, entry);
+ ret = octeon_setup_msi_irq(dev, entry);
if (ret < 0)
return ret;
if (ret > 0)
@@ -210,14 +210,13 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)

return 0;
}
-
/**
* Called when a device no longer needs its MSI interrupts. All
* MSI interrupts for the device are freed.
*
* @irq: The devices first irq number. There may be multple in sequence.
*/
-void arch_teardown_msi_irq(unsigned int irq)
+static void octeon_teardown_msi_irq(unsigned int irq)
{
int number_irqs;
u64 bitmask;
@@ -226,8 +225,8 @@ void arch_teardown_msi_irq(unsigned int irq)

if ((irq < OCTEON_IRQ_MSI_BIT0)
|| (irq > msi_irq_size + OCTEON_IRQ_MSI_BIT0))
- panic("arch_teardown_msi_irq: Attempted to teardown illegal "
- "MSI interrupt (%d)", irq);
+ panic("octeon_teardown_msi_irq: Attempted to teardown illegal "
+ "MSI interrupt (%d)", irq);

irq -= OCTEON_IRQ_MSI_BIT0;
index = irq / 64;
@@ -240,7 +239,7 @@ void arch_teardown_msi_irq(unsigned int irq)
*/
number_irqs = 0;
while ((irq0 + number_irqs < 64) &&
- (msi_multiple_irq_bitmask[index]
+ (msi_multiple_irq_bitmask[index]
& (1ull << (irq0 + number_irqs))))
number_irqs++;
number_irqs++;
@@ -249,8 +248,8 @@ void arch_teardown_msi_irq(unsigned int irq)
/* Shift the mask to the correct bit location */
bitmask <<= irq0;
if ((msi_free_irq_bitmask[index] & bitmask) != bitmask)
- panic("arch_teardown_msi_irq: Attempted to teardown MSI "
- "interrupt (%d) not in use", irq);
+ panic("octeon_teardown_msi_irq: Attempted to teardown MSI "
+ "interrupt (%d) not in use", irq);

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

+static struct msi_chip octeon_msi_chip = {
+ .setup_irqs = octeon_setup_msi_irqs,
+ .teardown_irq = octeon_teardown_msi_irq,
+};
+
+struct msi_chip *arch_find_msi_chip(struct pci_dev *dev)
+{
+ return &octeon_msi_chip;
+}
+
static DEFINE_RAW_SPINLOCK(octeon_irq_msi_lock);

static u64 msi_rcv_reg[4];
--
1.7.1

--
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
Thierry Reding
2014-09-25 07:34:36 UTC
Permalink
On Thu, Sep 25, 2014 at 11:14:22AM +0800, Yijing Wang wrote:
[...]
Post by Yijing Wang
diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c
[...]
Post by Yijing Wang
/* Make sure the search for available interrupts didn't fail */
if (irq >= 64) {
if (request_private_bits) {
- pr_err("arch_setup_msi_irq: Unable to find %d free interrupts, trying just one",
+ pr_err("octeon_setup_msi_irq: Unable to find %d free interrupts, trying just one",
1 << request_private_bits);
Perhaps while at it make this (and other similar changes in this patch):

pr_err("%s(): Unable to ...", __func__, ...);

So that it becomes more resilient against this kind of rename?
Post by Yijing Wang
request_private_bits = 0;
goto try_only_one;
} else
- panic("arch_setup_msi_irq: Unable to find a free MSI interrupt");
+ panic("octeon_setup_msi_irq: Unable to find a free MSI interrupt");
@@ -210,14 +210,13 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
return 0;
}
-
This...
Post by Yijing Wang
@@ -240,7 +239,7 @@ void arch_teardown_msi_irq(unsigned int irq)
*/
number_irqs = 0;
while ((irq0 + number_irqs < 64) &&
- (msi_multiple_irq_bitmask[index]
+ (msi_multiple_irq_bitmask[index]
... and this seem like unrelated whitespace changes.
Post by Yijing Wang
& (1ull << (irq0 + number_irqs))))
number_irqs++;
number_irqs++;
@@ -249,8 +248,8 @@ void arch_teardown_msi_irq(unsigned int irq)
/* Shift the mask to the correct bit location */
bitmask <<= irq0;
if ((msi_free_irq_bitmask[index] & bitmask) != bitmask)
- panic("arch_teardown_msi_irq: Attempted to teardown MSI "
- "interrupt (%d) not in use", irq);
+ panic("octeon_teardown_msi_irq: Attempted to teardown MSI "
+ "interrupt (%d) not in use", irq);
And the second line here also needlessly changes the indentation.

Thierry
Yijing Wang
2014-09-26 02:12:00 UTC
Permalink
Post by Thierry Reding
[...]
Post by Yijing Wang
diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c
[...]
Post by Yijing Wang
/* Make sure the search for available interrupts didn't fail */
if (irq >= 64) {
if (request_private_bits) {
- pr_err("arch_setup_msi_irq: Unable to find %d free interrupts, trying just one",
+ pr_err("octeon_setup_msi_irq: Unable to find %d free interrupts, trying just one",
1 << request_private_bits);
pr_err("%s(): Unable to ...", __func__, ...);
Will update it, thanks!
Post by Thierry Reding
So that it becomes more resilient against this kind of rename?
Post by Yijing Wang
request_private_bits = 0;
goto try_only_one;
} else
- panic("arch_setup_msi_irq: Unable to find a free MSI interrupt");
+ panic("octeon_setup_msi_irq: Unable to find a free MSI interrupt");
@@ -210,14 +210,13 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
return 0;
}
-
This...
OK
Post by Thierry Reding
Post by Yijing Wang
@@ -240,7 +239,7 @@ void arch_teardown_msi_irq(unsigned int irq)
*/
number_irqs = 0;
while ((irq0 + number_irqs < 64) &&
- (msi_multiple_irq_bitmask[index]
+ (msi_multiple_irq_bitmask[index]
... and this seem like unrelated whitespace changes.
OK
Post by Thierry Reding
Post by Yijing Wang
& (1ull << (irq0 + number_irqs))))
number_irqs++;
number_irqs++;
@@ -249,8 +248,8 @@ void arch_teardown_msi_irq(unsigned int irq)
/* Shift the mask to the correct bit location */
bitmask <<= irq0;
if ((msi_free_irq_bitmask[index] & bitmask) != bitmask)
- panic("arch_teardown_msi_irq: Attempted to teardown MSI "
- "interrupt (%d) not in use", irq);
+ panic("octeon_teardown_msi_irq: Attempted to teardown MSI "
+ "interrupt (%d) not in use", irq);
And the second line here also needlessly changes the indentation.
OK
Post by Thierry Reding
Thierry
--
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-09-25 03:14:13 UTC
Permalink
Currently, pcie-designware, pcie-rcar, pci-tegra drivers
use irq chip_data to save the msi_chip pointer. They
already call irq_set_chip_data() in their own MSI irq map
functions. So irq_set_chip_data() in arch_setup_msi_irq()
is useless.

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

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 51d7e62..50f67a3 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -41,14 +41,13 @@ int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
if (err < 0)
return err;

- irq_set_chip_data(desc->irq, chip);
-
return 0;
}

void __weak arch_teardown_msi_irq(unsigned int irq)
{
- struct msi_chip *chip = irq_get_chip_data(irq);
+ struct msi_desc *entry = irq_get_msi_desc(irq);
+ struct msi_chip *chip = entry->dev->bus->msi;

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

--
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
Thierry Reding
2014-09-25 07:19:20 UTC
Permalink
Post by Yijing Wang
Currently, pcie-designware, pcie-rcar, pci-tegra drivers
use irq chip_data to save the msi_chip pointer. They
already call irq_set_chip_data() in their own MSI irq map
functions. So irq_set_chip_data() in arch_setup_msi_irq()
is useless.
Again, I think this should be the other way around. If drivers do
something that's already handled by the core, then the duplicate code
should be dropped from the drivers.

Thierry
Yijing Wang
2014-09-26 02:04:45 UTC
Permalink
Post by Thierry Reding
Post by Yijing Wang
Currently, pcie-designware, pcie-rcar, pci-tegra drivers
use irq chip_data to save the msi_chip pointer. They
already call irq_set_chip_data() in their own MSI irq map
functions. So irq_set_chip_data() in arch_setup_msi_irq()
is useless.
Again, I think this should be the other way around. If drivers do
something that's already handled by the core, then the duplicate code
should be dropped from the drivers.
Hi Thierry, this is different thing, because chip_data is specific to IRQ
controller, and in other platform, like in x86, chip_data is used to save irq_cfg.
So we can not call irq_set_chip_data() in core code.

x86 irq piece code

int arch_setup_hwirq(unsigned int irq, int node)
{
struct irq_cfg *cfg;
unsigned long flags;
int ret;

cfg = alloc_irq_cfg(irq, node);
if (!cfg)
return -ENOMEM;

raw_spin_lock_irqsave(&vector_lock, flags);
ret = __assign_irq_vector(irq, cfg, apic->target_cpus());
raw_spin_unlock_irqrestore(&vector_lock, flags);

if (!ret)
irq_set_chip_data(irq, cfg); ------------->Save irq_cfg
else
free_irq_cfg(irq, cfg);
return ret;
}

Thanks!
Yijing.
Post by Thierry Reding
Thierry
--
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
Thierry Reding
2014-09-26 08:09:22 UTC
Permalink
Post by Yijing Wang
Post by Thierry Reding
Post by Yijing Wang
Currently, pcie-designware, pcie-rcar, pci-tegra drivers
use irq chip_data to save the msi_chip pointer. They
already call irq_set_chip_data() in their own MSI irq map
functions. So irq_set_chip_data() in arch_setup_msi_irq()
is useless.
Again, I think this should be the other way around. If drivers do
something that's already handled by the core, then the duplicate code
should be dropped from the drivers.
Hi Thierry, this is different thing, because chip_data is specific to IRQ
controller, and in other platform, like in x86, chip_data is used to save irq_cfg.
So we can not call irq_set_chip_data() in core code.
x86 irq piece code
int arch_setup_hwirq(unsigned int irq, int node)
{
struct irq_cfg *cfg;
unsigned long flags;
int ret;
cfg = alloc_irq_cfg(irq, node);
if (!cfg)
return -ENOMEM;
raw_spin_lock_irqsave(&vector_lock, flags);
ret = __assign_irq_vector(irq, cfg, apic->target_cpus());
raw_spin_unlock_irqrestore(&vector_lock, flags);
if (!ret)
irq_set_chip_data(irq, cfg); ------------->Save irq_cfg
else
free_irq_cfg(irq, cfg);
return ret;
}
Okay, makes sense to keep irq_set_chip_data() for driver-specific data
then.

Thierry
Thierry Reding
2014-09-26 08:09:49 UTC
Permalink
Post by Yijing Wang
Currently, pcie-designware, pcie-rcar, pci-tegra drivers
use irq chip_data to save the msi_chip pointer. They
already call irq_set_chip_data() in their own MSI irq map
functions. So irq_set_chip_data() in arch_setup_msi_irq()
is useless.
---
drivers/pci/msi.c | 5 ++---
1 files changed, 2 insertions(+), 3 deletions(-)
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 51d7e62..50f67a3 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -41,14 +41,13 @@ int __weak arch_setup_msi_irq(struct pci_dev *dev, struct msi_desc *desc)
if (err < 0)
return err;
- irq_set_chip_data(desc->irq, chip);
-
return 0;
}
void __weak arch_teardown_msi_irq(unsigned int irq)
{
- struct msi_chip *chip = irq_get_chip_data(irq);
+ struct msi_desc *entry = irq_get_msi_desc(irq);
+ struct msi_chip *chip = entry->dev->bus->msi;
if (!chip || !chip->teardown_irq)
return;
--
1.7.1
Thierry Reding
2014-09-25 07:42:36 UTC
Permalink
This series is based Bjorn's pci/msi branch
git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci/msi
Currently, there are a lot of weak arch functions in MSI code.
Thierry Reding Introduced MSI chip framework to configure MSI/MSI-X in arm.
This series use MSI chip framework to refactor MSI code across all platforms
to eliminate weak arch functions. Then all MSI irqs will be managed in a
unified framework. Because this series changed a lot of ARCH MSI code,
so tests in the platforms which MSI code modified are warmly welcomed!
Apart from the comments to the individual patches I very much like where
this is going. Thanks for taking care of this.

Thierry
Liviu Dudau
2014-09-25 14:48:55 UTC
Permalink
Post by Thierry Reding
This series is based Bjorn's pci/msi branch
git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci/msi
Currently, there are a lot of weak arch functions in MSI code.
Thierry Reding Introduced MSI chip framework to configure MSI/MSI-X in arm.
This series use MSI chip framework to refactor MSI code across all platforms
to eliminate weak arch functions. Then all MSI irqs will be managed in a
unified framework. Because this series changed a lot of ARCH MSI code,
so tests in the platforms which MSI code modified are warmly welcomed!
Apart from the comments to the individual patches I very much like where
this is going. Thanks for taking care of this.
Thierry
I am actually in disagreement with you, Thierry. I don't like the general direction
of the patches, or at least I don't like the fact that we don't have a portable
way of setting up the msi_chip without having to rely on weak architectural hooks.
I'm surprised no one considers the case of a platform having more than one host
bridge and possibly more than one MSI unit. With the current proposed patchset I
can't see how that would work.

What I would like to see is a way of creating the pci_host_bridge structure outside
the pci_create_root_bus(). That would then allow us to pass this sort of platform
details like associated msi_chip into the host bridge and the child busses will
have an easy way of finding the information needed by finding the root bus and then
the host bridge structure. Then the generic pci_scan_root_bus() can be used by (mostly)
everyone and the drivers can remove their kludges that try to work around the
current limitations.

Best regards,
Liviu

---------------------
.oooO
( )
\ ( Oooo.
\_) ( )
) /
(_/

One small step
for me ...

--
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
Thierry Reding
2014-09-25 16:49:38 UTC
Permalink
Post by Liviu Dudau
Post by Thierry Reding
This series is based Bjorn's pci/msi branch
git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci/msi
Currently, there are a lot of weak arch functions in MSI code.
Thierry Reding Introduced MSI chip framework to configure MSI/MSI-X in arm.
This series use MSI chip framework to refactor MSI code across all platforms
to eliminate weak arch functions. Then all MSI irqs will be managed in a
unified framework. Because this series changed a lot of ARCH MSI code,
so tests in the platforms which MSI code modified are warmly welcomed!
Apart from the comments to the individual patches I very much like where
this is going. Thanks for taking care of this.
Thierry
I am actually in disagreement with you, Thierry. I don't like the general direction
of the patches, or at least I don't like the fact that we don't have a portable
way of setting up the msi_chip without having to rely on weak architectural hooks.
Oh, good. That's actually one of the things I said I wasn't happy with
either. =)
Post by Liviu Dudau
I'm surprised no one considers the case of a platform having more than one host
bridge and possibly more than one MSI unit. With the current proposed patchset I
can't see how that would work.
The PCI core can already deal with that. An MSI chip can be set per bus
and the weak pcibios_add_bus() can be used to set that. Often it might
not even be necessary to do it via pcibios_add_bus() if you create the
root bus directly, since you can attach the MSI chip at that time.
Post by Liviu Dudau
What I would like to see is a way of creating the pci_host_bridge structure outside
the pci_create_root_bus(). That would then allow us to pass this sort of platform
details like associated msi_chip into the host bridge and the child busses will
have an easy way of finding the information needed by finding the root bus and then
the host bridge structure. Then the generic pci_scan_root_bus() can be used by (mostly)
everyone and the drivers can remove their kludges that try to work around the
current limitations.
I think both issues are orthogonal. Last time I checked a lot of work
was still necessary to unify host bridges enough so that it could be
shared across architectures. But perhaps some of that work has
happened in the meantime.

But like I said, when you create the root bus, you can easily attach the
MSI chip to it.

Thierry
Liviu Dudau
2014-09-25 17:16:12 UTC
Permalink
Post by Thierry Reding
Post by Liviu Dudau
Post by Thierry Reding
This series is based Bjorn's pci/msi branch
git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci/msi
Currently, there are a lot of weak arch functions in MSI code.
Thierry Reding Introduced MSI chip framework to configure MSI/MSI-X in arm.
This series use MSI chip framework to refactor MSI code across all platforms
to eliminate weak arch functions. Then all MSI irqs will be managed in a
unified framework. Because this series changed a lot of ARCH MSI code,
so tests in the platforms which MSI code modified are warmly welcomed!
Apart from the comments to the individual patches I very much like where
this is going. Thanks for taking care of this.
Thierry
I am actually in disagreement with you, Thierry. I don't like the general direction
of the patches, or at least I don't like the fact that we don't have a portable
way of setting up the msi_chip without having to rely on weak architectural hooks.
Oh, good. That's actually one of the things I said I wasn't happy with
either. =)
Post by Liviu Dudau
I'm surprised no one considers the case of a platform having more than one host
bridge and possibly more than one MSI unit. With the current proposed patchset I
can't see how that would work.
The PCI core can already deal with that. An MSI chip can be set per bus
and the weak pcibios_add_bus() can be used to set that. Often it might
not even be necessary to do it via pcibios_add_bus() if you create the
root bus directly, since you can attach the MSI chip at that time.
But I'm thinking that we need to move away from pcibios_add_bus() interface to do
something that should be generic. You don't need to be called for every bus when all
you want is just the root bus in order to add the MSI chip. Also, from looking at
the current patchset, a lot of architectures would set the MSI chip to a global
variable, which means you don't have an option to choose the MSI chip based on the
bus.
Post by Thierry Reding
Post by Liviu Dudau
What I would like to see is a way of creating the pci_host_bridge structure outside
the pci_create_root_bus(). That would then allow us to pass this sort of platform
details like associated msi_chip into the host bridge and the child busses will
have an easy way of finding the information needed by finding the root bus and then
the host bridge structure. Then the generic pci_scan_root_bus() can be used by (mostly)
everyone and the drivers can remove their kludges that try to work around the
current limitations.
I think both issues are orthogonal. Last time I checked a lot of work
was still necessary to unify host bridges enough so that it could be
shared across architectures. But perhaps some of that work has
happened in the meantime.
Breaking out the host bridge creation from root bus creation is not difficult, just not
agree upon. That would be the first step in making the generic host brige structure
useful for sharing, specially if used as a sort of "parent" structure that you can
wrap with your actual host bridge structure.
Post by Thierry Reding
But like I said, when you create the root bus, you can easily attach the
MSI chip to it.
Not if you want to use the generic pci_scan_root_bus() function. One needs to copy the code
and add their own needed modifications. Which makes it hard to fix bugs and prevents code
reuse.

Best regards,
Liviu
Post by Thierry Reding
Thierry
--
-------------------
.oooO
( )
\ ( Oooo.
\_) ( )
) /
(_/

One small step
for me ...
Yijing Wang
2014-09-26 06:20:35 UTC
Permalink
Post by Liviu Dudau
Post by Thierry Reding
The PCI core can already deal with that. An MSI chip can be set per bus
and the weak pcibios_add_bus() can be used to set that. Often it might
not even be necessary to do it via pcibios_add_bus() if you create the
root bus directly, since you can attach the MSI chip at that time.
But I'm thinking that we need to move away from pcibios_add_bus() interface to do
something that should be generic. You don't need to be called for every bus when all
you want is just the root bus in order to add the MSI chip. Also, from looking at
the current patchset, a lot of architectures would set the MSI chip to a global
variable, which means you don't have an option to choose the MSI chip based on the
bus.
I also agree to remove the pcibios_add_bus() in arm which call .add_bus() to associate msi_chip
and PCI bus.

In my opinions, all PCI devices under the same PCI hostbridge must share same msi chip, right ?
So if we can associate msi chip and PCI hostbridge, every PCI device can find correct msi chip.
PCI hostbridge private attributes can be saved in PCI sysdata, and this data will be propagate to
PCI root bus and its child buses.
Post by Liviu Dudau
Post by Thierry Reding
Post by Liviu Dudau
What I would like to see is a way of creating the pci_host_bridge structure outside
the pci_create_root_bus(). That would then allow us to pass this sort of platform
details like associated msi_chip into the host bridge and the child busses will
have an easy way of finding the information needed by finding the root bus and then
the host bridge structure. Then the generic pci_scan_root_bus() can be used by (mostly)
everyone and the drivers can remove their kludges that try to work around the
current limitations.
I think both issues are orthogonal. Last time I checked a lot of work
was still necessary to unify host bridges enough so that it could be
shared across architectures. But perhaps some of that work has
happened in the meantime.
Breaking out the host bridge creation from root bus creation is not difficult, just not
agree upon. That would be the first step in making the generic host brige structure
useful for sharing, specially if used as a sort of "parent" structure that you can
wrap with your actual host bridge structure.
Breaking out the host bridge creation is a good idea, but there need a lot of changes, we can
do it in another series. And if we save msi chip in pci sysdata now, it will be easy to
move it to generic pci host bridge. We can also move the pci domain number and other common info to it.

Thanks!
Yijing.
Post by Liviu Dudau
Post by Thierry Reding
But like I said, when you create the root bus, you can easily attach the
MSI chip to it.
Not if you want to use the generic pci_scan_root_bus() function. One needs to copy the code
and add their own needed modifications. Which makes it hard to fix bugs and prevents code
reuse.
Best regards,
Liviu
Post by Thierry Reding
Thierry
--
Thanks!
Yijing
Thierry Reding
2014-09-26 08:54:32 UTC
Permalink
Post by Yijing Wang
Post by Liviu Dudau
Post by Thierry Reding
The PCI core can already deal with that. An MSI chip can be set per bus
and the weak pcibios_add_bus() can be used to set that. Often it might
not even be necessary to do it via pcibios_add_bus() if you create the
root bus directly, since you can attach the MSI chip at that time.
But I'm thinking that we need to move away from pcibios_add_bus() interface to do
something that should be generic. You don't need to be called for every bus when all
you want is just the root bus in order to add the MSI chip. Also, from looking at
the current patchset, a lot of architectures would set the MSI chip to a global
variable, which means you don't have an option to choose the MSI chip based on the
bus.
I also agree to remove the pcibios_add_bus() in arm which call .add_bus() to associate msi_chip
and PCI bus.
In my opinions, all PCI devices under the same PCI hostbridge must share same msi chip, right ?
So if we can associate msi chip and PCI hostbridge, every PCI device can find correct msi chip.
PCI hostbridge private attributes can be saved in PCI sysdata, and this data will be propagate to
PCI root bus and its child buses.
struct pci_sys_data is architecture specific, so the code won't become
any more generic than it is now.
Post by Yijing Wang
Post by Liviu Dudau
Post by Thierry Reding
Post by Liviu Dudau
What I would like to see is a way of creating the pci_host_bridge structure outside
the pci_create_root_bus(). That would then allow us to pass this sort of platform
details like associated msi_chip into the host bridge and the child busses will
have an easy way of finding the information needed by finding the root bus and then
the host bridge structure. Then the generic pci_scan_root_bus() can be used by (mostly)
everyone and the drivers can remove their kludges that try to work around the
current limitations.
I think both issues are orthogonal. Last time I checked a lot of work
was still necessary to unify host bridges enough so that it could be
shared across architectures. But perhaps some of that work has
happened in the meantime.
Breaking out the host bridge creation from root bus creation is not difficult, just not
agree upon. That would be the first step in making the generic host brige structure
useful for sharing, specially if used as a sort of "parent" structure that you can
wrap with your actual host bridge structure.
Breaking out the host bridge creation is a good idea, but there need a lot of changes, we can
do it in another series.
I agree, this can be done step by step.
Post by Yijing Wang
And if we save msi chip in pci sysdata now, it will be easy to
move it to generic pci host bridge. We can also move the pci domain number and other common info to it.
But like I said above, we wouldn't gain anything by moving the MSI chip
into struct pci_sys_data, since the core code couldn't access it from
there. The code wouldn't become more generic than the current approach
of using pcibios_add_bus(). At least for Tegra it's trivial to just hook
it up in tegra_pcie_scan_bus() directly (patch attached). So I think a
generic solution would be to allow it to be easily associated with a
bus.

Perhaps it would be as simple as adding a pci_scan_root_bus_with_msi()
or something with a less awkward name, or extending the existing
pci_scan_root_bus() with an MSI chip parameter. The function already has
too many arguments for my taste, though, so I'd like to avoid the
latter.

Thierry
Thierry Reding
2014-09-26 09:05:38 UTC
Permalink
On Fri, Sep 26, 2014 at 10:54:32AM +0200, Thierry Reding wrote:
[...]
At least for Tegra it's trivial to just hook it up in tegra_pcie_scan_bus()
directly (patch attached).
Really attached this time.

Thierry
Yijing Wang
2014-09-28 02:32:07 UTC
Permalink
Post by Thierry Reding
[...]
At least for Tegra it's trivial to just hook it up in tegra_pcie_scan_bus()
directly (patch attached).
Really attached this time.
Thierry
It looks good to me, so I will update the arm pci hostbridge driver to assign
pci root bus the msi chip instead of current pcibios_add_bus(). But for other
platforms which only have a one msi chip, I will kept the arch_find_msi_chip()
temporarily for more comments, especially from Bjorn.

Thanks!
Yijing.
--
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
Yijing Wang
2014-09-28 06:11:44 UTC
Permalink
Post by Yijing Wang
Post by Thierry Reding
[...]
At least for Tegra it's trivial to just hook it up in tegra_pcie_scan_bus()
directly (patch attached).
Really attached this time.
Thierry
It looks good to me, so I will update the arm pci hostbridge driver to assign
pci root bus the msi chip instead of current pcibios_add_bus(). But for other
platforms which only have a one msi chip, I will kept the arch_find_msi_chip()
temporarily for more comments, especially from Bjorn.
Oh, sorry, I found designware and rcar use pci_scan_root_bus(), so we can not simply
assign msi chip to root bus in all host drivers's scan functions.
Post by Yijing Wang
Thanks!
Yijing.
--
Thanks!
Yijing
Lucas Stach
2014-09-29 08:37:30 UTC
Permalink
Post by Yijing Wang
Post by Yijing Wang
Post by Thierry Reding
[...]
At least for Tegra it's trivial to just hook it up in tegra_pcie_scan_bus()
directly (patch attached).
Really attached this time.
Thierry
It looks good to me, so I will update the arm pci hostbridge driver to assign
pci root bus the msi chip instead of current pcibios_add_bus(). But for other
platforms which only have a one msi chip, I will kept the arch_find_msi_chip()
temporarily for more comments, especially from Bjorn.
Oh, sorry, I found designware and rcar use pci_scan_root_bus(), so we can not simply
assign msi chip to root bus in all host drivers's scan functions.
Designware will switch away from pci_scan_root_bus() in the 3.18 cycle
and I would think it would be no problem to to the same with rcar.

Regards,
Lucas
--
Pengutronix e.K. | Lucas Stach |
Industrial Linux Solutions | http://www.pengutronix.de/ |
Yijing Wang
2014-09-29 10:13:17 UTC
Permalink
Post by Lucas Stach
Post by Yijing Wang
Post by Yijing Wang
Post by Thierry Reding
[...]
At least for Tegra it's trivial to just hook it up in tegra_pcie_scan_bus()
directly (patch attached).
Really attached this time.
Thierry
It looks good to me, so I will update the arm pci hostbridge driver to assign
pci root bus the msi chip instead of current pcibios_add_bus(). But for other
platforms which only have a one msi chip, I will kept the arch_find_msi_chip()
temporarily for more comments, especially from Bjorn.
Oh, sorry, I found designware and rcar use pci_scan_root_bus(), so we can not simply
assign msi chip to root bus in all host drivers's scan functions.
Designware will switch away from pci_scan_root_bus() in the 3.18 cycle
and I would think it would be no problem to to the same with rcar.
Good.
Post by Lucas Stach
Regards,
Lucas
--
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-09-26 03:42:23 UTC
Permalink
Post by Thierry Reding
Post by Liviu Dudau
I am actually in disagreement with you, Thierry. I don't like the general direction
of the patches, or at least I don't like the fact that we don't have a portable
way of setting up the msi_chip without having to rely on weak architectural hooks.
Oh, good. That's actually one of the things I said I wasn't happy with
either. =)
Hm, I decide to drop weak arch_find_msi_chip(), no one likes it.
Let's find a better solution :)
Post by Thierry Reding
Post by Liviu Dudau
I'm surprised no one considers the case of a platform having more than one host
bridge and possibly more than one MSI unit. With the current proposed patchset I
can't see how that would work.
The PCI core can already deal with that. An MSI chip can be set per bus
and the weak pcibios_add_bus() can be used to set that. Often it might
not even be necessary to do it via pcibios_add_bus() if you create the
root bus directly, since you can attach the MSI chip at that time.
Yes, PCI hostbridge driver find the matched msi chip during its initialization,
and assign the msi chip to PCI bus in pcibios_add_bus().
Post by Thierry Reding
Post by Liviu Dudau
What I would like to see is a way of creating the pci_host_bridge structure outside
the pci_create_root_bus(). That would then allow us to pass this sort of platform
details like associated msi_chip into the host bridge and the child busses will
have an easy way of finding the information needed by finding the root bus and then
the host bridge structure. Then the generic pci_scan_root_bus() can be used by (mostly)
everyone and the drivers can remove their kludges that try to work around the
current limitations.
So I think maybe save msi chip in PCI arch sysdata is a good candidate.
Post by Thierry Reding
I think both issues are orthogonal. Last time I checked a lot of work
was still necessary to unify host bridges enough so that it could be
shared across architectures. But perhaps some of that work has
happened in the meantime.
But like I said, when you create the root bus, you can easily attach the
MSI chip to it.
Thierry
--
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
Liviu Dudau
2014-09-26 08:50:30 UTC
Permalink
Post by Yijing Wang
Post by Thierry Reding
Post by Liviu Dudau
I am actually in disagreement with you, Thierry. I don't like the general direction
of the patches, or at least I don't like the fact that we don't have a portable
way of setting up the msi_chip without having to rely on weak architectural hooks.
Oh, good. That's actually one of the things I said I wasn't happy with
either. =)
Hm, I decide to drop weak arch_find_msi_chip(), no one likes it.
Let's find a better solution :)
Post by Thierry Reding
Post by Liviu Dudau
I'm surprised no one considers the case of a platform having more than one host
bridge and possibly more than one MSI unit. With the current proposed patchset I
can't see how that would work.
The PCI core can already deal with that. An MSI chip can be set per bus
and the weak pcibios_add_bus() can be used to set that. Often it might
not even be necessary to do it via pcibios_add_bus() if you create the
root bus directly, since you can attach the MSI chip at that time.
Yes, PCI hostbridge driver find the matched msi chip during its initialization,
and assign the msi chip to PCI bus in pcibios_add_bus().
Post by Thierry Reding
Post by Liviu Dudau
What I would like to see is a way of creating the pci_host_bridge structure outside
the pci_create_root_bus(). That would then allow us to pass this sort of platform
details like associated msi_chip into the host bridge and the child busses will
have an easy way of finding the information needed by finding the root bus and then
the host bridge structure. Then the generic pci_scan_root_bus() can be used by (mostly)
everyone and the drivers can remove their kludges that try to work around the
current limitations.
So I think maybe save msi chip in PCI arch sysdata is a good candidate.
Except that arch sysdata at the moment is an opaque pointer. I am all in favour in
changing the type of sysdata from void* into pci_host_bridge* and arches can wrap their old
sysdata around the pci_host_bridge*.

Best regards,
Liviu
Post by Yijing Wang
Post by Thierry Reding
I think both issues are orthogonal. Last time I checked a lot of work
was still necessary to unify host bridges enough so that it could be
shared across architectures. But perhaps some of that work has
happened in the meantime.
But like I said, when you create the root bus, you can easily attach the
MSI chip to it.
Thierry
--
Thanks!
Yijing
--
-------------------
.oooO
( )
\ ( Oooo.
\_) ( )
) /
(_/

One small step
for me ...
Yijing Wang
2014-09-28 02:16:12 UTC
Permalink
Post by Liviu Dudau
Post by Yijing Wang
Post by Thierry Reding
Post by Liviu Dudau
What I would like to see is a way of creating the pci_host_bridge structure outside
the pci_create_root_bus(). That would then allow us to pass this sort of platform
details like associated msi_chip into the host bridge and the child busses will
have an easy way of finding the information needed by finding the root bus and then
the host bridge structure. Then the generic pci_scan_root_bus() can be used by (mostly)
everyone and the drivers can remove their kludges that try to work around the
current limitations.
So I think maybe save msi chip in PCI arch sysdata is a good candidate.
Except that arch sysdata at the moment is an opaque pointer. I am all in favour in
changing the type of sysdata from void* into pci_host_bridge* and arches can wrap their old
sysdata around the pci_host_bridge*.
I inspected every arch and found there are almost no common stuff, and generic data struct should
be created in generic PCI code. Another, I don't like associate msi chip and every PCI device, further more,
almost all platforms except arm have only one MSI controller, and currently, PCI enumerating code doesn't need
to know the MSI chip details, like for legacy IRQ, PCI device doesn't need to know which IRQ controller they
should deliver IRQ to. I would think more about it, and hope other PCI guys can give some comments, especially from Bjorn.

Thanks!
Yijing.
Post by Liviu Dudau
Best regards,
Liviu
Post by Yijing Wang
Post by Thierry Reding
I think both issues are orthogonal. Last time I checked a lot of work
was still necessary to unify host bridges enough so that it could be
shared across architectures. But perhaps some of that work has
happened in the meantime.
But like I said, when you create the root bus, you can easily attach the
MSI chip to it.
Thierry
--
Thanks!
Yijing
--
Thanks!
Yijing
Liviu Dudau
2014-09-28 11:21:45 UTC
Permalink
Post by Yijing Wang
Post by Liviu Dudau
Post by Yijing Wang
Post by Thierry Reding
Post by Liviu Dudau
What I would like to see is a way of creating the pci_host_bridge structure outside
the pci_create_root_bus(). That would then allow us to pass this sort of platform
details like associated msi_chip into the host bridge and the child busses will
have an easy way of finding the information needed by finding the root bus and then
the host bridge structure. Then the generic pci_scan_root_bus() can be used by (mostly)
everyone and the drivers can remove their kludges that try to work around the
current limitations.
So I think maybe save msi chip in PCI arch sysdata is a good candidate.
Except that arch sysdata at the moment is an opaque pointer. I am all in favour in
changing the type of sysdata from void* into pci_host_bridge* and arches can wrap their old
sysdata around the pci_host_bridge*.
I inspected every arch and found there are almost no common stuff,
I will disagree here. Most (all?) of the structures that are passed as sysdata argument to
pci_create_root_bus() or pci_scan_root_bus() have a set of resources for storing the MEM and
IO ranges, which struct pci_host_bridge already has. So that can be factored out of the
arch code. Same for pci_domain_nr. Then there are some variables that are used for communication
with the platform code due to convoluted way(s) in which PCI code gets instantiated.

What I am arguing here is not that the arch equivalent of pci_host_bridge structure is already
common, but that by moving the members that are common out of arch sysdata into pci_host_bridge
we will have more commonality and it will be easier to re-factor the code.
Post by Yijing Wang
and generic data struct should
be created in generic PCI code.
Not necessarily. What I have in mind is something like this:

- drivers/pci/ exports pci_init_host_bridge() that does the initialisation of bridge->windows
and anything else that is needed (like find_pci_host_bridge() function).
- arch code does:

struct pci_controller {
struct pci_host_bridge bridge;
.....
};

#define to_pci_controller(bridge) container_of(bridge, struct pci_controller, bridge)

static inline struct pci_controller *get_host_controller(const struct pci_bus *bus)
{
struct pci_host_bridge *bridge = find_pci_host_bridge(bus);
if (bridge)
return to_pci_controller(bridge);

return NULL;
}

int arch_pci_init(....)
{
struct pci_controller *hose;
....
hose = kzalloc(sizeof(*hose), GFP_KERNEL);
pci_init_host_bridge(&hose->bridge);
....
pci_scan_root_bus(...., &hose->bridge, &resources);
....
return 0;
}

Then finding the right structure will be easy.
Post by Yijing Wang
Another, I don't like associate msi chip and every PCI device, further more,
almost all platforms except arm have only one MSI controller, and currently, PCI enumerating code doesn't need
to know the MSI chip details, like for legacy IRQ, PCI device doesn't need to know which IRQ controller they
should deliver IRQ to. I would think more about it, and hope other PCI guys can give some comments, especially from Bjorn.
I wasn't suggesing to associate an msi chip with every PCI device, but with the pci_host_bridge.
I don't expect a host bridge to have more than one msi chip, so that should be OK. Also, I'm
thinking that getting the associated msi chip should be some sort of pci_host_bridge ops function,
and for arches that don't care about MSI it doesn't get implemented.

Best regards,
Liviu
Post by Yijing Wang
Thanks!
Yijing.
Post by Liviu Dudau
Best regards,
Liviu
Post by Yijing Wang
Post by Thierry Reding
I think both issues are orthogonal. Last time I checked a lot of work
was still necessary to unify host bridges enough so that it could be
shared across architectures. But perhaps some of that work has
happened in the meantime.
But like I said, when you create the root bus, you can easily attach the
MSI chip to it.
Thierry
--
Thanks!
Yijing
--
Thanks!
Yijing
--
-------------------
.oooO
( )
\ ( Oooo.
\_) ( )
) /
(_/

One small step
for me ...
Yijing Wang
2014-09-29 01:44:17 UTC
Permalink
Post by Liviu Dudau
Post by Yijing Wang
Post by Liviu Dudau
Post by Yijing Wang
Post by Thierry Reding
Post by Liviu Dudau
What I would like to see is a way of creating the pci_host_bridge structure outside
the pci_create_root_bus(). That would then allow us to pass this sort of platform
details like associated msi_chip into the host bridge and the child busses will
have an easy way of finding the information needed by finding the root bus and then
the host bridge structure. Then the generic pci_scan_root_bus() can be used by (mostly)
everyone and the drivers can remove their kludges that try to work around the
current limitations.
So I think maybe save msi chip in PCI arch sysdata is a good candidate.
Except that arch sysdata at the moment is an opaque pointer. I am all in favour in
changing the type of sysdata from void* into pci_host_bridge* and arches can wrap their old
sysdata around the pci_host_bridge*.
I inspected every arch and found there are almost no common stuff,
I will disagree here. Most (all?) of the structures that are passed as sysdata argument to
Most.
Post by Liviu Dudau
pci_create_root_bus() or pci_scan_root_bus() have a set of resources for storing the MEM and
IO ranges, which struct pci_host_bridge already has. So that can be factored out of the
arch code. Same for pci_domain_nr. Then there are some variables that are used for communication
with the platform code due to convoluted way(s) in which PCI code gets instantiated.
Yes, currently some archs store MEM and IO resource in pci sysdata, and others not, move the MEM and IO
resource to pci_host_bride could make code become simple, we can clean up the resource list argument in
pci scan functions.
Post by Liviu Dudau
What I am arguing here is not that the arch equivalent of pci_host_bridge structure is already
common, but that by moving the members that are common out of arch sysdata into pci_host_bridge
we will have more commonality and it will be easier to re-factor the code.
Now, I got it, thanks!
Post by Liviu Dudau
Post by Yijing Wang
and generic data struct should
be created in generic PCI code.
This is a good idea, what I'm worried is this series is already large, so I think we need to post
another series to do it.
Post by Liviu Dudau
- drivers/pci/ exports pci_init_host_bridge() that does the initialisation of bridge->windows
and anything else that is needed (like find_pci_host_bridge() function).
struct pci_controller {
struct pci_host_bridge bridge;
.....
};
#define to_pci_controller(bridge) container_of(bridge, struct pci_controller, bridge)
static inline struct pci_controller *get_host_controller(const struct pci_bus *bus)
{
struct pci_host_bridge *bridge = find_pci_host_bridge(bus);
if (bridge)
return to_pci_controller(bridge);
return NULL;
}
int arch_pci_init(....)
{
struct pci_controller *hose;
....
hose = kzalloc(sizeof(*hose), GFP_KERNEL);
pci_init_host_bridge(&hose->bridge);
....
pci_scan_root_bus(...., &hose->bridge, &resources);
....
return 0;
}
Then finding the right structure will be easy.
Post by Yijing Wang
Another, I don't like associate msi chip and every PCI device, further more,
almost all platforms except arm have only one MSI controller, and currently, PCI enumerating code doesn't need
to know the MSI chip details, like for legacy IRQ, PCI device doesn't need to know which IRQ controller they
should deliver IRQ to. I would think more about it, and hope other PCI guys can give some comments, especially from Bjorn.
I wasn't suggesing to associate an msi chip with every PCI device, but with the pci_host_bridge.
I don't expect a host bridge to have more than one msi chip, so that should be OK. Also, I'm
thinking that getting the associated msi chip should be some sort of pci_host_bridge ops function,
and for arches that don't care about MSI it doesn't get implemented.
Currently, a property "msi-parent" was introduced in arm, and all msi chip integrated in irq chip controller will
be added to of_pci_msi_chip_list. PCI host driver find the match msi chip by its of_node.

Thanks!
Yijing.
Post by Liviu Dudau
Best regards,
Liviu
Post by Yijing Wang
Thanks!
Yijing.
Post by Liviu Dudau
Best regards,
Liviu
Post by Yijing Wang
Post by Thierry Reding
I think both issues are orthogonal. Last time I checked a lot of work
was still necessary to unify host bridges enough so that it could be
shared across architectures. But perhaps some of that work has
happened in the meantime.
But like I said, when you create the root bus, you can easily attach the
MSI chip to it.
Thierry
--
Thanks!
Yijing
--
Thanks!
Yijing
--
Thanks!
Yijing
Liviu Dudau
2014-09-29 09:26:00 UTC
Permalink
Post by Yijing Wang
Post by Liviu Dudau
Post by Yijing Wang
Post by Liviu Dudau
Post by Yijing Wang
Post by Thierry Reding
Post by Liviu Dudau
What I would like to see is a way of creating the pci_host_bridge structure outside
the pci_create_root_bus(). That would then allow us to pass this sort of platform
details like associated msi_chip into the host bridge and the child busses will
have an easy way of finding the information needed by finding the root bus and then
the host bridge structure. Then the generic pci_scan_root_bus() can be used by (mostly)
everyone and the drivers can remove their kludges that try to work around the
current limitations.
So I think maybe save msi chip in PCI arch sysdata is a good candidate.
Except that arch sysdata at the moment is an opaque pointer. I am all in favour in
changing the type of sysdata from void* into pci_host_bridge* and arches can wrap their old
sysdata around the pci_host_bridge*.
I inspected every arch and found there are almost no common stuff,
I will disagree here. Most (all?) of the structures that are passed as sysdata argument to
Most.
Post by Liviu Dudau
pci_create_root_bus() or pci_scan_root_bus() have a set of resources for storing the MEM and
IO ranges, which struct pci_host_bridge already has. So that can be factored out of the
arch code. Same for pci_domain_nr. Then there are some variables that are used for communication
with the platform code due to convoluted way(s) in which PCI code gets instantiated.
Yes, currently some archs store MEM and IO resource in pci sysdata, and others not, move the MEM and IO
resource to pci_host_bride could make code become simple, we can clean up the resource list argument in
pci scan functions.
Post by Liviu Dudau
What I am arguing here is not that the arch equivalent of pci_host_bridge structure is already
common, but that by moving the members that are common out of arch sysdata into pci_host_bridge
we will have more commonality and it will be easier to re-factor the code.
Now, I got it, thanks!
Post by Liviu Dudau
Post by Yijing Wang
and generic data struct should
be created in generic PCI code.
This is a good idea, what I'm worried is this series is already large, so I think we need to post
another series to do it.
I wasn't asking to do it here, I was just offering a suggestion (and sharing some experience) when
it comes to handling msi chip in an arch independent way.
Post by Yijing Wang
Post by Liviu Dudau
- drivers/pci/ exports pci_init_host_bridge() that does the initialisation of bridge->windows
and anything else that is needed (like find_pci_host_bridge() function).
struct pci_controller {
struct pci_host_bridge bridge;
.....
};
#define to_pci_controller(bridge) container_of(bridge, struct pci_controller, bridge)
static inline struct pci_controller *get_host_controller(const struct pci_bus *bus)
{
struct pci_host_bridge *bridge = find_pci_host_bridge(bus);
if (bridge)
return to_pci_controller(bridge);
return NULL;
}
int arch_pci_init(....)
{
struct pci_controller *hose;
....
hose = kzalloc(sizeof(*hose), GFP_KERNEL);
pci_init_host_bridge(&hose->bridge);
....
pci_scan_root_bus(...., &hose->bridge, &resources);
....
return 0;
}
Then finding the right structure will be easy.
Post by Yijing Wang
Another, I don't like associate msi chip and every PCI device, further more,
almost all platforms except arm have only one MSI controller, and currently, PCI enumerating code doesn't need
to know the MSI chip details, like for legacy IRQ, PCI device doesn't need to know which IRQ controller they
should deliver IRQ to. I would think more about it, and hope other PCI guys can give some comments, especially from Bjorn.
I wasn't suggesing to associate an msi chip with every PCI device, but with the pci_host_bridge.
I don't expect a host bridge to have more than one msi chip, so that should be OK. Also, I'm
thinking that getting the associated msi chip should be some sort of pci_host_bridge ops function,
and for arches that don't care about MSI it doesn't get implemented.
Currently, a property "msi-parent" was introduced in arm, and all msi chip integrated in irq chip controller will
be added to of_pci_msi_chip_list. PCI host driver find the match msi chip by its of_node.
OK. But as you might have seen that still implies open coding a separate version of pci_scan_root_bus().

Best regards,
Liviu
Post by Yijing Wang
Thanks!
Yijing.
Post by Liviu Dudau
Best regards,
Liviu
Post by Yijing Wang
Thanks!
Yijing.
Post by Liviu Dudau
Best regards,
Liviu
Post by Yijing Wang
Post by Thierry Reding
I think both issues are orthogonal. Last time I checked a lot of work
was still necessary to unify host bridges enough so that it could be
shared across architectures. But perhaps some of that work has
happened in the meantime.
But like I said, when you create the root bus, you can easily attach the
MSI chip to it.
Thierry
--
Thanks!
Yijing
--
Thanks!
Yijing
--
Thanks!
Yijing
--
-------------------
.oooO
( )
\ ( Oooo.
\_) ( )
) /
(_/

One small step
for me ...
Yijing Wang
2014-09-29 10:12:26 UTC
Permalink
Post by Liviu Dudau
Post by Yijing Wang
This is a good idea, what I'm worried is this series is already large, so I think we need to post
another series to do it.
I wasn't asking to do it here, I was just offering a suggestion (and sharing some experience) when
it comes to handling msi chip in an arch independent way.
It's a good suggestion, thanks! :)
--
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
Konrad Rzeszutek Wilk
2014-09-25 14:23:40 UTC
Permalink
This series is based Bjorn's pci/msi branch
git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci/msi
Is there a git tree for these patches?
Currently, there are a lot of weak arch functions in MSI code.
Thierry Reding Introduced MSI chip framework to configure MSI/MSI-X in arm.
This series use MSI chip framework to refactor MSI code across all platforms
to eliminate weak arch functions. Then all MSI irqs will be managed in a
unified framework. Because this series changed a lot of ARCH MSI code,
so tests in the platforms which MSI code modified are warmly welcomed!
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.
PCI/MSI: Clean up struct msi_chip argument
PCI/MSI: Remove useless bus->msi assignment
MSI: Remove the redundant irq_set_chip_data()
x86/xen/MSI: Eliminate arch_msix_mask_irq() and arch_msi_mask_irq()
s390/MSI: Use __msi_mask_irq() instead of default_msi_mask_irq()
PCI/MSI: Introduce weak arch_find_msi_chip() to find MSI chip
PCI/MSI: Refactor struct msi_chip to make it become more common
x86/MSI: Use MSI chip framework to configure MSI/MSI-X irq
x86/xen/MSI: Use MSI chip framework to configure MSI/MSI-X irq
Irq_remapping/MSI: Use MSI chip framework to configure MSI/MSI-X irq
x86/MSI: Remove unused MSI weak arch functions
MIPS/Octeon/MSI: Use MSI chip framework to configure MSI/MSI-X irq
MIPS/Xlp: Remove the dead function destroy_irq() to fix build error
MIPS/Xlp/MSI: Use MSI chip framework to configure MSI/MSI-X irq
MIPS/Xlr/MSI: Use MSI chip framework to configure MSI/MSI-X irq
Powerpc/MSI: Use MSI chip framework to configure MSI/MSI-X irq
s390/MSI: Use MSI chip framework to configure MSI/MSI-X irq
arm/iop13xx/MSI: Use MSI chip framework to configure MSI/MSI-X irq
IA64/MSI: Use MSI chip framework to configure MSI/MSI-X irq
Sparc/MSI: Use MSI chip framework to configure MSI/MSI-X irq
tile/MSI: Use MSI chip framework to configure MSI/MSI-X irq
PCI/MSI: Clean up unused MSI arch functions
arch/arm/mach-iop13xx/include/mach/pci.h | 2 +
arch/arm/mach-iop13xx/iq81340mc.c | 1 +
arch/arm/mach-iop13xx/iq81340sc.c | 1 +
arch/arm/mach-iop13xx/msi.c | 9 ++-
arch/arm/mach-iop13xx/pci.c | 6 ++
arch/ia64/kernel/msi_ia64.c | 18 ++++-
arch/mips/pci/msi-octeon.c | 35 ++++++----
arch/mips/pci/msi-xlp.c | 18 ++++--
arch/mips/pci/pci-xlr.c | 15 ++++-
arch/powerpc/kernel/msi.c | 14 +++-
arch/s390/pci/pci.c | 18 ++++-
arch/sparc/kernel/pci.c | 14 +++-
arch/tile/kernel/pci_gx.c | 14 +++-
arch/x86/include/asm/apic.h | 4 +
arch/x86/include/asm/pci.h | 4 +-
arch/x86/include/asm/x86_init.h | 7 --
arch/x86/kernel/apic/io_apic.c | 16 ++++-
arch/x86/kernel/x86_init.c | 34 ---------
arch/x86/pci/xen.c | 60 +++++++++-------
drivers/iommu/irq_remapping.c | 9 ++-
drivers/irqchip/irq-armada-370-xp.c | 8 +--
drivers/pci/host/pci-tegra.c | 8 ++-
drivers/pci/host/pcie-designware.c | 4 +-
drivers/pci/host/pcie-rcar.c | 8 ++-
drivers/pci/msi.c | 114 ++++++++++++++----------------
drivers/pci/probe.c | 1 -
include/linux/msi.h | 26 ++-----
27 files changed, 266 insertions(+), 202 deletions(-)
Yijing Wang
2014-09-26 02:47:58 UTC
Permalink
Post by Konrad Rzeszutek Wilk
This series is based Bjorn's pci/msi branch
git://git.kernel.org/pub/scm/linux/kernel/git/helgaas/pci.git pci/msi
Is there a git tree for these patches?
Hi Konrad, my git tree in company can not be pulled from outside.
I will try to update this series to github these days.
Post by Konrad Rzeszutek Wilk
Currently, there are a lot of weak arch functions in MSI code.
Thierry Reding Introduced MSI chip framework to configure MSI/MSI-X in arm.
This series use MSI chip framework to refactor MSI code across all platforms
to eliminate weak arch functions. Then all MSI irqs will be managed in a
unified framework. Because this series changed a lot of ARCH MSI code,
so tests in the platforms which MSI code modified are warmly welcomed!
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.
PCI/MSI: Clean up struct msi_chip argument
PCI/MSI: Remove useless bus->msi assignment
MSI: Remove the redundant irq_set_chip_data()
x86/xen/MSI: Eliminate arch_msix_mask_irq() and arch_msi_mask_irq()
s390/MSI: Use __msi_mask_irq() instead of default_msi_mask_irq()
PCI/MSI: Introduce weak arch_find_msi_chip() to find MSI chip
PCI/MSI: Refactor struct msi_chip to make it become more common
x86/MSI: Use MSI chip framework to configure MSI/MSI-X irq
x86/xen/MSI: Use MSI chip framework to configure MSI/MSI-X irq
Irq_remapping/MSI: Use MSI chip framework to configure MSI/MSI-X irq
x86/MSI: Remove unused MSI weak arch functions
MIPS/Octeon/MSI: Use MSI chip framework to configure MSI/MSI-X irq
MIPS/Xlp: Remove the dead function destroy_irq() to fix build error
MIPS/Xlp/MSI: Use MSI chip framework to configure MSI/MSI-X irq
MIPS/Xlr/MSI: Use MSI chip framework to configure MSI/MSI-X irq
Powerpc/MSI: Use MSI chip framework to configure MSI/MSI-X irq
s390/MSI: Use MSI chip framework to configure MSI/MSI-X irq
arm/iop13xx/MSI: Use MSI chip framework to configure MSI/MSI-X irq
IA64/MSI: Use MSI chip framework to configure MSI/MSI-X irq
Sparc/MSI: Use MSI chip framework to configure MSI/MSI-X irq
tile/MSI: Use MSI chip framework to configure MSI/MSI-X irq
PCI/MSI: Clean up unused MSI arch functions
arch/arm/mach-iop13xx/include/mach/pci.h | 2 +
arch/arm/mach-iop13xx/iq81340mc.c | 1 +
arch/arm/mach-iop13xx/iq81340sc.c | 1 +
arch/arm/mach-iop13xx/msi.c | 9 ++-
arch/arm/mach-iop13xx/pci.c | 6 ++
arch/ia64/kernel/msi_ia64.c | 18 ++++-
arch/mips/pci/msi-octeon.c | 35 ++++++----
arch/mips/pci/msi-xlp.c | 18 ++++--
arch/mips/pci/pci-xlr.c | 15 ++++-
arch/powerpc/kernel/msi.c | 14 +++-
arch/s390/pci/pci.c | 18 ++++-
arch/sparc/kernel/pci.c | 14 +++-
arch/tile/kernel/pci_gx.c | 14 +++-
arch/x86/include/asm/apic.h | 4 +
arch/x86/include/asm/pci.h | 4 +-
arch/x86/include/asm/x86_init.h | 7 --
arch/x86/kernel/apic/io_apic.c | 16 ++++-
arch/x86/kernel/x86_init.c | 34 ---------
arch/x86/pci/xen.c | 60 +++++++++-------
drivers/iommu/irq_remapping.c | 9 ++-
drivers/irqchip/irq-armada-370-xp.c | 8 +--
drivers/pci/host/pci-tegra.c | 8 ++-
drivers/pci/host/pcie-designware.c | 4 +-
drivers/pci/host/pcie-rcar.c | 8 ++-
drivers/pci/msi.c | 114 ++++++++++++++----------------
drivers/pci/probe.c | 1 -
include/linux/msi.h | 26 ++-----
27 files changed, 266 insertions(+), 202 deletions(-)
.
--
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...