2015-07-09 07:59:05

by Jiang Liu

[permalink] [raw]
Subject: [RFC Patch V1 00/12] Reorganize struct msi_desc to prepare for support of generic MSI

Recently Marc Zyngier <[email protected]> has posted a patch set at
https://lkml.org/lkml/2015/7/7/712
to enhance PCI MSI code to support generic MSI.

This is a companion patch set to refine struct msi_desc and related data
structures to support generic MSI, and it would be better to combined with
Marc's patch set. It's also requested by
Stuart Yoder <[email protected]>

It first introduces a helper function msi_desc_to_pci_sysdata(), and
convert current PCI drivers to use helper functions to access fields
in struct msi_desc.
Then it moves msi_list from struct pci_dev into struct device and
refines struct msi_desc.
At last it moves alloc_msi_entry() into kernel/irq/msi.c for reuse.

Currently msi_desc_to_pci_sysdata() and msi_desc_to_pci_dev() are
implemented as normal functions instead of inlines to avoid header file
inclusion issue. If inlined version is preferred for performance, we could
move all of first_pci_msi_entry, for_each_pci_msi_entry, msi_desc_to_pci_dev
and msi_desc_to_pci_sysdata from linxu/kernel/msi.h into linux/kernel/pci.h.

This patch set is based on v4.2-rc1 and passes 0day test suite. You
may access the code at:
https://github.com/jiangliu/linux.git msi_desc_v1

Thanks!
Gerry

Jiang Liu (12):
PCI: Add helper function msi_desc_to_pci_sysdata()
MIPS, PCI: Use for_pci_msi_entry() to access MSI device list
PowerPC, PCI: Use for_pci_msi_entry() to access MSI device list
s390/pci: Use for_pci_msi_entry() to access MSI device list
x86, PCI: Use for_pci_msi_entry() to access MSI device list
PCI: Use for_pci_msi_entry() to access MSI device list
sparc, PCI: Use helper functions to access fields in struct msi_desc
PCI: Use helper functions to access fields in struct msi_desc
genirq: Move msi_list from struct pci_dev to struct device
genirq, PCI: Store 'struct device *' instead 'struct pci_dev *' in
struct msi_desc
genirq, PCI: Reorginize struct msi_desc to prepare for support of
generic MSI
genirq, PCI: Move alloc_msi_entry() from PCI MSI code into generic
MSI code

arch/mips/pci/msi-octeon.c | 2 +-
arch/powerpc/platforms/cell/axon_msi.c | 6 +--
arch/powerpc/platforms/pasemi/msi.c | 4 +-
arch/powerpc/platforms/powernv/pci.c | 4 +-
arch/powerpc/platforms/pseries/msi.c | 6 +--
arch/powerpc/sysdev/fsl_msi.c | 4 +-
arch/powerpc/sysdev/mpic_u3msi.c | 4 +-
arch/powerpc/sysdev/ppc4xx_hsta_msi.c | 4 +-
arch/powerpc/sysdev/ppc4xx_msi.c | 4 +-
arch/s390/pci/pci.c | 6 +--
arch/sparc/kernel/pci.c | 2 +-
arch/x86/pci/xen.c | 8 ++--
drivers/base/core.c | 3 ++
drivers/pci/host/pci-keystone-dw.c | 6 +--
drivers/pci/host/pcie-designware.c | 4 +-
drivers/pci/host/pcie-xilinx.c | 12 ++---
drivers/pci/msi.c | 82 +++++++++++++++++---------------
drivers/pci/xen-pcifront.c | 2 +-
include/linux/device.h | 4 ++
include/linux/msi.h | 55 +++++++++++----------
include/linux/pci.h | 1 -
kernel/irq/msi.c | 17 +++++++
22 files changed, 136 insertions(+), 104 deletions(-)

--
1.7.10.4


2015-07-09 07:59:15

by Jiang Liu

[permalink] [raw]
Subject: [RFC Patch V1 01/12] PCI: Add helper function msi_desc_to_pci_sysdata()

Add helper function msi_desc_to_pci_sysdata() to retrieve sysdata from
an MSI descriptor. To avoid pulling include/linux/pci.h into
include/linux/msi.h, msi_desc_to_pci_sysdata() is implemented as a normal
function instead of an inline function.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/pci/msi.c | 8 ++++++++
include/linux/msi.h | 7 +++++++
2 files changed, 15 insertions(+)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index f66be868ad21..7b4c20c9f9ca 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -1137,6 +1137,14 @@ int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
}
EXPORT_SYMBOL(pci_enable_msix_range);

+void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
+{
+ struct pci_dev *dev = msi_desc_to_pci_dev(desc);
+
+ return dev->bus->sysdata;
+}
+EXPORT_SYMBOL_GPL(msi_desc_to_pci_sysdata);
+
#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
/**
* pci_msi_domain_write_msg - Helper to write MSI message to PCI config space
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 8ac4a68ffae2..cfbd2afeaf64 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -60,6 +60,13 @@ static inline struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
{
return desc->dev;
}
+
+void *msi_desc_to_pci_sysdata(struct msi_desc *desc);
+#else /* CONFIG_PCI_MSI */
+static inline void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
+{
+ return NULL;
+}
#endif /* CONFIG_PCI_MSI */

void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
--
1.7.10.4

2015-07-09 07:59:27

by Jiang Liu

[permalink] [raw]
Subject: [RFC Patch V1 02/12] MIPS, PCI: Use for_pci_msi_entry() to access MSI device list

Use accessor for_pci_msi_entry() to access MSI device list, so we could
easily move msi_list from struct pci_dev into struct device later.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/mips/pci/msi-octeon.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c
index cffaaf4aae3c..2a5bb849b10e 100644
--- a/arch/mips/pci/msi-octeon.c
+++ b/arch/mips/pci/msi-octeon.c
@@ -200,7 +200,7 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
if (type == PCI_CAP_ID_MSI && nvec > 1)
return 1;

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
ret = arch_setup_msi_irq(dev, entry);
if (ret < 0)
return ret;
--
1.7.10.4

2015-07-09 07:59:54

by Jiang Liu

[permalink] [raw]
Subject: [RFC Patch V1 03/12] PowerPC, PCI: Use for_pci_msi_entry() to access MSI device list

Use accessor for_pci_msi_entry() to access MSI device list, so we could
easily move msi_list from struct pci_dev into struct device later.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/powerpc/platforms/cell/axon_msi.c | 6 +++---
arch/powerpc/platforms/pasemi/msi.c | 4 ++--
arch/powerpc/platforms/powernv/pci.c | 4 ++--
arch/powerpc/platforms/pseries/msi.c | 6 +++---
arch/powerpc/sysdev/fsl_msi.c | 4 ++--
arch/powerpc/sysdev/mpic_u3msi.c | 4 ++--
arch/powerpc/sysdev/ppc4xx_hsta_msi.c | 4 ++--
arch/powerpc/sysdev/ppc4xx_msi.c | 4 ++--
8 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index fe51de4fcf13..306888acb737 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -213,7 +213,7 @@ static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg)
return -ENODEV;
}

- entry = list_first_entry(&dev->msi_list, struct msi_desc, list);
+ entry = first_pci_msi_entry(dev);

for (; dn; dn = of_get_next_parent(dn)) {
if (entry->msi_attrib.is_64) {
@@ -269,7 +269,7 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
if (rc)
return rc;

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
virq = irq_create_direct_mapping(msic->irq_domain);
if (virq == NO_IRQ) {
dev_warn(&dev->dev,
@@ -292,7 +292,7 @@ static void axon_msi_teardown_msi_irqs(struct pci_dev *dev)

dev_dbg(&dev->dev, "axon_msi: tearing down msi irqs\n");

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
if (entry->irq == NO_IRQ)
continue;

diff --git a/arch/powerpc/platforms/pasemi/msi.c b/arch/powerpc/platforms/pasemi/msi.c
index 27f2b187a91b..e66ef1943338 100644
--- a/arch/powerpc/platforms/pasemi/msi.c
+++ b/arch/powerpc/platforms/pasemi/msi.c
@@ -66,7 +66,7 @@ static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev)

pr_debug("pasemi_msi_teardown_msi_irqs, pdev %p\n", pdev);

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
if (entry->irq == NO_IRQ)
continue;

@@ -94,7 +94,7 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
msg.address_hi = 0;
msg.address_lo = PASEMI_MSI_ADDR;

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
/* Allocate 16 interrupts for now, since that's the grouping for
* affinity. This can be changed later if it turns out 32 is too
* few MSIs for someone, but restrictions will apply to how the
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index 765d8ed558d0..bc6d4e02e29c 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -61,7 +61,7 @@ int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
if (pdev->no_64bit_msi && !phb->msi32_support)
return -ENODEV;

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
if (!entry->msi_attrib.is_64 && !phb->msi32_support) {
pr_warn("%s: Supports only 64-bit MSIs\n",
pci_name(pdev));
@@ -103,7 +103,7 @@ void pnv_teardown_msi_irqs(struct pci_dev *pdev)
if (WARN_ON(!phb))
return;

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
if (entry->irq == NO_IRQ)
continue;
irq_set_msi_desc(entry->irq, NULL);
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
index c22bb647cce6..272e9ec1ab54 100644
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -118,7 +118,7 @@ static void rtas_teardown_msi_irqs(struct pci_dev *pdev)
{
struct msi_desc *entry;

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
if (entry->irq == NO_IRQ)
continue;

@@ -350,7 +350,7 @@ static int check_msix_entries(struct pci_dev *pdev)
* So we must reject such requests. */

expected = 0;
- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
if (entry->msi_attrib.entry_nr != expected) {
pr_debug("rtas_msi: bad MSI-X entries.\n");
return -EINVAL;
@@ -462,7 +462,7 @@ again:
}

i = 0;
- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
hwirq = rtas_query_irq_number(pdn, i++);
if (hwirq < 0) {
pr_debug("rtas_msi: error (%d) getting hwirq\n", rc);
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 5236e5427c38..5916da1856a7 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -129,7 +129,7 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev)
struct msi_desc *entry;
struct fsl_msi *msi_data;

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
if (entry->irq == NO_IRQ)
continue;
msi_data = irq_get_chip_data(entry->irq);
@@ -219,7 +219,7 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
}
}

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
/*
* Loop over all the MSI devices until we find one that has an
* available interrupt.
diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c
index fc46ef3b816e..70fbd5694a8b 100644
--- a/arch/powerpc/sysdev/mpic_u3msi.c
+++ b/arch/powerpc/sysdev/mpic_u3msi.c
@@ -108,7 +108,7 @@ static void u3msi_teardown_msi_irqs(struct pci_dev *pdev)
{
struct msi_desc *entry;

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
if (entry->irq == NO_IRQ)
continue;

@@ -140,7 +140,7 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
return -ENXIO;
}

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1);
if (hwirq < 0) {
pr_debug("u3msi: failed allocating hwirq\n");
diff --git a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
index 2bc33674ebfc..0d88ba242754 100644
--- a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
+++ b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
@@ -50,7 +50,7 @@ static int hsta_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
return -EINVAL;
}

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
irq = msi_bitmap_alloc_hwirqs(&ppc4xx_hsta_msi.bmp, 1);
if (irq < 0) {
pr_debug("%s: Failed to allocate msi interrupt\n",
@@ -108,7 +108,7 @@ static void hsta_teardown_msi_irqs(struct pci_dev *dev)
struct msi_desc *entry;
int irq;

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
if (entry->irq == NO_IRQ)
continue;

diff --git a/arch/powerpc/sysdev/ppc4xx_msi.c b/arch/powerpc/sysdev/ppc4xx_msi.c
index 6eb21f2ea585..24d0470c1698 100644
--- a/arch/powerpc/sysdev/ppc4xx_msi.c
+++ b/arch/powerpc/sysdev/ppc4xx_msi.c
@@ -93,7 +93,7 @@ static int ppc4xx_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
if (!msi_data->msi_virqs)
return -ENOMEM;

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
int_no = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1);
if (int_no >= 0)
break;
@@ -127,7 +127,7 @@ void ppc4xx_teardown_msi_irqs(struct pci_dev *dev)

dev_dbg(&dev->dev, "PCIE-MSI: tearing down msi irqs\n");

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
if (entry->irq == NO_IRQ)
continue;
irq_set_msi_desc(entry->irq, NULL);
--
1.7.10.4

2015-07-09 08:00:07

by Jiang Liu

[permalink] [raw]
Subject: [RFC Patch V1 04/12] s390/pci: Use for_pci_msi_entry() to access MSI device list

Use accessor for_pci_msi_entry() to access MSI device list, so we could
easily move msi_list from struct pci_dev into struct device later.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/s390/pci/pci.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 598f023cf8a6..34f162753403 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -414,7 +414,7 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)

/* Request MSI interrupts */
hwirq = 0;
- list_for_each_entry(msi, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(msi, pdev) {
rc = -EIO;
irq = irq_alloc_desc(0); /* Alloc irq on node 0 */
if (irq < 0)
@@ -440,7 +440,7 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
return (msi_vecs == nvec) ? 0 : msi_vecs;

out_msi:
- list_for_each_entry(msi, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(msi, pdev) {
if (hwirq-- == 0)
break;
irq_set_msi_desc(msi->irq, NULL);
@@ -470,7 +470,7 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
return;

/* Release MSI interrupts */
- list_for_each_entry(msi, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(msi, pdev) {
if (msi->msi_attrib.is_msix)
__pci_msix_desc_mask_irq(msi, 1);
else
--
1.7.10.4

2015-07-09 08:04:14

by Jiang Liu

[permalink] [raw]
Subject: [RFC Patch V1 05/12] x86, PCI: Use for_pci_msi_entry() to access MSI device list

Use accessor for_pci_msi_entry() to access MSI device list, so we could
easily move msi_list from struct pci_dev into struct device later.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/x86/pci/xen.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index d22f4b5bbc04..ff31ab464213 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -179,7 +179,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
if (ret)
goto error;
i = 0;
- list_for_each_entry(msidesc, &dev->msi_list, list) {
+ for_each_pci_msi_entry(msidesc, dev) {
irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i],
(type == PCI_CAP_ID_MSI) ? nvec : 1,
(type == PCI_CAP_ID_MSIX) ?
@@ -230,7 +230,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
if (type == PCI_CAP_ID_MSI && nvec > 1)
return 1;

- list_for_each_entry(msidesc, &dev->msi_list, list) {
+ for_each_pci_msi_entry(msidesc, dev) {
__pci_read_msi_msg(msidesc, &msg);
pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff);
@@ -274,7 +274,7 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
int ret = 0;
struct msi_desc *msidesc;

- list_for_each_entry(msidesc, &dev->msi_list, list) {
+ for_each_pci_msi_entry(msidesc, dev) {
struct physdev_map_pirq map_irq;
domid_t domid;

@@ -386,7 +386,7 @@ static void xen_teardown_msi_irqs(struct pci_dev *dev)
{
struct msi_desc *msidesc;

- msidesc = list_entry(dev->msi_list.next, struct msi_desc, list);
+ msidesc = first_pci_msi_entry(dev);
if (msidesc->msi_attrib.is_msix)
xen_pci_frontend_disable_msix(dev);
else
--
1.7.10.4

2015-07-09 08:00:15

by Jiang Liu

[permalink] [raw]
Subject: [RFC Patch V1 06/12] PCI: Use for_pci_msi_entry() to access MSI device list

Use accessor for_pci_msi_entry() to access MSI device list, so we could easily
move msi_list from struct pci_dev into struct device later.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/pci/msi.c | 39 ++++++++++++++++++++-------------------
drivers/pci/xen-pcifront.c | 2 +-
2 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 7b4c20c9f9ca..d09afa78d7a1 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -131,7 +131,7 @@ int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
if (type == PCI_CAP_ID_MSI && nvec > 1)
return 1;

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
ret = arch_setup_msi_irq(dev, entry);
if (ret < 0)
return ret;
@@ -151,7 +151,7 @@ void default_teardown_msi_irqs(struct pci_dev *dev)
int i;
struct msi_desc *entry;

- list_for_each_entry(entry, &dev->msi_list, list)
+ for_each_pci_msi_entry(entry, dev)
if (entry->irq)
for (i = 0; i < entry->nvec_used; i++)
arch_teardown_msi_irq(entry->irq + i);
@@ -168,7 +168,7 @@ static void default_restore_msi_irq(struct pci_dev *dev, int irq)

entry = NULL;
if (dev->msix_enabled) {
- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
if (irq == entry->irq)
break;
}
@@ -282,7 +282,7 @@ void default_restore_msi_irqs(struct pci_dev *dev)
{
struct msi_desc *entry;

- list_for_each_entry(entry, &dev->msi_list, list)
+ for_each_pci_msi_entry(entry, dev)
default_restore_msi_irq(dev, entry->irq);
}

@@ -363,21 +363,22 @@ EXPORT_SYMBOL_GPL(pci_write_msi_msg);

static void free_msi_irqs(struct pci_dev *dev)
{
+ struct list_head *msi_list = dev_to_msi_list(&dev->dev);
struct msi_desc *entry, *tmp;
struct attribute **msi_attrs;
struct device_attribute *dev_attr;
int i, count = 0;

- list_for_each_entry(entry, &dev->msi_list, list)
+ for_each_pci_msi_entry(entry, dev)
if (entry->irq)
for (i = 0; i < entry->nvec_used; i++)
BUG_ON(irq_has_action(entry->irq + i));

pci_msi_teardown_msi_irqs(dev);

- list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
+ list_for_each_entry_safe(entry, tmp, msi_list, list) {
if (entry->msi_attrib.is_msix) {
- if (list_is_last(&entry->list, &dev->msi_list))
+ if (list_is_last(&entry->list, msi_list))
iounmap(entry->mask_base);
}

@@ -448,7 +449,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev)

if (!dev->msix_enabled)
return;
- BUG_ON(list_empty(&dev->msi_list));
+ BUG_ON(list_empty(dev_to_msi_list(&dev->dev)));

/* route the table */
pci_intx_for_msi(dev, 0);
@@ -456,7 +457,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL);

arch_restore_msi_irqs(dev);
- list_for_each_entry(entry, &dev->msi_list, list)
+ for_each_pci_msi_entry(entry, dev)
msix_mask_irq(entry, entry->masked);

pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0);
@@ -501,7 +502,7 @@ static int populate_msi_sysfs(struct pci_dev *pdev)
int count = 0;

/* Determine how many msi entries we have */
- list_for_each_entry(entry, &pdev->msi_list, list)
+ for_each_pci_msi_entry(entry, pdev)
++num_msi;
if (!num_msi)
return 0;
@@ -510,7 +511,7 @@ static int populate_msi_sysfs(struct pci_dev *pdev)
msi_attrs = kzalloc(sizeof(void *) * (num_msi + 1), GFP_KERNEL);
if (!msi_attrs)
return -ENOMEM;
- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL);
if (!msi_dev_attr)
goto error_attrs;
@@ -599,7 +600,7 @@ static int msi_verify_entries(struct pci_dev *dev)
{
struct msi_desc *entry;

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
if (!dev->no_64bit_msi || !entry->msg.address_hi)
continue;
dev_err(&dev->dev, "Device has broken 64-bit MSI but arch"
@@ -636,7 +637,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
mask = msi_mask(entry->msi_attrib.multi_cap);
msi_mask_irq(entry, mask, mask);

- list_add_tail(&entry->list, &dev->msi_list);
+ list_add_tail(&entry->list, dev_to_msi_list(&dev->dev));

/* Configure MSI capability structure */
ret = pci_msi_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI);
@@ -713,7 +714,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base,
entry->mask_base = base;
entry->nvec_used = 1;

- list_add_tail(&entry->list, &dev->msi_list);
+ list_add_tail(&entry->list, dev_to_msi_list(&dev->dev));
}

return 0;
@@ -725,7 +726,7 @@ static void msix_program_entries(struct pci_dev *dev,
struct msi_desc *entry;
int i = 0;

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
int offset = entries[i].entry * PCI_MSIX_ENTRY_SIZE +
PCI_MSIX_ENTRY_VECTOR_CTRL;

@@ -806,7 +807,7 @@ out_avail:
struct msi_desc *entry;
int avail = 0;

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
if (entry->irq != 0)
avail++;
}
@@ -895,8 +896,8 @@ void pci_msi_shutdown(struct pci_dev *dev)
if (!pci_msi_enable || !dev || !dev->msi_enabled)
return;

- BUG_ON(list_empty(&dev->msi_list));
- desc = list_first_entry(&dev->msi_list, struct msi_desc, list);
+ BUG_ON(list_empty(dev_to_msi_list(&dev->dev)));
+ desc = first_msi_entry(dev);

pci_msi_set_enable(dev, 0);
pci_intx_for_msi(dev, 1);
@@ -1001,7 +1002,7 @@ void pci_msix_shutdown(struct pci_dev *dev)
return;

/* Return the device with MSI-X masked as initial states */
- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
/* Keep cached states to be restored */
__pci_msix_desc_mask_irq(entry, 1);
}
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index 8b7a900cd28b..c777b97207d5 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -265,7 +265,7 @@ static int pci_frontend_enable_msix(struct pci_dev *dev,
}

i = 0;
- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
op.msix_entries[i].entry = entry->msi_attrib.entry_nr;
/* Vector is useless at this point. */
op.msix_entries[i].vector = -1;
--
1.7.10.4

2015-07-09 08:00:22

by Jiang Liu

[permalink] [raw]
Subject: [RFC Patch V1 07/12] sparc, PCI: Use helper functions to access fields in struct msi_desc

Use helper functions to access fields in struct msi_desc, so we could
easily refine struct msi_desc later.

Signed-off-by: Jiang Liu <[email protected]>
---
arch/sparc/kernel/pci.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index c928bc64b4ba..048b406d9e02 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -918,7 +918,7 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
void arch_teardown_msi_irq(unsigned int irq)
{
struct msi_desc *entry = irq_get_msi_desc(irq);
- struct pci_dev *pdev = entry->dev;
+ struct pci_dev *pdev = msi_desc_to_pci_dev(entry);
struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;

if (pbm->teardown_msi_irq)
--
1.7.10.4

2015-07-09 08:00:34

by Jiang Liu

[permalink] [raw]
Subject: [RFC Patch V1 08/12] PCI: Use helper functions to access fields in struct msi_desc

Use helper functions to access fields in struct msi_desc, so we could
easily refine msi_desc later.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/pci/host/pci-keystone-dw.c | 6 +++---
drivers/pci/host/pcie-designware.c | 4 ++--
drivers/pci/host/pcie-xilinx.c | 12 +++++-------
drivers/pci/msi.c | 13 ++++++++-----
4 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
index f34892e0edb4..e792086c1639 100644
--- a/drivers/pci/host/pci-keystone-dw.c
+++ b/drivers/pci/host/pci-keystone-dw.c
@@ -109,7 +109,7 @@ static void ks_dw_pcie_msi_irq_ack(struct irq_data *d)
struct pcie_port *pp;

msi = irq_get_msi_desc(irq);
- pp = sys_to_pcie(msi->dev->bus->sysdata);
+ pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));
ks_pcie = to_keystone_pcie(pp);
offset = irq - irq_linear_revmap(pp->irq_domain, 0);
update_reg_offset_bit_pos(offset, &reg_offset, &bit_pos);
@@ -148,7 +148,7 @@ static void ks_dw_pcie_msi_irq_mask(struct irq_data *d)
u32 offset;

msi = irq_get_msi_desc(irq);
- pp = sys_to_pcie(msi->dev->bus->sysdata);
+ pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));
ks_pcie = to_keystone_pcie(pp);
offset = irq - irq_linear_revmap(pp->irq_domain, 0);

@@ -170,7 +170,7 @@ static void ks_dw_pcie_msi_irq_unmask(struct irq_data *d)
u32 offset;

msi = irq_get_msi_desc(irq);
- pp = sys_to_pcie(msi->dev->bus->sysdata);
+ pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));
ks_pcie = to_keystone_pcie(pp);
offset = irq - irq_linear_revmap(pp->irq_domain, 0);

diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 69486be7181e..65596f96763c 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -255,7 +255,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
{
int irq, pos0, i;
- struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
+ struct pcie_port *pp = sys_to_pcie(msi_desc_to_pci_sysdata(desc));

pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
order_base_2(no_irqs));
@@ -327,7 +327,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
{
struct irq_data *data = irq_get_irq_data(irq);
struct msi_desc *msi = irq_data_get_msi(data);
- struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
+ struct pcie_port *pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));

clear_irq_range(pp, irq, 1, data->hwirq);
}
diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c
index f1a06a091ccb..64454f416639 100644
--- a/drivers/pci/host/pcie-xilinx.c
+++ b/drivers/pci/host/pcie-xilinx.c
@@ -227,18 +227,16 @@ static struct pci_ops xilinx_pcie_ops = {
*/
static void xilinx_pcie_destroy_msi(unsigned int irq)
{
- struct irq_desc *desc;
struct msi_desc *msi;
struct xilinx_pcie_port *port;

- desc = irq_to_desc(irq);
- msi = irq_desc_get_msi_desc(desc);
- port = sys_to_pcie(msi->dev->bus->sysdata);
-
- if (!test_bit(irq, msi_irq_in_use))
+ if (!test_bit(irq, msi_irq_in_use)) {
+ msi = irq_get_msi_desc(irq);
+ port = sys_to_pcie(msi_desc_to_pci_sys_data(msi));
dev_err(port->dev, "Trying to free unused MSI#%d\n", irq);
- else
+ } else {
clear_bit(irq, msi_irq_in_use);
+ }
}

/**
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index d09afa78d7a1..6497608545e2 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -208,7 +208,8 @@ u32 __pci_msi_desc_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)

mask_bits &= ~mask;
mask_bits |= flag;
- pci_write_config_dword(desc->dev, desc->mask_pos, mask_bits);
+ pci_write_config_dword(msi_desc_to_pci_dev(desc), desc->mask_pos,
+ mask_bits);

return mask_bits;
}
@@ -288,7 +289,9 @@ void default_restore_msi_irqs(struct pci_dev *dev)

void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
{
- BUG_ON(entry->dev->current_state != PCI_D0);
+ struct pci_dev *dev = msi_desc_to_pci_dev(entry);
+
+ BUG_ON(dev->current_state != PCI_D0);

if (entry->msi_attrib.is_msix) {
void __iomem *base = entry->mask_base +
@@ -298,7 +301,6 @@ void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR);
msg->data = readl(base + PCI_MSIX_ENTRY_DATA);
} else {
- struct pci_dev *dev = entry->dev;
int pos = dev->msi_cap;
u16 data;

@@ -318,7 +320,9 @@ void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)

void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
{
- if (entry->dev->current_state != PCI_D0) {
+ struct pci_dev *dev = msi_desc_to_pci_dev(entry);
+
+ if (dev->current_state != PCI_D0) {
/* Don't touch the hardware now */
} else if (entry->msi_attrib.is_msix) {
void __iomem *base;
@@ -329,7 +333,6 @@ void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR);
writel(msg->data, base + PCI_MSIX_ENTRY_DATA);
} else {
- struct pci_dev *dev = entry->dev;
int pos = dev->msi_cap;
u16 msgctl;

--
1.7.10.4

2015-07-09 08:00:47

by Jiang Liu

[permalink] [raw]
Subject: [RFC Patch V1 09/12] genirq: Move msi_list from struct pci_dev to struct device

Move msi_list from struct pci_dev into struct device, so we could support
non-PCI-device based generic MSI interrupts.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/base/core.c | 3 +++
drivers/pci/msi.c | 3 +--
include/linux/device.h | 4 ++++
include/linux/msi.h | 2 +-
include/linux/pci.h | 1 -
5 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index dafae6d2f7ac..18e2a89aa138 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -662,6 +662,9 @@ void device_initialize(struct device *dev)
INIT_LIST_HEAD(&dev->devres_head);
device_pm_init(dev);
set_dev_node(dev, -1);
+#ifdef CONFIG_GENERIC_MSI_IRQ
+ INIT_LIST_HEAD(&dev->msi_list);
+#endif
}
EXPORT_SYMBOL_GPL(device_initialize);

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 6497608545e2..0050ad436718 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -900,7 +900,7 @@ void pci_msi_shutdown(struct pci_dev *dev)
return;

BUG_ON(list_empty(dev_to_msi_list(&dev->dev)));
- desc = first_msi_entry(dev);
+ desc = first_pci_msi_entry(dev);

pci_msi_set_enable(dev, 0);
pci_intx_for_msi(dev, 1);
@@ -1044,7 +1044,6 @@ EXPORT_SYMBOL(pci_msi_enabled);

void pci_msi_init_pci_dev(struct pci_dev *dev)
{
- INIT_LIST_HEAD(&dev->msi_list);
}

/**
diff --git a/include/linux/device.h b/include/linux/device.h
index 5a31bf3a4024..22227e7fe463 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -713,6 +713,7 @@ struct device_dma_parameters {
* along with subsystem-level and driver-level callbacks.
* @pins: For device pin management.
* See Documentation/pinctrl.txt for details.
+ * @msi_list: Hosts MSI descriptors
* @numa_node: NUMA node this device is close to.
* @dma_mask: Dma mask (if dma'ble device).
* @coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping as not all
@@ -776,6 +777,9 @@ struct device {
#ifdef CONFIG_PINCTRL
struct dev_pin_info *pins;
#endif
+#ifdef CONFIG_GENERIC_MSI_IRQ
+ struct list_head msi_list;
+#endif

#ifdef CONFIG_NUMA
int numa_node; /* NUMA node this device is close to */
diff --git a/include/linux/msi.h b/include/linux/msi.h
index cfbd2afeaf64..57fe766a14bf 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -45,7 +45,7 @@ struct msi_desc {

/* Helpers to hide struct msi_desc implementation details */
#define msi_desc_to_dev(desc) (&(desc)->dev.dev)
-#define dev_to_msi_list(dev) (&to_pci_dev((dev))->msi_list)
+#define dev_to_msi_list(dev) (&(dev)->msi_list)
#define first_msi_entry(dev) \
list_first_entry(dev_to_msi_list((dev)), struct msi_desc, list)
#define for_each_msi_entry(desc, dev) \
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 8a0321a8fb59..fbf245f5eba7 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -366,7 +366,6 @@ struct pci_dev {
struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
#ifdef CONFIG_PCI_MSI
- struct list_head msi_list;
const struct attribute_group **msi_irq_groups;
#endif
struct pci_vpd *vpd;
--
1.7.10.4

2015-07-09 08:01:01

by David Miller

[permalink] [raw]
Subject: Re: [RFC Patch V1 07/12] sparc, PCI: Use helper functions to access fields in struct msi_desc

From: Jiang Liu <[email protected]>
Date: Thu, 9 Jul 2015 16:00:42 +0800

> Use helper functions to access fields in struct msi_desc, so we could
> easily refine struct msi_desc later.
>
> Signed-off-by: Jiang Liu <[email protected]>

Acked-by: David S. Miller <[email protected]>

2015-07-09 08:02:50

by Jiang Liu

[permalink] [raw]
Subject: [RFC Patch V1 10/12] genirq, PCI: Store 'struct device *' instead 'struct pci_dev *' in struct msi_desc

Store 'struct device *' instead 'struct pci_dev *' in struct msi_desc,
so struct msi_desc may be reused by generic MSI drivers.

Signed-off-by: Jiang Liu <[email protected]>
---
drivers/pci/msi.c | 7 ++++++-
include/linux/msi.h | 11 ++++-------
2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 0050ad436718..260c1653701d 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -413,7 +413,7 @@ static struct msi_desc *alloc_msi_entry(struct pci_dev *dev)
return NULL;

INIT_LIST_HEAD(&desc->list);
- desc->dev = dev;
+ desc->dev = &dev->dev;

return desc;
}
@@ -1140,6 +1140,11 @@ int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
}
EXPORT_SYMBOL(pci_enable_msix_range);

+struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
+{
+ return to_pci_dev(desc->dev);
+}
+
void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
{
struct pci_dev *dev = msi_desc_to_pci_dev(desc);
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 57fe766a14bf..5f77e231f515 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -14,6 +14,7 @@ extern int pci_msi_ignore_mask;
/* Helper functions */
struct irq_data;
struct msi_desc;
+struct pci_dev;
void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg);

@@ -37,14 +38,14 @@ struct msi_desc {
void __iomem *mask_base;
u8 mask_pos;
};
- struct pci_dev *dev;
+ struct device *dev;

/* Last set MSI message */
struct msi_msg msg;
};

/* Helpers to hide struct msi_desc implementation details */
-#define msi_desc_to_dev(desc) (&(desc)->dev.dev)
+#define msi_desc_to_dev(desc) ((desc)->dev)
#define dev_to_msi_list(dev) (&(dev)->msi_list)
#define first_msi_entry(dev) \
list_first_entry(dev_to_msi_list((dev)), struct msi_desc, list)
@@ -56,11 +57,7 @@ struct msi_desc {
#define for_each_pci_msi_entry(desc, pdev) \
for_each_msi_entry((desc), &(pdev)->dev)

-static inline struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
-{
- return desc->dev;
-}
-
+struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc);
void *msi_desc_to_pci_sysdata(struct msi_desc *desc);
#else /* CONFIG_PCI_MSI */
static inline void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
--
1.7.10.4

2015-07-09 08:00:55

by Jiang Liu

[permalink] [raw]
Subject: [RFC Patch V1 11/12] genirq, PCI: Reorginize struct msi_desc to prepare for support of generic MSI

Reorganize struct msi_desc so it could be reused by other MSI drivers.

Signed-off-by: Jiang Liu <[email protected]>
---
include/linux/msi.h | 41 +++++++++++++++++++++--------------------
1 file changed, 21 insertions(+), 20 deletions(-)

diff --git a/include/linux/msi.h b/include/linux/msi.h
index 5f77e231f515..f6845bc83774 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -19,29 +19,30 @@ void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg);

struct msi_desc {
- struct {
- __u8 is_msix : 1;
- __u8 multiple: 3; /* log2 num of messages allocated */
- __u8 multi_cap : 3; /* log2 num of messages supported */
- __u8 maskbit : 1; /* mask-pending bit supported ? */
- __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */
- __u16 entry_nr; /* specific enabled entry */
- unsigned default_irq; /* default pre-assigned irq */
- } msi_attrib;
-
- u32 masked; /* mask bits */
- unsigned int irq;
- unsigned int nvec_used; /* number of messages */
- struct list_head list;
+ struct list_head list;
+ unsigned int irq;
+ unsigned int nvec_used; /* number of messages */
+ struct device * dev;
+ struct msi_msg msg; /* Last set MSI message */

union {
- void __iomem *mask_base;
- u8 mask_pos;
+ struct { /* For PCI MSI/MSI-X */
+ u32 masked; /* mask bits */
+ struct {
+ __u8 is_msix : 1;
+ __u8 multiple: 3; /* log2 num of messages allocated */
+ __u8 multi_cap : 3; /* log2 num of messages supported */
+ __u8 maskbit : 1; /* mask-pending bit supported ? */
+ __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */
+ __u16 entry_nr; /* specific enabled entry */
+ unsigned default_irq; /* default pre-assigned irq */
+ } msi_attrib;
+ union {
+ u8 mask_pos;
+ void __iomem *mask_base;
+ };
+ };
};
- struct device *dev;
-
- /* Last set MSI message */
- struct msi_msg msg;
};

/* Helpers to hide struct msi_desc implementation details */
--
1.7.10.4

2015-07-09 08:01:15

by Jiang Liu

[permalink] [raw]
Subject: [RFC Patch V1 12/12] genirq, PCI: Move alloc_msi_entry() from PCI MSI code into generic MSI code

Move alloc_msi_entry() from PCI MSI code into generic MSI code, so it
could be reused by other generic MSI drivers.
Also introduce free_msi_entry() for completeness.

This is suggested by Stuart Yoder <[email protected]>.

Signed-off-by: Stuart Yoder <[email protected]>
Signed-off-by: Jiang Liu <[email protected]>
---
drivers/pci/msi.c | 16 ++--------------
include/linux/msi.h | 2 ++
kernel/irq/msi.c | 17 +++++++++++++++++
3 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 260c1653701d..373d96e06cbd 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -406,18 +406,6 @@ static void free_msi_irqs(struct pci_dev *dev)
}
}

-static struct msi_desc *alloc_msi_entry(struct pci_dev *dev)
-{
- struct msi_desc *desc = kzalloc(sizeof(*desc), GFP_KERNEL);
- if (!desc)
- return NULL;
-
- INIT_LIST_HEAD(&desc->list);
- desc->dev = &dev->dev;
-
- return desc;
-}
-
static void pci_intx_for_msi(struct pci_dev *dev, int enable)
{
if (!(dev->dev_flags & PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG))
@@ -572,7 +560,7 @@ static struct msi_desc *msi_setup_entry(struct pci_dev *dev, int nvec)
struct msi_desc *entry;

/* MSI Entry Initialization */
- entry = alloc_msi_entry(dev);
+ entry = alloc_msi_entry(&dev->dev);
if (!entry)
return NULL;

@@ -700,7 +688,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base,
int i;

for (i = 0; i < nvec; i++) {
- entry = alloc_msi_entry(dev);
+ entry = alloc_msi_entry(&dev->dev);
if (!entry) {
if (!i)
iounmap(base);
diff --git a/include/linux/msi.h b/include/linux/msi.h
index f6845bc83774..c10ec5687efa 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -67,6 +67,8 @@ static inline void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
}
#endif /* CONFIG_PCI_MSI */

+struct msi_desc *alloc_msi_entry(struct device *dev);
+void free_msi_entry(struct msi_desc *entry);
void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void pci_write_msi_msg(unsigned int irq, struct msi_msg *msg);
diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
index 7bf1f1bbb7fa..7e6512b9dc1f 100644
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -18,6 +18,23 @@
/* Temparory solution for building, will be removed later */
#include <linux/pci.h>

+struct msi_desc *alloc_msi_entry(struct device *dev)
+{
+ struct msi_desc *desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+ if (!desc)
+ return NULL;
+
+ INIT_LIST_HEAD(&desc->list);
+ desc->dev = dev;
+
+ return desc;
+}
+
+void free_msi_entry(struct msi_desc *entry)
+{
+ kfree(entry);
+}
+
void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
{
*msg = entry->msg;
--
1.7.10.4

2015-07-09 11:03:24

by Sergei Shtylyov

[permalink] [raw]
Subject: Re: [RFC Patch V1 02/12] MIPS, PCI: Use for_pci_msi_entry() to access MSI device list

Hello.

On 7/9/2015 11:00 AM, Jiang Liu wrote:

> Use accessor for_pci_msi_entry() to access MSI device list, so we could

Maybe for_each_pci_msi_entry()?

> easily move msi_list from struct pci_dev into struct device later.

> Signed-off-by: Jiang Liu <[email protected]>
> ---
> arch/mips/pci/msi-octeon.c | 2 +-
> 1 file changed, 1 insertion(+), 1 deletion(-)

> diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c
> index cffaaf4aae3c..2a5bb849b10e 100644
> --- a/arch/mips/pci/msi-octeon.c
> +++ b/arch/mips/pci/msi-octeon.c
> @@ -200,7 +200,7 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
> if (type == PCI_CAP_ID_MSI && nvec > 1)
> return 1;
>
> - list_for_each_entry(entry, &dev->msi_list, list) {
> + for_each_pci_msi_entry(entry, dev) {
> ret = arch_setup_msi_irq(dev, entry);
> if (ret < 0)
> return ret;

WBR, Sergei

2015-07-09 19:08:53

by Konrad Rzeszutek Wilk

[permalink] [raw]
Subject: Re: [RFC Patch V1 05/12] x86, PCI: Use for_pci_msi_entry() to access MSI device list

On Thu, Jul 09, 2015 at 04:00:40PM +0800, Jiang Liu wrote:
> Use accessor for_pci_msi_entry() to access MSI device list, so we could
> easily move msi_list from struct pci_dev into struct device later.
>
> Signed-off-by: Jiang Liu <[email protected]>

Looks pretty simple. Acked- by: Konrad Rzeszutek Wilk <[email protected]>
> ---
> arch/x86/pci/xen.c | 8 ++++----
> 1 file changed, 4 insertions(+), 4 deletions(-)
>
> diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
> index d22f4b5bbc04..ff31ab464213 100644
> --- a/arch/x86/pci/xen.c
> +++ b/arch/x86/pci/xen.c
> @@ -179,7 +179,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
> if (ret)
> goto error;
> i = 0;
> - list_for_each_entry(msidesc, &dev->msi_list, list) {
> + for_each_pci_msi_entry(msidesc, dev) {
> irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i],
> (type == PCI_CAP_ID_MSI) ? nvec : 1,
> (type == PCI_CAP_ID_MSIX) ?
> @@ -230,7 +230,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
> if (type == PCI_CAP_ID_MSI && nvec > 1)
> return 1;
>
> - list_for_each_entry(msidesc, &dev->msi_list, list) {
> + for_each_pci_msi_entry(msidesc, dev) {
> __pci_read_msi_msg(msidesc, &msg);
> pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
> ((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff);
> @@ -274,7 +274,7 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
> int ret = 0;
> struct msi_desc *msidesc;
>
> - list_for_each_entry(msidesc, &dev->msi_list, list) {
> + for_each_pci_msi_entry(msidesc, dev) {
> struct physdev_map_pirq map_irq;
> domid_t domid;
>
> @@ -386,7 +386,7 @@ static void xen_teardown_msi_irqs(struct pci_dev *dev)
> {
> struct msi_desc *msidesc;
>
> - msidesc = list_entry(dev->msi_list.next, struct msi_desc, list);
> + msidesc = first_pci_msi_entry(dev);
> if (msidesc->msi_attrib.is_msix)
> xen_pci_frontend_disable_msix(dev);
> else
> --
> 1.7.10.4
>

2015-07-09 19:09:40

by Konrad Rzeszutek Wilk

[permalink] [raw]
Subject: Re: [RFC Patch V1 06/12] PCI: Use for_pci_msi_entry() to access MSI device list

On Thu, Jul 09, 2015 at 04:00:41PM +0800, Jiang Liu wrote:
> Use accessor for_pci_msi_entry() to access MSI device list, so we could easily
> move msi_list from struct pci_dev into struct device later.
>
> Signed-off-by: Jiang Liu <[email protected]>
> ---
> drivers/pci/msi.c | 39 ++++++++++++++++++++-------------------
> drivers/pci/xen-pcifront.c | 2 +-

Acked-by on the Xen bits.

> 2 files changed, 21 insertions(+), 20 deletions(-)
>
> diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
> index 7b4c20c9f9ca..d09afa78d7a1 100644
> --- a/drivers/pci/msi.c
> +++ b/drivers/pci/msi.c
> @@ -131,7 +131,7 @@ int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
> if (type == PCI_CAP_ID_MSI && nvec > 1)
> return 1;
>
> - list_for_each_entry(entry, &dev->msi_list, list) {
> + for_each_pci_msi_entry(entry, dev) {
> ret = arch_setup_msi_irq(dev, entry);
> if (ret < 0)
> return ret;
> @@ -151,7 +151,7 @@ void default_teardown_msi_irqs(struct pci_dev *dev)
> int i;
> struct msi_desc *entry;
>
> - list_for_each_entry(entry, &dev->msi_list, list)
> + for_each_pci_msi_entry(entry, dev)
> if (entry->irq)
> for (i = 0; i < entry->nvec_used; i++)
> arch_teardown_msi_irq(entry->irq + i);
> @@ -168,7 +168,7 @@ static void default_restore_msi_irq(struct pci_dev *dev, int irq)
>
> entry = NULL;
> if (dev->msix_enabled) {
> - list_for_each_entry(entry, &dev->msi_list, list) {
> + for_each_pci_msi_entry(entry, dev) {
> if (irq == entry->irq)
> break;
> }
> @@ -282,7 +282,7 @@ void default_restore_msi_irqs(struct pci_dev *dev)
> {
> struct msi_desc *entry;
>
> - list_for_each_entry(entry, &dev->msi_list, list)
> + for_each_pci_msi_entry(entry, dev)
> default_restore_msi_irq(dev, entry->irq);
> }
>
> @@ -363,21 +363,22 @@ EXPORT_SYMBOL_GPL(pci_write_msi_msg);
>
> static void free_msi_irqs(struct pci_dev *dev)
> {
> + struct list_head *msi_list = dev_to_msi_list(&dev->dev);
> struct msi_desc *entry, *tmp;
> struct attribute **msi_attrs;
> struct device_attribute *dev_attr;
> int i, count = 0;
>
> - list_for_each_entry(entry, &dev->msi_list, list)
> + for_each_pci_msi_entry(entry, dev)
> if (entry->irq)
> for (i = 0; i < entry->nvec_used; i++)
> BUG_ON(irq_has_action(entry->irq + i));
>
> pci_msi_teardown_msi_irqs(dev);
>
> - list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
> + list_for_each_entry_safe(entry, tmp, msi_list, list) {
> if (entry->msi_attrib.is_msix) {
> - if (list_is_last(&entry->list, &dev->msi_list))
> + if (list_is_last(&entry->list, msi_list))
> iounmap(entry->mask_base);
> }
>
> @@ -448,7 +449,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
>
> if (!dev->msix_enabled)
> return;
> - BUG_ON(list_empty(&dev->msi_list));
> + BUG_ON(list_empty(dev_to_msi_list(&dev->dev)));
>
> /* route the table */
> pci_intx_for_msi(dev, 0);
> @@ -456,7 +457,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
> PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL);
>
> arch_restore_msi_irqs(dev);
> - list_for_each_entry(entry, &dev->msi_list, list)
> + for_each_pci_msi_entry(entry, dev)
> msix_mask_irq(entry, entry->masked);
>
> pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0);
> @@ -501,7 +502,7 @@ static int populate_msi_sysfs(struct pci_dev *pdev)
> int count = 0;
>
> /* Determine how many msi entries we have */
> - list_for_each_entry(entry, &pdev->msi_list, list)
> + for_each_pci_msi_entry(entry, pdev)
> ++num_msi;
> if (!num_msi)
> return 0;
> @@ -510,7 +511,7 @@ static int populate_msi_sysfs(struct pci_dev *pdev)
> msi_attrs = kzalloc(sizeof(void *) * (num_msi + 1), GFP_KERNEL);
> if (!msi_attrs)
> return -ENOMEM;
> - list_for_each_entry(entry, &pdev->msi_list, list) {
> + for_each_pci_msi_entry(entry, pdev) {
> msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL);
> if (!msi_dev_attr)
> goto error_attrs;
> @@ -599,7 +600,7 @@ static int msi_verify_entries(struct pci_dev *dev)
> {
> struct msi_desc *entry;
>
> - list_for_each_entry(entry, &dev->msi_list, list) {
> + for_each_pci_msi_entry(entry, dev) {
> if (!dev->no_64bit_msi || !entry->msg.address_hi)
> continue;
> dev_err(&dev->dev, "Device has broken 64-bit MSI but arch"
> @@ -636,7 +637,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
> mask = msi_mask(entry->msi_attrib.multi_cap);
> msi_mask_irq(entry, mask, mask);
>
> - list_add_tail(&entry->list, &dev->msi_list);
> + list_add_tail(&entry->list, dev_to_msi_list(&dev->dev));
>
> /* Configure MSI capability structure */
> ret = pci_msi_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI);
> @@ -713,7 +714,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base,
> entry->mask_base = base;
> entry->nvec_used = 1;
>
> - list_add_tail(&entry->list, &dev->msi_list);
> + list_add_tail(&entry->list, dev_to_msi_list(&dev->dev));
> }
>
> return 0;
> @@ -725,7 +726,7 @@ static void msix_program_entries(struct pci_dev *dev,
> struct msi_desc *entry;
> int i = 0;
>
> - list_for_each_entry(entry, &dev->msi_list, list) {
> + for_each_pci_msi_entry(entry, dev) {
> int offset = entries[i].entry * PCI_MSIX_ENTRY_SIZE +
> PCI_MSIX_ENTRY_VECTOR_CTRL;
>
> @@ -806,7 +807,7 @@ out_avail:
> struct msi_desc *entry;
> int avail = 0;
>
> - list_for_each_entry(entry, &dev->msi_list, list) {
> + for_each_pci_msi_entry(entry, dev) {
> if (entry->irq != 0)
> avail++;
> }
> @@ -895,8 +896,8 @@ void pci_msi_shutdown(struct pci_dev *dev)
> if (!pci_msi_enable || !dev || !dev->msi_enabled)
> return;
>
> - BUG_ON(list_empty(&dev->msi_list));
> - desc = list_first_entry(&dev->msi_list, struct msi_desc, list);
> + BUG_ON(list_empty(dev_to_msi_list(&dev->dev)));
> + desc = first_msi_entry(dev);
>
> pci_msi_set_enable(dev, 0);
> pci_intx_for_msi(dev, 1);
> @@ -1001,7 +1002,7 @@ void pci_msix_shutdown(struct pci_dev *dev)
> return;
>
> /* Return the device with MSI-X masked as initial states */
> - list_for_each_entry(entry, &dev->msi_list, list) {
> + for_each_pci_msi_entry(entry, dev) {
> /* Keep cached states to be restored */
> __pci_msix_desc_mask_irq(entry, 1);
> }
> diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
> index 8b7a900cd28b..c777b97207d5 100644
> --- a/drivers/pci/xen-pcifront.c
> +++ b/drivers/pci/xen-pcifront.c
> @@ -265,7 +265,7 @@ static int pci_frontend_enable_msix(struct pci_dev *dev,
> }
>
> i = 0;
> - list_for_each_entry(entry, &dev->msi_list, list) {
> + for_each_pci_msi_entry(entry, dev) {
> op.msix_entries[i].entry = entry->msi_attrib.entry_nr;
> /* Vector is useless at this point. */
> op.msix_entries[i].vector = -1;
> --
> 1.7.10.4
>

2015-07-10 00:21:18

by Paul Gortmaker

[permalink] [raw]
Subject: Re: [RFC Patch V1 09/12] genirq: Move msi_list from struct pci_dev to struct device

[[RFC Patch V1 09/12] genirq: Move msi_list from struct pci_dev to struct device] On 09/07/2015 (Thu 16:00) Jiang Liu wrote:

> Move msi_list from struct pci_dev into struct device, so we could support
> non-PCI-device based generic MSI interrupts.

This is not just a simple move, as the new instances are within a
Kconfig option. I did not get the 0/12 so I don't know if this is
expected, but the commit log here does not seem stand-alone enough
to get through on its own merits; it needs more details.

Paul.
--

>
> Signed-off-by: Jiang Liu <[email protected]>
> ---
> drivers/base/core.c | 3 +++
> drivers/pci/msi.c | 3 +--
> include/linux/device.h | 4 ++++
> include/linux/msi.h | 2 +-
> include/linux/pci.h | 1 -
> 5 files changed, 9 insertions(+), 4 deletions(-)
>
> diff --git a/drivers/base/core.c b/drivers/base/core.c
> index dafae6d2f7ac..18e2a89aa138 100644
> --- a/drivers/base/core.c
> +++ b/drivers/base/core.c
> @@ -662,6 +662,9 @@ void device_initialize(struct device *dev)
> INIT_LIST_HEAD(&dev->devres_head);
> device_pm_init(dev);
> set_dev_node(dev, -1);
> +#ifdef CONFIG_GENERIC_MSI_IRQ
> + INIT_LIST_HEAD(&dev->msi_list);
> +#endif
> }
> EXPORT_SYMBOL_GPL(device_initialize);
>
> diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
> index 6497608545e2..0050ad436718 100644
> --- a/drivers/pci/msi.c
> +++ b/drivers/pci/msi.c
> @@ -900,7 +900,7 @@ void pci_msi_shutdown(struct pci_dev *dev)
> return;
>
> BUG_ON(list_empty(dev_to_msi_list(&dev->dev)));
> - desc = first_msi_entry(dev);
> + desc = first_pci_msi_entry(dev);
>
> pci_msi_set_enable(dev, 0);
> pci_intx_for_msi(dev, 1);
> @@ -1044,7 +1044,6 @@ EXPORT_SYMBOL(pci_msi_enabled);
>
> void pci_msi_init_pci_dev(struct pci_dev *dev)
> {
> - INIT_LIST_HEAD(&dev->msi_list);
> }
>
> /**
> diff --git a/include/linux/device.h b/include/linux/device.h
> index 5a31bf3a4024..22227e7fe463 100644
> --- a/include/linux/device.h
> +++ b/include/linux/device.h
> @@ -713,6 +713,7 @@ struct device_dma_parameters {
> * along with subsystem-level and driver-level callbacks.
> * @pins: For device pin management.
> * See Documentation/pinctrl.txt for details.
> + * @msi_list: Hosts MSI descriptors
> * @numa_node: NUMA node this device is close to.
> * @dma_mask: Dma mask (if dma'ble device).
> * @coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping as not all
> @@ -776,6 +777,9 @@ struct device {
> #ifdef CONFIG_PINCTRL
> struct dev_pin_info *pins;
> #endif
> +#ifdef CONFIG_GENERIC_MSI_IRQ
> + struct list_head msi_list;
> +#endif
>
> #ifdef CONFIG_NUMA
> int numa_node; /* NUMA node this device is close to */
> diff --git a/include/linux/msi.h b/include/linux/msi.h
> index cfbd2afeaf64..57fe766a14bf 100644
> --- a/include/linux/msi.h
> +++ b/include/linux/msi.h
> @@ -45,7 +45,7 @@ struct msi_desc {
>
> /* Helpers to hide struct msi_desc implementation details */
> #define msi_desc_to_dev(desc) (&(desc)->dev.dev)
> -#define dev_to_msi_list(dev) (&to_pci_dev((dev))->msi_list)
> +#define dev_to_msi_list(dev) (&(dev)->msi_list)
> #define first_msi_entry(dev) \
> list_first_entry(dev_to_msi_list((dev)), struct msi_desc, list)
> #define for_each_msi_entry(desc, dev) \
> diff --git a/include/linux/pci.h b/include/linux/pci.h
> index 8a0321a8fb59..fbf245f5eba7 100644
> --- a/include/linux/pci.h
> +++ b/include/linux/pci.h
> @@ -366,7 +366,6 @@ struct pci_dev {
> struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
> struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
> #ifdef CONFIG_PCI_MSI
> - struct list_head msi_list;
> const struct attribute_group **msi_irq_groups;
> #endif
> struct pci_vpd *vpd;
> --
> 1.7.10.4
>

2015-07-10 01:42:07

by Yijing Wang

[permalink] [raw]
Subject: Re: [RFC Patch V1 00/12] Reorganize struct msi_desc to prepare for support of generic MSI

On 2015/7/9 16:00, Jiang Liu wrote:
> Recently Marc Zyngier <[email protected]> has posted a patch set at
> https://lkml.org/lkml/2015/7/7/712
> to enhance PCI MSI code to support generic MSI.
>
> This is a companion patch set to refine struct msi_desc and related data
> structures to support generic MSI, and it would be better to combined with
> Marc's patch set. It's also requested by
> Stuart Yoder <[email protected]>
>
> It first introduces a helper function msi_desc_to_pci_sysdata(), and
> convert current PCI drivers to use helper functions to access fields
> in struct msi_desc.
> Then it moves msi_list from struct pci_dev into struct device and
> refines struct msi_desc.
> At last it moves alloc_msi_entry() into kernel/irq/msi.c for reuse.
>
> Currently msi_desc_to_pci_sysdata() and msi_desc_to_pci_dev() are
> implemented as normal functions instead of inlines to avoid header file
> inclusion issue. If inlined version is preferred for performance, we could
> move all of first_pci_msi_entry, for_each_pci_msi_entry, msi_desc_to_pci_dev
> and msi_desc_to_pci_sysdata from linxu/kernel/msi.h into linux/kernel/pci.h.
>
> This patch set is based on v4.2-rc1 and passes 0day test suite. You
> may access the code at:
> https://github.com/jiangliu/linux.git msi_desc_v1
>
> Thanks!
> Gerry
>
> Jiang Liu (12):
> PCI: Add helper function msi_desc_to_pci_sysdata()
> MIPS, PCI: Use for_pci_msi_entry() to access MSI device list
> PowerPC, PCI: Use for_pci_msi_entry() to access MSI device list
> s390/pci: Use for_pci_msi_entry() to access MSI device list
> x86, PCI: Use for_pci_msi_entry() to access MSI device list
> PCI: Use for_pci_msi_entry() to access MSI device list
> sparc, PCI: Use helper functions to access fields in struct msi_desc
> PCI: Use helper functions to access fields in struct msi_desc
> genirq: Move msi_list from struct pci_dev to struct device
> genirq, PCI: Store 'struct device *' instead 'struct pci_dev *' in
> struct msi_desc
> genirq, PCI: Reorginize struct msi_desc to prepare for support of
> generic MSI
> genirq, PCI: Move alloc_msi_entry() from PCI MSI code into generic
> MSI code

Great, it loos good to me, for patch 1,6,8,9,10,11,12, Reviewed-by: Yijing Wang <[email protected]>

>
> arch/mips/pci/msi-octeon.c | 2 +-
> arch/powerpc/platforms/cell/axon_msi.c | 6 +--
> arch/powerpc/platforms/pasemi/msi.c | 4 +-
> arch/powerpc/platforms/powernv/pci.c | 4 +-
> arch/powerpc/platforms/pseries/msi.c | 6 +--
> arch/powerpc/sysdev/fsl_msi.c | 4 +-
> arch/powerpc/sysdev/mpic_u3msi.c | 4 +-
> arch/powerpc/sysdev/ppc4xx_hsta_msi.c | 4 +-
> arch/powerpc/sysdev/ppc4xx_msi.c | 4 +-
> arch/s390/pci/pci.c | 6 +--
> arch/sparc/kernel/pci.c | 2 +-
> arch/x86/pci/xen.c | 8 ++--
> drivers/base/core.c | 3 ++
> drivers/pci/host/pci-keystone-dw.c | 6 +--
> drivers/pci/host/pcie-designware.c | 4 +-
> drivers/pci/host/pcie-xilinx.c | 12 ++---
> drivers/pci/msi.c | 82 +++++++++++++++++---------------
> drivers/pci/xen-pcifront.c | 2 +-
> include/linux/device.h | 4 ++
> include/linux/msi.h | 55 +++++++++++----------
> include/linux/pci.h | 1 -
> kernel/irq/msi.c | 17 +++++++
> 22 files changed, 136 insertions(+), 104 deletions(-)
>


--
Thanks!
Yijing

2015-07-10 12:42:05

by Marc Zyngier

[permalink] [raw]
Subject: Re: [RFC Patch V1 11/12] genirq, PCI: Reorginize struct msi_desc to prepare for support of generic MSI

Hi Gerry,

On 09/07/15 09:00, Jiang Liu wrote:
> Reorganize struct msi_desc so it could be reused by other MSI drivers.
>
> Signed-off-by: Jiang Liu <[email protected]>
> ---
> include/linux/msi.h | 41 +++++++++++++++++++++--------------------
> 1 file changed, 21 insertions(+), 20 deletions(-)
>
> diff --git a/include/linux/msi.h b/include/linux/msi.h
> index 5f77e231f515..f6845bc83774 100644
> --- a/include/linux/msi.h
> +++ b/include/linux/msi.h
> @@ -19,29 +19,30 @@ void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
> void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg);
>
> struct msi_desc {
> - struct {
> - __u8 is_msix : 1;
> - __u8 multiple: 3; /* log2 num of messages allocated */
> - __u8 multi_cap : 3; /* log2 num of messages supported */
> - __u8 maskbit : 1; /* mask-pending bit supported ? */
> - __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */
> - __u16 entry_nr; /* specific enabled entry */
> - unsigned default_irq; /* default pre-assigned irq */
> - } msi_attrib;
> -
> - u32 masked; /* mask bits */
> - unsigned int irq;
> - unsigned int nvec_used; /* number of messages */
> - struct list_head list;
> + struct list_head list;
> + unsigned int irq;
> + unsigned int nvec_used; /* number of messages */
> + struct device * dev;
> + struct msi_msg msg; /* Last set MSI message */
>
> union {
> - void __iomem *mask_base;
> - u8 mask_pos;
> + struct { /* For PCI MSI/MSI-X */
> + u32 masked; /* mask bits */
> + struct {
> + __u8 is_msix : 1;
> + __u8 multiple: 3; /* log2 num of messages allocated */
> + __u8 multi_cap : 3; /* log2 num of messages supported */
> + __u8 maskbit : 1; /* mask-pending bit supported ? */
> + __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */
> + __u16 entry_nr; /* specific enabled entry */
> + unsigned default_irq; /* default pre-assigned irq */
> + } msi_attrib;
> + union {
> + u8 mask_pos;
> + void __iomem *mask_base;
> + };
> + };

Is this union the location where you would expect some non-PCI MSI
infrastructure to store their own data? If that's the case, maybe a
small comment to that effect would be good, as it is not completely
obvious from looking at the data structure.

> };
> - struct device *dev;
> -
> - /* Last set MSI message */
> - struct msi_msg msg;
> };
>
> /* Helpers to hide struct msi_desc implementation details */
>

Thanks,

M.
--
Jazz is not dead. It just smells funny...

2015-07-10 12:55:01

by Marc Zyngier

[permalink] [raw]
Subject: Re: [RFC Patch V1 00/12] Reorganize struct msi_desc to prepare for support of generic MSI

Hi Gerry,

On 09/07/15 09:00, Jiang Liu wrote:
> Recently Marc Zyngier <[email protected]> has posted a patch set at
> https://lkml.org/lkml/2015/7/7/712
> to enhance PCI MSI code to support generic MSI.
>
> This is a companion patch set to refine struct msi_desc and related data
> structures to support generic MSI, and it would be better to combined with
> Marc's patch set. It's also requested by
> Stuart Yoder <[email protected]>
>
> It first introduces a helper function msi_desc_to_pci_sysdata(), and
> convert current PCI drivers to use helper functions to access fields
> in struct msi_desc.
> Then it moves msi_list from struct pci_dev into struct device and
> refines struct msi_desc.
> At last it moves alloc_msi_entry() into kernel/irq/msi.c for reuse.
>
> Currently msi_desc_to_pci_sysdata() and msi_desc_to_pci_dev() are
> implemented as normal functions instead of inlines to avoid header file
> inclusion issue. If inlined version is preferred for performance, we could
> move all of first_pci_msi_entry, for_each_pci_msi_entry, msi_desc_to_pci_dev
> and msi_desc_to_pci_sysdata from linxu/kernel/msi.h into linux/kernel/pci.h.
>
> This patch set is based on v4.2-rc1 and passes 0day test suite. You
> may access the code at:
> https://github.com/jiangliu/linux.git msi_desc_v1

Thanks a lot for doing this, it looks much helpful. I have a good look
at it, and apart from a small nit I commented on, I'm very happy with
this move.

For the whole set:
Reviewed-by: Marc Zyngier <[email protected]>

Thanks,

M.
--
Jazz is not dead. It just smells funny...

2015-07-12 11:18:45

by Jingoo Han

[permalink] [raw]
Subject: Re: [RFC Patch V1 08/12] PCI: Use helper functions to access fields in struct msi_desc

On Thursday, July 09, 2015 5:01 PM, Jiang Liu wrote:
>
> Use helper functions to access fields in struct msi_desc, so we could
> easily refine msi_desc later.
>
> Signed-off-by: Jiang Liu <[email protected]>

For pcie-designware.c,

Acked-by: Jingoo Han <[email protected]>

Best regards,
Jingoo Han

> ---
> drivers/pci/host/pci-keystone-dw.c | 6 +++---
> drivers/pci/host/pcie-designware.c | 4 ++--
> drivers/pci/host/pcie-xilinx.c | 12 +++++-------
> drivers/pci/msi.c | 13 ++++++++-----
> 4 files changed, 18 insertions(+), 17 deletions(-)
>
> diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
> index f34892e0edb4..e792086c1639 100644
> --- a/drivers/pci/host/pci-keystone-dw.c
> +++ b/drivers/pci/host/pci-keystone-dw.c
> @@ -109,7 +109,7 @@ static void ks_dw_pcie_msi_irq_ack(struct irq_data *d)
> struct pcie_port *pp;
>
> msi = irq_get_msi_desc(irq);
> - pp = sys_to_pcie(msi->dev->bus->sysdata);
> + pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));
> ks_pcie = to_keystone_pcie(pp);
> offset = irq - irq_linear_revmap(pp->irq_domain, 0);
> update_reg_offset_bit_pos(offset, &reg_offset, &bit_pos);
> @@ -148,7 +148,7 @@ static void ks_dw_pcie_msi_irq_mask(struct irq_data *d)
> u32 offset;
>
> msi = irq_get_msi_desc(irq);
> - pp = sys_to_pcie(msi->dev->bus->sysdata);
> + pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));
> ks_pcie = to_keystone_pcie(pp);
> offset = irq - irq_linear_revmap(pp->irq_domain, 0);
>
> @@ -170,7 +170,7 @@ static void ks_dw_pcie_msi_irq_unmask(struct irq_data *d)
> u32 offset;
>
> msi = irq_get_msi_desc(irq);
> - pp = sys_to_pcie(msi->dev->bus->sysdata);
> + pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));
> ks_pcie = to_keystone_pcie(pp);
> offset = irq - irq_linear_revmap(pp->irq_domain, 0);
>
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index 69486be7181e..65596f96763c 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -255,7 +255,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
> static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
> {
> int irq, pos0, i;
> - struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
> + struct pcie_port *pp = sys_to_pcie(msi_desc_to_pci_sysdata(desc));
>
> pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
> order_base_2(no_irqs));
> @@ -327,7 +327,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
> {
> struct irq_data *data = irq_get_irq_data(irq);
> struct msi_desc *msi = irq_data_get_msi(data);
> - struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
> + struct pcie_port *pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));
>
> clear_irq_range(pp, irq, 1, data->hwirq);
> }
> diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c
> index f1a06a091ccb..64454f416639 100644
> --- a/drivers/pci/host/pcie-xilinx.c
> +++ b/drivers/pci/host/pcie-xilinx.c
> @@ -227,18 +227,16 @@ static struct pci_ops xilinx_pcie_ops = {
> */
> static void xilinx_pcie_destroy_msi(unsigned int irq)
> {
> - struct irq_desc *desc;
> struct msi_desc *msi;
> struct xilinx_pcie_port *port;
>
> - desc = irq_to_desc(irq);
> - msi = irq_desc_get_msi_desc(desc);
> - port = sys_to_pcie(msi->dev->bus->sysdata);
> -
> - if (!test_bit(irq, msi_irq_in_use))
> + if (!test_bit(irq, msi_irq_in_use)) {
> + msi = irq_get_msi_desc(irq);
> + port = sys_to_pcie(msi_desc_to_pci_sys_data(msi));
> dev_err(port->dev, "Trying to free unused MSI#%d\n", irq);
> - else
> + } else {
> clear_bit(irq, msi_irq_in_use);
> + }
> }
>
> /**
> diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
> index d09afa78d7a1..6497608545e2 100644
> --- a/drivers/pci/msi.c
> +++ b/drivers/pci/msi.c
> @@ -208,7 +208,8 @@ u32 __pci_msi_desc_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)
>
> mask_bits &= ~mask;
> mask_bits |= flag;
> - pci_write_config_dword(desc->dev, desc->mask_pos, mask_bits);
> + pci_write_config_dword(msi_desc_to_pci_dev(desc), desc->mask_pos,
> + mask_bits);
>
> return mask_bits;
> }
> @@ -288,7 +289,9 @@ void default_restore_msi_irqs(struct pci_dev *dev)
>
> void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
> {
> - BUG_ON(entry->dev->current_state != PCI_D0);
> + struct pci_dev *dev = msi_desc_to_pci_dev(entry);
> +
> + BUG_ON(dev->current_state != PCI_D0);
>
> if (entry->msi_attrib.is_msix) {
> void __iomem *base = entry->mask_base +
> @@ -298,7 +301,6 @@ void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
> msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR);
> msg->data = readl(base + PCI_MSIX_ENTRY_DATA);
> } else {
> - struct pci_dev *dev = entry->dev;
> int pos = dev->msi_cap;
> u16 data;
>
> @@ -318,7 +320,9 @@ void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
>
> void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
> {
> - if (entry->dev->current_state != PCI_D0) {
> + struct pci_dev *dev = msi_desc_to_pci_dev(entry);
> +
> + if (dev->current_state != PCI_D0) {
> /* Don't touch the hardware now */
> } else if (entry->msi_attrib.is_msix) {
> void __iomem *base;
> @@ -329,7 +333,6 @@ void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
> writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR);
> writel(msg->data, base + PCI_MSIX_ENTRY_DATA);
> } else {
> - struct pci_dev *dev = entry->dev;
> int pos = dev->msi_cap;
> u16 msgctl;
>
> --
> 1.7.10.4

2015-07-13 12:47:32

by Sebastian Ott

[permalink] [raw]
Subject: Re: [RFC Patch V1 04/12] s390/pci: Use for_pci_msi_entry() to access MSI device list

On Thu, 9 Jul 2015, Jiang Liu wrote:

> Use accessor for_pci_msi_entry() to access MSI device list, so we could
> easily move msi_list from struct pci_dev into struct device later.
>
> Signed-off-by: Jiang Liu <[email protected]>

Acked-by: Sebastian Ott <[email protected]>

Regards,
Sebastian

> ---
> arch/s390/pci/pci.c | 6 +++---
> 1 file changed, 3 insertions(+), 3 deletions(-)
>
> diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
> index 598f023cf8a6..34f162753403 100644
> --- a/arch/s390/pci/pci.c
> +++ b/arch/s390/pci/pci.c
> @@ -414,7 +414,7 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
>
> /* Request MSI interrupts */
> hwirq = 0;
> - list_for_each_entry(msi, &pdev->msi_list, list) {
> + for_each_pci_msi_entry(msi, pdev) {
> rc = -EIO;
> irq = irq_alloc_desc(0); /* Alloc irq on node 0 */
> if (irq < 0)
> @@ -440,7 +440,7 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
> return (msi_vecs == nvec) ? 0 : msi_vecs;
>
> out_msi:
> - list_for_each_entry(msi, &pdev->msi_list, list) {
> + for_each_pci_msi_entry(msi, pdev) {
> if (hwirq-- == 0)
> break;
> irq_set_msi_desc(msi->irq, NULL);
> @@ -470,7 +470,7 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
> return;
>
> /* Release MSI interrupts */
> - list_for_each_entry(msi, &pdev->msi_list, list) {
> + for_each_pci_msi_entry(msi, pdev) {
> if (msi->msi_attrib.is_msix)
> __pci_msix_desc_mask_irq(msi, 1);
> else
> --
> 1.7.10.4
>
>

2015-07-21 08:32:05

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [RFC Patch V1 00/12] Reorganize struct msi_desc to prepare for support of generic MSI

On Thu, 9 Jul 2015, Jiang Liu wrote:
> Recently Marc Zyngier <[email protected]> has posted a patch set at
> https://lkml.org/lkml/2015/7/7/712
> to enhance PCI MSI code to support generic MSI.
>
> This is a companion patch set to refine struct msi_desc and related data
> structures to support generic MSI, and it would be better to combined with
> Marc's patch set. It's also requested by
> Stuart Yoder <[email protected]>
>
> It first introduces a helper function msi_desc_to_pci_sysdata(), and
> convert current PCI drivers to use helper functions to access fields
> in struct msi_desc.
> Then it moves msi_list from struct pci_dev into struct device and
> refines struct msi_desc.
> At last it moves alloc_msi_entry() into kernel/irq/msi.c for reuse.
>
> Currently msi_desc_to_pci_sysdata() and msi_desc_to_pci_dev() are
> implemented as normal functions instead of inlines to avoid header file
> inclusion issue. If inlined version is preferred for performance, we could
> move all of first_pci_msi_entry, for_each_pci_msi_entry, msi_desc_to_pci_dev
> and msi_desc_to_pci_sysdata from linxu/kernel/msi.h into linux/kernel/pci.h.
>
> This patch set is based on v4.2-rc1 and passes 0day test suite. You
> may access the code at:
> https://github.com/jiangliu/linux.git msi_desc_v1

Bjorn,

this patch series is a prerequisite for proper support of non-pci
based MSI. If there are no objections from your side, I'd like to move
it through the irq tree so we can build the non-pci MSI stuff on top.

Thanks,

tglx

2015-07-21 13:30:44

by Bjorn Helgaas

[permalink] [raw]
Subject: Re: [RFC Patch V1 00/12] Reorganize struct msi_desc to prepare for support of generic MSI

[+cc Paul]

On Thu, Jul 09, 2015 at 04:00:35PM +0800, Jiang Liu wrote:
> Recently Marc Zyngier <[email protected]> has posted a patch set at
> https://lkml.org/lkml/2015/7/7/712
> to enhance PCI MSI code to support generic MSI.
>
> This is a companion patch set to refine struct msi_desc and related data
> structures to support generic MSI, and it would be better to combined with
> Marc's patch set. It's also requested by
> Stuart Yoder <[email protected]>
>
> It first introduces a helper function msi_desc_to_pci_sysdata(), and
> convert current PCI drivers to use helper functions to access fields
> in struct msi_desc.
> Then it moves msi_list from struct pci_dev into struct device and
> refines struct msi_desc.
> At last it moves alloc_msi_entry() into kernel/irq/msi.c for reuse.
>
> Currently msi_desc_to_pci_sysdata() and msi_desc_to_pci_dev() are
> implemented as normal functions instead of inlines to avoid header file
> inclusion issue. If inlined version is preferred for performance, we could
> move all of first_pci_msi_entry, for_each_pci_msi_entry, msi_desc_to_pci_dev
> and msi_desc_to_pci_sysdata from linxu/kernel/msi.h into linux/kernel/pci.h.
>
> This patch set is based on v4.2-rc1 and passes 0day test suite. You
> may access the code at:
> https://github.com/jiangliu/linux.git msi_desc_v1
>
> Thanks!
> Gerry
>
> Jiang Liu (12):
> PCI: Add helper function msi_desc_to_pci_sysdata()
> MIPS, PCI: Use for_pci_msi_entry() to access MSI device list
> PowerPC, PCI: Use for_pci_msi_entry() to access MSI device list
> s390/pci: Use for_pci_msi_entry() to access MSI device list
> x86, PCI: Use for_pci_msi_entry() to access MSI device list
> PCI: Use for_pci_msi_entry() to access MSI device list
> sparc, PCI: Use helper functions to access fields in struct msi_desc
> PCI: Use helper functions to access fields in struct msi_desc
> genirq: Move msi_list from struct pci_dev to struct device
> genirq, PCI: Store 'struct device *' instead 'struct pci_dev *' in
> struct msi_desc
> genirq, PCI: Reorginize struct msi_desc to prepare for support of
> generic MSI
> genirq, PCI: Move alloc_msi_entry() from PCI MSI code into generic
> MSI code

Sergei pointed out typos in the "Use for_pci_msi_entry()" subject and
changelogs; I assume you'll fix those.

Paul had a question on 09/12 regarding Kconfig, and I didn't see a
resolution to that.

For the PCI parts:

Acked-by: Bjorn Helgaas <[email protected]>

Thomas, I assume you'll take this via your tree.

Bjorn

2015-07-21 15:51:48

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [RFC Patch V1 00/12] Reorganize struct msi_desc to prepare for support of generic MSI

On Tue, 21 Jul 2015, Bjorn Helgaas wrote:
> Sergei pointed out typos in the "Use for_pci_msi_entry()" subject and
> changelogs; I assume you'll fix those.

Yes.

> Paul had a question on 09/12 regarding Kconfig, and I didn't see a
> resolution to that.

I'll reply to that right now.

> For the PCI parts:
>
> Acked-by: Bjorn Helgaas <[email protected]>
>
> Thomas, I assume you'll take this via your tree.

That's the plan

Thanks,

tglx

2015-07-21 22:03:30

by Thomas Gleixner

[permalink] [raw]
Subject: Re: [RFC Patch V1 09/12] genirq: Move msi_list from struct pci_dev to struct device

On Thu, 9 Jul 2015, Paul Gortmaker wrote:

> [[RFC Patch V1 09/12] genirq: Move msi_list from struct pci_dev to struct device] On 09/07/2015 (Thu 16:00) Jiang Liu wrote:
>
> > Move msi_list from struct pci_dev into struct device, so we could support
> > non-PCI-device based generic MSI interrupts.
>
> This is not just a simple move, as the new instances are within a
> Kconfig option. I did not get the 0/12 so I don't know if this is
> expected, but the commit log here does not seem stand-alone enough
> to get through on its own merits; it needs more details.

config PCI_MSI
select GENERIC_MSI_IRQ

So it's not changing anything, but I agree it might be mentioned in
the changelog.

Thanks,

tglx

Subject: [tip:irq/core] PCI: Add helper function msi_desc_to_pci_sysdata()

Commit-ID: c179c9b978b90bdf9cb39f5b5716dede157f1eaf
Gitweb: http://git.kernel.org/tip/c179c9b978b90bdf9cb39f5b5716dede157f1eaf
Author: Jiang Liu <[email protected]>
AuthorDate: Thu, 9 Jul 2015 16:00:36 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Wed, 22 Jul 2015 18:37:42 +0200

PCI: Add helper function msi_desc_to_pci_sysdata()

Add helper function msi_desc_to_pci_sysdata() to retrieve sysdata from
an MSI descriptor. To avoid pulling include/linux/pci.h into
include/linux/msi.h, msi_desc_to_pci_sysdata() is implemented as a normal
function instead of an inline function.

Signed-off-by: Jiang Liu <[email protected]>
Reviewed-by: Yijing Wang <[email protected]>
Acked-by: Bjorn Helgaas <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: [email protected]
Cc: Grant Likely <[email protected]>
Cc: Marc Zyngier <[email protected]>
Cc: Stuart Yoder <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Alexander Gordeev <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
drivers/pci/msi.c | 8 ++++++++
include/linux/msi.h | 7 +++++++
2 files changed, 15 insertions(+)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 157eb88..ab41742 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -1137,6 +1137,14 @@ int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
}
EXPORT_SYMBOL(pci_enable_msix_range);

+void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
+{
+ struct pci_dev *dev = msi_desc_to_pci_dev(desc);
+
+ return dev->bus->sysdata;
+}
+EXPORT_SYMBOL_GPL(msi_desc_to_pci_sysdata);
+
#ifdef CONFIG_PCI_MSI_IRQ_DOMAIN
/**
* pci_msi_domain_write_msg - Helper to write MSI message to PCI config space
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 8ac4a68..cfbd2af 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -60,6 +60,13 @@ static inline struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
{
return desc->dev;
}
+
+void *msi_desc_to_pci_sysdata(struct msi_desc *desc);
+#else /* CONFIG_PCI_MSI */
+static inline void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
+{
+ return NULL;
+}
#endif /* CONFIG_PCI_MSI */

void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg);

Subject: [tip:irq/core] MIPS/PCI: Use for_pci_msi_entry() to access MSI device list

Commit-ID: bbcffac3a8b60f2f01a3fcb322167f6b8aba3416
Gitweb: http://git.kernel.org/tip/bbcffac3a8b60f2f01a3fcb322167f6b8aba3416
Author: Jiang Liu <[email protected]>
AuthorDate: Thu, 9 Jul 2015 16:00:37 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Wed, 22 Jul 2015 18:37:42 +0200

MIPS/PCI: Use for_pci_msi_entry() to access MSI device list

Use accessor for_each_pci_msi_entry() to access MSI device list, so we
could easily move msi_list from struct pci_dev into struct device
later.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: Bjorn Helgaas <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Marc Zyngier <[email protected]>
Cc: Stuart Yoder <[email protected]>
Cc: Yijing Wang <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Ralf Baechle <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
arch/mips/pci/msi-octeon.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/mips/pci/msi-octeon.c b/arch/mips/pci/msi-octeon.c
index cffaaf4..2a5bb84 100644
--- a/arch/mips/pci/msi-octeon.c
+++ b/arch/mips/pci/msi-octeon.c
@@ -200,7 +200,7 @@ int arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
if (type == PCI_CAP_ID_MSI && nvec > 1)
return 1;

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
ret = arch_setup_msi_irq(dev, entry);
if (ret < 0)
return ret;

Subject: [tip:irq/core] powerpc/PCI: Use for_pci_msi_entry() to access MSI device list

Commit-ID: 2921d1790eeeaf574df94fc5b1aa066e7d86d8f7
Gitweb: http://git.kernel.org/tip/2921d1790eeeaf574df94fc5b1aa066e7d86d8f7
Author: Jiang Liu <[email protected]>
AuthorDate: Thu, 9 Jul 2015 16:00:38 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Wed, 22 Jul 2015 18:37:42 +0200

powerpc/PCI: Use for_pci_msi_entry() to access MSI device list

Use accessor for_each_pci_msi_entry() to access MSI device list, so we
could easily move msi_list from struct pci_dev into struct device
later.

Signed-off-by: Jiang Liu <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: Bjorn Helgaas <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Marc Zyngier <[email protected]>
Cc: Stuart Yoder <[email protected]>
Cc: Yijing Wang <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Arnd Bergmann <[email protected]>
Cc: Benjamin Herrenschmidt <[email protected]>
Cc: Paul Mackerras <[email protected]>
Cc: Michael Ellerman <[email protected]>
Cc: Olof Johansson <[email protected]>
Cc: Gavin Shan <[email protected]>
Cc: Alexey Kardashevskiy <[email protected]>
Cc: David Gibson <[email protected]>
Cc: Daniel Axtens <[email protected]>
Cc: Wei Yang <[email protected]>
Cc: Nishanth Aravamudan <[email protected]>
Cc: Alexander Gordeev <[email protected]>
Cc: Scott Wood <[email protected]>
Cc: Laurentiu Tudor <[email protected]>
Cc: Tudor Laurentiu <[email protected]>
Cc: Hongtao Jia <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
arch/powerpc/platforms/cell/axon_msi.c | 6 +++---
arch/powerpc/platforms/pasemi/msi.c | 4 ++--
arch/powerpc/platforms/powernv/pci.c | 4 ++--
arch/powerpc/platforms/pseries/msi.c | 6 +++---
arch/powerpc/sysdev/fsl_msi.c | 4 ++--
arch/powerpc/sysdev/mpic_u3msi.c | 4 ++--
arch/powerpc/sysdev/ppc4xx_hsta_msi.c | 4 ++--
arch/powerpc/sysdev/ppc4xx_msi.c | 4 ++--
8 files changed, 18 insertions(+), 18 deletions(-)

diff --git a/arch/powerpc/platforms/cell/axon_msi.c b/arch/powerpc/platforms/cell/axon_msi.c
index fe51de4..306888a 100644
--- a/arch/powerpc/platforms/cell/axon_msi.c
+++ b/arch/powerpc/platforms/cell/axon_msi.c
@@ -213,7 +213,7 @@ static int setup_msi_msg_address(struct pci_dev *dev, struct msi_msg *msg)
return -ENODEV;
}

- entry = list_first_entry(&dev->msi_list, struct msi_desc, list);
+ entry = first_pci_msi_entry(dev);

for (; dn; dn = of_get_next_parent(dn)) {
if (entry->msi_attrib.is_64) {
@@ -269,7 +269,7 @@ static int axon_msi_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
if (rc)
return rc;

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
virq = irq_create_direct_mapping(msic->irq_domain);
if (virq == NO_IRQ) {
dev_warn(&dev->dev,
@@ -292,7 +292,7 @@ static void axon_msi_teardown_msi_irqs(struct pci_dev *dev)

dev_dbg(&dev->dev, "axon_msi: tearing down msi irqs\n");

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
if (entry->irq == NO_IRQ)
continue;

diff --git a/arch/powerpc/platforms/pasemi/msi.c b/arch/powerpc/platforms/pasemi/msi.c
index 27f2b18..e66ef19 100644
--- a/arch/powerpc/platforms/pasemi/msi.c
+++ b/arch/powerpc/platforms/pasemi/msi.c
@@ -66,7 +66,7 @@ static void pasemi_msi_teardown_msi_irqs(struct pci_dev *pdev)

pr_debug("pasemi_msi_teardown_msi_irqs, pdev %p\n", pdev);

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
if (entry->irq == NO_IRQ)
continue;

@@ -94,7 +94,7 @@ static int pasemi_msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
msg.address_hi = 0;
msg.address_lo = PASEMI_MSI_ADDR;

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
/* Allocate 16 interrupts for now, since that's the grouping for
* affinity. This can be changed later if it turns out 32 is too
* few MSIs for someone, but restrictions will apply to how the
diff --git a/arch/powerpc/platforms/powernv/pci.c b/arch/powerpc/platforms/powernv/pci.c
index 765d8ed..bc6d4e0 100644
--- a/arch/powerpc/platforms/powernv/pci.c
+++ b/arch/powerpc/platforms/powernv/pci.c
@@ -61,7 +61,7 @@ int pnv_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
if (pdev->no_64bit_msi && !phb->msi32_support)
return -ENODEV;

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
if (!entry->msi_attrib.is_64 && !phb->msi32_support) {
pr_warn("%s: Supports only 64-bit MSIs\n",
pci_name(pdev));
@@ -103,7 +103,7 @@ void pnv_teardown_msi_irqs(struct pci_dev *pdev)
if (WARN_ON(!phb))
return;

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
if (entry->irq == NO_IRQ)
continue;
irq_set_msi_desc(entry->irq, NULL);
diff --git a/arch/powerpc/platforms/pseries/msi.c b/arch/powerpc/platforms/pseries/msi.c
index c22bb64..272e9ec 100644
--- a/arch/powerpc/platforms/pseries/msi.c
+++ b/arch/powerpc/platforms/pseries/msi.c
@@ -118,7 +118,7 @@ static void rtas_teardown_msi_irqs(struct pci_dev *pdev)
{
struct msi_desc *entry;

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
if (entry->irq == NO_IRQ)
continue;

@@ -350,7 +350,7 @@ static int check_msix_entries(struct pci_dev *pdev)
* So we must reject such requests. */

expected = 0;
- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
if (entry->msi_attrib.entry_nr != expected) {
pr_debug("rtas_msi: bad MSI-X entries.\n");
return -EINVAL;
@@ -462,7 +462,7 @@ again:
}

i = 0;
- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
hwirq = rtas_query_irq_number(pdn, i++);
if (hwirq < 0) {
pr_debug("rtas_msi: error (%d) getting hwirq\n", rc);
diff --git a/arch/powerpc/sysdev/fsl_msi.c b/arch/powerpc/sysdev/fsl_msi.c
index 5236e54..5916da1 100644
--- a/arch/powerpc/sysdev/fsl_msi.c
+++ b/arch/powerpc/sysdev/fsl_msi.c
@@ -129,7 +129,7 @@ static void fsl_teardown_msi_irqs(struct pci_dev *pdev)
struct msi_desc *entry;
struct fsl_msi *msi_data;

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
if (entry->irq == NO_IRQ)
continue;
msi_data = irq_get_chip_data(entry->irq);
@@ -219,7 +219,7 @@ static int fsl_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
}
}

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
/*
* Loop over all the MSI devices until we find one that has an
* available interrupt.
diff --git a/arch/powerpc/sysdev/mpic_u3msi.c b/arch/powerpc/sysdev/mpic_u3msi.c
index fc46ef3..70fbd56 100644
--- a/arch/powerpc/sysdev/mpic_u3msi.c
+++ b/arch/powerpc/sysdev/mpic_u3msi.c
@@ -108,7 +108,7 @@ static void u3msi_teardown_msi_irqs(struct pci_dev *pdev)
{
struct msi_desc *entry;

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
if (entry->irq == NO_IRQ)
continue;

@@ -140,7 +140,7 @@ static int u3msi_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
return -ENXIO;
}

- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
hwirq = msi_bitmap_alloc_hwirqs(&msi_mpic->msi_bitmap, 1);
if (hwirq < 0) {
pr_debug("u3msi: failed allocating hwirq\n");
diff --git a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
index 2bc3367..0d88ba2 100644
--- a/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
+++ b/arch/powerpc/sysdev/ppc4xx_hsta_msi.c
@@ -50,7 +50,7 @@ static int hsta_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
return -EINVAL;
}

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
irq = msi_bitmap_alloc_hwirqs(&ppc4xx_hsta_msi.bmp, 1);
if (irq < 0) {
pr_debug("%s: Failed to allocate msi interrupt\n",
@@ -108,7 +108,7 @@ static void hsta_teardown_msi_irqs(struct pci_dev *dev)
struct msi_desc *entry;
int irq;

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
if (entry->irq == NO_IRQ)
continue;

diff --git a/arch/powerpc/sysdev/ppc4xx_msi.c b/arch/powerpc/sysdev/ppc4xx_msi.c
index 6eb21f2..24d0470 100644
--- a/arch/powerpc/sysdev/ppc4xx_msi.c
+++ b/arch/powerpc/sysdev/ppc4xx_msi.c
@@ -93,7 +93,7 @@ static int ppc4xx_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
if (!msi_data->msi_virqs)
return -ENOMEM;

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
int_no = msi_bitmap_alloc_hwirqs(&msi_data->bitmap, 1);
if (int_no >= 0)
break;
@@ -127,7 +127,7 @@ void ppc4xx_teardown_msi_irqs(struct pci_dev *dev)

dev_dbg(&dev->dev, "PCIE-MSI: tearing down msi irqs\n");

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
if (entry->irq == NO_IRQ)
continue;
irq_set_msi_desc(entry->irq, NULL);

Subject: [tip:irq/core] s390/pci: Use for_pci_msi_entry() to access MSI device list

Commit-ID: df516f4278c154f5bb5e594fd54c2b0cb0af7a7c
Gitweb: http://git.kernel.org/tip/df516f4278c154f5bb5e594fd54c2b0cb0af7a7c
Author: Jiang Liu <[email protected]>
AuthorDate: Thu, 9 Jul 2015 16:00:39 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Wed, 22 Jul 2015 18:37:42 +0200

s390/pci: Use for_pci_msi_entry() to access MSI device list

Use accessor for_each_pci_msi_entry() to access MSI device list, so we could
easily move msi_list from struct pci_dev into struct device later.

Signed-off-by: Jiang Liu <[email protected]>
Acked-by: Sebastian Ott <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: [email protected]
Cc: Bjorn Helgaas <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Marc Zyngier <[email protected]>
Cc: Stuart Yoder <[email protected]>
Cc: Yijing Wang <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Gerald Schaefer <[email protected]>
Cc: Martin Schwidefsky <[email protected]>
Cc: Heiko Carstens <[email protected]>
Cc: [email protected]
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
arch/s390/pci/pci.c | 6 +++---
1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/arch/s390/pci/pci.c b/arch/s390/pci/pci.c
index 598f023..34f1627 100644
--- a/arch/s390/pci/pci.c
+++ b/arch/s390/pci/pci.c
@@ -414,7 +414,7 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)

/* Request MSI interrupts */
hwirq = 0;
- list_for_each_entry(msi, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(msi, pdev) {
rc = -EIO;
irq = irq_alloc_desc(0); /* Alloc irq on node 0 */
if (irq < 0)
@@ -440,7 +440,7 @@ int arch_setup_msi_irqs(struct pci_dev *pdev, int nvec, int type)
return (msi_vecs == nvec) ? 0 : msi_vecs;

out_msi:
- list_for_each_entry(msi, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(msi, pdev) {
if (hwirq-- == 0)
break;
irq_set_msi_desc(msi->irq, NULL);
@@ -470,7 +470,7 @@ void arch_teardown_msi_irqs(struct pci_dev *pdev)
return;

/* Release MSI interrupts */
- list_for_each_entry(msi, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(msi, pdev) {
if (msi->msi_attrib.is_msix)
__pci_msix_desc_mask_irq(msi, 1);
else

Subject: [tip:irq/core] x86/PCI: Use for_pci_msi_entry() to access MSI device list

Commit-ID: 39118e31e1daae43048f5deaa3e0894d2732a7d6
Gitweb: http://git.kernel.org/tip/39118e31e1daae43048f5deaa3e0894d2732a7d6
Author: Jiang Liu <[email protected]>
AuthorDate: Thu, 9 Jul 2015 16:00:40 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Wed, 22 Jul 2015 18:37:43 +0200

x86/PCI: Use for_pci_msi_entry() to access MSI device list

Use accessor for_each_pci_msi_entry() to access MSI device list, so we
could easily move msi_list from struct pci_dev into struct device
later.

Signed-off-by: Jiang Liu <[email protected]>
Acked-by: Konrad Rzeszutek Wilk <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: Bjorn Helgaas <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Marc Zyngier <[email protected]>
Cc: Stuart Yoder <[email protected]>
Cc: Yijing Wang <[email protected]>
Cc: Borislav Petkov <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
arch/x86/pci/xen.c | 8 ++++----
1 file changed, 4 insertions(+), 4 deletions(-)

diff --git a/arch/x86/pci/xen.c b/arch/x86/pci/xen.c
index d22f4b5..ff31ab4 100644
--- a/arch/x86/pci/xen.c
+++ b/arch/x86/pci/xen.c
@@ -179,7 +179,7 @@ static int xen_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
if (ret)
goto error;
i = 0;
- list_for_each_entry(msidesc, &dev->msi_list, list) {
+ for_each_pci_msi_entry(msidesc, dev) {
irq = xen_bind_pirq_msi_to_irq(dev, msidesc, v[i],
(type == PCI_CAP_ID_MSI) ? nvec : 1,
(type == PCI_CAP_ID_MSIX) ?
@@ -230,7 +230,7 @@ static int xen_hvm_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
if (type == PCI_CAP_ID_MSI && nvec > 1)
return 1;

- list_for_each_entry(msidesc, &dev->msi_list, list) {
+ for_each_pci_msi_entry(msidesc, dev) {
__pci_read_msi_msg(msidesc, &msg);
pirq = MSI_ADDR_EXT_DEST_ID(msg.address_hi) |
((msg.address_lo >> MSI_ADDR_DEST_ID_SHIFT) & 0xff);
@@ -274,7 +274,7 @@ static int xen_initdom_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
int ret = 0;
struct msi_desc *msidesc;

- list_for_each_entry(msidesc, &dev->msi_list, list) {
+ for_each_pci_msi_entry(msidesc, dev) {
struct physdev_map_pirq map_irq;
domid_t domid;

@@ -386,7 +386,7 @@ static void xen_teardown_msi_irqs(struct pci_dev *dev)
{
struct msi_desc *msidesc;

- msidesc = list_entry(dev->msi_list.next, struct msi_desc, list);
+ msidesc = first_pci_msi_entry(dev);
if (msidesc->msi_attrib.is_msix)
xen_pci_frontend_disable_msix(dev);
else

Subject: [tip:irq/core] PCI: Use for_each_pci_msi_entry() to access MSI device list

Commit-ID: 5004e98a91e8ad600f5b00872e9ddad810258f08
Gitweb: http://git.kernel.org/tip/5004e98a91e8ad600f5b00872e9ddad810258f08
Author: Jiang Liu <[email protected]>
AuthorDate: Thu, 9 Jul 2015 16:00:41 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Wed, 22 Jul 2015 18:37:43 +0200

PCI: Use for_each_pci_msi_entry() to access MSI device list

Use accessor for_each_pci_msi_entry() to access MSI device list, so we
could easily move msi_list from struct pci_dev into struct device
later.

Signed-off-by: Jiang Liu <[email protected]>
Reviewed-by: Yijing Wang <[email protected]>
Acked-by: Bjorn Helgaas <[email protected]>
Acked-by: Konrad Rzeszutek Wilk <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: [email protected]
Cc: [email protected]
Cc: Grant Likely <[email protected]>
Cc: Marc Zyngier <[email protected]>
Cc: Stuart Yoder <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Boris Ostrovsky <[email protected]>
Cc: David Vrabel <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
drivers/pci/msi.c | 39 ++++++++++++++++++++-------------------
drivers/pci/xen-pcifront.c | 2 +-
2 files changed, 21 insertions(+), 20 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index ab41742..540613e 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -131,7 +131,7 @@ int __weak arch_setup_msi_irqs(struct pci_dev *dev, int nvec, int type)
if (type == PCI_CAP_ID_MSI && nvec > 1)
return 1;

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
ret = arch_setup_msi_irq(dev, entry);
if (ret < 0)
return ret;
@@ -151,7 +151,7 @@ void default_teardown_msi_irqs(struct pci_dev *dev)
int i;
struct msi_desc *entry;

- list_for_each_entry(entry, &dev->msi_list, list)
+ for_each_pci_msi_entry(entry, dev)
if (entry->irq)
for (i = 0; i < entry->nvec_used; i++)
arch_teardown_msi_irq(entry->irq + i);
@@ -168,7 +168,7 @@ static void default_restore_msi_irq(struct pci_dev *dev, int irq)

entry = NULL;
if (dev->msix_enabled) {
- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
if (irq == entry->irq)
break;
}
@@ -282,7 +282,7 @@ void default_restore_msi_irqs(struct pci_dev *dev)
{
struct msi_desc *entry;

- list_for_each_entry(entry, &dev->msi_list, list)
+ for_each_pci_msi_entry(entry, dev)
default_restore_msi_irq(dev, entry->irq);
}

@@ -363,21 +363,22 @@ EXPORT_SYMBOL_GPL(pci_write_msi_msg);

static void free_msi_irqs(struct pci_dev *dev)
{
+ struct list_head *msi_list = dev_to_msi_list(&dev->dev);
struct msi_desc *entry, *tmp;
struct attribute **msi_attrs;
struct device_attribute *dev_attr;
int i, count = 0;

- list_for_each_entry(entry, &dev->msi_list, list)
+ for_each_pci_msi_entry(entry, dev)
if (entry->irq)
for (i = 0; i < entry->nvec_used; i++)
BUG_ON(irq_has_action(entry->irq + i));

pci_msi_teardown_msi_irqs(dev);

- list_for_each_entry_safe(entry, tmp, &dev->msi_list, list) {
+ list_for_each_entry_safe(entry, tmp, msi_list, list) {
if (entry->msi_attrib.is_msix) {
- if (list_is_last(&entry->list, &dev->msi_list))
+ if (list_is_last(&entry->list, msi_list))
iounmap(entry->mask_base);
}

@@ -448,7 +449,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev)

if (!dev->msix_enabled)
return;
- BUG_ON(list_empty(&dev->msi_list));
+ BUG_ON(list_empty(dev_to_msi_list(&dev->dev)));

/* route the table */
pci_intx_for_msi(dev, 0);
@@ -456,7 +457,7 @@ static void __pci_restore_msix_state(struct pci_dev *dev)
PCI_MSIX_FLAGS_ENABLE | PCI_MSIX_FLAGS_MASKALL);

arch_restore_msi_irqs(dev);
- list_for_each_entry(entry, &dev->msi_list, list)
+ for_each_pci_msi_entry(entry, dev)
msix_mask_irq(entry, entry->masked);

pci_msix_clear_and_set_ctrl(dev, PCI_MSIX_FLAGS_MASKALL, 0);
@@ -501,7 +502,7 @@ static int populate_msi_sysfs(struct pci_dev *pdev)
int count = 0;

/* Determine how many msi entries we have */
- list_for_each_entry(entry, &pdev->msi_list, list)
+ for_each_pci_msi_entry(entry, pdev)
++num_msi;
if (!num_msi)
return 0;
@@ -510,7 +511,7 @@ static int populate_msi_sysfs(struct pci_dev *pdev)
msi_attrs = kzalloc(sizeof(void *) * (num_msi + 1), GFP_KERNEL);
if (!msi_attrs)
return -ENOMEM;
- list_for_each_entry(entry, &pdev->msi_list, list) {
+ for_each_pci_msi_entry(entry, pdev) {
msi_dev_attr = kzalloc(sizeof(*msi_dev_attr), GFP_KERNEL);
if (!msi_dev_attr)
goto error_attrs;
@@ -599,7 +600,7 @@ static int msi_verify_entries(struct pci_dev *dev)
{
struct msi_desc *entry;

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
if (!dev->no_64bit_msi || !entry->msg.address_hi)
continue;
dev_err(&dev->dev, "Device has broken 64-bit MSI but arch"
@@ -636,7 +637,7 @@ static int msi_capability_init(struct pci_dev *dev, int nvec)
mask = msi_mask(entry->msi_attrib.multi_cap);
msi_mask_irq(entry, mask, mask);

- list_add_tail(&entry->list, &dev->msi_list);
+ list_add_tail(&entry->list, dev_to_msi_list(&dev->dev));

/* Configure MSI capability structure */
ret = pci_msi_setup_msi_irqs(dev, nvec, PCI_CAP_ID_MSI);
@@ -713,7 +714,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base,
entry->mask_base = base;
entry->nvec_used = 1;

- list_add_tail(&entry->list, &dev->msi_list);
+ list_add_tail(&entry->list, dev_to_msi_list(&dev->dev));
}

return 0;
@@ -725,7 +726,7 @@ static void msix_program_entries(struct pci_dev *dev,
struct msi_desc *entry;
int i = 0;

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
int offset = entries[i].entry * PCI_MSIX_ENTRY_SIZE +
PCI_MSIX_ENTRY_VECTOR_CTRL;

@@ -806,7 +807,7 @@ out_avail:
struct msi_desc *entry;
int avail = 0;

- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
if (entry->irq != 0)
avail++;
}
@@ -895,8 +896,8 @@ void pci_msi_shutdown(struct pci_dev *dev)
if (!pci_msi_enable || !dev || !dev->msi_enabled)
return;

- BUG_ON(list_empty(&dev->msi_list));
- desc = list_first_entry(&dev->msi_list, struct msi_desc, list);
+ BUG_ON(list_empty(dev_to_msi_list(&dev->dev)));
+ desc = first_msi_entry(dev);

pci_msi_set_enable(dev, 0);
pci_intx_for_msi(dev, 1);
@@ -1001,7 +1002,7 @@ void pci_msix_shutdown(struct pci_dev *dev)
return;

/* Return the device with MSI-X masked as initial states */
- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
/* Keep cached states to be restored */
__pci_msix_desc_mask_irq(entry, 1);
}
diff --git a/drivers/pci/xen-pcifront.c b/drivers/pci/xen-pcifront.c
index 8b7a900..c777b97 100644
--- a/drivers/pci/xen-pcifront.c
+++ b/drivers/pci/xen-pcifront.c
@@ -265,7 +265,7 @@ static int pci_frontend_enable_msix(struct pci_dev *dev,
}

i = 0;
- list_for_each_entry(entry, &dev->msi_list, list) {
+ for_each_pci_msi_entry(entry, dev) {
op.msix_entries[i].entry = entry->msi_attrib.entry_nr;
/* Vector is useless at this point. */
op.msix_entries[i].vector = -1;

Subject: [tip:irq/core] sparc/PCI: Use helper functions to access fields in struct msi_desc

Commit-ID: 3bf15f53c963a43c317e65e1709e9f020c04f024
Gitweb: http://git.kernel.org/tip/3bf15f53c963a43c317e65e1709e9f020c04f024
Author: Jiang Liu <[email protected]>
AuthorDate: Thu, 9 Jul 2015 16:00:42 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Wed, 22 Jul 2015 18:37:43 +0200

sparc/PCI: Use helper functions to access fields in struct msi_desc

Use helper functions to access fields in struct msi_desc, so we could
easily refine struct msi_desc later.

Signed-off-by: Jiang Liu <[email protected]>
Acked-by: David S. Miller <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: [email protected]
Cc: Bjorn Helgaas <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Marc Zyngier <[email protected]>
Cc: Stuart Yoder <[email protected]>
Cc: Yijing Wang <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Eric Snowberg <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
arch/sparc/kernel/pci.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/arch/sparc/kernel/pci.c b/arch/sparc/kernel/pci.c
index c928bc6..048b406 100644
--- a/arch/sparc/kernel/pci.c
+++ b/arch/sparc/kernel/pci.c
@@ -918,7 +918,7 @@ int arch_setup_msi_irq(struct pci_dev *pdev, struct msi_desc *desc)
void arch_teardown_msi_irq(unsigned int irq)
{
struct msi_desc *entry = irq_get_msi_desc(irq);
- struct pci_dev *pdev = entry->dev;
+ struct pci_dev *pdev = msi_desc_to_pci_dev(entry);
struct pci_pbm_info *pbm = pdev->dev.archdata.host_controller;

if (pbm->teardown_msi_irq)

Subject: [tip:irq/core] PCI: Use helper functions to access fields in struct msi_desc

Commit-ID: e39758e0ea769e632e5e3c9f314160e55c2153ff
Gitweb: http://git.kernel.org/tip/e39758e0ea769e632e5e3c9f314160e55c2153ff
Author: Jiang Liu <[email protected]>
AuthorDate: Thu, 9 Jul 2015 16:00:43 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Wed, 22 Jul 2015 18:37:43 +0200

PCI: Use helper functions to access fields in struct msi_desc

Use helper functions to access fields in struct msi_desc, so we could
easily refine msi_desc later.

Signed-off-by: Jiang Liu <[email protected]>
Reviewed-by: Yijing Wang <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: [email protected]
Cc: Bjorn Helgaas <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Marc Zyngier <[email protected]>
Cc: Stuart Yoder <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Murali Karicheri <[email protected]>
Cc: Jingoo Han <[email protected]>
Cc: Pratyush Anand <[email protected]>
Cc: Michal Simek <[email protected]>
Cc: Soeren Brinkmann <[email protected]>
Cc: Srikanth Thokala <[email protected]>
Cc: Rob Herring <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
drivers/pci/host/pci-keystone-dw.c | 6 +++---
drivers/pci/host/pcie-designware.c | 4 ++--
drivers/pci/host/pcie-xilinx.c | 12 +++++-------
drivers/pci/msi.c | 13 ++++++++-----
4 files changed, 18 insertions(+), 17 deletions(-)

diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
index e42d077..6f3abc2 100644
--- a/drivers/pci/host/pci-keystone-dw.c
+++ b/drivers/pci/host/pci-keystone-dw.c
@@ -108,7 +108,7 @@ static void ks_dw_pcie_msi_irq_ack(struct irq_data *d)
struct pcie_port *pp;

msi = irq_data_get_msi_desc(d);
- pp = sys_to_pcie(msi->dev->bus->sysdata);
+ pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));
ks_pcie = to_keystone_pcie(pp);
offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);
update_reg_offset_bit_pos(offset, &reg_offset, &bit_pos);
@@ -146,7 +146,7 @@ static void ks_dw_pcie_msi_irq_mask(struct irq_data *d)
u32 offset;

msi = irq_data_get_msi_desc(d);
- pp = sys_to_pcie(msi->dev->bus->sysdata);
+ pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));
ks_pcie = to_keystone_pcie(pp);
offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);

@@ -167,7 +167,7 @@ static void ks_dw_pcie_msi_irq_unmask(struct irq_data *d)
u32 offset;

msi = irq_data_get_msi_desc(d);
- pp = sys_to_pcie(msi->dev->bus->sysdata);
+ pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));
ks_pcie = to_keystone_pcie(pp);
offset = d->irq - irq_linear_revmap(pp->irq_domain, 0);

diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index 85c7735..aae6dcb 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -255,7 +255,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
{
int irq, pos0, i;
- struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
+ struct pcie_port *pp = sys_to_pcie(msi_desc_to_pci_sysdata(desc));

pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
order_base_2(no_irqs));
@@ -327,7 +327,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
{
struct irq_data *data = irq_get_irq_data(irq);
struct msi_desc *msi = irq_data_get_msi_desc(data);
- struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
+ struct pcie_port *pp = sys_to_pcie(msi_desc_to_pci_sysdata(msi));

clear_irq_range(pp, irq, 1, data->hwirq);
}
diff --git a/drivers/pci/host/pcie-xilinx.c b/drivers/pci/host/pcie-xilinx.c
index f1a06a0..64454f4 100644
--- a/drivers/pci/host/pcie-xilinx.c
+++ b/drivers/pci/host/pcie-xilinx.c
@@ -227,18 +227,16 @@ static struct pci_ops xilinx_pcie_ops = {
*/
static void xilinx_pcie_destroy_msi(unsigned int irq)
{
- struct irq_desc *desc;
struct msi_desc *msi;
struct xilinx_pcie_port *port;

- desc = irq_to_desc(irq);
- msi = irq_desc_get_msi_desc(desc);
- port = sys_to_pcie(msi->dev->bus->sysdata);
-
- if (!test_bit(irq, msi_irq_in_use))
+ if (!test_bit(irq, msi_irq_in_use)) {
+ msi = irq_get_msi_desc(irq);
+ port = sys_to_pcie(msi_desc_to_pci_sys_data(msi));
dev_err(port->dev, "Trying to free unused MSI#%d\n", irq);
- else
+ } else {
clear_bit(irq, msi_irq_in_use);
+ }
}

/**
diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 540613e..f0714c3 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -208,7 +208,8 @@ u32 __pci_msi_desc_mask_irq(struct msi_desc *desc, u32 mask, u32 flag)

mask_bits &= ~mask;
mask_bits |= flag;
- pci_write_config_dword(desc->dev, desc->mask_pos, mask_bits);
+ pci_write_config_dword(msi_desc_to_pci_dev(desc), desc->mask_pos,
+ mask_bits);

return mask_bits;
}
@@ -288,7 +289,9 @@ void default_restore_msi_irqs(struct pci_dev *dev)

void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
{
- BUG_ON(entry->dev->current_state != PCI_D0);
+ struct pci_dev *dev = msi_desc_to_pci_dev(entry);
+
+ BUG_ON(dev->current_state != PCI_D0);

if (entry->msi_attrib.is_msix) {
void __iomem *base = entry->mask_base +
@@ -298,7 +301,6 @@ void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
msg->address_hi = readl(base + PCI_MSIX_ENTRY_UPPER_ADDR);
msg->data = readl(base + PCI_MSIX_ENTRY_DATA);
} else {
- struct pci_dev *dev = entry->dev;
int pos = dev->msi_cap;
u16 data;

@@ -318,7 +320,9 @@ void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg)

void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
{
- if (entry->dev->current_state != PCI_D0) {
+ struct pci_dev *dev = msi_desc_to_pci_dev(entry);
+
+ if (dev->current_state != PCI_D0) {
/* Don't touch the hardware now */
} else if (entry->msi_attrib.is_msix) {
void __iomem *base;
@@ -329,7 +333,6 @@ void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
writel(msg->address_hi, base + PCI_MSIX_ENTRY_UPPER_ADDR);
writel(msg->data, base + PCI_MSIX_ENTRY_DATA);
} else {
- struct pci_dev *dev = entry->dev;
int pos = dev->msi_cap;
u16 msgctl;

Subject: [tip:irq/core] genirq/MSI: Move msi_list from struct pci_dev to struct device

Commit-ID: 4a7cc831670550e6b48ef5760e7213f89935ff0d
Gitweb: http://git.kernel.org/tip/4a7cc831670550e6b48ef5760e7213f89935ff0d
Author: Jiang Liu <[email protected]>
AuthorDate: Thu, 9 Jul 2015 16:00:44 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Wed, 22 Jul 2015 18:37:43 +0200

genirq/MSI: Move msi_list from struct pci_dev to struct device

Move msi_list from struct pci_dev into struct device, so we can
support non-PCI-device based generic MSI interrupts.

msi_list is now conditional under CONFIG_GENERIC_MSI_IRQ, which is
selected from CONFIG_PCI_MSI, so no functional change for PCI MSI
users.

Signed-off-by: Jiang Liu <[email protected]>
Reviewed-by: Yijing Wang <[email protected]>
Acked-by: Bjorn Helgaas <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: [email protected]
Cc: Grant Likely <[email protected]>
Cc: Marc Zyngier <[email protected]>
Cc: Stuart Yoder <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Greg Kroah-Hartman <[email protected]>
Cc: Joe Perches <[email protected]>
Cc: Dmitry Torokhov <[email protected]>
Cc: Paul Gortmaker <[email protected]>
Cc: Luis R. Rodriguez <[email protected]>
Cc: Rafael J. Wysocki <[email protected]>
Cc: Joerg Roedel <[email protected]>
Cc: Alexander Gordeev <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
drivers/base/core.c | 3 +++
drivers/pci/msi.c | 3 +--
include/linux/device.h | 4 ++++
include/linux/msi.h | 2 +-
include/linux/pci.h | 1 -
5 files changed, 9 insertions(+), 4 deletions(-)

diff --git a/drivers/base/core.c b/drivers/base/core.c
index dafae6d..18e2a89 100644
--- a/drivers/base/core.c
+++ b/drivers/base/core.c
@@ -662,6 +662,9 @@ void device_initialize(struct device *dev)
INIT_LIST_HEAD(&dev->devres_head);
device_pm_init(dev);
set_dev_node(dev, -1);
+#ifdef CONFIG_GENERIC_MSI_IRQ
+ INIT_LIST_HEAD(&dev->msi_list);
+#endif
}
EXPORT_SYMBOL_GPL(device_initialize);

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index f0714c3..4ef5021 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -900,7 +900,7 @@ void pci_msi_shutdown(struct pci_dev *dev)
return;

BUG_ON(list_empty(dev_to_msi_list(&dev->dev)));
- desc = first_msi_entry(dev);
+ desc = first_pci_msi_entry(dev);

pci_msi_set_enable(dev, 0);
pci_intx_for_msi(dev, 1);
@@ -1044,7 +1044,6 @@ EXPORT_SYMBOL(pci_msi_enabled);

void pci_msi_init_pci_dev(struct pci_dev *dev)
{
- INIT_LIST_HEAD(&dev->msi_list);
}

/**
diff --git a/include/linux/device.h b/include/linux/device.h
index 5a31bf3..22227e7 100644
--- a/include/linux/device.h
+++ b/include/linux/device.h
@@ -713,6 +713,7 @@ struct device_dma_parameters {
* along with subsystem-level and driver-level callbacks.
* @pins: For device pin management.
* See Documentation/pinctrl.txt for details.
+ * @msi_list: Hosts MSI descriptors
* @numa_node: NUMA node this device is close to.
* @dma_mask: Dma mask (if dma'ble device).
* @coherent_dma_mask: Like dma_mask, but for alloc_coherent mapping as not all
@@ -776,6 +777,9 @@ struct device {
#ifdef CONFIG_PINCTRL
struct dev_pin_info *pins;
#endif
+#ifdef CONFIG_GENERIC_MSI_IRQ
+ struct list_head msi_list;
+#endif

#ifdef CONFIG_NUMA
int numa_node; /* NUMA node this device is close to */
diff --git a/include/linux/msi.h b/include/linux/msi.h
index cfbd2af..57fe766 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -45,7 +45,7 @@ struct msi_desc {

/* Helpers to hide struct msi_desc implementation details */
#define msi_desc_to_dev(desc) (&(desc)->dev.dev)
-#define dev_to_msi_list(dev) (&to_pci_dev((dev))->msi_list)
+#define dev_to_msi_list(dev) (&(dev)->msi_list)
#define first_msi_entry(dev) \
list_first_entry(dev_to_msi_list((dev)), struct msi_desc, list)
#define for_each_msi_entry(desc, dev) \
diff --git a/include/linux/pci.h b/include/linux/pci.h
index 8a0321a..fbf245f 100644
--- a/include/linux/pci.h
+++ b/include/linux/pci.h
@@ -366,7 +366,6 @@ struct pci_dev {
struct bin_attribute *res_attr[DEVICE_COUNT_RESOURCE]; /* sysfs file for resources */
struct bin_attribute *res_attr_wc[DEVICE_COUNT_RESOURCE]; /* sysfs file for WC mapping of resources */
#ifdef CONFIG_PCI_MSI
- struct list_head msi_list;
const struct attribute_group **msi_irq_groups;
#endif
struct pci_vpd *vpd;

Subject: [tip:irq/core] genirq/MSI: Store 'struct device' instead of ' struct pci_dev' in struct msi_desc

Commit-ID: 25a98bd4ff9355a218d2e7aa4d6e3c9bc2c27d6f
Gitweb: http://git.kernel.org/tip/25a98bd4ff9355a218d2e7aa4d6e3c9bc2c27d6f
Author: Jiang Liu <[email protected]>
AuthorDate: Thu, 9 Jul 2015 16:00:45 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Wed, 22 Jul 2015 18:37:43 +0200

genirq/MSI: Store 'struct device' instead of 'struct pci_dev' in struct msi_desc

Store 'struct device *' instead of 'struct pci_dev *' in struct msi_desc,
so struct msi_desc can be reused by non PCI based MSI drivers.

Signed-off-by: Jiang Liu <[email protected]>
Reviewed-by: Yijing Wang <[email protected]>
Reviewed-by: Marc Zyngier <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: [email protected]
Cc: Bjorn Helgaas <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Stuart Yoder <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Alexander Gordeev <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
drivers/pci/msi.c | 7 ++++++-
include/linux/msi.h | 11 ++++-------
2 files changed, 10 insertions(+), 8 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 4ef5021..897e1a4 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -413,7 +413,7 @@ static struct msi_desc *alloc_msi_entry(struct pci_dev *dev)
return NULL;

INIT_LIST_HEAD(&desc->list);
- desc->dev = dev;
+ desc->dev = &dev->dev;

return desc;
}
@@ -1140,6 +1140,11 @@ int pci_enable_msix_range(struct pci_dev *dev, struct msix_entry *entries,
}
EXPORT_SYMBOL(pci_enable_msix_range);

+struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
+{
+ return to_pci_dev(desc->dev);
+}
+
void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
{
struct pci_dev *dev = msi_desc_to_pci_dev(desc);
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 57fe766..5f77e23 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -14,6 +14,7 @@ extern int pci_msi_ignore_mask;
/* Helper functions */
struct irq_data;
struct msi_desc;
+struct pci_dev;
void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg);

@@ -37,14 +38,14 @@ struct msi_desc {
void __iomem *mask_base;
u8 mask_pos;
};
- struct pci_dev *dev;
+ struct device *dev;

/* Last set MSI message */
struct msi_msg msg;
};

/* Helpers to hide struct msi_desc implementation details */
-#define msi_desc_to_dev(desc) (&(desc)->dev.dev)
+#define msi_desc_to_dev(desc) ((desc)->dev)
#define dev_to_msi_list(dev) (&(dev)->msi_list)
#define first_msi_entry(dev) \
list_first_entry(dev_to_msi_list((dev)), struct msi_desc, list)
@@ -56,11 +57,7 @@ struct msi_desc {
#define for_each_pci_msi_entry(desc, pdev) \
for_each_msi_entry((desc), &(pdev)->dev)

-static inline struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc)
-{
- return desc->dev;
-}
-
+struct pci_dev *msi_desc_to_pci_dev(struct msi_desc *desc);
void *msi_desc_to_pci_sysdata(struct msi_desc *desc);
#else /* CONFIG_PCI_MSI */
static inline void *msi_desc_to_pci_sysdata(struct msi_desc *desc)

Subject: [tip:irq/core] genirq/MSI: Reorginize struct msi_desc to prepare for support of generic MSI

Commit-ID: fc88419cfac50b05c7c1ea218b08e70c31d1b71f
Gitweb: http://git.kernel.org/tip/fc88419cfac50b05c7c1ea218b08e70c31d1b71f
Author: Jiang Liu <[email protected]>
AuthorDate: Thu, 9 Jul 2015 16:00:46 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Wed, 22 Jul 2015 18:37:44 +0200

genirq/MSI: Reorginize struct msi_desc to prepare for support of generic MSI

Reorganize struct msi_desc so it could be reused by other MSI
drivers. We have the following layout now:

struct msi_desc {
/* Shared device/bus independent data */
...
union {
/* PCI specific data */
struct {
...
};
};
};

We need to have anonymous union and a anonymous structure for the PCI
fields, otherwise we would have to change all instances using these
fields.

For non PCI devices we will enforce a proper namespace and a non
anonymous structure.

[ tglx: Added proper comments to the structure and massaged changelog ]

Signed-off-by: Jiang Liu <[email protected]>
Reviewed-by: Yijing Wang <[email protected]>
Reviewed-by: Marc Zyngier <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: [email protected]
Cc: Bjorn Helgaas <[email protected]>
Cc: Grant Likely <[email protected]>
Cc: Stuart Yoder <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Alexander Gordeev <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
include/linux/msi.h | 70 ++++++++++++++++++++++++++++++++++++++---------------
1 file changed, 50 insertions(+), 20 deletions(-)

diff --git a/include/linux/msi.h b/include/linux/msi.h
index 5f77e23..518e8c4 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -18,30 +18,60 @@ struct pci_dev;
void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void get_cached_msi_msg(unsigned int irq, struct msi_msg *msg);

+/**
+ * struct msi_desc - Descriptor structure for MSI based interrupts
+ * @list: List head for management
+ * @irq: The base interrupt number
+ * @nvec_used: The number of vectors used
+ * @dev: Pointer to the device which uses this descriptor
+ * @msg: The last set MSI message cached for reuse
+ *
+ * @masked: [PCI MSI/X] Mask bits
+ * @is_msix: [PCI MSI/X] True if MSI-X
+ * @multiple: [PCI MSI/X] log2 num of messages allocated
+ * @multi_cap: [PCI MSI/X] log2 num of messages supported
+ * @maskbit: [PCI MSI/X] Mask-Pending bit supported?
+ * @is_64: [PCI MSI/X] Address size: 0=32bit 1=64bit
+ * @entry_nr: [PCI MSI/X] Entry which is described by this descriptor
+ * @default_irq:[PCI MSI/X] The default pre-assigned non-MSI irq
+ * @mask_pos: [PCI MSI] Mask register position
+ * @mask_base: [PCI MSI-X] Mask register base address
+ */
struct msi_desc {
- struct {
- __u8 is_msix : 1;
- __u8 multiple: 3; /* log2 num of messages allocated */
- __u8 multi_cap : 3; /* log2 num of messages supported */
- __u8 maskbit : 1; /* mask-pending bit supported ? */
- __u8 is_64 : 1; /* Address size: 0=32bit 1=64bit */
- __u16 entry_nr; /* specific enabled entry */
- unsigned default_irq; /* default pre-assigned irq */
- } msi_attrib;
-
- u32 masked; /* mask bits */
- unsigned int irq;
- unsigned int nvec_used; /* number of messages */
- struct list_head list;
+ /* Shared device/bus type independent data */
+ struct list_head list;
+ unsigned int irq;
+ unsigned int nvec_used;
+ struct device *dev;
+ struct msi_msg msg;

union {
- void __iomem *mask_base;
- u8 mask_pos;
- };
- struct device *dev;
+ /* PCI MSI/X specific data */
+ struct {
+ u32 masked;
+ struct {
+ __u8 is_msix : 1;
+ __u8 multiple : 3;
+ __u8 multi_cap : 3;
+ __u8 maskbit : 1;
+ __u8 is_64 : 1;
+ __u16 entry_nr;
+ unsigned default_irq;
+ } msi_attrib;
+ union {
+ u8 mask_pos;
+ void __iomem *mask_base;
+ };
+ };

- /* Last set MSI message */
- struct msi_msg msg;
+ /*
+ * Non PCI variants add their data structure here. New
+ * entries need to use a named structure. We want
+ * proper name spaces for this. The PCI part is
+ * anonymous for now as it would require an immediate
+ * tree wide cleanup.
+ */
+ };
};

/* Helpers to hide struct msi_desc implementation details */

Subject: [tip:irq/core] genirq/MSI: Move alloc_msi_entry() from PCI into generic MSI code

Commit-ID: aa48b6f708868ab9c22ca737f27a0da832bf7f08
Gitweb: http://git.kernel.org/tip/aa48b6f708868ab9c22ca737f27a0da832bf7f08
Author: Jiang Liu <[email protected]>
AuthorDate: Thu, 9 Jul 2015 16:00:47 +0800
Committer: Thomas Gleixner <[email protected]>
CommitDate: Wed, 22 Jul 2015 18:37:44 +0200

genirq/MSI: Move alloc_msi_entry() from PCI into generic MSI code

Move alloc_msi_entry() from PCI MSI code into generic MSI code, so it
can be reused by other generic MSI drivers. Also introduce
free_msi_entry() for completeness.

Suggested-by: Stuart Yoder <[email protected]>.
Signed-off-by: Jiang Liu <[email protected]>
Reviewed-by: Marc Zyngier <[email protected]>
Reviewed-by: Yijing Wang <[email protected]>
Acked-by: Bjorn Helgaas <[email protected]>
Cc: Tony Luck <[email protected]>
Cc: [email protected]
Cc: Grant Likely <[email protected]>
Cc: Borislav Petkov <[email protected]>
Cc: Alexander Gordeev <[email protected]>
Link: http://lkml.kernel.org/r/[email protected]
Signed-off-by: Thomas Gleixner <[email protected]>
---
drivers/pci/msi.c | 16 ++--------------
include/linux/msi.h | 2 ++
kernel/irq/msi.c | 17 +++++++++++++++++
3 files changed, 21 insertions(+), 14 deletions(-)

diff --git a/drivers/pci/msi.c b/drivers/pci/msi.c
index 897e1a4..cd4c78c 100644
--- a/drivers/pci/msi.c
+++ b/drivers/pci/msi.c
@@ -406,18 +406,6 @@ static void free_msi_irqs(struct pci_dev *dev)
}
}

-static struct msi_desc *alloc_msi_entry(struct pci_dev *dev)
-{
- struct msi_desc *desc = kzalloc(sizeof(*desc), GFP_KERNEL);
- if (!desc)
- return NULL;
-
- INIT_LIST_HEAD(&desc->list);
- desc->dev = &dev->dev;
-
- return desc;
-}
-
static void pci_intx_for_msi(struct pci_dev *dev, int enable)
{
if (!(dev->dev_flags & PCI_DEV_FLAGS_MSI_INTX_DISABLE_BUG))
@@ -572,7 +560,7 @@ static struct msi_desc *msi_setup_entry(struct pci_dev *dev, int nvec)
struct msi_desc *entry;

/* MSI Entry Initialization */
- entry = alloc_msi_entry(dev);
+ entry = alloc_msi_entry(&dev->dev);
if (!entry)
return NULL;

@@ -700,7 +688,7 @@ static int msix_setup_entries(struct pci_dev *dev, void __iomem *base,
int i;

for (i = 0; i < nvec; i++) {
- entry = alloc_msi_entry(dev);
+ entry = alloc_msi_entry(&dev->dev);
if (!entry) {
if (!i)
iounmap(base);
diff --git a/include/linux/msi.h b/include/linux/msi.h
index 518e8c4..f83c87e 100644
--- a/include/linux/msi.h
+++ b/include/linux/msi.h
@@ -96,6 +96,8 @@ static inline void *msi_desc_to_pci_sysdata(struct msi_desc *desc)
}
#endif /* CONFIG_PCI_MSI */

+struct msi_desc *alloc_msi_entry(struct device *dev);
+void free_msi_entry(struct msi_desc *entry);
void __pci_read_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void __pci_write_msi_msg(struct msi_desc *entry, struct msi_msg *msg);
void pci_write_msi_msg(unsigned int irq, struct msi_msg *msg);
diff --git a/kernel/irq/msi.c b/kernel/irq/msi.c
index 7bf1f1b..7e6512b 100644
--- a/kernel/irq/msi.c
+++ b/kernel/irq/msi.c
@@ -18,6 +18,23 @@
/* Temparory solution for building, will be removed later */
#include <linux/pci.h>

+struct msi_desc *alloc_msi_entry(struct device *dev)
+{
+ struct msi_desc *desc = kzalloc(sizeof(*desc), GFP_KERNEL);
+ if (!desc)
+ return NULL;
+
+ INIT_LIST_HEAD(&desc->list);
+ desc->dev = dev;
+
+ return desc;
+}
+
+void free_msi_entry(struct msi_desc *entry)
+{
+ kfree(entry);
+}
+
void __get_cached_msi_msg(struct msi_desc *entry, struct msi_msg *msg)
{
*msg = entry->msg;