[PATCH RFC v4 6/9] phy: qcom: qmp-pcie: Add clock and reset lists for secondary PHY selector

Qiang Yu qiang.yu at oss.qualcomm.com
Mon May 18 22:47:17 PDT 2026


PHY instances sharing a single DT node each need their own clocks and
resets. The current driver uses a single hardcoded clock list with no
way to select per-instance resources. Add the infrastructure needed
before wiring up multi-PHY probe.

qmp_pciephy_secondary_clk_l[] and qmp_pcie_get_clk_list(id) are added
to select the appropriate clock list by PHY selector index.
qmp_pcie_num_clks() replaces the hard-coded ARRAY_SIZE(qmp_pciephy_clk_l)
in qmp_pcie_init(), qmp_pcie_exit(), and qmp_pcie_clk_init().

struct qmp_pcie::phy is replaced with an id field so each instance can
identify its index within a multi-PHY provider.

Signed-off-by: Qiang Yu <qiang.yu at oss.qualcomm.com>
---
 drivers/phy/qualcomm/phy-qcom-qmp-pcie.c | 49 ++++++++++++++++++++++++++------
 1 file changed, 40 insertions(+), 9 deletions(-)

diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
index 6332f15f78ca..b100302be12a 100644
--- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
+++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
@@ -3335,7 +3335,7 @@ struct qmp_pcie {
 	struct reset_control_bulk_data *nocsr_reset;
 	struct regulator_bulk_data *vregs;
 
-	struct phy *phy;
+	u32 id;
 	int mode;
 
 	struct clk_fixed_rate pipe_clk_fixed;
@@ -3379,6 +3379,24 @@ static const char * const qmp_pciephy_clk_l[] = {
 	"aux", "cfg_ahb", "ref", "refgen", "rchng", "phy_aux",
 };
 
+static const char * const qmp_pciephy_secondary_clk_l[] = {
+	"ref", "phy_b_aux", "cfg_ahb_b", "rchng_b",
+};
+
+static int qmp_pcie_get_clk_list(u32 id, const char * const **clk_list)
+{
+	switch (id) {
+	case QMP_PHY_SELECTOR_0:
+		*clk_list = qmp_pciephy_clk_l;
+		return ARRAY_SIZE(qmp_pciephy_clk_l);
+	case QMP_PHY_SELECTOR_1:
+		*clk_list = qmp_pciephy_secondary_clk_l;
+		return ARRAY_SIZE(qmp_pciephy_secondary_clk_l);
+	default:
+		return -EINVAL;
+	}
+}
+
 /* list of regulators */
 static const char * const qmp_phy_vreg_l[] = {
 	"vdda-phy", "vdda-pll",
@@ -4781,6 +4799,13 @@ static void qmp_pcie_init_registers(struct qmp_pcie *qmp, const struct qmp_phy_c
 	qmp_configure(qmp->dev, ln_shrd, tbls->ln_shrd, tbls->ln_shrd_num);
 }
 
+static int qmp_pcie_num_clks(const struct qmp_pcie *qmp)
+{
+	const char * const *clk_list;
+
+	return qmp_pcie_get_clk_list(qmp->id, &clk_list);
+}
+
 static int qmp_pcie_init(struct phy *phy)
 {
 	struct qmp_pcie *qmp = phy_get_drvdata(phy);
@@ -4840,7 +4865,7 @@ static int qmp_pcie_init(struct phy *phy)
 		}
 	}
 
-	ret = clk_bulk_prepare_enable(ARRAY_SIZE(qmp_pciephy_clk_l), qmp->clks);
+	ret = clk_bulk_prepare_enable(qmp_pcie_num_clks(qmp), qmp->clks);
 	if (ret)
 		goto err_assert_reset;
 
@@ -4865,7 +4890,7 @@ static int qmp_pcie_exit(struct phy *phy)
 	else
 		reset_control_bulk_assert(cfg->num_resets, qmp->resets);
 
-	clk_bulk_disable_unprepare(ARRAY_SIZE(qmp_pciephy_clk_l), qmp->clks);
+	clk_bulk_disable_unprepare(qmp_pcie_num_clks(qmp), qmp->clks);
 
 	regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
 
@@ -5079,16 +5104,21 @@ static int qmp_pcie_reset_init(struct qmp_pcie *qmp)
 
 static int qmp_pcie_clk_init(struct qmp_pcie *qmp)
 {
+	const char * const *clk_list;
 	struct device *dev = qmp->dev;
-	int num = ARRAY_SIZE(qmp_pciephy_clk_l);
+	int num;
 	int i;
 
+	num = qmp_pcie_get_clk_list(qmp->id, &clk_list);
+	if (num < 0)
+		return num;
+
 	qmp->clks = devm_kcalloc(dev, num, sizeof(*qmp->clks), GFP_KERNEL);
 	if (!qmp->clks)
 		return -ENOMEM;
 
 	for (i = 0; i < num; i++)
-		qmp->clks[i].id = qmp_pciephy_clk_l[i];
+		qmp->clks[i].id = clk_list[i];
 
 	return devm_clk_bulk_get_optional(dev, num, qmp->clks);
 }
@@ -5414,6 +5444,7 @@ static int qmp_pcie_probe(struct platform_device *pdev)
 	struct phy_provider *phy_provider;
 	struct device_node *np;
 	struct qmp_pcie *qmp;
+	struct phy *phy;
 	int ret;
 
 	qmp = devm_kzalloc(dev, sizeof(*qmp), GFP_KERNEL);
@@ -5468,14 +5499,14 @@ static int qmp_pcie_probe(struct platform_device *pdev)
 
 	qmp->mode = PHY_MODE_PCIE_RC;
 
-	qmp->phy = devm_phy_create(dev, np, &qmp_pcie_phy_ops);
-	if (IS_ERR(qmp->phy)) {
-		ret = PTR_ERR(qmp->phy);
+	phy = devm_phy_create(dev, np, &qmp_pcie_phy_ops);
+	if (IS_ERR(phy)) {
+		ret = PTR_ERR(phy);
 		dev_err(dev, "failed to create PHY: %d\n", ret);
 		goto err_node_put;
 	}
 
-	phy_set_drvdata(qmp->phy, qmp);
+	phy_set_drvdata(phy, qmp);
 
 	of_node_put(np);
 

-- 
2.34.1




More information about the linux-phy mailing list