summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorBjorn Helgaas <bhelgaas@google.com>2026-06-23 17:32:05 -0500
committerBjorn Helgaas <bhelgaas@google.com>2026-06-23 17:32:05 -0500
commitbcb446d61dd2eba82605a4fa04360d98ada1638f (patch)
tree7b2003991f649f5fce036151f1f6721a6a25c34c
parentbf27eed0409340c168a075ddf0007b6b15efd9a8 (diff)
parent26b67fa10ef84ea667942491b50e6261a45f098d (diff)
downloadlwn-bcb446d61dd2eba82605a4fa04360d98ada1638f.tar.gz
lwn-bcb446d61dd2eba82605a4fa04360d98ada1638f.zip
Merge branch 'pci/controller/dwc'
- Apply ECRC TLP Digest workaround for all DesignWare cores prior to 5.10a, not just 4.90a and 5.00a (Manikanta Maddireddy) - Use common struct dw_pcie 'mode' rather than duplicating it in artpec6, dra7xx, dwc-pcie, and keembay driver structs (Hans Zhang) - Use DEFINE_SHOW_ATTRIBUTE for ltssm_status debugfs to reduce boilerplate and fix a seq_file memory leak by including a .release() callback (Hans Zhang) - Fix a signedness bug in fault injection test code (Dan Carpenter) - Avoid NULL pointer dereference when tearing down debugfs for controller that lacks RAS DES capability (Shuvam Pandey) * pci/controller/dwc: PCI: dwc: Avoid dwc_pcie_rasdes_debugfs_deinit() NULL dereference when no RAS DES capability PCI: dwc: Fix signedness bug in fault injection test code PCI: dwc: Use DEFINE_SHOW_ATTRIBUTE for ltssm_status debugfs PCI: keembay: Use common mode field in struct dw_pcie PCI: dwc: Use common mode field in struct dw_pcie PCI: artpec6: Use common mode field in struct dw_pcie PCI: dra7xx: Use common mode field in struct dw_pcie PCI: dwc: Apply ECRC workaround for DesignWare cores prior to 5.10a
-rw-r--r--drivers/pci/controller/dwc/pci-dra7xx.c11
-rw-r--r--drivers/pci/controller/dwc/pcie-artpec6.c9
-rw-r--r--drivers/pci/controller/dwc/pcie-designware-debugfs.c22
-rw-r--r--drivers/pci/controller/dwc/pcie-designware-plat.c7
-rw-r--r--drivers/pci/controller/dwc/pcie-designware.c16
-rw-r--r--drivers/pci/controller/dwc/pcie-designware.h1
-rw-r--r--drivers/pci/controller/dwc/pcie-keembay.c9
7 files changed, 34 insertions, 41 deletions
diff --git a/drivers/pci/controller/dwc/pci-dra7xx.c b/drivers/pci/controller/dwc/pci-dra7xx.c
index cd904659c321..3fc889944f02 100644
--- a/drivers/pci/controller/dwc/pci-dra7xx.c
+++ b/drivers/pci/controller/dwc/pci-dra7xx.c
@@ -92,7 +92,6 @@ struct dra7xx_pcie {
struct phy **phy;
struct irq_domain *irq_domain;
struct clk *clk;
- enum dw_pcie_device_mode mode;
};
struct dra7xx_pcie_of_data {
@@ -328,7 +327,7 @@ static irqreturn_t dra7xx_pcie_irq_handler(int irq, void *arg)
dev_dbg(dev, "Link Request Reset\n");
if (reg & LINK_UP_EVT) {
- if (dra7xx->mode == DW_PCIE_EP_TYPE)
+ if (dra7xx->pci->mode == DW_PCIE_EP_TYPE)
dw_pcie_ep_linkup(ep);
dev_dbg(dev, "Link-up state change\n");
}
@@ -828,7 +827,7 @@ static int dra7xx_pcie_probe(struct platform_device *pdev)
default:
dev_err(dev, "INVALID device type %d\n", mode);
}
- dra7xx->mode = mode;
+ dra7xx->pci->mode = mode;
ret = devm_request_threaded_irq(dev, irq, NULL, dra7xx_pcie_irq_handler,
IRQF_SHARED | IRQF_ONESHOT,
@@ -841,7 +840,7 @@ static int dra7xx_pcie_probe(struct platform_device *pdev)
return 0;
err_deinit:
- if (dra7xx->mode == DW_PCIE_RC_TYPE)
+ if (dra7xx->pci->mode == DW_PCIE_RC_TYPE)
dw_pcie_host_deinit(&dra7xx->pci->pp);
else
dw_pcie_ep_deinit(&dra7xx->pci->ep);
@@ -865,7 +864,7 @@ static int dra7xx_pcie_suspend(struct device *dev)
struct dw_pcie *pci = dra7xx->pci;
u32 val;
- if (dra7xx->mode != DW_PCIE_RC_TYPE)
+ if (pci->mode != DW_PCIE_RC_TYPE)
return 0;
/* clear MSE */
@@ -882,7 +881,7 @@ static int dra7xx_pcie_resume(struct device *dev)
struct dw_pcie *pci = dra7xx->pci;
u32 val;
- if (dra7xx->mode != DW_PCIE_RC_TYPE)
+ if (pci->mode != DW_PCIE_RC_TYPE)
return 0;
/* set MSE */
diff --git a/drivers/pci/controller/dwc/pcie-artpec6.c b/drivers/pci/controller/dwc/pcie-artpec6.c
index 55cb957ae1f3..5cd227dda9a1 100644
--- a/drivers/pci/controller/dwc/pcie-artpec6.c
+++ b/drivers/pci/controller/dwc/pcie-artpec6.c
@@ -34,7 +34,6 @@ struct artpec6_pcie {
struct regmap *regmap; /* DT axis,syscon-pcie */
void __iomem *phy_base; /* DT phy */
enum artpec_pcie_variants variant;
- enum dw_pcie_device_mode mode;
};
struct artpec_pcie_of_data {
@@ -100,7 +99,7 @@ static u64 artpec6_pcie_cpu_addr_fixup(struct dw_pcie *pci, u64 cpu_addr)
struct dw_pcie_rp *pp = &pci->pp;
struct dw_pcie_ep *ep = &pci->ep;
- switch (artpec6_pcie->mode) {
+ switch (artpec6_pcie->pci->mode) {
case DW_PCIE_RC_TYPE:
return cpu_addr - pp->cfg0_base;
case DW_PCIE_EP_TYPE:
@@ -413,7 +412,7 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
artpec6_pcie->pci = pci;
artpec6_pcie->variant = variant;
- artpec6_pcie->mode = mode;
+ artpec6_pcie->pci->mode = mode;
artpec6_pcie->phy_base =
devm_platform_ioremap_resource_byname(pdev, "phy");
@@ -428,7 +427,7 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, artpec6_pcie);
- switch (artpec6_pcie->mode) {
+ switch (artpec6_pcie->pci->mode) {
case DW_PCIE_RC_TYPE:
if (!IS_ENABLED(CONFIG_PCIE_ARTPEC6_HOST))
return -ENODEV;
@@ -464,7 +463,7 @@ static int artpec6_pcie_probe(struct platform_device *pdev)
break;
default:
- dev_err(dev, "INVALID device type %d\n", artpec6_pcie->mode);
+ dev_err(dev, "INVALID device type %d\n", artpec6_pcie->pci->mode);
}
return 0;
diff --git a/drivers/pci/controller/dwc/pcie-designware-debugfs.c b/drivers/pci/controller/dwc/pcie-designware-debugfs.c
index d0884253be97..c24cbc4677a3 100644
--- a/drivers/pci/controller/dwc/pcie-designware-debugfs.c
+++ b/drivers/pci/controller/dwc/pcie-designware-debugfs.c
@@ -306,6 +306,7 @@ static ssize_t err_inj_write(struct file *file, const char __user *buf,
u32 val, counter, vc_num, err_group, type_mask;
int val_diff = 0;
char *kern_buf;
+ int ret;
err_group = err_inj_list[pdata->idx].err_inj_group;
type_mask = err_inj_type_mask[err_group];
@@ -327,10 +328,10 @@ static ssize_t err_inj_write(struct file *file, const char __user *buf,
return -EINVAL;
}
} else {
- val = kstrtou32(kern_buf, 0, &counter);
- if (val) {
+ ret = kstrtou32(kern_buf, 0, &counter);
+ if (ret) {
kfree(kern_buf);
- return val;
+ return ret;
}
}
@@ -507,11 +508,6 @@ static int ltssm_status_show(struct seq_file *s, void *v)
return 0;
}
-static int ltssm_status_open(struct inode *inode, struct file *file)
-{
- return single_open(file, ltssm_status_show, inode->i_private);
-}
-
#define dwc_debugfs_create(name) \
debugfs_create_file(#name, 0644, rasdes_debug, pci, \
&dbg_ ## name ## _fops)
@@ -548,15 +544,15 @@ static const struct file_operations dwc_pcie_counter_value_ops = {
.read = counter_value_read,
};
-static const struct file_operations dwc_pcie_ltssm_status_ops = {
- .open = ltssm_status_open,
- .read = seq_read,
-};
+DEFINE_SHOW_ATTRIBUTE(ltssm_status);
static void dwc_pcie_rasdes_debugfs_deinit(struct dw_pcie *pci)
{
struct dwc_pcie_rasdes_info *rinfo = pci->debugfs->rasdes_info;
+ if (!rinfo)
+ return;
+
mutex_destroy(&rinfo->reg_event_lock);
}
@@ -642,7 +638,7 @@ err_deinit:
static void dwc_pcie_ltssm_debugfs_init(struct dw_pcie *pci, struct dentry *dir)
{
debugfs_create_file("ltssm_status", 0444, dir, pci,
- &dwc_pcie_ltssm_status_ops);
+ &ltssm_status_fops);
}
static int dw_pcie_ptm_check_capability(void *drvdata)
diff --git a/drivers/pci/controller/dwc/pcie-designware-plat.c b/drivers/pci/controller/dwc/pcie-designware-plat.c
index d103ab759c4e..d02286678a0a 100644
--- a/drivers/pci/controller/dwc/pcie-designware-plat.c
+++ b/drivers/pci/controller/dwc/pcie-designware-plat.c
@@ -22,7 +22,6 @@
struct dw_plat_pcie {
struct dw_pcie *pci;
- enum dw_pcie_device_mode mode;
};
struct dw_plat_pcie_of_data {
@@ -118,11 +117,11 @@ static int dw_plat_pcie_probe(struct platform_device *pdev)
pci->dev = dev;
dw_plat_pcie->pci = pci;
- dw_plat_pcie->mode = mode;
+ dw_plat_pcie->pci->mode = mode;
platform_set_drvdata(pdev, dw_plat_pcie);
- switch (dw_plat_pcie->mode) {
+ switch (dw_plat_pcie->pci->mode) {
case DW_PCIE_RC_TYPE:
if (!IS_ENABLED(CONFIG_PCIE_DW_PLAT_HOST))
return -ENODEV;
@@ -148,7 +147,7 @@ static int dw_plat_pcie_probe(struct platform_device *pdev)
break;
default:
- dev_err(dev, "INVALID device type %d\n", dw_plat_pcie->mode);
+ dev_err(dev, "INVALID device type %d\n", dw_plat_pcie->pci->mode);
ret = -EINVAL;
break;
}
diff --git a/drivers/pci/controller/dwc/pcie-designware.c b/drivers/pci/controller/dwc/pcie-designware.c
index 22164e0068a9..89f2934c7cce 100644
--- a/drivers/pci/controller/dwc/pcie-designware.c
+++ b/drivers/pci/controller/dwc/pcie-designware.c
@@ -491,13 +491,13 @@ static inline void dw_pcie_writel_atu_ob(struct dw_pcie *pci, u32 index, u32 reg
static inline u32 dw_pcie_enable_ecrc(u32 val)
{
/*
- * DWC versions 0x3530302a and 0x3536322a have a design issue where
- * the 'TD' bit in the Control register-1 of the ATU outbound
- * region acts like an override for the ECRC setting, i.e., the
- * presence of TLP Digest (ECRC) in the outgoing TLPs is solely
- * determined by this bit. This is contrary to the PCIe spec which
- * says that the enablement of the ECRC is solely determined by the
- * AER registers.
+ * DesignWare core versions prior to 5.10A have a design issue where the
+ * 'TD' bit in the Control register-1 of the ATU outbound region acts
+ * like an override for the ECRC setting, i.e., the presence of TLP
+ * Digest (ECRC) in the outgoing TLPs is solely determined by this
+ * bit. This is contrary to the PCIe spec which says that the
+ * enablement of the ECRC is solely determined by the AER
+ * registers.
*
* Because of this, even when the ECRC is enabled through AER
* registers, the transactions going through ATU won't have TLP
@@ -567,7 +567,7 @@ int dw_pcie_prog_outbound_atu(struct dw_pcie *pci,
if (upper_32_bits(limit_addr) > upper_32_bits(parent_bus_addr) &&
dw_pcie_ver_is_ge(pci, 460A))
val |= PCIE_ATU_INCREASE_REGION_SIZE;
- if (dw_pcie_ver_is(pci, 490A) || dw_pcie_ver_is(pci, 500A))
+ if (!dw_pcie_ver_is_ge(pci, 510A))
val = dw_pcie_enable_ecrc(val);
dw_pcie_writel_atu_ob(pci, atu->index, PCIE_ATU_REGION_CTRL1, val);
diff --git a/drivers/pci/controller/dwc/pcie-designware.h b/drivers/pci/controller/dwc/pcie-designware.h
index f3314ceff8d7..7f4bb88c7b22 100644
--- a/drivers/pci/controller/dwc/pcie-designware.h
+++ b/drivers/pci/controller/dwc/pcie-designware.h
@@ -35,6 +35,7 @@
#define DW_PCIE_VER_480A 0x3438302a
#define DW_PCIE_VER_490A 0x3439302a
#define DW_PCIE_VER_500A 0x3530302a
+#define DW_PCIE_VER_510A 0x3531302a
#define DW_PCIE_VER_520A 0x3532302a
#define DW_PCIE_VER_540A 0x3534302a
#define DW_PCIE_VER_562A 0x3536322a
diff --git a/drivers/pci/controller/dwc/pcie-keembay.c b/drivers/pci/controller/dwc/pcie-keembay.c
index 7cf2c312ecec..2459c4d66b88 100644
--- a/drivers/pci/controller/dwc/pcie-keembay.c
+++ b/drivers/pci/controller/dwc/pcie-keembay.c
@@ -58,7 +58,6 @@
struct keembay_pcie {
struct dw_pcie pci;
void __iomem *apb_base;
- enum dw_pcie_device_mode mode;
struct clk *clk_master;
struct clk *clk_aux;
@@ -117,7 +116,7 @@ static int keembay_pcie_start_link(struct dw_pcie *pci)
u32 val;
int ret;
- if (pcie->mode == DW_PCIE_EP_TYPE)
+ if (pcie->pci.mode == DW_PCIE_EP_TYPE)
return 0;
keembay_pcie_ltssm_set(pcie, false);
@@ -409,7 +408,7 @@ static int keembay_pcie_probe(struct platform_device *pdev)
pci->dev = dev;
pci->ops = &keembay_pcie_ops;
- pcie->mode = mode;
+ pcie->pci.mode = mode;
pcie->apb_base = devm_platform_ioremap_resource_byname(pdev, "apb");
if (IS_ERR(pcie->apb_base))
@@ -417,7 +416,7 @@ static int keembay_pcie_probe(struct platform_device *pdev)
platform_set_drvdata(pdev, pcie);
- switch (pcie->mode) {
+ switch (pcie->pci.mode) {
case DW_PCIE_RC_TYPE:
if (!IS_ENABLED(CONFIG_PCIE_KEEMBAY_HOST))
return -ENODEV;
@@ -443,7 +442,7 @@ static int keembay_pcie_probe(struct platform_device *pdev)
break;
default:
- dev_err(dev, "Invalid device type %d\n", pcie->mode);
+ dev_err(dev, "Invalid device type %d\n", pcie->pci.mode);
return -ENODEV;
}