PCI: qcom: Use bulk reset APIs for handling resets for IP rev 2.1.0
authorManivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Thu, 16 Mar 2023 08:11:05 +0000 (13:41 +0530)
committerLorenzo Pieralisi <lpieralisi@kernel.org>
Tue, 11 Apr 2023 09:31:10 +0000 (11:31 +0200)
All the resets are asserted and deasserted at the same time. So the bulk
reset APIs can be used to handle them together. This simplifies the code
a lot.

While at it, let's also move the qcom_pcie_resources_2_1_0 struct below
qcom_pcie_resources_1_0_0 to keep it sorted.

Link: https://lore.kernel.org/r/20230316081117.14288-8-manivannan.sadhasivam@linaro.org
Signed-off-by: Manivannan Sadhasivam <manivannan.sadhasivam@linaro.org>
Signed-off-by: Lorenzo Pieralisi <lpieralisi@kernel.org>
drivers/pci/controller/dwc/pcie-qcom.c

index 249033d1b24880e35bde4fb99736da81ed17ba78..10e792604042d6b193189a6024abf76efee944ce 100644 (file)
 
 #define PERST_DELAY_US                         1000
 
-#define QCOM_PCIE_2_1_0_MAX_SUPPLY             3
-#define QCOM_PCIE_2_1_0_MAX_CLOCKS             5
-
 #define QCOM_PCIE_CRC8_POLYNOMIAL              (BIT(2) | BIT(1) | BIT(0))
 
-struct qcom_pcie_resources_2_1_0 {
-       struct clk_bulk_data clks[QCOM_PCIE_2_1_0_MAX_CLOCKS];
-       struct reset_control *pci_reset;
-       struct reset_control *axi_reset;
-       struct reset_control *ahb_reset;
-       struct reset_control *por_reset;
-       struct reset_control *phy_reset;
-       struct reset_control *ext_reset;
-       struct regulator_bulk_data supplies[QCOM_PCIE_2_1_0_MAX_SUPPLY];
-};
-
 struct qcom_pcie_resources_1_0_0 {
        struct clk *iface;
        struct clk *aux;
@@ -168,6 +154,16 @@ struct qcom_pcie_resources_1_0_0 {
        struct regulator *vdda;
 };
 
+#define QCOM_PCIE_2_1_0_MAX_CLOCKS             5
+#define QCOM_PCIE_2_1_0_MAX_RESETS             6
+#define QCOM_PCIE_2_1_0_MAX_SUPPLY             3
+struct qcom_pcie_resources_2_1_0 {
+       struct clk_bulk_data clks[QCOM_PCIE_2_1_0_MAX_CLOCKS];
+       struct reset_control_bulk_data resets[QCOM_PCIE_2_1_0_MAX_RESETS];
+       int num_resets;
+       struct regulator_bulk_data supplies[QCOM_PCIE_2_1_0_MAX_SUPPLY];
+};
+
 #define QCOM_PCIE_2_3_2_MAX_SUPPLY     2
 struct qcom_pcie_resources_2_3_2 {
        struct clk *aux_clk;
@@ -295,6 +291,7 @@ static int qcom_pcie_get_resources_2_1_0(struct qcom_pcie *pcie)
        struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0;
        struct dw_pcie *pci = pcie->pci;
        struct device *dev = pci->dev;
+       bool is_apq = of_device_is_compatible(dev->of_node, "qcom,pcie-apq8064");
        int ret;
 
        res->supplies[0].supply = "vdda";
@@ -321,28 +318,20 @@ static int qcom_pcie_get_resources_2_1_0(struct qcom_pcie *pcie)
        if (ret < 0)
                return ret;
 
-       res->pci_reset = devm_reset_control_get_exclusive(dev, "pci");
-       if (IS_ERR(res->pci_reset))
-               return PTR_ERR(res->pci_reset);
-
-       res->axi_reset = devm_reset_control_get_exclusive(dev, "axi");
-       if (IS_ERR(res->axi_reset))
-               return PTR_ERR(res->axi_reset);
-
-       res->ahb_reset = devm_reset_control_get_exclusive(dev, "ahb");
-       if (IS_ERR(res->ahb_reset))
-               return PTR_ERR(res->ahb_reset);
+       res->resets[0].id = "pci";
+       res->resets[1].id = "axi";
+       res->resets[2].id = "ahb";
+       res->resets[3].id = "por";
+       res->resets[4].id = "phy";
+       res->resets[5].id = "ext";
 
-       res->por_reset = devm_reset_control_get_exclusive(dev, "por");
-       if (IS_ERR(res->por_reset))
-               return PTR_ERR(res->por_reset);
-
-       res->ext_reset = devm_reset_control_get_optional_exclusive(dev, "ext");
-       if (IS_ERR(res->ext_reset))
-               return PTR_ERR(res->ext_reset);
+       /* ext is optional on APQ8016 */
+       res->num_resets = is_apq ? 5 : 6;
+       ret = devm_reset_control_bulk_get_exclusive(dev, res->num_resets, res->resets);
+       if (ret < 0)
+               return ret;
 
-       res->phy_reset = devm_reset_control_get_exclusive(dev, "phy");
-       return PTR_ERR_OR_ZERO(res->phy_reset);
+       return 0;
 }
 
 static void qcom_pcie_deinit_2_1_0(struct qcom_pcie *pcie)
@@ -350,12 +339,7 @@ static void qcom_pcie_deinit_2_1_0(struct qcom_pcie *pcie)
        struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0;
 
        clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
-       reset_control_assert(res->pci_reset);
-       reset_control_assert(res->axi_reset);
-       reset_control_assert(res->ahb_reset);
-       reset_control_assert(res->por_reset);
-       reset_control_assert(res->ext_reset);
-       reset_control_assert(res->phy_reset);
+       reset_control_bulk_assert(res->num_resets, res->resets);
 
        writel(1, pcie->parf + PARF_PHY_CTRL);
 
@@ -370,12 +354,11 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
        int ret;
 
        /* reset the PCIe interface as uboot can leave it undefined state */
-       reset_control_assert(res->pci_reset);
-       reset_control_assert(res->axi_reset);
-       reset_control_assert(res->ahb_reset);
-       reset_control_assert(res->por_reset);
-       reset_control_assert(res->ext_reset);
-       reset_control_assert(res->phy_reset);
+       ret = reset_control_bulk_assert(res->num_resets, res->resets);
+       if (ret < 0) {
+               dev_err(dev, "cannot assert resets\n");
+               return ret;
+       }
 
        ret = regulator_bulk_enable(ARRAY_SIZE(res->supplies), res->supplies);
        if (ret < 0) {
@@ -383,58 +366,14 @@ static int qcom_pcie_init_2_1_0(struct qcom_pcie *pcie)
                return ret;
        }
 
-       ret = reset_control_deassert(res->ahb_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert ahb reset\n");
-               goto err_deassert_ahb;
-       }
-
-       ret = reset_control_deassert(res->ext_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert ext reset\n");
-               goto err_deassert_ext;
-       }
-
-       ret = reset_control_deassert(res->phy_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert phy reset\n");
-               goto err_deassert_phy;
-       }
-
-       ret = reset_control_deassert(res->pci_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert pci reset\n");
-               goto err_deassert_pci;
-       }
-
-       ret = reset_control_deassert(res->por_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert por reset\n");
-               goto err_deassert_por;
-       }
-
-       ret = reset_control_deassert(res->axi_reset);
-       if (ret) {
-               dev_err(dev, "cannot deassert axi reset\n");
-               goto err_deassert_axi;
+       ret = reset_control_bulk_deassert(res->num_resets, res->resets);
+       if (ret < 0) {
+               dev_err(dev, "cannot deassert resets\n");
+               regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
+               return ret;
        }
 
        return 0;
-
-err_deassert_axi:
-       reset_control_assert(res->por_reset);
-err_deassert_por:
-       reset_control_assert(res->pci_reset);
-err_deassert_pci:
-       reset_control_assert(res->phy_reset);
-err_deassert_phy:
-       reset_control_assert(res->ext_reset);
-err_deassert_ext:
-       reset_control_assert(res->ahb_reset);
-err_deassert_ahb:
-       regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
-
-       return ret;
 }
 
 static int qcom_pcie_post_init_2_1_0(struct qcom_pcie *pcie)