From: sashiko-bot@kernel.org
To: "Sarath Ganapathiraju" <sarath.ganapathiraju@oss.qualcomm.com>
Cc: linux-clk@vger.kernel.org, devicetree@vger.kernel.org,
robh@kernel.org, conor+dt@kernel.org
Subject: Re: [PATCH v12 2/2] clk: qcom: Add LPASS VA CSR heartbeat pulse clock
Date: Wed, 21 Oct 2026 13:04:47 +0000 [thread overview]
Message-ID: <sashiko-outbox-180284@kernel.org> (raw)
In-Reply-To: <20261021-master-v12-2-9b3df51fd1d7@oss.qualcomm.com>
Thank you for your contribution! Sashiko AI review found 2 potential issue(s) to consider:
- [High] clk: qcom: enable runtime PM after PM clocks in lpass_va_csr_probe()
- [Medium] clk: qcom: lpass-va-csr: stale REGCACHE_MAPLE state across runtime suspend
--
commit 5fda051342340a0aea8fc87d53199c8e2fe790df
Author: Sarath Ganapathiraju <sarath.ganapathiraju@oss.qualcomm.com>
clk: qcom: Add LPASS VA CSR heartbeat pulse clock
This commit adds the Qualcomm LPASS VA CSR clock driver, modeling the
hardware rate generator as a clock provider that manages LPASS vote clocks
and restores counter and delay registers via runtime PM.
> diff --git a/drivers/clk/qcom/lpass-va-csr.c b/drivers/clk/qcom/lpass-va-csr.c
> new file mode 100644
> index 0000000000000..e5fb870aa36de
> --- /dev/null
> +++ b/drivers/clk/qcom/lpass-va-csr.c
> @@ -0,0 +1,180 @@
[ ... ]
> +#define LPASS_RATE_GEN_CTRL 0xd000
> +#define LPASS_RATE_GEN_COUNTER_0 0xd004
> +#define LPASS_RATE_GEN_DELAY 0xd010
> +
> +#define LPASS_RATE_GEN_MAX_REG LPASS_RATE_GEN_DELAY
> +
> +#define LPASS_RG_CTRL_EN BIT(0)
[ ... ]
> +static const struct regmap_config lpass_rate_gen_regmap_config = {
> + .name = "lpass_rate_gen",
> + .reg_bits = 32,
> + .val_bits = 32,
> + .reg_stride = 4,
> + .max_register = LPASS_RATE_GEN_MAX_REG,
> + .cache_type = REGCACHE_MAPLE,
> +};
> +
> +struct lpass_va_csr {
> + const struct lpass_va_csr_data *data;
> + struct clk_regmap hb;
> +};
> +
> +static const struct clk_ops lpass_va_csr_hb_ops = {
> + .enable = clk_enable_regmap,
> + .disable = clk_disable_regmap,
> + .is_enabled = clk_is_enabled_regmap,
> +};
> +
> +static int lpass_va_csr_runtime_resume(struct device *dev)
> +{
> + struct lpass_va_csr *csr = dev_get_drvdata(dev);
> + const struct lpass_va_csr_data *data = csr->data;
> + int ret;
> +
> + ret = pm_clk_resume(dev);
> + if (ret)
> + return ret;
> +
> + ret = regmap_write(csr->hb.regmap, LPASS_RATE_GEN_COUNTER_0,
> + data->counter_0);
> + if (ret)
> + goto err_pm_clk_suspend;
> +
> + ret = regmap_write(csr->hb.regmap, LPASS_RATE_GEN_DELAY, data->delay);
> + if (ret)
> + goto err_pm_clk_suspend;
> +
> + return 0;
> +
> +err_pm_clk_suspend:
> + pm_clk_suspend(dev);
> + return ret;
> +}
> +
> +static int lpass_va_csr_runtime_suspend(struct device *dev)
> +{
> + return pm_clk_suspend(dev);
> +}
[Severity: Medium]
Can setting .cache_type = REGCACHE_MAPLE in lpass_rate_gen_regmap_config
cause clk_enable_regmap() and clk_is_enabled_regmap() to use stale cached
state for LPASS_RATE_GEN_CTRL after LPASS register context is lost across
runtime suspend?
Neither lpass_va_csr_runtime_suspend() nor lpass_va_csr_runtime_resume()
marks the regcache dirty or drops cached registers, and
lpass_va_csr_runtime_resume() only rewrites LPASS_RATE_GEN_COUNTER_0 and
LPASS_RATE_GEN_DELAY.
If LPASS_RATE_GEN_CTRL has LPASS_RG_CTRL_EN set in hardware when first read
(for example, when loaded as a module or booted with clk_ignore_unused and
inspected via debugfs clk_summary -> clk_core_is_enabled() ->
clk_is_enabled_regmap() -> regmap_read()), _regmap_read() caches that
enabled bit in the maple cache.
If the device then runtime-suspends and loses LPASS register context,
hardware resets LPASS_RATE_GEN_CTRL to 0 while the cache retains the set
bit. On a subsequent clk_prepare_enable(), clk_enable_regmap() in
drivers/clk/qcom/clk-regmap.c calls regmap_update_bits():
drivers/clk/qcom/clk-regmap.c:clk_enable_regmap() {
...
return regmap_update_bits(rclk->regmap, rclk->enable_reg,
rclk->enable_mask, val);
}
Because _regmap_update_bits() sees the cached value already has
enable_mask set, it skips the hardware write and leaves the clock disabled
in hardware.
Should .cache_type be omitted from lpass_rate_gen_regmap_config (or
LPASS_RATE_GEN_CTRL marked volatile / the cache invalidated across runtime
suspend)?
> +
> +static int lpass_va_csr_probe(struct platform_device *pdev)
> +{
[ ... ]
> + platform_set_drvdata(pdev, csr);
> +
> + ret = devm_pm_runtime_enable(dev);
> + if (ret)
> + return dev_err_probe(dev, ret, "failed to enable PM runtime\n");
> +
> + ret = devm_pm_clk_create(dev);
> + if (ret)
> + return ret;
> +
> + ret = of_pm_clk_add_clks(dev);
> + if (ret < 0)
> + return dev_err_probe(dev, ret, "failed to get vote clocks\n");
[Severity: High]
What happens if runtime PM is enabled before the PM vote clocks are created
and added in lpass_va_csr_probe()?
In drivers/base/power/clock_ops.c, pm_clk_resume() returns 0 immediately
when dev_to_psd(dev) is NULL or the clock list is empty:
drivers/base/power/clock_ops.c:pm_clk_resume() {
struct pm_subsys_data *psd = dev_to_psd(dev);
...
if (!psd)
return 0;
Because devm_pm_runtime_enable(dev) is called before devm_pm_clk_create(dev)
and of_pm_clk_add_clks(dev), a runtime resume triggered in that window (such
as via sysfs power/control) runs lpass_va_csr_runtime_resume(), receives 0
from pm_clk_resume(dev), and calls regmap_write() on
LPASS_RATE_GEN_COUNTER_0 and LPASS_RATE_GEN_DELAY without the vote clocks
enabled.
In addition, because devres callbacks execute in reverse registration order
on driver unbind or probe error, pm_clk_destroy() (registered by
devm_pm_clk_create()) runs before pm_runtime_disable_action() (registered by
devm_pm_runtime_enable()):
drivers/base/power/clock_ops.c:pm_clk_destroy() {
...
dev_pm_put_subsys_data(dev);
list_for_each_entry_safe_reverse(ce, c, &list, node) {
list_del(&ce->node);
__pm_clk_remove(ce);
}
}
This disables and removes the vote clocks and clears dev->power.subsys_data
while runtime PM is still enabled on the device.
Should devm_pm_clk_create(dev) and of_pm_clk_add_clks(dev) be called before
devm_pm_runtime_enable(dev) in lpass_va_csr_probe()?
[ ... ]
> +}
> +
[ ... ]
>+MODULE_DESCRIPTION("Qualcomm LPASS VA CSR heartbeat pulse clock provider");
>+MODULE_LICENSE("GPL");
--
Sashiko AI review · https://sashiko.dev/#/patchset/20261021-master-v12-0-9b3df51fd1d7@oss.qualcomm.com?part=2
prev parent reply other threads:[~2026-10-21 13:04 UTC|newest]
Thread overview: 7+ messages / expand[flat|nested] mbox.gz Atom feed top
2026-10-21 12:40 [PATCH v12 0/2] Add LPASS VA CSR HeartBeat pulse clock support Sarath Ganapathiraju via B4 Relay
2026-10-21 12:40 ` Sarath Ganapathiraju
2026-10-21 12:40 ` [PATCH v12 1/2] dt-bindings: clock: qcom: Add LPASS VA CSR HeartBeat pulse clock Sarath Ganapathiraju via B4 Relay
2026-10-21 12:40 ` Sarath Ganapathiraju
2026-10-21 12:40 ` [PATCH v12 2/2] clk: qcom: Add LPASS VA CSR heartbeat " Sarath Ganapathiraju via B4 Relay
2026-10-21 12:40 ` Sarath Ganapathiraju
2026-10-21 13:04 ` 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=sashiko-outbox-180284@kernel.org \
--to=sashiko-bot@kernel.org \
--cc=conor+dt@kernel.org \
--cc=devicetree@vger.kernel.org \
--cc=linux-clk@vger.kernel.org \
--cc=robh@kernel.org \
--cc=sarath.ganapathiraju@oss.qualcomm.com \
--cc=sashiko-reviews@lists.linux.dev \
/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.