From: Vladimir Oltean <vladimir.oltean@nxp.com>
To: linux-phy@lists.infradead.org
Cc: Vinod Koul <vkoul@kernel.org>,
Neil Armstrong <neil.armstrong@linaro.org>,
dri-devel@lists.freedesktop.org, freedreno@lists.freedesktop.org,
linux-arm-kernel@lists.infradead.org,
linux-arm-msm@vger.kernel.org, linux-can@vger.kernel.org,
linux-gpio@vger.kernel.org, linux-ide@vger.kernel.org,
linux-kernel@vger.kernel.org, linux-media@vger.kernel.org,
linux-pci@vger.kernel.org, linux-renesas-soc@vger.kernel.org,
linux-riscv@lists.infradead.org,
linux-rockchip@lists.infradead.org,
linux-samsung-soc@vger.kernel.org, linux-scsi@vger.kernel.org,
linux-sunxi@lists.linux.dev, linux-tegra@vger.kernel.org,
linux-usb@vger.kernel.org, netdev@vger.kernel.org,
spacemit@lists.linux.dev, UNGLinuxDriver@microchip.com,
"James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>,
"Martin K. Petersen" <martin.petersen@oracle.com>,
Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>,
Nitin Rawat <quic_nitirawa@quicinc.com>,
Manivannan Sadhasivam <mani@kernel.org>
Subject: [PATCH v8 phy-next 11/31] scsi: ufs: qcom: call phy_init() before phy_power_on()
Date: Tue, 5 May 2026 13:05:03 +0300 [thread overview]
Message-ID: <20260505100523.1922388-12-vladimir.oltean@nxp.com> (raw)
In-Reply-To: <20260505100523.1922388-1-vladimir.oltean@nxp.com>
The Qualcomm UFS host controller interacts with the QMP PHY in a way
which violates the Generic PHY API expectation, documented in section
"Order of API calls" from Documentation/driver-api/phy/phy.rst, and then
tries to hide it.
Namely, calls must be made in the phy_init() -> phy_power_on() ->
phy_power_off() -> phy_exit() sequence.
What we actually have is:
ufshcd_init()
-> ufshcd_hba_init()
-> ufshcd_setup_clocks(hba, true)
-> ufshcd_vops_setup_clocks(hba, true, POST_CHANGE)
-> ufs_qcom_setup_clocks(hba, true, POST_CHANGE)
-> ufs_qcom_init() has not run, simply ignore
-> ufshcd_variant_hba_init()
-> ufs_qcom_init()
-> ufs_qcom_setup_clocks(hba, true, POST_CHANGE)
-> phy_power_on(phy)
-> ufshcd_hba_enable()
-> ufshcd_vops_hce_enable_notify()
-> ufs_qcom_hce_enable_notify()
-> ufs_qcom_power_up_sequence()
-> if (phy->power_count) phy_power_off(phy)
-> phy_init(phy)
This "works" because the way that the "phy_power_on was called before
phy_init\n" warning condition is detected in phy-core.c is if the
power_count is positive at the phy_init() call time.
By having that "if (phy->power_count) phy_power_off(phy)" logic, the
ufs-qcom.c technically sidesteps the test, but actually violates the
Generic PHY API even more (calls phy_power_on() *and* phy_power_off()
before phy_init()).
The reason why I stumbled upon this was that I was trying to remove
dereferences of phy->power_count (a PHY internal field) from consumer
drivers.
phy_init(), implemented as qmp_ufs_phy_init(), calls qmp->ufs_reset =
devm_reset_control_get_exclusive(), so my understanding is that it needs
to be called:
- no earlier than ufs_qcom_init() -> devm_reset_controller_register()
which makes qmp->ufs_reset available
- no later than ufs_qcom_power_up_sequence() -> phy_calibrate() ->
qmp_ufs_phy_calibrate() where the qmp->ufs_reset is needed; although
phy_init() should be the first PHY API call made.
The only mystery is why is the current phy_init() placement so late, in
ufs_qcom_power_up_sequence(), but I guess the answer is that the
placement is vestigial. After the incremental work of commit
c9b589791fc1 ("phy: qcom: Utilize UFS reset controller") from
Evan Green and commit cbfd6c124f27 ("phy: qcom-qmp-ufs: Refactor
phy_power_on and phy_calibrate callbacks") from Nitin Rawat, the entire
multi-stage PHY init procedure was moved to phy_power_on(), but nobody
bothered to move phy_init() anywhere else more natural.
So hopefully if the calculations are right, any placement within that
bounding box should be good, and I'm picking the new phy_init() location
to be in ufs_qcom_init().
Even with phy_init() out of the way, ufs_qcom_power_up_sequence() ->
phy_power_off() is still needed, for a separate reason which will be
dealt with separately.
Signed-off-by: Vladimir Oltean <vladimir.oltean@nxp.com>
---
Cc: "James E.J. Bottomley" <James.Bottomley@HansenPartnership.com>
Cc: "Martin K. Petersen" <martin.petersen@oracle.com>
Cc: Dmitry Baryshkov <dmitry.baryshkov@oss.qualcomm.com>
Cc: Nitin Rawat <quic_nitirawa@quicinc.com>
Cc: Manivannan Sadhasivam <mani@kernel.org>
v7->v8: patch is new
Commit was previously posted here but did not get any testing.
https://lore.kernel.org/linux-phy/20260327112858.r5lpqygtvsane2vf@skbuf/
---
drivers/ufs/host/ufs-qcom.c | 22 ++++++++--------------
1 file changed, 8 insertions(+), 14 deletions(-)
diff --git a/drivers/ufs/host/ufs-qcom.c b/drivers/ufs/host/ufs-qcom.c
index bc037db46624..9039b087bf21 100644
--- a/drivers/ufs/host/ufs-qcom.c
+++ b/drivers/ufs/host/ufs-qcom.c
@@ -513,13 +513,6 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
/* phy initialization - calibrate the phy */
- ret = phy_init(phy);
- if (ret) {
- dev_err(hba->dev, "%s: phy init failed, ret = %d\n",
- __func__, ret);
- return ret;
- }
-
ret = phy_set_mode_ext(phy, mode, host->phy_gear);
if (ret)
goto out_disable_phy;
@@ -529,23 +522,18 @@ static int ufs_qcom_power_up_sequence(struct ufs_hba *hba)
if (ret) {
dev_err(hba->dev, "%s: phy power on failed, ret = %d\n",
__func__, ret);
- goto out_disable_phy;
+ return ret;
}
ret = phy_calibrate(phy);
if (ret) {
dev_err(hba->dev, "Failed to calibrate PHY: %d\n", ret);
- goto out_disable_phy;
+ return ret;
}
ufs_qcom_select_unipro_mode(host);
return 0;
-
-out_disable_phy:
- phy_exit(phy);
-
- return ret;
}
/*
@@ -1625,6 +1613,12 @@ static int ufs_qcom_init(struct ufs_hba *hba)
if (err)
goto out_variant_clear;
+ err = phy_init(host->generic_phy);
+ if (err) {
+ dev_err(hba->dev, "phy_init failed: %pe\n", ERR_PTR(err));
+ goto out_variant_clear;
+ }
+
ufs_qcom_setup_clocks(hba, true, POST_CHANGE);
ufs_qcom_get_default_testbus_cfg(host);
--
2.34.1
next prev parent reply other threads:[~2026-05-05 10:07 UTC|newest]
Thread overview: 30+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <20260505100523.1922388-1-vladimir.oltean@nxp.com>
2026-05-05 10:04 ` [PATCH v8 phy-next 01/31] PCI: cadence: Preserve all error codes in cdns_plat_pcie_probe() Vladimir Oltean
2026-05-05 16:26 ` Bjorn Helgaas
2026-05-05 10:04 ` [PATCH v8 phy-next 02/31] ata: add <linux/pm_runtime.h> where missing Vladimir Oltean
2026-05-05 10:04 ` [PATCH v8 phy-next 03/31] PCI: Add missing headers transitively included by <linux/phy/phy.h> Vladimir Oltean
2026-05-05 10:04 ` [PATCH v8 phy-next 04/31] usb: add " Vladimir Oltean
2026-05-05 10:04 ` [PATCH v8 phy-next 05/31] drm: add <linux/pm_runtime.h> where missing Vladimir Oltean
2026-05-05 10:04 ` [PATCH v8 phy-next 06/31] phy: " Vladimir Oltean
2026-05-05 10:04 ` [PATCH v8 phy-next 07/31] phy: spacemit: include missing <linux/phy/phy.h> Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 08/31] net: lan969x: include missing <linux/of.h> Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 09/31] PCI: Remove device links to PHY Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 10/31] scsi: ufs: exynos: use dedicated API for updating PHY bus width Vladimir Oltean
2026-05-05 10:05 ` Vladimir Oltean [this message]
2026-05-05 10:05 ` [PATCH v8 phy-next 12/31] scsi: ufs: qcom: make use of QMP PHY dynamic gear switching ability Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 13/31] scsi: ufs: qcom: keep separate track of PHY power state Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 14/31] scsi: ufs: qcom: include missing <linux/interrupt.h> Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 15/31] drm/rockchip: dw_hdmi: avoid direct dereference of phy->dev.of_node Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 16/31] usb: host: tegra: " Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 17/31] usb: gadget: tegra-xudc: " Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 19/31] phy: make phy_get_mode(), phy_get_bus_width() NULL tolerant Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 20/31] phy: introduce phy_get_max_link_rate() helper for consumers Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 21/31] drm/rockchip: dsi: include PHY provider header Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 22/31] drm: bridge: cdns-mhdp8546: use consumer API for getting PHY bus width Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 23/31] media: sunxi: a83-mips-csi2: include PHY provider header Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 24/31] net: renesas: rswitch: " Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 25/31] pinctrl: tegra-xusb: " Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 26/31] power: supply: cpcap-charger: include missing <linux/property.h> Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 27/31] phy: move ulpi_phy.h from include/linux/phy/ to drivers/phy/ Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 28/31] phy: include PHY provider header (1/2) Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 29/31] phy: include PHY provider header (2/2) Vladimir Oltean
2026-05-05 10:05 ` [PATCH v8 phy-next 31/31] MAINTAINERS: add regexes for linux-phy Vladimir Oltean
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=20260505100523.1922388-12-vladimir.oltean@nxp.com \
--to=vladimir.oltean@nxp.com \
--cc=James.Bottomley@HansenPartnership.com \
--cc=UNGLinuxDriver@microchip.com \
--cc=dmitry.baryshkov@oss.qualcomm.com \
--cc=dri-devel@lists.freedesktop.org \
--cc=freedreno@lists.freedesktop.org \
--cc=linux-arm-kernel@lists.infradead.org \
--cc=linux-arm-msm@vger.kernel.org \
--cc=linux-can@vger.kernel.org \
--cc=linux-gpio@vger.kernel.org \
--cc=linux-ide@vger.kernel.org \
--cc=linux-kernel@vger.kernel.org \
--cc=linux-media@vger.kernel.org \
--cc=linux-pci@vger.kernel.org \
--cc=linux-phy@lists.infradead.org \
--cc=linux-renesas-soc@vger.kernel.org \
--cc=linux-riscv@lists.infradead.org \
--cc=linux-rockchip@lists.infradead.org \
--cc=linux-samsung-soc@vger.kernel.org \
--cc=linux-scsi@vger.kernel.org \
--cc=linux-sunxi@lists.linux.dev \
--cc=linux-tegra@vger.kernel.org \
--cc=linux-usb@vger.kernel.org \
--cc=mani@kernel.org \
--cc=martin.petersen@oracle.com \
--cc=neil.armstrong@linaro.org \
--cc=netdev@vger.kernel.org \
--cc=quic_nitirawa@quicinc.com \
--cc=spacemit@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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox