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

From: Qiang Yu

Date: Tue May 19 2026 - 01:51:10 EST


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@xxxxxxxxxxxxxxxx>
---
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