From: sashiko-bot@kernel.org
To: "Qiang Yu" <qiang.yu@oss.qualcomm.com>
Cc: olteanv@gmail.com, vkoul@kernel.org, linux-pci@vger.kernel.org,
linux-phy@lists.infradead.org, neil.armstrong@linaro.org
Subject: Re: [PATCH 4/4] phy: qcom-qmp-pcie: Split phy_ops into init/exit/reset/power_on
Date: Wed, 16 Sep 2026 06:17:02 +0000 [thread overview]
Message-ID: <20260916061703.5F02C1F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260915-align_pcie_init_sequence_0916-v1-4-0b2195836f30@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] phy: qcom-qmp-pcie: nocsr_reset left asserted when skip_init is false
--
commit 09fee607f4ad44d50cee755a3e356ff08d5879e2
Author: Qiang Yu <qiang.yu@oss.qualcomm.com>
phy: qcom-qmp-pcie: Split phy_ops into init/exit/reset/power_on
This commit splits the combined power_on and power_off operations into
separate init, exit, reset, and power_on functions. It reorders regulator,
clock, and reset toggling to align with HPG requirements. It also introduces
a skip_reset field to share the initialization state between functions.
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> index d30194c6ed17f..2b6741a4120c5 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
[ ... ]
> @@ -5833,12 +5809,62 @@ static int qmp_pcie_exit(struct phy *phy)
> 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->num_pipe_clks, qmp->pipe_clks);
>
> regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
>
> return 0;
> }
>
> +static int qmp_pcie_reset(struct phy *phy)
> +{
> + struct qmp_pcie *qmp = phy_get_drvdata(phy);
> + const struct qmp_phy_cfg *cfg = qmp->cfg;
> + int ret;
> +
> + if (qmp->skip_reset)
> + return 0;
> +
> + if (qmp->skip_init) {
> + ret = reset_control_assert(qmp->nocsr_reset);
> + if (ret) {
> + dev_err(qmp->dev, "no-csr reset assert failed\n");
> + return ret;
> + }
> +
> + usleep_range(200, 300);
> +
> + ret = reset_control_deassert(qmp->nocsr_reset);
> + if (ret) {
> + dev_err(qmp->dev, "no-csr reset deassert failed\n");
> + return ret;
> + }
> +
> + return 0;
> + }
> +
> + /*
> + * Toggle BCR reset for PHY that doesn't support no_csr reset or has not
> + * been initialized.
> + */
> + ret = reset_control_bulk_assert(cfg->num_resets, qmp->resets);
[Severity: High]
Does this fallback path in qmp_pcie_reset() fail to deassert nocsr_reset
when skip_init evaluates to false?
Since qmp_pcie_exit() explicitly asserts nocsr_reset on exit, if skip_init
is false on the next initialization (for example, after a system suspend or
resume where power loss clears PHY CSRs like QPHY_START_CTRL), wouldn't this
execution path only toggle the bulk resets and leave nocsr_reset stuck in
the asserted state?
> + if (ret) {
> + dev_err(qmp->dev, "reset assert failed\n");
> + return ret;
> + }
> +
> + usleep_range(200, 300);
> +
> + ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets);
> + if (ret) {
> + dev_err(qmp->dev, "reset deassert failed\n");
> + reset_control_bulk_assert(cfg->num_resets, qmp->resets);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> static int qmp_pcie_power_on(struct phy *phy)
> {
> struct qmp_pcie *qmp = phy_get_drvdata(phy);
[ ... ]
> @@ -5870,22 +5893,6 @@ static int qmp_pcie_power_on(struct phy *phy)
> qmp_pcie_init_registers(qmp, &cfg->tbls);
> qmp_pcie_init_registers(qmp, mode_tbls);
>
> -skip_tbls_init:
> - ret = clk_bulk_prepare_enable(qmp->num_pipe_clks, qmp->pipe_clks);
> - if (ret)
> - return ret;
> -
> - if (!skip_reset) {
> - ret = reset_control_deassert(qmp->nocsr_reset);
> - if (ret) {
> - dev_err(qmp->dev, "no-csr reset deassert failed\n");
> - goto err_disable_pipe_clk;
> - }
> - }
> -
> - if (qmp->skip_init)
> - goto skip_serdes_start;
> -
> /* Pull PHY out of reset state */
> qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
[Severity: High]
With the explicit nocsr_reset deassertion removed from qmp_pcie_power_on(),
does the code now rely entirely on qmp_pcie_reset() to deassert it?
Since qmp_pcie_reset() doesn't seem to deassert nocsr_reset when skip_init
is false, this appears to set the PHY up to silently fail or time out on
initialization.
>
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260915-align_pcie_init_sequence_0916-v1-0-0b2195836f30@oss.qualcomm.com?part=4
WARNING: multiple messages have this Message-ID (diff)
From: sashiko-bot@kernel.org
To: "Qiang Yu" <qiang.yu@oss.qualcomm.com>
Cc: olteanv@gmail.com, vkoul@kernel.org, linux-pci@vger.kernel.org,
linux-phy@lists.infradead.org, neil.armstrong@linaro.org
Subject: Re: [PATCH 4/4] phy: qcom-qmp-pcie: Split phy_ops into init/exit/reset/power_on
Date: Wed, 16 Sep 2026 06:17:02 +0000 [thread overview]
Message-ID: <20260916061703.5F02C1F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260915-align_pcie_init_sequence_0916-v1-4-0b2195836f30@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 1 potential issue(s) to consider:
- [High] phy: qcom-qmp-pcie: nocsr_reset left asserted when skip_init is false
--
commit 09fee607f4ad44d50cee755a3e356ff08d5879e2
Author: Qiang Yu <qiang.yu@oss.qualcomm.com>
phy: qcom-qmp-pcie: Split phy_ops into init/exit/reset/power_on
This commit splits the combined power_on and power_off operations into
separate init, exit, reset, and power_on functions. It reorders regulator,
clock, and reset toggling to align with HPG requirements. It also introduces
a skip_reset field to share the initialization state between functions.
> diff --git a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> index d30194c6ed17f..2b6741a4120c5 100644
> --- a/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
> +++ b/drivers/phy/qualcomm/phy-qcom-qmp-pcie.c
[ ... ]
> @@ -5833,12 +5809,62 @@ static int qmp_pcie_exit(struct phy *phy)
> 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->num_pipe_clks, qmp->pipe_clks);
>
> regulator_bulk_disable(cfg->num_vregs, qmp->vregs);
>
> return 0;
> }
>
> +static int qmp_pcie_reset(struct phy *phy)
> +{
> + struct qmp_pcie *qmp = phy_get_drvdata(phy);
> + const struct qmp_phy_cfg *cfg = qmp->cfg;
> + int ret;
> +
> + if (qmp->skip_reset)
> + return 0;
> +
> + if (qmp->skip_init) {
> + ret = reset_control_assert(qmp->nocsr_reset);
> + if (ret) {
> + dev_err(qmp->dev, "no-csr reset assert failed\n");
> + return ret;
> + }
> +
> + usleep_range(200, 300);
> +
> + ret = reset_control_deassert(qmp->nocsr_reset);
> + if (ret) {
> + dev_err(qmp->dev, "no-csr reset deassert failed\n");
> + return ret;
> + }
> +
> + return 0;
> + }
> +
> + /*
> + * Toggle BCR reset for PHY that doesn't support no_csr reset or has not
> + * been initialized.
> + */
> + ret = reset_control_bulk_assert(cfg->num_resets, qmp->resets);
[Severity: High]
Does this fallback path in qmp_pcie_reset() fail to deassert nocsr_reset
when skip_init evaluates to false?
Since qmp_pcie_exit() explicitly asserts nocsr_reset on exit, if skip_init
is false on the next initialization (for example, after a system suspend or
resume where power loss clears PHY CSRs like QPHY_START_CTRL), wouldn't this
execution path only toggle the bulk resets and leave nocsr_reset stuck in
the asserted state?
> + if (ret) {
> + dev_err(qmp->dev, "reset assert failed\n");
> + return ret;
> + }
> +
> + usleep_range(200, 300);
> +
> + ret = reset_control_bulk_deassert(cfg->num_resets, qmp->resets);
> + if (ret) {
> + dev_err(qmp->dev, "reset deassert failed\n");
> + reset_control_bulk_assert(cfg->num_resets, qmp->resets);
> + return ret;
> + }
> +
> + return 0;
> +}
> +
> static int qmp_pcie_power_on(struct phy *phy)
> {
> struct qmp_pcie *qmp = phy_get_drvdata(phy);
[ ... ]
> @@ -5870,22 +5893,6 @@ static int qmp_pcie_power_on(struct phy *phy)
> qmp_pcie_init_registers(qmp, &cfg->tbls);
> qmp_pcie_init_registers(qmp, mode_tbls);
>
> -skip_tbls_init:
> - ret = clk_bulk_prepare_enable(qmp->num_pipe_clks, qmp->pipe_clks);
> - if (ret)
> - return ret;
> -
> - if (!skip_reset) {
> - ret = reset_control_deassert(qmp->nocsr_reset);
> - if (ret) {
> - dev_err(qmp->dev, "no-csr reset deassert failed\n");
> - goto err_disable_pipe_clk;
> - }
> - }
> -
> - if (qmp->skip_init)
> - goto skip_serdes_start;
> -
> /* Pull PHY out of reset state */
> qphy_clrbits(pcs, cfg->regs[QPHY_SW_RESET], SW_RESET);
[Severity: High]
With the explicit nocsr_reset deassertion removed from qmp_pcie_power_on(),
does the code now rely entirely on qmp_pcie_reset() to deassert it?
Since qmp_pcie_reset() doesn't seem to deassert nocsr_reset when skip_init
is false, this appears to set the PHY up to silently fail or time out on
initialization.
>
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260915-align_pcie_init_sequence_0916-v1-0-0b2195836f30@oss.qualcomm.com?part=4
--
linux-phy mailing list
linux-phy@lists.infradead.org
https://lists.infradead.org/mailman/listinfo/linux-phy
next prev parent reply other threads:[~2026-09-16 6:17 UTC|newest]
Thread overview: 34+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-16 6:04 [PATCH 0/4] PCI: qcom: Align PHY init sequence with HPG Qiang Yu
2026-09-16 6:04 ` Qiang Yu
2026-09-16 6:04 ` [PATCH 1/4] PCI: qcom: Move PHY init and add PHY reset call to align " Qiang Yu
2026-09-16 6:04 ` Qiang Yu
2026-09-16 6:12 ` sashiko-bot
2026-09-16 6:12 ` sashiko-bot
2026-09-21 9:14 ` Kathiravan Thirumoorthy
2026-09-21 9:14 ` Kathiravan Thirumoorthy
2026-09-16 6:04 ` [PATCH 2/4] PCI: qcom-ep: Move PHY init and drive PHY reset " Qiang Yu
2026-09-16 6:04 ` Qiang Yu
2026-09-16 6:14 ` sashiko-bot
2026-09-16 6:14 ` sashiko-bot
2026-10-12 15:29 ` Manivannan Sadhasivam
2026-10-12 15:29 ` Manivannan Sadhasivam
2026-09-16 6:04 ` [PATCH 3/4] phy: qcom-qmp-pcie-multiphy: Split phy_ops into init/exit/reset/power_on Qiang Yu
2026-09-16 6:04 ` Qiang Yu
2026-09-16 6:11 ` sashiko-bot
2026-09-16 6:11 ` sashiko-bot
2026-10-12 15:32 ` Manivannan Sadhasivam
2026-10-12 15:32 ` Manivannan Sadhasivam
2026-09-16 6:04 ` [PATCH 4/4] phy: qcom-qmp-pcie: " Qiang Yu
2026-09-16 6:04 ` Qiang Yu
2026-09-16 6:17 ` sashiko-bot [this message]
2026-09-16 6:17 ` sashiko-bot
2026-10-12 15:33 ` Manivannan Sadhasivam
2026-10-12 15:33 ` Manivannan Sadhasivam
2026-09-21 9:15 ` Kathiravan Thirumoorthy
2026-09-21 9:15 ` Kathiravan Thirumoorthy
2026-10-13 14:26 ` Michael Burch
2026-10-13 14:26 ` Michael Burch
2026-09-16 15:55 ` [PATCH 0/4] PCI: qcom: Align PHY init sequence with HPG Bjorn Helgaas
2026-09-16 15:55 ` Bjorn Helgaas
2026-09-21 11:16 ` Manivannan Sadhasivam
2026-09-21 11:16 ` Manivannan Sadhasivam
Reply instructions:
You may reply publicly to this message via plain-text email
using any one of the following methods:
* Save the following mbox file, import it into your mail client,
and reply-to-all from there: mbox
Avoid top-posting and favor interleaved quoting:
https://en.wikipedia.org/wiki/Posting_style#Interleaved_style
* Reply using the --to, --cc, and --in-reply-to
switches of git-send-email(1):
git send-email \
--in-reply-to=20260916061703.5F02C1F000FF@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-phy@lists.infradead.org \
--cc=neil.armstrong@linaro.org \
--cc=olteanv@gmail.com \
--cc=qiang.yu@oss.qualcomm.com \
--cc=sashiko-reviews@lists.linux.dev \
--cc=vkoul@kernel.org \
/path/to/YOUR_REPLY
https://kernel.org/pub/software/scm/git/docs/git-send-email.html
* If your mail client supports setting the In-Reply-To header
via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line
before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.