mirror of
https://github.com/torvalds/linux.git
synced 2026-11-07 06:17:02 +01:00
dmaengine: ste_dma40: Fix probe runtime PM disable
Some d40_probe() error paths jump to destroy_cache before runtime PM has
been enabled for the DMA controller device. The label unconditionally calls
pm_runtime_disable(), which increments disable_depth even though this probe
attempt never enabled runtime PM.
Use devm_pm_runtime_set_active_enabled() to mark the controller active,
enable runtime PM and register balanced cleanup for probe failure. This
avoids both the disable-depth imbalance and ad-hoc probe state tracking.
The interrupt handler uses pm_runtime_get_if_active() and cannot
acknowledge a pending interrupt while runtime PM is disabled. Request the
IRQ only after enabling runtime PM so the handler cannot enter an
unacknowledged interrupt loop during probe.
Fixes: 0618c077a8 ("dmaengine: ste_dma40: Fix PM disable depth imbalance in d40_probe")
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/dmaengine/20260618051539.15E201F000E9@smtp.kernel.org/
Assisted-by: LLM
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Signed-off-by: Linus Walleij <linusw@kernel.org>
Link: https://patch.msgid.link/20260927-dma40-fixes-v7-5-89f595e8851d@kernel.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
parent
8175ead572
commit
c6809b381e
|
|
@ -3752,12 +3752,6 @@ static int __init d40_probe(struct platform_device *pdev)
|
|||
goto destroy_cache;
|
||||
}
|
||||
|
||||
ret = request_irq(base->irq, d40_handle_interrupt, 0, D40_NAME, base);
|
||||
if (ret) {
|
||||
d40_err(dev, "No IRQ defined\n");
|
||||
goto destroy_cache;
|
||||
}
|
||||
|
||||
if (base->plat_data->use_esram_lcla) {
|
||||
|
||||
base->lcpa_regulator = regulator_get(base->dev, "lcla_esram");
|
||||
|
|
@ -3782,10 +3776,20 @@ static int __init d40_probe(struct platform_device *pdev)
|
|||
|
||||
pm_runtime_irq_safe(base->dev);
|
||||
pm_runtime_set_autosuspend_delay(base->dev, DMA40_AUTOSUSPEND_DELAY);
|
||||
pm_runtime_use_autosuspend(base->dev);
|
||||
pm_runtime_mark_last_busy(base->dev);
|
||||
pm_runtime_set_active(base->dev);
|
||||
pm_runtime_enable(base->dev);
|
||||
|
||||
ret = devm_pm_runtime_set_active_enabled(base->dev);
|
||||
if (ret) {
|
||||
d40_err(dev, "Failed to enable runtime PM: %d\n", ret);
|
||||
goto destroy_cache;
|
||||
}
|
||||
pm_runtime_use_autosuspend(base->dev);
|
||||
|
||||
ret = request_irq(base->irq, d40_handle_interrupt, 0, D40_NAME, base);
|
||||
if (ret) {
|
||||
d40_err(dev, "No IRQ defined\n");
|
||||
goto destroy_cache;
|
||||
}
|
||||
|
||||
ret = d40_dmaengine_init(base, num_reserved_chans);
|
||||
if (ret)
|
||||
|
|
@ -3821,7 +3825,6 @@ static int __init d40_probe(struct platform_device *pdev)
|
|||
regulator_disable(base->lcpa_regulator);
|
||||
regulator_put(base->lcpa_regulator);
|
||||
}
|
||||
pm_runtime_disable(base->dev);
|
||||
|
||||
report_failure:
|
||||
d40_err(dev, "probe failed\n");
|
||||
|
|
|
|||
Loading…
Reference in New Issue
Block a user