From: sashiko-bot@kernel.org
To: "Kartik Rajput" <kkartik@nvidia.com>
Cc: robh@kernel.org, olteanv@gmail.com, neil.armstrong@linaro.org,
linux-phy@lists.infradead.org, conor+dt@kernel.org,
devicetree@vger.kernel.org, vkoul@kernel.org
Subject: Re: [PATCH 2/2] phy: tegra: Add Tegra264 MPHY driver
Date: Wed, 09 Sep 2026 09:54:19 +0000 [thread overview]
Message-ID: <20260909095419.C30C81F00A3D@smtp.kernel.org> (raw)
In-Reply-To: <20260909-tegra264-mphy-v1-2-ce61a80dc065@nvidia.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] Data race on shared `mphy->power_count` and clock state across multiple PHY instances.
- [High] TX PHY lacks power management operations, creating a fragile API contract that risks system crashes.
- [High] Wrong base address pointer used for `MPHY_RX_APB_CAPABILITY` registers.
- [Medium] Missing reset assertion for `mphy->rst_clk_ctl` in the normal `tegra_mphy_rx_power_off` path.
--
commit bceb08380e03847a80ce77db39c3ff271cbccb0c
Author: Kartik Rajput <kkartik@nvidia.com>
phy: tegra: Add Tegra264 MPHY driver
Add a driver for the MIPI M-PHY found on NVIDIA Tegra264 SoCs. The
M-PHY has two lanes, each with a transmit and a receive direction,
exposed as four PHYs to the UFS host controller.
> diff --git a/drivers/phy/tegra/phy-tegra-mphy.c b/drivers/phy/tegra/phy-tegra-mphy.c
> index 0000000000000..01cafe1c7477f
> --- /dev/null
> +++ b/drivers/phy/tegra/phy-tegra-mphy.c
[ ... ]
> +static int tegra_mphy_rx_power_on(struct phy *phy)
> +{
> + struct tegra_mphy *mphy = dev_get_drvdata(phy->dev.parent);
> + struct tegra_mphy_lane *lane = phy_get_drvdata(phy);
> + u32 value;
> + int err;
> +
> + if (mphy->power_count++ == 0) {
^^^^^^^^^^^^^^^^^^^^^^^
[Severity: High]
Since l0 and l1 are distinct PHY instances exposed to the consumer, can
concurrent phy_power_on() or phy_power_off() calls race on this shared
mphy->power_count?
The PHY framework's internal mutex only serializes operations on a per-PHY
basis. An unprotected read-modify-write here could lead to corrupted
reference counts, unbalanced clock states, and hardware faults.
> + err = clk_bulk_prepare_enable(mphy->num_clks, mphy->clks);
> + if (err) {
> + mphy->power_count--;
> + dev_err(&phy->dev, "failed to enable clocks: %d\n", err);
> + return err;
> + }
> + reset_control_deassert(mphy->rst_clk_ctl);
> + }
> +
> + reset_control_deassert(lane->rst_rx);
> + reset_control_deassert(lane->rst_tx);
^^^^^^^^^^^^^^^^^^^^
[Severity: High]
Is it intentional that the RX power-on path handles the reset logic for the
independently exposed TX PHY?
The TX PHY currently lacks .power_on and .power_off callbacks and seems to
rely implicitly on the RX PHY to enable hardware clocks. If the TX PHY is
accessed via phy_configure() before the RX PHY is fully powered on, could
this result in unclocked memory-mapped I/O and trigger a synchronous
external abort?
> +
> + err = tegra_mphy_rx_write_kick_go(lane, MPHY_RX_APB_VENDOR3B, MPHY_EQ_TIMEOUT);
> + if (err) {
> + dev_err(&phy->dev, "eq_timeout programming failed: %d\n", err);
> + goto err_reset;
> + }
> +
> + err = tegra_mphy_rx_write_kick_go(lane, MPHY_RX_APB_VENDOR49, MPHY_PWR_CHANGE_CLK_BOOST);
> + if (err) {
> + dev_err(&phy->dev, "pwr_change_clk_boost programming failed: %d\n", err);
> + goto err_reset;
> + }
> +
> + value = readl(lane->regs + MPHY_RX_APB_CAPABILITY_88_8B);
^^^^^^^^^^
[Severity: High]
Should this use lane->rx_regs instead of lane->regs for offset application?
Using lane->regs misdirects the read/write operations to offsets 0x88 and
0x94 instead of 0x2088 and 0x2094 (since MPHY_RX_OFFSET is 0x2000), which
may lead to memory corruption and failed configurations.
> + value &= ~RX_HS_G1_SYNC_LENGTH_CAPABILITY(~0);
> + value |= RX_HS_G1_SYNC_LENGTH_CAPABILITY(0xf);
> + writel(value, lane->regs + MPHY_RX_APB_CAPABILITY_88_8B);
> +
> + value = readl(lane->regs + MPHY_RX_APB_CAPABILITY_94_97);
^^^^^^^^^^
[Severity: High]
Does this also need to use lane->rx_regs instead of lane->regs?
> + value &= ~RX_HS_G3_SYNC_LENGTH_CAPABILITY(~0);
> + value |= RX_HS_G3_SYNC_LENGTH_CAPABILITY(0xf);
> + value &= ~RX_HS_G2_SYNC_LENGTH_CAPABILITY(~0);
> + value |= RX_HS_G2_SYNC_LENGTH_CAPABILITY(0xf);
> + writel(value, lane->regs + MPHY_RX_APB_CAPABILITY_94_97);
[ ... ]
> +static int tegra_mphy_rx_power_off(struct phy *phy)
> +{
> + struct tegra_mphy *mphy = dev_get_drvdata(phy->dev.parent);
> + struct tegra_mphy_lane *lane = phy_get_drvdata(phy);
> +
> + if (WARN_ON(mphy->power_count == 0))
> + return -EINVAL;
> +
> + reset_control_assert(lane->rst_rx);
> + reset_control_assert(lane->rst_tx);
> +
> + if (--mphy->power_count == 0)
> + clk_bulk_disable_unprepare(mphy->num_clks, mphy->clks);
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
[Severity: Medium]
Should mphy->rst_clk_ctl be asserted here before or after disabling the
clocks?
The driver intentionally deasserts mphy->rst_clk_ctl in
tegra_mphy_rx_power_on() when power_count goes from 0 to 1, but omits the
corresponding reset_control_assert() in this successful power-off path,
which leaks the reset state across power cycles.
> +
> + return 0;
> +}
[ ... ]
> +static const struct phy_ops tegra_mphy_tx_ops = {
> + .configure = tegra_mphy_tx_configure,
> + .calibrate = tegra_mphy_tx_calibrate,
> +};
^^
[Severity: High]
Are .power_on and .power_off callbacks intentionally omitted for the TX PHY
ops?
Leaving the TX PHY exposed to configuration while in an unclocked state
creates a fragile API contract that risks system crashes.
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260909-tegra264-mphy-v1-0-ce61a80dc065@nvidia.com?part=2
prev parent reply other threads:[~2026-09-09 9:54 UTC|newest]
Thread overview: 5+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-09-09 9:43 [PATCH 0/2] Add M-PHY support for NVIDIA Tegra264 Kartik Rajput
2026-09-09 9:43 ` [PATCH 1/2] dt-bindings: phy: Add nvidia,tegra264-mphy Kartik Rajput
2026-09-13 8:38 ` Krzysztof Kozlowski
2026-09-09 9:43 ` [PATCH 2/2] phy: tegra: Add Tegra264 MPHY driver Kartik Rajput
2026-09-09 9:54 ` sashiko-bot [this message]
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=20260909095419.C30C81F00A3D@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=kkartik@nvidia.com \
--cc=linux-phy@lists.infradead.org \
--cc=neil.armstrong@linaro.org \
--cc=olteanv@gmail.com \
--cc=robh@kernel.org \
--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 a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox