dmaengine: ste_dma40: Init hardware before registration

d40_probe() enables the interrupt handler and registers DMAengine devices
before calling d40_hw_init(). An interrupt pending from the bootloader can
therefore reach the handler while the hardware interrupt state is not
initialized and channel lookup entries are empty. The handler deliberately
does not acknowledge an interrupt for an unknown channel, so a level IRQ
can retrigger continuously.

Initialize the hardware and set the DMA segment limit before requesting
the IRQ or registering DMAengine devices. d40_hw_init() clears pending
logical and physical interrupt status, so request_irq() can enable the
line normally after the hardware state is initialized.

This ensures that the handler and clients only observe initialized
hardware.

Fixes: 8d318a50b3 ("DMAENGINE: Support for ST-Ericssons DMA40 block v3")
Reported-by: sashiko-bot@kernel.org
Closes: https://lore.kernel.org/dmaengine/20260819225215.5EA2F1F000E9@smtp.kernel.org/
Assisted-by: LLM
Signed-off-by: Linus Walleij <linusw@kernel.org>
Reviewed-by: Frank Li <Frank.Li@nxp.com>
Link: https://patch.msgid.link/20260927-dma40-fixes-v7-9-89f595e8851d@kernel.org
Signed-off-by: Vinod Koul <vkoul@kernel.org>
This commit is contained in:
Linus Walleij 2026-09-27 11:03:22 +02:00 committed by Vinod Koul
parent b96967644c
commit ffd583a734

View File

@ -3830,20 +3830,19 @@ static int __init d40_probe(struct platform_device *pdev)
}
pm_runtime_use_autosuspend(base->dev);
dma_set_max_seg_size(base->dev, STEDMA40_MAX_SEG_SIZE);
d40_hw_init(base);
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)
goto destroy_cache;
dma_set_max_seg_size(base->dev, STEDMA40_MAX_SEG_SIZE);
d40_hw_init(base);
ret = of_dma_controller_register(np, d40_xlate, NULL);
if (ret) {
dev_err(dev,