From: sashiko-bot@kernel.org
To: "Michal Wilczynski" <m.wilczynski@samsung.com>
Cc: vkoul@kernel.org, robh@kernel.org, olteanv@gmail.com,
linux-phy@lists.infradead.org, lee@kernel.org,
mfd@lists.linux.dev, conor+dt@kernel.org,
dri-devel@lists.freedesktop.org, linux-clk@vger.kernel.org,
neil.armstrong@linaro.org, devicetree@vger.kernel.org
Subject: Re: [PATCH v4 18/20] phy: starfive: Add jh7110-inno-hdmi-phy driver
Date: Tue, 15 Sep 2026 15:46:16 +0000 [thread overview]
Message-ID: <20260915154616.B1D171F000FF@smtp.kernel.org> (raw)
In-Reply-To: <20260915-jh7110-clean-send-v4-18-f0e4fd6f2cc8@samsung.com>
Thank you for your contribution! Sashiko AI review found 4 potential issue(s) to consider:
- [High] clk: starfive: Unsafe hardware access in .set_rate causes CPU stall during probe
- [Medium] clk: starfive: Pre-PLL is unconditionally powered on in .set_rate causing a power leak
- [Medium] clk: starfive: Resource lifecycle inversion with refoclk and devres clock provider
- [Medium] clk: starfive: Data race on cached clock state variables between CCF and PHY frameworks
--
commit 5469b7909aa9bb8690ee9fbfe18ef57f4c2d5820
Author: Michal Wilczynski <m.wilczynski@samsung.com>
phy: starfive: Add jh7110-inno-hdmi-phy driver
Add the HDMI PHY driver for the StarFive JH7110.
> diff --git a/drivers/phy/starfive/phy-jh7110-inno-hdmi.c b/drivers/phy/starfive/phy-jh7110-inno-hdmi.c
> new file mode 100644
> index 0000000000000..2575cb5ed624a
> --- /dev/null
> +++ b/drivers/phy/starfive/phy-jh7110-inno-hdmi.c
> @@ -0,0 +1,579 @@
[ ... ]
> +static int starfive_hdmi_phy_clk_set_rate(struct clk_hw *hw, unsigned long rate,
> + unsigned long parent_rate)
> +{
> + struct starfive_hdmi_phy *inno = to_starfive_hdmi_phy(hw);
> + const struct inno_hdmi_phy_pre_pll_config *cfg;
> +
> + /*
> + * The JH7110 only drives 8bpc, so the TMDS clock always matches the
> + * pixel clock.
> + */
> + cfg = inno_hdmi_phy_pre_pll_lookup(&inno->pre_pll, rate, rate);
> + if (IS_ERR(cfg))
> + return PTR_ERR(cfg);
> +
> + dev_dbg(inno->dev, "%s rate %lu tmdsclk %lu\n",
> + __func__, rate, cfg->tmdsclock);
> +
> + if (inno->pixclock == rate && inno->tmdsclock == cfg->tmdsclock)
> + return 0;
> +
> + inno_update_bits(inno, STF_INNO_BIAS_CONTROL,
> + STF_INNO_BIAS_ENABLE, STF_INNO_BIAS_ENABLE);
[Severity: High]
Does this execute an unclocked hardware access if the clock is gated?
The commit message notes that accessing the PHY registers while the HDMI
controller's system clock is gated wedges the CPU. Because
starfive_hdmi_phy_probe() unconditionally calls clk_set_rate() before the
sibling HDMI bridge driver has bound and enabled the shared system clock, the
hardware is gated.
Could a clk_hw_is_prepared(hw) check be added here similarly to how it was
used in .recalc_rate?
> + inno_write(inno, STF_INNO_RX_CONTROL, STF_INNO_RX_ENABLE);
> +
> + inno_hdmi_phy_pre_pll_power_down(&inno->pre_pll, true);
> + inno_hdmi_phy_pre_pll_configure(&inno->pre_pll, cfg);
> + inno_hdmi_phy_pre_pll_power_down(&inno->pre_pll, false);
[Severity: Medium]
Will the Pre-PLL remain powered on indefinitely if the clock isn't prepared?
Since .set_rate turns the Pre-PLL on, and the driver omits the .is_prepared
callback in starfive_hdmi_phy_clk_ops, the CCF relies on the software prepare
count (which is 0). When clk_disable_unused() runs, it skips unprepared clocks
with a 0 count, meaning .unprepare() won't be invoked to turn the PLL off.
> +
> + inno->pixclock = rate;
> + inno->tmdsclock = cfg->tmdsclock;
[Severity: Medium]
Could there be a data race on inno->pixclock and inno->tmdsclock between the
CCF and PHY frameworks?
The CCF callbacks (such as .set_rate and .recalc_rate) read and write
inno->pixclock and inno->tmdsclock under the CCF core's prepare_lock.
Concurrently, the PHY framework operations (such as .power_off calling
starfive_hdmi_phy_power_down()) write to these exact same variables under the
PHY framework's internal phy->mutex.
If userspace triggers a sysfs clock summary read (triggering .recalc_rate)
concurrently with a DRM display modeset or power down sequence, could
.recalc_rate overwrite the 0 set by power_down with stale hardware values?
This might prevent a subsequent set_rate from applying the correct settings.
> +
> + return 0;
> +}
> +
> +static const struct clk_ops starfive_hdmi_phy_clk_ops = {
> + .prepare = starfive_hdmi_phy_clk_prepare,
> + .unprepare = starfive_hdmi_phy_clk_unprepare,
> + .recalc_rate = starfive_hdmi_phy_clk_recalc_rate,
> + .determine_rate = starfive_hdmi_phy_clk_determine_rate,
> + .set_rate = starfive_hdmi_phy_clk_set_rate,
> +};
[Severity: Medium]
The omission of the .is_prepared callback here is what causes
clk_disable_unused() to assume the clock is already physically disabled,
leading to the power leak mentioned in .set_rate.
> +
> +static void starfive_hdmi_phy_power_down(struct starfive_hdmi_phy *inno)
> +{
> + inno_write(inno, STF_INNO_TMDS_CONTROL, 0x00);
> + inno_write(inno, STF_INNO_SERIALIER_CONTROL, 0x00);
> + inno_write(inno, STF_INNO_LDO_CONTROL, 0x00);
> + inno_update_bits(inno, STF_INNO_BIAS_CONTROL,
> + STF_INNO_BIAS_ENABLE, 0x00);
> + inno_write(inno, STF_INNO_RX_CONTROL, 0x00);
> +
> + /* Power down Post-PLL */
> + inno_update_bits(inno, STF_INNO_POST_PLL_DIV_1,
> + STF_INNO_POST_PLL_POWER_DOWN,
> + STF_INNO_POST_PLL_POWER_DOWN);
> +
> + inno->tmdsclock = 0;
> + inno->pixclock = 0;
[Severity: Medium]
This is where the concurrent writes from the PHY framework happen, as noted
in the previous comment about the data race with the CCF callbacks.
> +}
[ ... ]
> +static int starfive_hdmi_phy_probe(struct platform_device *pdev)
> +{
[ ... ]
> + ret = of_clk_add_provider(dev->of_node, of_clk_src_simple_get, inno->phyclk);
> + if (ret) {
> + dev_err(dev, "Failed to add clock provider: %d\n", ret);
> + goto err_disable_refoclk;
> + }
> +
> + ret = clk_set_rate(inno->phyclk, 297000000);
[Severity: High]
This unconditionally triggers a rate change during probe, which leads to the
unsafe hardware access in .set_rate described earlier, since the sibling bridge
driver is not guaranteed to have enabled the shared system clock yet.
> + if (ret) {
> + dev_err(dev, "Failed to set default rate: %d\n", ret);
> + goto err_del_clk_provider;
> + }
> +
> + /* Create and register the PHY provider */
> + inno->phy = devm_phy_create(inno->dev, NULL, &starfive_hdmi_phy_ops);
> + if (IS_ERR(inno->phy)) {
> + ret = PTR_ERR(inno->phy);
> + dev_err(inno->dev, "failed to create HDMI PHY: %d\n", ret);
> + goto err_del_clk_provider;
> + }
> +
> + phy_set_drvdata(inno->phy, inno);
> +
> + phy_provider = devm_of_phy_provider_register(inno->dev,
> + of_phy_simple_xlate);
> + ret = PTR_ERR_OR_ZERO(phy_provider);
> + if (ret)
> + goto err_del_clk_provider;
> +
> + return 0;
> +
> +err_del_clk_provider:
> + of_clk_del_provider(dev->of_node);
> +err_disable_refoclk:
> + clk_disable_unprepare(inno->refoclk);
> + return ret;
[Severity: Medium]
Is it safe to manually disable the reference clock here before devres
unregisters the clock and PHY providers?
The clock and PHY providers are registered using devm_clk_register() and
devm_of_phy_provider_register(). Disabling refoclk manually here (and in
remove) creates a window where operations could execute with a disabled parent
clock if a consumer triggers a clock or PHY operation before devres cleans up
the providers.
Would it be better to bind the refoclk enable state to devres via
devm_clk_get_enabled() or devm_add_action_or_reset()?
> +}
> +
> +static void starfive_hdmi_phy_remove(struct platform_device *pdev)
> +{
> + struct starfive_hdmi_phy *inno = platform_get_drvdata(pdev);
> +
> + of_clk_del_provider(pdev->dev.of_node);
> + clk_disable_unprepare(inno->refoclk);
[Severity: Medium]
As in the probe error path, manually disabling the reference clock before
devres unregisters the providers creates a use-after-disable window.
> +}
--
Sashiko AI review · https://sashiko.dev/#/patchset/20260915-jh7110-clean-send-v4-0-f0e4fd6f2cc8@samsung.com?part=18
next prev parent reply other threads:[~2026-09-15 15:46 UTC|newest]
Thread overview: 74+ messages / expand[flat|nested] mbox.gz Atom feed top
[not found] <CGME20260915153213eucas1p148f013af239a334fc78cdc249c0f8a61@eucas1p1.samsung.com>
2026-09-15 15:32 ` [PATCH v4 00/20] drm: starfive: jh7110: Enable display subsystem Michal Wilczynski
2026-09-15 15:32 ` [PATCH v4 01/20] dt-bindings: phy: Add starfive,jh7110-inno-hdmi-phy Michal Wilczynski
2026-09-15 15:35 ` sashiko-bot
2026-09-17 6:51 ` Krzysztof Kozlowski
2026-09-18 0:34 ` Joshua Peisach
2026-09-18 6:16 ` Krzysztof Kozlowski
2026-09-18 6:21 ` Icenowy Zheng
2026-09-18 6:41 ` Krzysztof Kozlowski
2026-09-25 21:27 ` Michal Wilczynski
2026-09-25 21:05 ` Michal Wilczynski
2026-09-30 11:01 ` Krzysztof Kozlowski
2026-10-03 15:36 ` Michal Wilczynski
2026-10-03 20:45 ` Krzysztof Kozlowski
2026-10-03 22:35 ` Michal Wilczynski
2026-10-04 7:15 ` Krzysztof Kozlowski
2026-10-05 7:27 ` Icenowy Zheng
2026-09-15 15:32 ` [PATCH v4 02/20] dt-bindings: display: bridge: Add starfive,jh7110-inno-hdmi-controller Michal Wilczynski
2026-09-15 15:35 ` sashiko-bot
2026-09-15 15:32 ` [PATCH v4 03/20] dt-bindings: mfd: Add starfive,jh7110-hdmi-subsystem Michal Wilczynski
2026-09-15 15:42 ` sashiko-bot
2026-09-17 6:54 ` Krzysztof Kozlowski
2026-09-28 18:34 ` Michal Wilczynski
2026-09-15 15:32 ` [PATCH v4 04/20] dt-bindings: soc: starfive: Add starfive,jh7110-vout-syscon Michal Wilczynski
2026-09-15 15:35 ` sashiko-bot
2026-09-17 6:55 ` Krzysztof Kozlowski
2026-09-15 15:32 ` [PATCH v4 05/20] dt-bindings: display: verisilicon: Add starfive,jh7110-dc8200 Michal Wilczynski
2026-09-15 15:35 ` sashiko-bot
2026-09-18 5:58 ` Icenowy Zheng
2026-09-27 15:26 ` Michal Wilczynski
2026-09-15 15:32 ` [PATCH v4 06/20] dt-bindings: soc: starfive: Add starfive,jh7110-vout-subsystem Michal Wilczynski
2026-09-15 15:35 ` sashiko-bot
2026-09-24 15:30 ` Rob Herring (Arm)
2026-09-15 15:32 ` [PATCH v4 07/20] drm/bridge: inno-hdmi: Split probe out of bind Michal Wilczynski
2026-09-15 15:44 ` sashiko-bot
2026-09-15 15:32 ` [PATCH v4 08/20] drm/bridge: inno-hdmi: Allow the register map to come from a parent Michal Wilczynski
2026-09-15 15:42 ` sashiko-bot
2026-09-15 15:32 ` [PATCH v4 09/20] drm/bridge: inno-hdmi: Add .disable platform operation Michal Wilczynski
2026-09-15 15:43 ` sashiko-bot
2026-09-15 15:32 ` [PATCH v4 10/20] drm/bridge: inno-hdmi: Add .mode_valid " Michal Wilczynski
2026-09-15 15:37 ` sashiko-bot
2026-09-15 15:32 ` [PATCH v4 11/20] drm/bridge: inno-hdmi: Make the PHY configuration table optional Michal Wilczynski
2026-09-15 15:40 ` sashiko-bot
2026-09-15 15:32 ` [PATCH v4 12/20] soc: starfive: Add jh7110-hdmi-subsystem driver Michal Wilczynski
2026-09-15 15:44 ` sashiko-bot
2026-09-29 15:04 ` Icenowy Zheng
2026-09-15 15:32 ` [PATCH v4 13/20] soc: starfive: Add jh7110-vout-subsystem driver Michal Wilczynski
2026-09-15 15:42 ` sashiko-bot
2026-09-29 15:04 ` Icenowy Zheng
2026-09-15 15:32 ` [PATCH v4 14/20] clk: starfive: jh7110-vout: Allow pixel clock rate propagation Michal Wilczynski
2026-09-15 15:38 ` sashiko-bot
2026-09-15 15:32 ` [PATCH v4 15/20] drm/bridge: starfive: Add JH7110 HDMI controller driver Michal Wilczynski
2026-09-15 15:42 ` sashiko-bot
2026-09-29 15:03 ` Icenowy Zheng
2026-09-15 15:32 ` [PATCH v4 16/20] phy: Add common Innosilicon HDMI PHY helpers Michal Wilczynski
2026-09-15 15:42 ` sashiko-bot
2026-10-03 14:22 ` Vinod Koul
2026-09-15 15:32 ` [PATCH v4 17/20] phy: rockchip: inno-hdmi: Use the common Innosilicon " Michal Wilczynski
2026-09-15 15:44 ` sashiko-bot
2026-09-15 15:32 ` [PATCH v4 18/20] phy: starfive: Add jh7110-inno-hdmi-phy driver Michal Wilczynski
2026-09-15 15:46 ` sashiko-bot [this message]
2026-09-26 3:31 ` Dominique Belhachemi
2026-09-27 12:05 ` Michal Wilczynski
2026-09-15 15:32 ` [PATCH v4 19/20] riscv: dts: starfive: jh7110: Update DT for display subsystem Michal Wilczynski
2026-09-15 15:49 ` sashiko-bot
2026-09-29 15:06 ` Icenowy Zheng
2026-09-15 15:32 ` [PATCH v4 20/20] MAINTAINERS: Add StarFive JH7110 display subsystem entry Michal Wilczynski
2026-09-16 0:45 ` [PATCH v4 00/20] drm: starfive: jh7110: Enable display subsystem Joshua Peisach
2026-09-17 17:22 ` Michal Wilczynski
2026-09-18 15:32 ` Joshua Peisach
2026-09-27 12:24 ` Michal Wilczynski
2026-09-20 6:09 ` Byron Stanoszek
2026-09-20 7:35 ` Icenowy Zheng
2026-09-25 20:09 ` Michal Wilczynski
2026-09-25 13:55 ` (subset) " Brian Masney
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=20260915154616.B1D171F000FF@smtp.kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=dri-devel@lists.freedesktop.org \
--cc=lee@kernel.org \
--cc=linux-clk@vger.kernel.org \
--cc=linux-phy@lists.infradead.org \
--cc=m.wilczynski@samsung.com \
--cc=mfd@lists.linux.dev \
--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