--- /dev/null
+From 652935ba05860eadaa19ac9efe7aea61fb7a3aef Mon Sep 17 00:00:00 2001
+Date: Wed, 17 Apr 2024 12:32:53 +0530
+Subject: [PATCH] PCI: qcom: Use devm_clk_bulk_get_all() API
+MIME-Version: 1.0
+Content-Type: text/plain; charset=UTF-8
+Content-Transfer-Encoding: 8bit
+
+There is no need for the device drivers to validate the clocks defined in
+Devicetree. The validation should be performed by the DT schema and the
+drivers should just get all the clocks from DT. Right now the driver
+hardcodes the clock info and validates them against DT which is redundant.
+
+So use devm_clk_bulk_get_all() that just gets all the clocks defined in DT
+and get rid of all static clocks info from the driver. This simplifies the
+driver.
+
+---
+ drivers/pci/controller/dwc/pcie-qcom.c | 177 ++++++++-----------------
+ 1 file changed, 58 insertions(+), 119 deletions(-)
+
+--- a/drivers/pci/controller/dwc/pcie-qcom.c
++++ b/drivers/pci/controller/dwc/pcie-qcom.c
+@@ -151,58 +151,56 @@
+
+ #define QCOM_PCIE_CRC8_POLYNOMIAL (BIT(2) | BIT(1) | BIT(0))
+
+-#define QCOM_PCIE_1_0_0_MAX_CLOCKS 4
+ struct qcom_pcie_resources_1_0_0 {
+- struct clk_bulk_data clks[QCOM_PCIE_1_0_0_MAX_CLOCKS];
++ struct clk_bulk_data *clks;
++ int num_clks;
+ struct reset_control *core;
+ 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 clk_bulk_data *clks;
++ int num_clks;
+ 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_CLOCKS 4
+ #define QCOM_PCIE_2_3_2_MAX_SUPPLY 2
+ struct qcom_pcie_resources_2_3_2 {
+- struct clk_bulk_data clks[QCOM_PCIE_2_3_2_MAX_CLOCKS];
++ struct clk_bulk_data *clks;
++ int num_clks;
+ struct regulator_bulk_data supplies[QCOM_PCIE_2_3_2_MAX_SUPPLY];
+ };
+
+-#define QCOM_PCIE_2_3_3_MAX_CLOCKS 5
+ #define QCOM_PCIE_2_3_3_MAX_RESETS 7
+ struct qcom_pcie_resources_2_3_3 {
+- struct clk_bulk_data clks[QCOM_PCIE_2_3_3_MAX_CLOCKS];
++ struct clk_bulk_data *clks;
++ int num_clks;
+ struct reset_control_bulk_data rst[QCOM_PCIE_2_3_3_MAX_RESETS];
+ };
+
+-#define QCOM_PCIE_2_4_0_MAX_CLOCKS 4
+ #define QCOM_PCIE_2_4_0_MAX_RESETS 12
+ struct qcom_pcie_resources_2_4_0 {
+- struct clk_bulk_data clks[QCOM_PCIE_2_4_0_MAX_CLOCKS];
++ struct clk_bulk_data *clks;
+ int num_clks;
+ struct reset_control_bulk_data resets[QCOM_PCIE_2_4_0_MAX_RESETS];
+ int num_resets;
+ };
+
+-#define QCOM_PCIE_2_7_0_MAX_CLOCKS 15
+ #define QCOM_PCIE_2_7_0_MAX_SUPPLIES 2
+ struct qcom_pcie_resources_2_7_0 {
+- struct clk_bulk_data clks[QCOM_PCIE_2_7_0_MAX_CLOCKS];
++ struct clk_bulk_data *clks;
+ int num_clks;
+ struct regulator_bulk_data supplies[QCOM_PCIE_2_7_0_MAX_SUPPLIES];
+ struct reset_control *rst;
+ };
+
+-#define QCOM_PCIE_2_9_0_MAX_CLOCKS 5
+ struct qcom_pcie_resources_2_9_0 {
+- struct clk_bulk_data clks[QCOM_PCIE_2_9_0_MAX_CLOCKS];
++ struct clk_bulk_data *clks;
++ int num_clks;
+ struct reset_control *rst;
+ };
+
+@@ -313,21 +311,11 @@ static int qcom_pcie_get_resources_2_1_0
+ if (ret)
+ return ret;
+
+- res->clks[0].id = "iface";
+- res->clks[1].id = "core";
+- res->clks[2].id = "phy";
+- res->clks[3].id = "aux";
+- res->clks[4].id = "ref";
+-
+- /* iface, core, phy are required */
+- ret = devm_clk_bulk_get(dev, 3, res->clks);
+- if (ret < 0)
+- return ret;
+-
+- /* aux, ref are optional */
+- ret = devm_clk_bulk_get_optional(dev, 2, res->clks + 3);
+- if (ret < 0)
+- return ret;
++ res->num_clks = devm_clk_bulk_get_all(dev, &res->clks);
++ if (res->num_clks < 0) {
++ dev_err(dev, "Failed to get clocks\n");
++ return res->num_clks;
++ }
+
+ res->resets[0].id = "pci";
+ res->resets[1].id = "axi";
+@@ -349,7 +337,7 @@ static void qcom_pcie_deinit_2_1_0(struc
+ {
+ struct qcom_pcie_resources_2_1_0 *res = &pcie->res.v2_1_0;
+
+- clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
++ clk_bulk_disable_unprepare(res->num_clks, res->clks);
+ reset_control_bulk_assert(res->num_resets, res->resets);
+
+ writel(1, pcie->parf + PARF_PHY_CTRL);
+@@ -401,7 +389,7 @@ static int qcom_pcie_post_init_2_1_0(str
+ val &= ~PHY_TEST_PWR_DOWN;
+ writel(val, pcie->parf + PARF_PHY_CTRL);
+
+- ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
++ ret = clk_bulk_prepare_enable(res->num_clks, res->clks);
+ if (ret)
+ return ret;
+
+@@ -452,20 +440,16 @@ static int qcom_pcie_get_resources_1_0_0
+ struct qcom_pcie_resources_1_0_0 *res = &pcie->res.v1_0_0;
+ struct dw_pcie *pci = pcie->pci;
+ struct device *dev = pci->dev;
+- int ret;
+
+ res->vdda = devm_regulator_get(dev, "vdda");
+ if (IS_ERR(res->vdda))
+ return PTR_ERR(res->vdda);
+
+- res->clks[0].id = "iface";
+- res->clks[1].id = "aux";
+- res->clks[2].id = "master_bus";
+- res->clks[3].id = "slave_bus";
+-
+- ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
+- if (ret < 0)
+- return ret;
++ res->num_clks = devm_clk_bulk_get_all(dev, &res->clks);
++ if (res->num_clks < 0) {
++ dev_err(dev, "Failed to get clocks\n");
++ return res->num_clks;
++ }
+
+ res->core = devm_reset_control_get_exclusive(dev, "core");
+ return PTR_ERR_OR_ZERO(res->core);
+@@ -476,7 +460,7 @@ static void qcom_pcie_deinit_1_0_0(struc
+ struct qcom_pcie_resources_1_0_0 *res = &pcie->res.v1_0_0;
+
+ reset_control_assert(res->core);
+- clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
++ clk_bulk_disable_unprepare(res->num_clks, res->clks);
+ regulator_disable(res->vdda);
+ }
+
+@@ -493,7 +477,7 @@ static int qcom_pcie_init_1_0_0(struct q
+ return ret;
+ }
+
+- ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
++ ret = clk_bulk_prepare_enable(res->num_clks, res->clks);
+ if (ret) {
+ dev_err(dev, "cannot prepare/enable clocks\n");
+ goto err_assert_reset;
+@@ -508,7 +492,7 @@ static int qcom_pcie_init_1_0_0(struct q
+ return 0;
+
+ err_disable_clks:
+- clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
++ clk_bulk_disable_unprepare(res->num_clks, res->clks);
+ err_assert_reset:
+ reset_control_assert(res->core);
+
+@@ -556,14 +540,11 @@ static int qcom_pcie_get_resources_2_3_2
+ if (ret)
+ return ret;
+
+- res->clks[0].id = "aux";
+- res->clks[1].id = "cfg";
+- res->clks[2].id = "bus_master";
+- res->clks[3].id = "bus_slave";
+-
+- ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
+- if (ret < 0)
+- return ret;
++ res->num_clks = devm_clk_bulk_get_all(dev, &res->clks);
++ if (res->num_clks < 0) {
++ dev_err(dev, "Failed to get clocks\n");
++ return res->num_clks;
++ }
+
+ return 0;
+ }
+@@ -572,7 +553,7 @@ static void qcom_pcie_deinit_2_3_2(struc
+ {
+ struct qcom_pcie_resources_2_3_2 *res = &pcie->res.v2_3_2;
+
+- clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
++ clk_bulk_disable_unprepare(res->num_clks, res->clks);
+ regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
+ }
+
+@@ -589,7 +570,7 @@ static int qcom_pcie_init_2_3_2(struct q
+ return ret;
+ }
+
+- ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
++ ret = clk_bulk_prepare_enable(res->num_clks, res->clks);
+ if (ret) {
+ dev_err(dev, "cannot prepare/enable clocks\n");
+ regulator_bulk_disable(ARRAY_SIZE(res->supplies), res->supplies);
+@@ -637,17 +618,11 @@ static int qcom_pcie_get_resources_2_4_0
+ bool is_ipq = of_device_is_compatible(dev->of_node, "qcom,pcie-ipq4019");
+ int ret;
+
+- res->clks[0].id = "aux";
+- res->clks[1].id = "master_bus";
+- res->clks[2].id = "slave_bus";
+- res->clks[3].id = "iface";
+-
+- /* qcom,pcie-ipq4019 is defined without "iface" */
+- res->num_clks = is_ipq ? 3 : 4;
+-
+- ret = devm_clk_bulk_get(dev, res->num_clks, res->clks);
+- if (ret < 0)
+- return ret;
++ res->num_clks = devm_clk_bulk_get_all(dev, &res->clks);
++ if (res->num_clks < 0) {
++ dev_err(dev, "Failed to get clocks\n");
++ return res->num_clks;
++ }
+
+ res->resets[0].id = "axi_m";
+ res->resets[1].id = "axi_s";
+@@ -718,15 +693,11 @@ static int qcom_pcie_get_resources_2_3_3
+ struct device *dev = pci->dev;
+ int ret;
+
+- res->clks[0].id = "iface";
+- res->clks[1].id = "axi_m";
+- res->clks[2].id = "axi_s";
+- res->clks[3].id = "ahb";
+- res->clks[4].id = "aux";
+-
+- ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
+- if (ret < 0)
+- return ret;
++ res->num_clks = devm_clk_bulk_get_all(dev, &res->clks);
++ if (res->num_clks < 0) {
++ dev_err(dev, "Failed to get clocks\n");
++ return res->num_clks;
++ }
+
+ res->rst[0].id = "axi_m";
+ res->rst[1].id = "axi_s";
+@@ -747,7 +718,7 @@ static void qcom_pcie_deinit_2_3_3(struc
+ {
+ struct qcom_pcie_resources_2_3_3 *res = &pcie->res.v2_3_3;
+
+- clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
++ clk_bulk_disable_unprepare(res->num_clks, res->clks);
+ }
+
+ static int qcom_pcie_init_2_3_3(struct qcom_pcie *pcie)
+@@ -777,7 +748,7 @@ static int qcom_pcie_init_2_3_3(struct q
+ */
+ usleep_range(2000, 2500);
+
+- ret = clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
++ ret = clk_bulk_prepare_enable(res->num_clks, res->clks);
+ if (ret) {
+ dev_err(dev, "cannot prepare/enable clocks\n");
+ goto err_assert_resets;
+@@ -838,8 +809,6 @@ static int qcom_pcie_get_resources_2_7_0
+ struct qcom_pcie_resources_2_7_0 *res = &pcie->res.v2_7_0;
+ struct dw_pcie *pci = pcie->pci;
+ struct device *dev = pci->dev;
+- unsigned int num_clks, num_opt_clks;
+- unsigned int idx;
+ int ret;
+
+ res->rst = devm_reset_control_array_get_exclusive(dev);
+@@ -853,36 +822,11 @@ static int qcom_pcie_get_resources_2_7_0
+ if (ret)
+ return ret;
+
+- idx = 0;
+- res->clks[idx++].id = "aux";
+- res->clks[idx++].id = "cfg";
+- res->clks[idx++].id = "bus_master";
+- res->clks[idx++].id = "bus_slave";
+- res->clks[idx++].id = "slave_q2a";
+-
+- num_clks = idx;
+-
+- ret = devm_clk_bulk_get(dev, num_clks, res->clks);
+- if (ret < 0)
+- return ret;
+-
+- res->clks[idx++].id = "tbu";
+- res->clks[idx++].id = "ddrss_sf_tbu";
+- res->clks[idx++].id = "aggre0";
+- res->clks[idx++].id = "aggre1";
+- res->clks[idx++].id = "noc_aggr";
+- res->clks[idx++].id = "noc_aggr_4";
+- res->clks[idx++].id = "noc_aggr_south_sf";
+- res->clks[idx++].id = "cnoc_qx";
+- res->clks[idx++].id = "sleep";
+- res->clks[idx++].id = "cnoc_sf_axi";
+-
+- num_opt_clks = idx - num_clks;
+- res->num_clks = idx;
+-
+- ret = devm_clk_bulk_get_optional(dev, num_opt_clks, res->clks + num_clks);
+- if (ret < 0)
+- return ret;
++ res->num_clks = devm_clk_bulk_get_all(dev, &res->clks);
++ if (res->num_clks < 0) {
++ dev_err(dev, "Failed to get clocks\n");
++ return res->num_clks;
++ }
+
+ return 0;
+ }
+@@ -1073,17 +1017,12 @@ static int qcom_pcie_get_resources_2_9_0
+ struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
+ struct dw_pcie *pci = pcie->pci;
+ struct device *dev = pci->dev;
+- int ret;
+-
+- res->clks[0].id = "iface";
+- res->clks[1].id = "axi_m";
+- res->clks[2].id = "axi_s";
+- res->clks[3].id = "axi_bridge";
+- res->clks[4].id = "rchng";
+
+- ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
+- if (ret < 0)
+- return ret;
++ res->num_clks = devm_clk_bulk_get_all(dev, &res->clks);
++ if (res->num_clks < 0) {
++ dev_err(dev, "Failed to get clocks\n");
++ return res->num_clks;
++ }
+
+ res->rst = devm_reset_control_array_get_exclusive(dev);
+ if (IS_ERR(res->rst))
+@@ -1096,7 +1035,7 @@ static void qcom_pcie_deinit_2_9_0(struc
+ {
+ struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
+
+- clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
++ clk_bulk_disable_unprepare(res->num_clks, res->clks);
+ }
+
+ static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
+@@ -1125,7 +1064,7 @@ static int qcom_pcie_init_2_9_0(struct q
+
+ usleep_range(2000, 2500);
+
+- return clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
++ return clk_bulk_prepare_enable(res->num_clks, res->clks);
+ }
+
+ static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
+++ /dev/null
-Subject: [PATCH] PCI: qcom: Add support for IPQ5018
-Date: Tue, 3 Oct 2023 17:38:44 +0530
-
-Added a new compatible 'qcom,pcie-ipq5018' and modified
-get_resources of 'ops 2_9_0' to get the clocks from the
-device-tree.
-
----
- drivers/pci/controller/dwc/pcie-qcom.c | 22 ++++++++--------------
- 1 file changed, 8 insertions(+), 14 deletions(-)
-
---- a/drivers/pci/controller/dwc/pcie-qcom.c
-+++ b/drivers/pci/controller/dwc/pcie-qcom.c
-@@ -202,8 +202,9 @@ struct qcom_pcie_resources_2_7_0 {
-
- #define QCOM_PCIE_2_9_0_MAX_CLOCKS 5
- struct qcom_pcie_resources_2_9_0 {
-- struct clk_bulk_data clks[QCOM_PCIE_2_9_0_MAX_CLOCKS];
-+ struct clk_bulk_data *clks;
- struct reset_control *rst;
-+ int num_clks;
- };
-
- union qcom_pcie_resources {
-@@ -1073,17 +1074,10 @@ static int qcom_pcie_get_resources_2_9_0
- struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
- struct dw_pcie *pci = pcie->pci;
- struct device *dev = pci->dev;
-- int ret;
--
-- res->clks[0].id = "iface";
-- res->clks[1].id = "axi_m";
-- res->clks[2].id = "axi_s";
-- res->clks[3].id = "axi_bridge";
-- res->clks[4].id = "rchng";
-
-- ret = devm_clk_bulk_get(dev, ARRAY_SIZE(res->clks), res->clks);
-- if (ret < 0)
-- return ret;
-+ res->num_clks = devm_clk_bulk_get_all(dev, &res->clks);
-+ if (res->num_clks < 0)
-+ return res->num_clks;
-
- res->rst = devm_reset_control_array_get_exclusive(dev);
- if (IS_ERR(res->rst))
-@@ -1096,7 +1090,7 @@ static void qcom_pcie_deinit_2_9_0(struc
- {
- struct qcom_pcie_resources_2_9_0 *res = &pcie->res.v2_9_0;
-
-- clk_bulk_disable_unprepare(ARRAY_SIZE(res->clks), res->clks);
-+ clk_bulk_disable_unprepare(res->num_clks, res->clks);
- }
-
- static int qcom_pcie_init_2_9_0(struct qcom_pcie *pcie)
-@@ -1125,7 +1119,7 @@ static int qcom_pcie_init_2_9_0(struct q
-
- usleep_range(2000, 2500);
-
-- return clk_bulk_prepare_enable(ARRAY_SIZE(res->clks), res->clks);
-+ return clk_bulk_prepare_enable(res->num_clks, res->clks);
- }
-
- static int qcom_pcie_post_init_2_9_0(struct qcom_pcie *pcie)
-@@ -1641,6 +1635,7 @@ static const struct of_device_id qcom_pc
- { .compatible = "qcom,pcie-apq8064", .data = &cfg_2_1_0 },
- { .compatible = "qcom,pcie-apq8084", .data = &cfg_1_0_0 },
- { .compatible = "qcom,pcie-ipq4019", .data = &cfg_2_4_0 },
-+ { .compatible = "qcom,pcie-ipq5018", .data = &cfg_2_9_0 },
- { .compatible = "qcom,pcie-ipq6018", .data = &cfg_2_9_0 },
- { .compatible = "qcom,pcie-ipq8064", .data = &cfg_2_1_0 },
- { .compatible = "qcom,pcie-ipq8064-v2", .data = &cfg_2_1_0 },