]> git.ipfire.org Git - thirdparty/kernel/linux.git/commitdiff
PCI: dwc: Disable BARs in common code instead of in each glue driver
authorNiklas Cassel <cassel@kernel.org>
Thu, 12 Mar 2026 13:02:35 +0000 (14:02 +0100)
committerManivannan Sadhasivam <mani@kernel.org>
Sun, 15 Mar 2026 16:34:28 +0000 (22:04 +0530)
The current EPC core design relies on an EPC driver disabling all BARs by
default. An EPF driver will then enable the BARs that it wants to enabled.

This design is there because there is no epc->ops->disable_bar().
(There is a epc->ops->clear_bar(), but that is only to disable a BAR that
has been enabled using epc->ops->set_bar() first.)

By default, an EPF driver will not be able to get/enable BARs that are
marked as BAR_RESERVED or BAR_DISABLED (see pci_epc_get_next_free_bar()).

Since the current EPC code design requires an EPC driver to disable all
BARs by default, move this to DWC common code from each glue driver.

BAR_RESERVED BARs are not disabled by default because these BARs are
hardware backed, and should only be disabled explicitly by an EPF driver
if absolutely necessary for the EPF driver to function correctly.
(This is similar to how e.g. NVMe may have vendor specific BARs outside of
the mandatory BAR0 which contains the NVMe registers.)

Note that there is currently no EPC operation to disable a BAR that has not
first been programmed using pci_epc_set_bar(). If an EPF driver ever wants
to disable a BAR marked as BAR_RESERVED, a disable_bar() operation would
have to be added first.

No functional changes intended.

Signed-off-by: Niklas Cassel <cassel@kernel.org>
Signed-off-by: Manivannan Sadhasivam <mani@kernel.org>
Tested-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Tested-by: Koichiro Den <den@valinux.co.jp>
Reviewed-by: Manikanta Maddireddy <mmaddireddy@nvidia.com>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260312130229.2282001-19-cassel@kernel.org
12 files changed:
drivers/pci/controller/dwc/pci-dra7xx.c
drivers/pci/controller/dwc/pci-imx6.c
drivers/pci/controller/dwc/pci-layerscape-ep.c
drivers/pci/controller/dwc/pcie-artpec6.c
drivers/pci/controller/dwc/pcie-designware-ep.c
drivers/pci/controller/dwc/pcie-designware-plat.c
drivers/pci/controller/dwc/pcie-dw-rockchip.c
drivers/pci/controller/dwc/pcie-qcom-ep.c
drivers/pci/controller/dwc/pcie-rcar-gen4.c
drivers/pci/controller/dwc/pcie-stm32-ep.c
drivers/pci/controller/dwc/pcie-tegra194.c
drivers/pci/controller/dwc/pcie-uniphier-ep.c

index d5d26229063f2ad33e6f0279dc59c49cf401aa91..cd904659c32168ee03449c313cc9c5100d7c5c33 100644 (file)
@@ -378,10 +378,6 @@ static void dra7xx_pcie_ep_init(struct dw_pcie_ep *ep)
 {
        struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
        struct dra7xx_pcie *dra7xx = to_dra7xx_pcie(pci);
-       enum pci_barno bar;
-
-       for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
-               dw_pcie_ep_reset_bar(pci, bar);
 
        dra7xx_pcie_enable_wrapper_interrupts(dra7xx);
 }
index ec1e3557ca5356a51a8a774b963590c6e6fa5e90..f5fe5cfc46c73cee3aded5cbe5ba4f2ffda6ce1d 100644 (file)
@@ -1401,15 +1401,6 @@ static const struct dw_pcie_ops dw_pcie_ops = {
        .stop_link = imx_pcie_stop_link,
 };
 
-static void imx_pcie_ep_init(struct dw_pcie_ep *ep)
-{
-       enum pci_barno bar;
-       struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-
-       for (bar = BAR_0; bar <= BAR_5; bar++)
-               dw_pcie_ep_reset_bar(pci, bar);
-}
-
 static int imx_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
                                  unsigned int type, u16 interrupt_num)
 {
@@ -1478,7 +1469,6 @@ imx_pcie_ep_get_features(struct dw_pcie_ep *ep)
 }
 
 static const struct dw_pcie_ep_ops pcie_ep_ops = {
-       .init = imx_pcie_ep_init,
        .raise_irq = imx_pcie_ep_raise_irq,
        .get_features = imx_pcie_ep_get_features,
 };
index 79d226e0cc804285da9927933558645977bc381d..8936975ff104e96d616c03949bb084f6bb93d939 100644 (file)
@@ -152,15 +152,11 @@ static void ls_pcie_ep_init(struct dw_pcie_ep *ep)
        struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
        struct ls_pcie_ep *pcie = to_ls_pcie_ep(pci);
        struct dw_pcie_ep_func *ep_func;
-       enum pci_barno bar;
 
        ep_func = dw_pcie_ep_get_func_from_ep(ep, 0);
        if (!ep_func)
                return;
 
-       for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
-               dw_pcie_ep_reset_bar(pci, bar);
-
        pcie->ls_epc->msi_capable = ep_func->msi_cap ? true : false;
        pcie->ls_epc->msix_capable = ep_func->msix_cap ? true : false;
 }
index e994b75986c34afc25b6e7767220ec1fa4c06025..55cb957ae1f3bdda330d5a9ec21ccc48048ae8ef 100644 (file)
@@ -340,15 +340,11 @@ static void artpec6_pcie_ep_init(struct dw_pcie_ep *ep)
 {
        struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
        struct artpec6_pcie *artpec6_pcie = to_artpec6_pcie(pci);
-       enum pci_barno bar;
 
        artpec6_pcie_assert_core_reset(artpec6_pcie);
        artpec6_pcie_init_phy(artpec6_pcie);
        artpec6_pcie_deassert_core_reset(artpec6_pcie);
        artpec6_pcie_wait_for_phy(artpec6_pcie);
-
-       for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
-               dw_pcie_ep_reset_bar(pci, bar);
 }
 
 static int artpec6_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
index 295076cf70de9768e4b34bd85fde86282b6783bb..386bfb7b2bf63ea07e85abae11be5cd37f05a525 100644 (file)
@@ -1114,6 +1114,28 @@ static void dw_pcie_ep_init_non_sticky_registers(struct dw_pcie *pci)
        dw_pcie_dbi_ro_wr_dis(pci);
 }
 
+static void dw_pcie_ep_disable_bars(struct dw_pcie_ep *ep)
+{
+       struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
+       enum pci_epc_bar_type bar_type;
+       enum pci_barno bar;
+
+       for (bar = 0; bar < PCI_STD_NUM_BARS; bar++) {
+               bar_type = dw_pcie_ep_get_bar_type(ep, bar);
+
+               /*
+                * Reserved BARs should not get disabled by default. All other
+                * BAR types are disabled by default.
+                *
+                * This is in line with the current EPC core design, where all
+                * BARs are disabled by default, and then the EPF driver enables
+                * the BARs it wishes to use.
+                */
+               if (bar_type != BAR_RESERVED)
+                       dw_pcie_ep_reset_bar(pci, bar);
+       }
+}
+
 /**
  * dw_pcie_ep_init_registers - Initialize DWC EP specific registers
  * @ep: DWC EP device
@@ -1196,6 +1218,8 @@ int dw_pcie_ep_init_registers(struct dw_pcie_ep *ep)
        if (ep->ops->init)
                ep->ops->init(ep);
 
+       dw_pcie_ep_disable_bars(ep);
+
        /*
         * PCIe r6.0, section 7.9.15 states that for endpoints that support
         * PTM, this capability structure is required in exactly one
index 8530746ec5cbb6f14d6832d443c156c7c9aea4ef..d103ab759c4ee504a9e6154f9d9daa5feb7fc6bf 100644 (file)
@@ -32,15 +32,6 @@ struct dw_plat_pcie_of_data {
 static const struct dw_pcie_host_ops dw_plat_pcie_host_ops = {
 };
 
-static void dw_plat_pcie_ep_init(struct dw_pcie_ep *ep)
-{
-       struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-       enum pci_barno bar;
-
-       for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
-               dw_pcie_ep_reset_bar(pci, bar);
-}
-
 static int dw_plat_pcie_ep_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
                                     unsigned int type, u16 interrupt_num)
 {
@@ -73,7 +64,6 @@ dw_plat_pcie_get_features(struct dw_pcie_ep *ep)
 }
 
 static const struct dw_pcie_ep_ops pcie_ep_ops = {
-       .init = dw_plat_pcie_ep_init,
        .raise_irq = dw_plat_pcie_ep_raise_irq,
        .get_features = dw_plat_pcie_get_features,
 };
index ecc28093c5894a0566f5e0c5ba873c6edf38a273..8db27199cfa6d01948d31a50e29c865f47aa7157 100644 (file)
@@ -361,13 +361,9 @@ static void rockchip_pcie_ep_hide_broken_ats_cap_rk3588(struct dw_pcie_ep *ep)
 static void rockchip_pcie_ep_init(struct dw_pcie_ep *ep)
 {
        struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-       enum pci_barno bar;
 
        rockchip_pcie_enable_l0s(pci);
        rockchip_pcie_ep_hide_broken_ats_cap_rk3588(ep);
-
-       for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
-               dw_pcie_ep_reset_bar(pci, bar);
 };
 
 static int rockchip_pcie_raise_irq(struct dw_pcie_ep *ep, u8 func_no,
@@ -415,9 +411,7 @@ static const struct pci_epc_bar_rsvd_region rk3588_bar4_rsvd[] = {
 /*
  * BAR4 on rk3588 exposes the ATU Port Logic Structure to the host regardless of
  * iATU settings for BAR4. This means that BAR4 cannot be used by an EPF driver,
- * so mark it as RESERVED. (rockchip_pcie_ep_init() will disable all BARs by
- * default.) If the host could write to BAR4, the iATU settings (for all other
- * BARs) would be overwritten, resulting in (all other BARs) no longer working.
+ * so mark it as RESERVED.
  */
 static const struct pci_epc_features rockchip_pcie_epc_features_rk3588 = {
        DWC_EPC_COMMON_FEATURES,
index ffb4409c0468c57263a7c78669116d63dae70d5f..8e8c58a42bc3b31a93997cdf7a20d7e59d67ef4d 100644 (file)
@@ -859,17 +859,7 @@ qcom_pcie_epc_get_features(struct dw_pcie_ep *pci_ep)
        return &qcom_pcie_epc_features;
 }
 
-static void qcom_pcie_ep_init(struct dw_pcie_ep *ep)
-{
-       struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-       enum pci_barno bar;
-
-       for (bar = BAR_0; bar <= BAR_5; bar++)
-               dw_pcie_ep_reset_bar(pci, bar);
-}
-
 static const struct dw_pcie_ep_ops pci_ep_ops = {
-       .init = qcom_pcie_ep_init,
        .raise_irq = qcom_pcie_ep_raise_irq,
        .get_features = qcom_pcie_epc_get_features,
 };
index 9dd05bac22b9b7a68579e9932ab293fb890333e6..1198ddc1752c8cbd5293fde9ca5f96a7f9efcf84 100644 (file)
@@ -386,15 +386,6 @@ static void rcar_gen4_pcie_ep_pre_init(struct dw_pcie_ep *ep)
        writel(PCIEDMAINTSTSEN_INIT, rcar->base + PCIEDMAINTSTSEN);
 }
 
-static void rcar_gen4_pcie_ep_init(struct dw_pcie_ep *ep)
-{
-       struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-       enum pci_barno bar;
-
-       for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
-               dw_pcie_ep_reset_bar(pci, bar);
-}
-
 static void rcar_gen4_pcie_ep_deinit(struct rcar_gen4_pcie *rcar)
 {
        writel(0, rcar->base + PCIEDMAINTSTSEN);
@@ -449,7 +440,6 @@ static unsigned int rcar_gen4_pcie_ep_get_dbi2_offset(struct dw_pcie_ep *ep,
 
 static const struct dw_pcie_ep_ops pcie_ep_ops = {
        .pre_init = rcar_gen4_pcie_ep_pre_init,
-       .init = rcar_gen4_pcie_ep_init,
        .raise_irq = rcar_gen4_pcie_ep_raise_irq,
        .get_features = rcar_gen4_pcie_ep_get_features,
        .get_dbi_offset = rcar_gen4_pcie_ep_get_dbi_offset,
index c1944b40ce02f5b03336d76b36904d806d3bbc4a..a7988dff104536dbfec8faf5f468bdc1d503c3b6 100644 (file)
@@ -28,15 +28,6 @@ struct stm32_pcie {
        unsigned int perst_irq;
 };
 
-static void stm32_pcie_ep_init(struct dw_pcie_ep *ep)
-{
-       struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-       enum pci_barno bar;
-
-       for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
-               dw_pcie_ep_reset_bar(pci, bar);
-}
-
 static int stm32_pcie_start_link(struct dw_pcie *pci)
 {
        struct stm32_pcie *stm32_pcie = to_stm32_pcie(pci);
@@ -82,7 +73,6 @@ stm32_pcie_get_features(struct dw_pcie_ep *ep)
 }
 
 static const struct dw_pcie_ep_ops stm32_pcie_ep_ops = {
-       .init = stm32_pcie_ep_init,
        .raise_irq = stm32_pcie_raise_irq,
        .get_features = stm32_pcie_get_features,
 };
index 61b9771004da1b4a3871b358ff3755065f0cd0f4..6881f0b94c73989ad20397517bbcb85fdc4b37ec 100644 (file)
@@ -1923,15 +1923,6 @@ static irqreturn_t tegra_pcie_ep_pex_rst_irq(int irq, void *arg)
        return IRQ_HANDLED;
 }
 
-static void tegra_pcie_ep_init(struct dw_pcie_ep *ep)
-{
-       struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-       enum pci_barno bar;
-
-       for (bar = 0; bar < PCI_STD_NUM_BARS; bar++)
-               dw_pcie_ep_reset_bar(pci, bar);
-};
-
 static int tegra_pcie_ep_raise_intx_irq(struct tegra_pcie_dw *pcie, u16 irq)
 {
        /* Tegra194 supports only INTA */
@@ -2007,7 +1998,6 @@ tegra_pcie_ep_get_features(struct dw_pcie_ep *ep)
 }
 
 static const struct dw_pcie_ep_ops pcie_ep_ops = {
-       .init = tegra_pcie_ep_init,
        .raise_irq = tegra_pcie_ep_raise_irq,
        .get_features = tegra_pcie_ep_get_features,
 };
index d6ec6823e180c11f76ab74c5ec91f625e9ef64d5..89fb782002223265b98764a779ab333317d3d7fb 100644 (file)
@@ -203,15 +203,6 @@ static void uniphier_pcie_stop_link(struct dw_pcie *pci)
        uniphier_pcie_ltssm_enable(priv, false);
 }
 
-static void uniphier_pcie_ep_init(struct dw_pcie_ep *ep)
-{
-       struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
-       enum pci_barno bar;
-
-       for (bar = BAR_0; bar <= BAR_5; bar++)
-               dw_pcie_ep_reset_bar(pci, bar);
-}
-
 static int uniphier_pcie_ep_raise_intx_irq(struct dw_pcie_ep *ep)
 {
        struct dw_pcie *pci = to_dw_pcie_from_ep(ep);
@@ -283,7 +274,6 @@ uniphier_pcie_get_features(struct dw_pcie_ep *ep)
 }
 
 static const struct dw_pcie_ep_ops uniphier_pcie_ep_ops = {
-       .init = uniphier_pcie_ep_init,
        .raise_irq = uniphier_pcie_ep_raise_irq,
        .get_features = uniphier_pcie_get_features,
 };