Skip to contentSkip to conversation

PCI: dwc: Enables MSI-X driver support

PATCH Superseded Gustavo Pimentel 3 participants 7 messages Mar 6, 2018

Subsystems (3)

v10 of 11 Superseded Latest is v11 →

lore
Share & tools
lore
#0 lore raw

v10 cover PCI: dwc: Enables MSI-X driver support

Implement a multiplexed IRQ domain hierarchy API in the pcie-designware host bridge driver that funnels all MSI IRQs into a single parent interrupt, moving away from the obsolete struct msi_controller based API.

Remove all existing dwc based host bridges MSI IRQs handlers, in that the hierarchical API now handles MSI IRQs through the hierarchical/chained MSI domain implementation.

The Synopsys PCIe Root Complex supports up to MSI 256 IRQs distributed over 8 controller registers, therefore the maximum number of MSI IRQs can be changed to 256. The number of controllers can be calculated based on the number of vectors used by the specific SoC driver.

Adds Synopsys Root Complex driver support for MSI-X feature.

The patch set was made against the Bjorn's master branch (v4.16-rc1).

Gustavo Pimentel (3):
PCI: dwc: Move MSI IRQs allocation to IRQ domains hierarchical API
PCI: dwc: Remove old MSI IRQs API
PCI: dwc: Expand maximum number of MSI IRQs from 32 to 256

 drivers/pci/dwc/pci-exynos.c           |  18 --
 drivers/pci/dwc/pci-imx6.c             |  18 --
 drivers/pci/dwc/pci-keystone-dw.c      |  91 +-------
 drivers/pci/dwc/pci-keystone.c         |   1 +
 drivers/pci/dwc/pci-keystone.h         |   4 +-
 drivers/pci/dwc/pci-layerscape.c       |   3 +-
 drivers/pci/dwc/pcie-artpec6.c         |  18 --
 drivers/pci/dwc/pcie-designware-host.c | 396 +++++++++++++++++++--------------
 drivers/pci/dwc/pcie-designware-plat.c |  16 --
 drivers/pci/dwc/pcie-designware.h      |  30 ++-
 drivers/pci/dwc/pcie-histb.c           |  15 --
 drivers/pci/dwc/pcie-qcom.c            |  16 --
 12 files changed, 256 insertions(+), 370 deletions(-)
Signature · 1 line
2.7.4
#1 lore raw

PATCH v10 1/3 PCI: dwc: Move MSI IRQs allocation to IRQ domains hierarchical API

Implement a multiplexed IRQ domain hierarchy API in the pcie-designware host bridge driver that funnels all MSI IRQs into a single parent interrupt, moving away from the obsolete struct msi_controller based API.

Although the old implementation API is still available, pcie-designware will now use the multiplexed IRQ domains hierarchical API.

Remove all existing dwc based host bridges MSI IRQs handlers, in that the hierarchical API now handles MSI IRQs through the hierarchical/chained MSI domain implementation.

---
Change v1->v2:
- num_vectors is now not configurable by the Device Tree. Now it is 32 by default and can be overridden by any specific SoC driver. Change v2->v3:
- Nothing changed, just to follow the patch set version.
Change v3->v4:
- Moved Kishon's fixes (PCI end point error and a dra7xx warning) from v3-0007 patch file to here.
- Undo the change of the function signature to be more coherent with the host mode specific functions (Thanks Kishon).
- Refactor the added functions in order to used host_data so that getting pp again back from pci could be avoided. (Thanks Kishon)
- Changed summary line to match the drivers/PCI convention and changelog to maintain the consistency (thanks Bjorn).
Change v4->v5:
- Implemented Kishon MSI multiple messages fix (thanks Kishon). Change v5->v6:
- Fixed rebase problem detected by Niklas (thanks Niklas). Change v6->v7:
- Implemented Marc review suggestions (thanks Marc).
Change v7->v8:
- Rebased against v4.16-rc1.
Change v8->v9:
- Squashed all patches [2-7] into this, following Lorenzo sugestion (thanks Lorenzo).
Change v9->v10:
- Log commit rewrite to be accurate by Lorenzo (thanks Lorenzo).
- Fixed kbuild test robot warning relatively to the raw_spin_lock.
- Extended patch fix to pcie-histb driver.

 drivers/pci/dwc/pci-exynos.c           |  18 --
 drivers/pci/dwc/pci-imx6.c             |  18 --
 drivers/pci/dwc/pci-keystone-dw.c      |  89 +---------
 drivers/pci/dwc/pci-keystone.c         |   1 +
 drivers/pci/dwc/pci-keystone.h         |   1 +
 drivers/pci/dwc/pcie-artpec6.c         |  18 --
 drivers/pci/dwc/pcie-designware-host.c | 294 +++++++++++++++++++++++++++++----
 drivers/pci/dwc/pcie-designware-plat.c |  16 --
 drivers/pci/dwc/pcie-designware.h      |  18 ++
 drivers/pci/dwc/pcie-histb.c           |  15 --
 drivers/pci/dwc/pcie-qcom.c            |  16 --
 11 files changed, 290 insertions(+), 214 deletions(-)
drivers/pci/dwc/pci-exynos.c +0 -18
index ca62781..4cc1e5d 100644
@@ -294,15 +294,6 @@ static irqreturn_t exynos_pcie_irq_handler(int irq, void *arg)
 	return IRQ_HANDLED;
 }
 
-static irqreturn_t exynos_pcie_msi_irq_handler(int irq, void *arg)
-{
-	struct exynos_pcie *ep = arg;
-	struct dw_pcie *pci = ep->pci;
-	struct pcie_port *pp = &pci->pp;
-
-	return dw_handle_msi_irq(pp);
-}
-
 static void exynos_pcie_msi_init(struct exynos_pcie *ep)
 {
 	struct dw_pcie *pci = ep->pci;
@@ -428,15 +419,6 @@ static int __init exynos_add_pcie_port(struct exynos_pcie *ep,
 			dev_err(dev, "failed to get msi irq\n");
 			return pp->msi_irq;
 		}
-
-		ret = devm_request_irq(dev, pp->msi_irq,
-					exynos_pcie_msi_irq_handler,
-					IRQF_SHARED | IRQF_NO_THREAD,
-					"exynos-pcie", ep);
-		if (ret) {
-			dev_err(dev, "failed to request msi irq\n");
-			return ret;
-		}
 	}
 
 	pp->root_bus_nr = -1;
drivers/pci/dwc/pci-imx6.c +0 -18
index 4fddbd0..4818ef8 100644
@@ -542,15 +542,6 @@ static int imx6_pcie_wait_for_speed_change(struct imx6_pcie *imx6_pcie)
 	return -EINVAL;
 }
 
-static irqreturn_t imx6_pcie_msi_handler(int irq, void *arg)
-{
-	struct imx6_pcie *imx6_pcie = arg;
-	struct dw_pcie *pci = imx6_pcie->pci;
-	struct pcie_port *pp = &pci->pp;
-
-	return dw_handle_msi_irq(pp);
-}
-
 static int imx6_pcie_establish_link(struct imx6_pcie *imx6_pcie)
 {
 	struct dw_pcie *pci = imx6_pcie->pci;
@@ -674,15 +665,6 @@ static int imx6_add_pcie_port(struct imx6_pcie *imx6_pcie,
 			dev_err(dev, "failed to get MSI irq\n");
 			return -ENODEV;
 		}
-
-		ret = devm_request_irq(dev, pp->msi_irq,
-				       imx6_pcie_msi_handler,
-				       IRQF_SHARED | IRQF_NO_THREAD,
-				       "mx6-pcie-msi", imx6_pcie);
-		if (ret) {
-			dev_err(dev, "failed to request MSI irq\n");
-			return ret;
-		}
 	}
 
 	pp->root_bus_nr = -1;
drivers/pci/dwc/pci-keystone-dw.c +4 -85

109 lines not on this page · raw message

drivers/pci/dwc/pci-keystone.c +1 -0
index d4f8ab9..d55ae07 100644
@@ -297,6 +297,7 @@ static const struct dw_pcie_host_ops keystone_pcie_host_ops = {
 	.msi_clear_irq = ks_dw_pcie_msi_clear_irq,
 	.get_msi_addr = ks_dw_pcie_get_msi_addr,
 	.msi_host_init = ks_dw_pcie_msi_host_init,
+	.msi_irq_ack = ks_dw_pcie_msi_irq_ack,
 	.scan_bus = ks_dw_pcie_v3_65_scan_bus,
 };
 
drivers/pci/dwc/pci-keystone.h +1 -0
index 1dd1f3e..aa50448 100644
@@ -49,6 +49,7 @@ int ks_dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 		unsigned int devfn, int where, int size, u32 *val);
 void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie);
 void ks_dw_pcie_initiate_link_train(struct keystone_pcie *ks_pcie);
+void ks_dw_pcie_msi_irq_ack(int i, struct pcie_port *pp);
 void ks_dw_pcie_msi_set_irq(struct pcie_port *pp, int irq);
 void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq);
 void ks_dw_pcie_v3_65_scan_bus(struct pcie_port *pp);
drivers/pci/dwc/pcie-artpec6.c +0 -18
index 93b3df9..e66cede 100644
@@ -383,15 +383,6 @@ static const struct dw_pcie_host_ops artpec6_pcie_host_ops = {
 	.host_init = artpec6_pcie_host_init,
 };
 
-static irqreturn_t artpec6_pcie_msi_handler(int irq, void *arg)
-{
-	struct artpec6_pcie *artpec6_pcie = arg;
-	struct dw_pcie *pci = artpec6_pcie->pci;
-	struct pcie_port *pp = &pci->pp;
-
-	return dw_handle_msi_irq(pp);
-}
-
 static int artpec6_add_pcie_port(struct artpec6_pcie *artpec6_pcie,
 				 struct platform_device *pdev)
 {
@@ -406,15 +397,6 @@ static int artpec6_add_pcie_port(struct artpec6_pcie *artpec6_pcie,
 			dev_err(dev, "failed to get MSI irq\n");
 			return pp->msi_irq;
 		}
-
-		ret = devm_request_irq(dev, pp->msi_irq,
-				       artpec6_pcie_msi_handler,
-				       IRQF_SHARED | IRQF_NO_THREAD,
-				       "artpec6-pcie-msi", artpec6_pcie);
-		if (ret) {
-			dev_err(dev, "failed to request MSI irq\n");
-			return ret;
-		}
 	}
 
 	pp->root_bus_nr = -1;
drivers/pci/dwc/pcie-designware-host.c +266 -28

367 lines not on this page · raw message

drivers/pci/dwc/pcie-designware-plat.c +0 -16
index ebdf28b..5416aa8 100644
@@ -25,13 +25,6 @@ struct dw_plat_pcie {
 	struct dw_pcie		*pci;
 };
 
-static irqreturn_t dw_plat_pcie_msi_irq_handler(int irq, void *arg)
-{
-	struct pcie_port *pp = arg;
-
-	return dw_handle_msi_irq(pp);
-}
-
 static int dw_plat_pcie_host_init(struct pcie_port *pp)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
@@ -63,15 +56,6 @@ static int dw_plat_add_pcie_port(struct pcie_port *pp,
 		pp->msi_irq = platform_get_irq(pdev, 0);
 		if (pp->msi_irq < 0)
 			return pp->msi_irq;
-
-		ret = devm_request_irq(dev, pp->msi_irq,
-					dw_plat_pcie_msi_irq_handler,
-					IRQF_SHARED | IRQF_NO_THREAD,
-					"dw-plat-pcie-msi", pp);
-		if (ret) {
-			dev_err(dev, "failed to request MSI IRQ\n");
-			return ret;
-		}
 	}
 
 	pp->root_bus_nr = -1;
drivers/pci/dwc/pcie-designware.h +18 -0
index 11b1386..c80ee86 100644
@@ -114,6 +114,7 @@
  */
 #define MAX_MSI_IRQS			32
 #define MAX_MSI_CTRLS			(MAX_MSI_IRQS / 32)
+#define MSI_DEF_NUM_VECTORS		32
 
 /* Maximum number of inbound/outbound iATUs */
 #define MAX_IATU_IN			256
@@ -149,7 +150,9 @@ struct dw_pcie_host_ops {
 	phys_addr_t (*get_msi_addr)(struct pcie_port *pp);
 	u32 (*get_msi_data)(struct pcie_port *pp, int pos);
 	void (*scan_bus)(struct pcie_port *pp);
+	void (*set_num_vectors)(struct pcie_port *pp);
 	int (*msi_host_init)(struct pcie_port *pp, struct msi_controller *chip);
+	void (*msi_irq_ack)(int irq, struct pcie_port *pp);
 };
 
 struct pcie_port {
@@ -174,7 +177,11 @@ struct pcie_port {
 	const struct dw_pcie_host_ops *ops;
 	int			msi_irq;
 	struct irq_domain	*irq_domain;
+	struct irq_domain	*msi_domain;
 	dma_addr_t		msi_data;
+	u32			num_vectors;
+	u32			irq_status[MAX_MSI_CTRLS];
+	raw_spinlock_t		lock;
 	DECLARE_BITMAP(msi_irq_in_use, MAX_MSI_IRQS);
 };
 
@@ -316,8 +323,10 @@ static inline void dw_pcie_dbi_ro_wr_dis(struct dw_pcie *pci)
 #ifdef CONFIG_PCIE_DW_HOST
 irqreturn_t dw_handle_msi_irq(struct pcie_port *pp);
 void dw_pcie_msi_init(struct pcie_port *pp);
+void dw_pcie_free_msi(struct pcie_port *pp);
 void dw_pcie_setup_rc(struct pcie_port *pp);
 int dw_pcie_host_init(struct pcie_port *pp);
+int dw_pcie_allocate_domains(struct pcie_port *pp);
 #else
 static inline irqreturn_t dw_handle_msi_irq(struct pcie_port *pp)
 {
@@ -328,6 +337,10 @@ static inline void dw_pcie_msi_init(struct pcie_port *pp)
 {
 }
 
+static inline void dw_pcie_free_msi(struct pcie_port *pp)
+{
+}
+
 static inline void dw_pcie_setup_rc(struct pcie_port *pp)
 {
 }
@@ -336,6 +349,11 @@ static inline int dw_pcie_host_init(struct pcie_port *pp)
 {
 	return 0;
 }
+
+static inline int dw_pcie_allocate_domains(struct pcie_port *pp)
+{
+	return 0;
+}
 #endif
 
 #ifdef CONFIG_PCIE_DW_EP
drivers/pci/dwc/pcie-histb.c +0 -15
index 70b5c0b..5d47b90 100644
@@ -207,13 +207,6 @@ static struct dw_pcie_host_ops histb_pcie_host_ops = {
 	.host_init = histb_pcie_host_init,
 };
 
-static irqreturn_t histb_pcie_msi_irq_handler(int irq, void *arg)
-{
-	struct pcie_port *pp = arg;
-
-	return dw_handle_msi_irq(pp);
-}
-
 static void histb_pcie_host_disable(struct histb_pcie *hipcie)
 {
 	reset_control_assert(hipcie->soft_reset);
@@ -393,14 +386,6 @@ static int histb_pcie_probe(struct platform_device *pdev)
 			dev_err(dev, "Failed to get MSI IRQ\n");
 			return pp->msi_irq;
 		}
-
-		ret = devm_request_irq(dev, pp->msi_irq,
-				       histb_pcie_msi_irq_handler,
-				       IRQF_SHARED, "histb-pcie-msi", pp);
-		if (ret) {
-			dev_err(dev, "cannot request MSI IRQ\n");
-			return ret;
-		}
 	}
 
 	hipcie->phy = devm_phy_get(dev, "phy");
drivers/pci/dwc/pcie-qcom.c +0 -16
index 6310c66..89e5cc5 100644
@@ -180,13 +180,6 @@ static void qcom_ep_reset_deassert(struct qcom_pcie *pcie)
 	usleep_range(PERST_DELAY_US, PERST_DELAY_US + 500);
 }
 
-static irqreturn_t qcom_pcie_msi_irq_handler(int irq, void *arg)
-{
-	struct pcie_port *pp = arg;
-
-	return dw_handle_msi_irq(pp);
-}
-
 static int qcom_pcie_establish_link(struct qcom_pcie *pcie)
 {
 	struct dw_pcie *pci = pcie->pci;
@@ -1262,15 +1255,6 @@ static int qcom_pcie_probe(struct platform_device *pdev)
 		pp->msi_irq = platform_get_irq_byname(pdev, "msi");
 		if (pp->msi_irq < 0)
 			return pp->msi_irq;
-
-		ret = devm_request_irq(dev, pp->msi_irq,
-				       qcom_pcie_msi_irq_handler,
-				       IRQF_SHARED | IRQF_NO_THREAD,
-				       "qcom-pcie-msi", pp);
-		if (ret) {
-			dev_err(dev, "cannot request msi irq\n");
-			return ret;
-		}
 	}
 
 	ret = phy_init(pcie->phy);
Signature · 1 line
2.7.4
#2 lore raw

Re: [PATCH v10 1/3] PCI: dwc: Move MSI IRQs allocation to IRQ domains hierarchical API

Am Dienstag, den 06.03.2018, 11:54 +0000 schrieb Gustavo Pimentel:

Quoted 18 lines

Implement a multiplexed IRQ domain hierarchy API in the pcie-designware host bridge driver that funnels all MSI IRQs into a single parent interrupt, moving away from the obsolete struct msi_controller based API.

Although the old implementation API is still available, pcie-designware will now use the multiplexed IRQ domains hierarchical API.

Remove all existing dwc based host bridges MSI IRQs handlers, in that the hierarchical API now handles MSI IRQs through the hierarchical/chained MSI domain implementation.

Quoted 5 lines

---

[...]

Quoted 17 lines

+static int dw_pcie_irq_domain_alloc(struct irq_domain *domain,

drivers/pci/dwc/pcie-designware-host.c irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) · line 223

Quoted 2 lines
drivers/pci/dwc/pcie-designware-host.c +2 -0
+				    unsigned int virq, unsigned int nr_irqs,
+				    void *args)

+{

drivers/pci/dwc/pcie-designware-host.c irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) · line 228

Quoted 4 lines
drivers/pci/dwc/pcie-designware-host.c +4 -0
+	struct pcie_port *pp = domain->host_data;
+	unsigned long flags;
+	unsigned long bit;
+	u32 i;

+

Review

Quoted 1 line
(quoted diff) +1 -0
+	raw_spin_lock_irqsave(&pp->lock, flags);

+

Review

Quoted 2 lines
(quoted diff) +2 -0
+	bit = bitmap_find_free_region(pp->msi_irq_in_use, pp->num_vectors,
+				      order_base_2(nr_irqs));

+

Review

Quoted 1 line
(quoted diff) +1 -0
+	raw_spin_unlock_irqrestore(&pp->lock, flags);

+

Quoted 1 line
drivers/pci/dwc/pcie-designware-host.c +1 -0
+	if (bit < 0)

drivers/pci/dwc/pcie-designware-host.c irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) · line 238

Quoted 1 line
drivers/pci/dwc/pcie-designware-host.c +1 -0
+		return -ENOSPC;

bit is an unsigned variable here, so this condition will never be true.

Quoted 9 lines

+

drivers/pci/dwc/pcie-designware-host.c irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) · line 244

Quoted 5 lines
drivers/pci/dwc/pcie-designware-host.c +5 -0
+	for (i = 0; i < nr_irqs; i++)
+		irq_domain_set_info(domain, virq + i, bit + i,
+				    &dw_pci_msi_bottom_irq_chip,
+				    pp, handle_edge_irq,
+				    NULL, NULL);

+

Review

Quoted 1 line
(quoted diff) +1 -0
+	return 0;

+}

Regards,
Lucas

#3 lore raw

Re: [PATCH v10 1/3] PCI: dwc: Move MSI IRQs allocation to IRQ domains hierarchical API

Quoted 34 lines · Lucas Stach

Am Dienstag, den 06.03.2018, 11:54 +0000 schrieb Gustavo Pimentel:

Quoted 18 lines

Implement a multiplexed IRQ domain hierarchy API in the pcie-designware host bridge driver that funnels all MSI IRQs into a single parent interrupt, moving away from the obsolete struct msi_controller based API.

Although the old implementation API is still available, pcie-designware will now use the multiplexed IRQ domains hierarchical API.

Remove all existing dwc based host bridges MSI IRQs handlers, in that the hierarchical API now handles MSI IRQs through the hierarchical/chained MSI domain implementation.

Quoted 5 lines

---

[...]

Quoted 14 lines

+static int dw_pcie_irq_domain_alloc(struct irq_domain *domain,

drivers/pci/dwc/pcie-designware-host.c irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) · line 223

Quoted 2 lines
drivers/pci/dwc/pcie-designware-host.c +2 -0
+				    unsigned int virq, unsigned int nr_irqs,
+				    void *args)

+{

drivers/pci/dwc/pcie-designware-host.c irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) · line 228

Quoted 4 lines
drivers/pci/dwc/pcie-designware-host.c +4 -0
+	struct pcie_port *pp = domain->host_data;
+	unsigned long flags;
+	unsigned long bit;
+	u32 i;

+

Review

Quoted 1 line
(quoted diff) +1 -0
+	raw_spin_lock_irqsave(&pp->lock, flags);

+

Review

Quoted 2 lines
(quoted diff) +2 -0
+	bit = bitmap_find_free_region(pp->msi_irq_in_use, pp->num_vectors,
+				      order_base_2(nr_irqs));

+

Quoted 6 lines

drivers/pci/dwc/pcie-designware-host.c irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) · line 238

Quoted 4 lines

Review

Quoted 1 line
(quoted diff) +1 -0
+	raw_spin_unlock_irqrestore(&pp->lock, flags);

+

Quoted 1 line
drivers/pci/dwc/pcie-designware-host.c +1 -0
+	if (bit < 0)
drivers/pci/dwc/pcie-designware-host.c +1 -0
+		return -ENOSPC;

bit is an unsigned variable here, so this condition will never be true.

I have fixed it up in my pci/dwc-msi branch, thanks for reporting it.

Lorenzo

Quoted 12 lines
Quoted 9 lines

+

drivers/pci/dwc/pcie-designware-host.c irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) · line 244

Quoted 5 lines
drivers/pci/dwc/pcie-designware-host.c +5 -0
+	for (i = 0; i < nr_irqs; i++)
+		irq_domain_set_info(domain, virq + i, bit + i,
+				    &dw_pci_msi_bottom_irq_chip,
+				    pp, handle_edge_irq,
+				    NULL, NULL);

+

Review

Quoted 1 line
(quoted diff) +1 -0
+	return 0;

+}

Regards,
Lucas

#4 lore raw

Re: [PATCH v10 1/3] PCI: dwc: Move MSI IRQs allocation to IRQ domains hierarchical API

Quoted 35 lines · Lorenzo Pieralisi
Quoted 34 lines · Lucas Stach

Am Dienstag, den 06.03.2018, 11:54 +0000 schrieb Gustavo Pimentel:

Quoted 18 lines

Implement a multiplexed IRQ domain hierarchy API in the pcie-designware host bridge driver that funnels all MSI IRQs into a single parent interrupt, moving away from the obsolete struct msi_controller based API.

Although the old implementation API is still available, pcie-designware will now use the multiplexed IRQ domains hierarchical API.

Remove all existing dwc based host bridges MSI IRQs handlers, in that the hierarchical API now handles MSI IRQs through the hierarchical/chained MSI domain implementation.

Quoted 5 lines

---

[...]

Quoted 14 lines

+static int dw_pcie_irq_domain_alloc(struct irq_domain *domain,

drivers/pci/dwc/pcie-designware-host.c irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) · line 223

Quoted 2 lines
drivers/pci/dwc/pcie-designware-host.c +2 -0
+				    unsigned int virq, unsigned int nr_irqs,
+				    void *args)

+{

drivers/pci/dwc/pcie-designware-host.c irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) · line 228

Quoted 4 lines
drivers/pci/dwc/pcie-designware-host.c +4 -0
+	struct pcie_port *pp = domain->host_data;
+	unsigned long flags;
+	unsigned long bit;
+	u32 i;

+

Review

Quoted 1 line
(quoted diff) +1 -0
+	raw_spin_lock_irqsave(&pp->lock, flags);

+

Review

Quoted 2 lines
(quoted diff) +2 -0
+	bit = bitmap_find_free_region(pp->msi_irq_in_use, pp->num_vectors,
+				      order_base_2(nr_irqs));

+

Quoted 8 lines
Quoted 6 lines

drivers/pci/dwc/pcie-designware-host.c irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) · line 238

Quoted 4 lines

Review

Quoted 1 line
(quoted diff) +1 -0
+	raw_spin_unlock_irqrestore(&pp->lock, flags);

+

Quoted 1 line
drivers/pci/dwc/pcie-designware-host.c +1 -0
+	if (bit < 0)
drivers/pci/dwc/pcie-designware-host.c +1 -0
+		return -ENOSPC;

bit is an unsigned variable here, so this condition will never be true.

I have fixed it up in my pci/dwc-msi branch, thanks for reporting it.

Thanks Lucas and Lorenzo

Quoted 15 lines

Lorenzo

Quoted 12 lines
Quoted 9 lines

+

drivers/pci/dwc/pcie-designware-host.c irqreturn_t dw_handle_msi_irq(struct pcie_port *pp) · line 244

Quoted 5 lines
drivers/pci/dwc/pcie-designware-host.c +5 -0
+	for (i = 0; i < nr_irqs; i++)
+		irq_domain_set_info(domain, virq + i, bit + i,
+				    &dw_pci_msi_bottom_irq_chip,
+				    pp, handle_edge_irq,
+				    NULL, NULL);

+

Review

Quoted 1 line
(quoted diff) +1 -0
+	return 0;

+}

Regards,
Lucas

#5 lore raw

PATCH v10 2/3 PCI: dwc: Remove old MSI IRQs API

In reply to Gustavo Pimentel

Remove the unused old MSI IRQs API from pcie-designware based on struct msi_controller that should now be considered obsolete.

---
Change v1->v2:
- Nothing changed, just to follow the patch set version.
Change v2->v3:
- Nothing changed, just to follow the patch set version.
Change v3->v4:
- Patch renamed from v3-0008 to v4-0009.
- Changed summary line to match the drivers/PCI convention and changelog to maintain the consistency (thanks Bjorn).
Change v4->v5:
- Nothing changed, just to follow the patch set version.
Change v5->v6:
- Nothing changed, just to follow the patch set version.
Change v6->v7:
- Nothing changed, just to follow the patch set version.
Change v7->v8:
- Rebased against v4.16-rc1.
Change v8->v9:
- Changed patch indexation, due patch series squash.
Change v9->v10:
- Log commit rewrite to be accurate by Lorenzo (thanks Lorenzo).

---
 drivers/pci/dwc/pci-keystone-dw.c      |   2 +-
 drivers/pci/dwc/pci-keystone.h         |   3 +-
 drivers/pci/dwc/pci-layerscape.c       |   3 +-
 drivers/pci/dwc/pcie-designware-host.c | 190 +--------------------------------
 drivers/pci/dwc/pcie-designware.h      |   2 +-
 5 files changed, 5 insertions(+), 195 deletions(-)
drivers/pci/dwc/pci-keystone-dw.c +1 -1
index 86e613a..0682213 100644
@@ -157,7 +157,7 @@ void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq)
 			 BIT(bit_pos));
 }
 
-int ks_dw_pcie_msi_host_init(struct pcie_port *pp, struct msi_controller *chip)
+int ks_dw_pcie_msi_host_init(struct pcie_port *pp)
 {
 	return dw_pcie_allocate_domains(pp);
 }
drivers/pci/dwc/pci-keystone.h +1 -2
index aa50448..8a13da3 100644
@@ -53,6 +53,5 @@ void ks_dw_pcie_msi_irq_ack(int i, struct pcie_port *pp);
 void ks_dw_pcie_msi_set_irq(struct pcie_port *pp, int irq);
 void ks_dw_pcie_msi_clear_irq(struct pcie_port *pp, int irq);
 void ks_dw_pcie_v3_65_scan_bus(struct pcie_port *pp);
-int ks_dw_pcie_msi_host_init(struct pcie_port *pp,
-		struct msi_controller *chip);
+int ks_dw_pcie_msi_host_init(struct pcie_port *pp);
 int ks_dw_pcie_link_up(struct dw_pcie *pci);
drivers/pci/dwc/pci-layerscape.c +1 -2
index a7b4159..3724d3e 100644
@@ -182,8 +182,7 @@ static int ls1021_pcie_host_init(struct pcie_port *pp)
 	return ls_pcie_host_init(pp);
 }
 
-static int ls_pcie_msi_host_init(struct pcie_port *pp,
-				 struct msi_controller *chip)
+static int ls_pcie_msi_host_init(struct pcie_port *pp)
 {
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 	struct device *dev = pci->dev;
drivers/pci/dwc/pcie-designware-host.c +1 -189

208 lines not on this page · raw message

drivers/pci/dwc/pcie-designware.h +1 -1
index c80ee86..923f956 100644
@@ -151,7 +151,7 @@ struct dw_pcie_host_ops {
 	u32 (*get_msi_data)(struct pcie_port *pp, int pos);
 	void (*scan_bus)(struct pcie_port *pp);
 	void (*set_num_vectors)(struct pcie_port *pp);
-	int (*msi_host_init)(struct pcie_port *pp, struct msi_controller *chip);
+	int (*msi_host_init)(struct pcie_port *pp);
 	void (*msi_irq_ack)(int irq, struct pcie_port *pp);
 };
 
Signature · 1 line
2.7.4
#6 lore raw

PATCH v10 3/3 PCI: dwc: Expand maximum number of MSI IRQs from 32 to 256

In reply to Gustavo Pimentel

The Synopsys PCIe Root Complex supports up to MSI 256 IRQs distributed over 8 controller registers, therefore the maximum number of MSI IRQs can be changed to 256. The number of controllers can be calculated based on the number of vectors used by the specific SoC driver.

Update the dwc host bridge driver maximum number of supported MSI IRQs.

---
Change v1->v2:
- New patch file.
Change v2->v3:
- Nothing changed, just to follow the patch set version.
Change v3->v4:
- Patch renamed from v3-0009 to v4-0010.
- Changed summary line to match the drivers/PCI convention and changelog to maintain the consistency (thanks Bjorn).
Change v4->v5:
- Nothing changed, just to follow the patch set version.
Change v5->v6:
- Nothing changed, just to follow the patch set version.
Change v6->v7:
- Nothing changed, just to follow the patch set version.
Change v7->v8:
- Rebased against v4.16-rc1.
Change v8->v9:
- Changed patch indexation, due patch series squash.
Change v9->v10:
- Log commit rewrite to be accurate by Lorenzo (thanks Lorenzo).

 drivers/pci/dwc/pcie-designware-host.c | 12 ++++++++----
 drivers/pci/dwc/pcie-designware.h      | 10 +++-------
 2 files changed, 11 insertions(+), 11 deletions(-)
drivers/pci/dwc/pcie-designware-host.c +8 -4
index 7cf39c9..6df6275 100644
@@ -76,11 +76,13 @@ static struct msi_domain_info dw_pcie_msi_domain_info = {
 /* MSI int handler */
 irqreturn_t dw_handle_msi_irq(struct pcie_port *pp)
 {
-	u32 val;
 	int i, pos, irq;
+	u32 val, num_ctrls;
 	irqreturn_t ret = IRQ_NONE;
 
-	for (i = 0; i < MAX_MSI_CTRLS; i++) {
+	num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL;
+
+	for (i = 0; i < num_ctrls; i++) {
 		dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_STATUS + i * 12, 4,
 				    &val);
 		if (!val)
@@ -639,13 +641,15 @@ static u8 dw_pcie_iatu_unroll_enabled(struct dw_pcie *pci)
 
 void dw_pcie_setup_rc(struct pcie_port *pp)
 {
-	u32 val, ctrl;
+	u32 val, ctrl, num_ctrls;
 	struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
 
 	dw_pcie_setup(pci);
 
+	num_ctrls = pp->num_vectors / MAX_MSI_IRQS_PER_CTRL;
+
 	/* Initialize IRQ Status array */
-	for (ctrl = 0; ctrl < MAX_MSI_CTRLS; ctrl++)
+	for (ctrl = 0; ctrl < num_ctrls; ctrl++)
 		dw_pcie_rd_own_conf(pp, PCIE_MSI_INTR0_ENABLE + (ctrl * 12), 4,
 				    &pp->irq_status[ctrl]);
 	/* setup RC BARs */
drivers/pci/dwc/pcie-designware.h +3 -7
index 923f956..fe811db 100644
@@ -107,13 +107,9 @@
 #define MSI_MESSAGE_DATA_32		0x58
 #define MSI_MESSAGE_DATA_64		0x5C
 
-/*
- * Maximum number of MSI IRQs can be 256 per controller. But keep
- * it 32 as of now. Probably we will never need more than 32. If needed,
- * then increment it in multiple of 32.
- */
-#define MAX_MSI_IRQS			32
-#define MAX_MSI_CTRLS			(MAX_MSI_IRQS / 32)
+#define MAX_MSI_IRQS			256
+#define MAX_MSI_IRQS_PER_CTRL		32
+#define MAX_MSI_CTRLS			(MAX_MSI_IRQS / MAX_MSI_IRQS_PER_CTRL)
 #define MSI_DEF_NUM_VECTORS		32
 
 /* Maximum number of inbound/outbound iATUs */
Signature · 1 line
2.7.4