* [PATCH 0/2] dmaengine: qcom: bam_dma: Fixes for unbind @ 2026-10-20 18:08 Mostafa Saleh 2026-10-20 18:08 ` [PATCH 1/2] dmaengine: qcom: bam_dma: Take a PM ref at remove() Mostafa Saleh 2026-10-20 18:08 ` [PATCH 2/2] dmaengine: qcom: bam_dma: Do not touch remote BAM in remove() Mostafa Saleh 0 siblings, 2 replies; 6+ messages in thread From: Mostafa Saleh @ 2026-10-20 18:08 UTC (permalink / raw) To: linux-kernel, dmaengine Cc: linux-arm-msm, vkoul, Frank.Li, bartosz.golaszewski, pramod.gurav, andy.gross, Mostafa Saleh On Lenovo Mini-x Gen 10 (X1P42100 based) I am using VFIO-platform to assing the QCE/BAM to VMs. During unbind: echo 1dc4000.dma-controller > /sys/bus/platform/drivers/bam-dma-engine/unbind echo 1dfa000.crypto > /sys/bus/platform/drivers/qcrypto/unbind I see a system reset quite often, looking more into this, that seems to be related to runtime PM, with those fixes I don't see that anymore. This patches apply on linux-next. Mostafa Saleh (2): dmaengine: qcom: bam_dma: Take a PM ref at remove() dmaengine: qcom: bam_dma: Do not touch remote BAM in remove() drivers/dma/qcom/bam_dma.c | 18 +++++++++++++----- 1 file changed, 13 insertions(+), 5 deletions(-) -- 2.56.0.212.g129ede20d9-goog ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 1/2] dmaengine: qcom: bam_dma: Take a PM ref at remove() 2026-10-20 18:08 [PATCH 0/2] dmaengine: qcom: bam_dma: Fixes for unbind Mostafa Saleh @ 2026-10-20 18:08 ` Mostafa Saleh 2026-10-20 18:47 ` Frank Li 2026-10-20 18:08 ` [PATCH 2/2] dmaengine: qcom: bam_dma: Do not touch remote BAM in remove() Mostafa Saleh 1 sibling, 1 reply; 6+ messages in thread From: Mostafa Saleh @ 2026-10-20 18:08 UTC (permalink / raw) To: linux-kernel, dmaengine Cc: linux-arm-msm, vkoul, Frank.Li, bartosz.golaszewski, pramod.gurav, andy.gross, Mostafa Saleh bam_dma_remove() calls pm_runtime_dont_use_autosuspend() and pm_runtime_force_suspend(), which on a BAM with its own clock disables bam_clk, and only then writes BAM_IRQ_SRCS_MSK_EE and terminates the channels, touching registers of a block whose clock has just been removed, causing the board to reset. Sashiko(Locally) also reports, it then calls clk_disable_unprepare() on a clock that runtime suspend already disabled, which can trigger "already disabled" warning in clk_core_disable(). Hold a runtime PM reference across the register accesses and the channel teardown. Once the hardware is quiet, disable runtime PM with the device still active and drop the clock exactly once, balancing the clk_prepare_enable() in probe. Fixes: 7d2545599f5b ("dmaengine: qcom-bam-dma: Add pm_runtime support") Signed-off-by: Mostafa Saleh <smostafa@google.com> --- drivers/dma/qcom/bam_dma.c | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c index f67a93a37d48..bd583f78e0c1 100644 --- a/drivers/dma/qcom/bam_dma.c +++ b/drivers/dma/qcom/bam_dma.c @@ -1403,12 +1403,10 @@ static void bam_dma_remove(struct platform_device *pdev) struct bam_device *bdev = platform_get_drvdata(pdev); u32 i; - pm_runtime_dont_use_autosuspend(&pdev->dev); - pm_runtime_force_suspend(&pdev->dev); - of_dma_controller_free(pdev->dev.of_node); dma_async_device_unregister(&bdev->common); + pm_runtime_get_sync(&pdev->dev); /* mask all interrupts for this execution environment */ writel_relaxed(0, bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); @@ -1428,6 +1426,9 @@ static void bam_dma_remove(struct platform_device *pdev) tasklet_kill(&bdev->task); + pm_runtime_dont_use_autosuspend(&pdev->dev); + pm_runtime_disable(&pdev->dev); + pm_runtime_put_noidle(&pdev->dev); clk_disable_unprepare(bdev->bamclk); } -- 2.56.0.212.g129ede20d9-goog ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] dmaengine: qcom: bam_dma: Take a PM ref at remove() 2026-10-20 18:08 ` [PATCH 1/2] dmaengine: qcom: bam_dma: Take a PM ref at remove() Mostafa Saleh @ 2026-10-20 18:47 ` Frank Li 2026-10-20 20:29 ` Mostafa Saleh 0 siblings, 1 reply; 6+ messages in thread From: Frank Li @ 2026-10-20 18:47 UTC (permalink / raw) To: Mostafa Saleh Cc: linux-kernel, dmaengine, linux-arm-msm, vkoul, Frank.Li, bartosz.golaszewski, pramod.gurav, andy.gross On Tue, Oct 20, 2026 at 06:08:02PM +0000, Mostafa Saleh wrote: > [You don't often get email from smostafa@google.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ] > > bam_dma_remove() calls pm_runtime_dont_use_autosuspend() and > pm_runtime_force_suspend(), which on a BAM with its own clock disables > bam_clk, and only then writes BAM_IRQ_SRCS_MSK_EE and terminates the > channels, touching registers of a block whose clock has just been > removed, causing the board to reset. > > Sashiko(Locally) also reports, it then calls clk_disable_unprepare() > on a clock that runtime suspend already disabled, which can trigger > "already disabled" warning in clk_core_disable(). > > Hold a runtime PM reference across the register accesses and the > channel teardown. Once the hardware is quiet, disable runtime PM with > the device still active and drop the clock exactly once, balancing the > clk_prepare_enable() in probe. > > Fixes: 7d2545599f5b ("dmaengine: qcom-bam-dma: Add pm_runtime support") > Signed-off-by: Mostafa Saleh <smostafa@google.com> > --- > drivers/dma/qcom/bam_dma.c | 7 ++++--- > 1 file changed, 4 insertions(+), 3 deletions(-) > > diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c > index f67a93a37d48..bd583f78e0c1 100644 > --- a/drivers/dma/qcom/bam_dma.c > +++ b/drivers/dma/qcom/bam_dma.c > @@ -1403,12 +1403,10 @@ static void bam_dma_remove(struct platform_device *pdev) > struct bam_device *bdev = platform_get_drvdata(pdev); > u32 i; > > - pm_runtime_dont_use_autosuspend(&pdev->dev); > - pm_runtime_force_suspend(&pdev->dev); > - > of_dma_controller_free(pdev->dev.of_node); > dma_async_device_unregister(&bdev->common); > > + pm_runtime_get_sync(&pdev->dev); > /* mask all interrupts for this execution environment */ > writel_relaxed(0, bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); > > @@ -1428,6 +1426,9 @@ static void bam_dma_remove(struct platform_device *pdev) > > tasklet_kill(&bdev->task); > > + pm_runtime_dont_use_autosuspend(&pdev->dev); After commit d1706f9da9f40dffe8621cc0ee03b847f41f1d6d Author: Joshua Crofts <joshua.crofts1@gmail.com> Date: Sat Sep 19 10:24:28 2026 +0200 PM: runtime: call pm_runtime_dont_use_autosuspend() on reinit() Add a pm_runtime_dont_use_autosuspend() call to pm_runtime_reinit() to ensure autosuspend is disabled on driver teardown. Suggested-by: Frank Li <Frank.Li@nxp.com> Signed-off-by: Joshua Crofts <joshua.crofts1@gmail.com> Link: https://patch.msgid.link/20260919-move-dont-use-autosuspend-v1-1-f6e2d1315c23@gmail.com Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> Needn't call pm_runtime_dont_use_autosuspend() > + pm_runtime_disable(&pdev->dev); Can you use devm_pm_*() call to fix this problem. Frank > + pm_runtime_put_noidle(&pdev->dev); > clk_disable_unprepare(bdev->bamclk); > } > > -- > 2.56.0.212.g129ede20d9-goog > ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 1/2] dmaengine: qcom: bam_dma: Take a PM ref at remove() 2026-10-20 18:47 ` Frank Li @ 2026-10-20 20:29 ` Mostafa Saleh 0 siblings, 0 replies; 6+ messages in thread From: Mostafa Saleh @ 2026-10-20 20:29 UTC (permalink / raw) To: Frank Li Cc: linux-kernel, dmaengine, linux-arm-msm, vkoul, Frank.Li, bartosz.golaszewski, pramod.gurav, andy.gross On Tue, Oct 20, 2026 at 01:47:30PM -0500, Frank Li wrote: > On Tue, Oct 20, 2026 at 06:08:02PM +0000, Mostafa Saleh wrote: > > [You don't often get email from smostafa@google.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ] > > > > bam_dma_remove() calls pm_runtime_dont_use_autosuspend() and > > pm_runtime_force_suspend(), which on a BAM with its own clock disables > > bam_clk, and only then writes BAM_IRQ_SRCS_MSK_EE and terminates the > > channels, touching registers of a block whose clock has just been > > removed, causing the board to reset. > > > > Sashiko(Locally) also reports, it then calls clk_disable_unprepare() > > on a clock that runtime suspend already disabled, which can trigger > > "already disabled" warning in clk_core_disable(). > > > > Hold a runtime PM reference across the register accesses and the > > channel teardown. Once the hardware is quiet, disable runtime PM with > > the device still active and drop the clock exactly once, balancing the > > clk_prepare_enable() in probe. > > > > Fixes: 7d2545599f5b ("dmaengine: qcom-bam-dma: Add pm_runtime support") > > Signed-off-by: Mostafa Saleh <smostafa@google.com> > > --- > > drivers/dma/qcom/bam_dma.c | 7 ++++--- > > 1 file changed, 4 insertions(+), 3 deletions(-) > > > > diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c > > index f67a93a37d48..bd583f78e0c1 100644 > > --- a/drivers/dma/qcom/bam_dma.c > > +++ b/drivers/dma/qcom/bam_dma.c > > @@ -1403,12 +1403,10 @@ static void bam_dma_remove(struct platform_device *pdev) > > struct bam_device *bdev = platform_get_drvdata(pdev); > > u32 i; > > > > - pm_runtime_dont_use_autosuspend(&pdev->dev); > > - pm_runtime_force_suspend(&pdev->dev); > > - > > of_dma_controller_free(pdev->dev.of_node); > > dma_async_device_unregister(&bdev->common); > > > > + pm_runtime_get_sync(&pdev->dev); > > /* mask all interrupts for this execution environment */ > > writel_relaxed(0, bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); > > > > @@ -1428,6 +1426,9 @@ static void bam_dma_remove(struct platform_device *pdev) > > > > tasklet_kill(&bdev->task); > > > > + pm_runtime_dont_use_autosuspend(&pdev->dev); > > After > > commit d1706f9da9f40dffe8621cc0ee03b847f41f1d6d > Author: Joshua Crofts <joshua.crofts1@gmail.com> > Date: Sat Sep 19 10:24:28 2026 +0200 > > PM: runtime: call pm_runtime_dont_use_autosuspend() on reinit() > > Add a pm_runtime_dont_use_autosuspend() call to pm_runtime_reinit() to > ensure autosuspend is disabled on driver teardown. > > Suggested-by: Frank Li <Frank.Li@nxp.com> > Signed-off-by: Joshua Crofts <joshua.crofts1@gmail.com> > Link: https://patch.msgid.link/20260919-move-dont-use-autosuspend-v1-1-f6e2d1315c23@gmail.com > Signed-off-by: Rafael J. Wysocki <rafael.j.wysocki@intel.com> > > > Needn't call pm_runtime_dont_use_autosuspend() I see, thanks for pointing that out, I will remove it in v2. > > > > + pm_runtime_disable(&pdev->dev); > > Can you use devm_pm_*() call to fix this problem. AFAICT, in that case we need to gate the clk_disable_unprepare() in remove() as the suspend() also runs after remove(), so clk_disable() would be called twice. The problem seems to be bam_dma_runtime_resume/suspend() calling clk_enable/disable() but also remove() calls disable(), so something as: --- a/drivers/dma/qcom/bam_dma.c +++ b/drivers/dma/qcom/bam_dma.c @@ -1379,7 +1379,7 @@ static int bam_dma_probe(struct platform_device *pdev) pm_runtime_use_autosuspend(&pdev->dev); pm_runtime_mark_last_busy(&pdev->dev); pm_runtime_set_active(&pdev->dev); - pm_runtime_enable(&pdev->dev); + devm_pm_runtime_enable(&pdev->dev); return 0; @@ -1433,9 +1433,10 @@ static void bam_dma_remove(struct platform_device *pdev) tasklet_kill(&bdev->task); - pm_runtime_disable(&pdev->dev); pm_runtime_put_noidle(&pdev->dev); +#ifndef CONFIG_PM clk_disable_unprepare(bdev->bamclk); +#endif } static int __maybe_unused bam_dma_runtime_suspend(struct device *dev) I can see example for both patterns in tree. However, 2) seems to be more common: 1) Gating CONFIG_PM: drivers/mailbox/mtk-cmdq-mailbox.c 2) Get/disable/put_noidle then clk_disable(): drivers/mmc/host/sdhci-msm.c Thanks, Mostafa > > Frank > > + pm_runtime_put_noidle(&pdev->dev); > > clk_disable_unprepare(bdev->bamclk); > > } > > > > -- > > 2.56.0.212.g129ede20d9-goog > > ^ permalink raw reply [flat|nested] 6+ messages in thread
* [PATCH 2/2] dmaengine: qcom: bam_dma: Do not touch remote BAM in remove() 2026-10-20 18:08 [PATCH 0/2] dmaengine: qcom: bam_dma: Fixes for unbind Mostafa Saleh 2026-10-20 18:08 ` [PATCH 1/2] dmaengine: qcom: bam_dma: Take a PM ref at remove() Mostafa Saleh @ 2026-10-20 18:08 ` Mostafa Saleh 2026-10-20 18:48 ` Frank Li 1 sibling, 1 reply; 6+ messages in thread From: Mostafa Saleh @ 2026-10-20 18:08 UTC (permalink / raw) To: linux-kernel, dmaengine Cc: linux-arm-msm, vkoul, Frank.Li, bartosz.golaszewski, pramod.gurav, andy.gross, Mostafa Saleh Unbinding the crypto BAM through sysfs on X1P42100 resets the board. bam_dma_remove() clears BAM_IRQ_SRCS_MSK_EE unconditionally. For a BAM that is controlled or powered remotely the register may not be accessible: the clock and power of the block belong to the remote side or to the consumer of the BAM, which is why bam_init() already avoids every register access for such a BAM when the DT provides num-channels and qcom,num-ees. The write is also unnecessary. On a remotely controlled BAM the driver only ever sets per channel bits in the EE mask, in bam_chan_init_hw(), and bam_free_chan() clears them again. Both run on behalf of a consumer, which keeps the block clocked while they do. Skip the write for both kinds of remotely managed BAM, using the same condition as bam_init(). Fixes: 5172c9eb89d4 ("dmaengine: qcom: bam_dma: add controlled-remotely dt property") Signed-off-by: Mostafa Saleh <smostafa@google.com> --- drivers/dma/qcom/bam_dma.c | 11 +++++++++-- 1 file changed, 9 insertions(+), 2 deletions(-) diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c index bd583f78e0c1..d818fa1dba57 100644 --- a/drivers/dma/qcom/bam_dma.c +++ b/drivers/dma/qcom/bam_dma.c @@ -1407,8 +1407,15 @@ static void bam_dma_remove(struct platform_device *pdev) dma_async_device_unregister(&bdev->common); pm_runtime_get_sync(&pdev->dev); - /* mask all interrupts for this execution environment */ - writel_relaxed(0, bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); + + /* + * Mask all interrupts for this execution environment. A remotely + * controlled or powered BAM is left alone: it may be unclocked, and + * the only bits this driver sets in its mask are the per channel + * ones that bam_free_chan() cleared. + */ + if (!bdev->controlled_remotely && !bdev->powered_remotely) + writel_relaxed(0, bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); free_irq(bdev->irq, bdev); -- 2.56.0.212.g129ede20d9-goog ^ permalink raw reply [flat|nested] 6+ messages in thread
* Re: [PATCH 2/2] dmaengine: qcom: bam_dma: Do not touch remote BAM in remove() 2026-10-20 18:08 ` [PATCH 2/2] dmaengine: qcom: bam_dma: Do not touch remote BAM in remove() Mostafa Saleh @ 2026-10-20 18:48 ` Frank Li 0 siblings, 0 replies; 6+ messages in thread From: Frank Li @ 2026-10-20 18:48 UTC (permalink / raw) To: Mostafa Saleh Cc: linux-kernel, dmaengine, linux-arm-msm, vkoul, Frank.Li, bartosz.golaszewski, pramod.gurav, andy.gross On Tue, Oct 20, 2026 at 06:08:03PM +0000, Mostafa Saleh wrote: > [You don't often get email from smostafa@google.com. Learn why this is important at https://aka.ms/LearnAboutSenderIdentification ] > > Unbinding the crypto BAM through sysfs on X1P42100 resets the board. > bam_dma_remove() clears BAM_IRQ_SRCS_MSK_EE unconditionally. For a BAM > that is controlled or powered remotely the register may not be > accessible: the clock and power of the block belong to the remote side > or to the consumer of the BAM, which is why bam_init() already avoids > every register access for such a BAM when the DT provides num-channels > and qcom,num-ees. > > The write is also unnecessary. On a remotely controlled BAM the driver > only ever sets per channel bits in the EE mask, in bam_chan_init_hw(), > and bam_free_chan() clears them again. Both run on behalf of a > consumer, which keeps the block clocked while they do. > > Skip the write for both kinds of remotely managed BAM, using the same > condition as bam_init(). > > Fixes: 5172c9eb89d4 ("dmaengine: qcom: bam_dma: add controlled-remotely dt property") > Signed-off-by: Mostafa Saleh <smostafa@google.com> > --- Reviewed-by: Frank Li <Frank.Li@nxp.com> > drivers/dma/qcom/bam_dma.c | 11 +++++++++-- > 1 file changed, 9 insertions(+), 2 deletions(-) > > diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c > index bd583f78e0c1..d818fa1dba57 100644 > --- a/drivers/dma/qcom/bam_dma.c > +++ b/drivers/dma/qcom/bam_dma.c > @@ -1407,8 +1407,15 @@ static void bam_dma_remove(struct platform_device *pdev) > dma_async_device_unregister(&bdev->common); > > pm_runtime_get_sync(&pdev->dev); > - /* mask all interrupts for this execution environment */ > - writel_relaxed(0, bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); > + > + /* > + * Mask all interrupts for this execution environment. A remotely > + * controlled or powered BAM is left alone: it may be unclocked, and > + * the only bits this driver sets in its mask are the per channel > + * ones that bam_free_chan() cleared. > + */ > + if (!bdev->controlled_remotely && !bdev->powered_remotely) > + writel_relaxed(0, bam_addr(bdev, 0, BAM_IRQ_SRCS_MSK_EE)); > > free_irq(bdev->irq, bdev); > > -- > 2.56.0.212.g129ede20d9-goog > ^ permalink raw reply [flat|nested] 6+ messages in thread
end of thread, other threads:[~2026-10-20 20:29 UTC | newest] Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed) -- links below jump to the message on this page -- 2026-10-20 18:08 [PATCH 0/2] dmaengine: qcom: bam_dma: Fixes for unbind Mostafa Saleh 2026-10-20 18:08 ` [PATCH 1/2] dmaengine: qcom: bam_dma: Take a PM ref at remove() Mostafa Saleh 2026-10-20 18:47 ` Frank Li 2026-10-20 20:29 ` Mostafa Saleh 2026-10-20 18:08 ` [PATCH 2/2] dmaengine: qcom: bam_dma: Do not touch remote BAM in remove() Mostafa Saleh 2026-10-20 18:48 ` Frank Li
This is a public inbox, see mirroring instructions for how to clone and mirror all data and code used for this inbox
all inboxes | Powered by JetHome®