mirror of https://lore.kernel.org/lkml/
 help / color / mirror / Atom feed
* [PATCH v2 0/2] dmaengine: qcom: bam_dma: Fixes for unbind
@ 2026-10-23 10:15 Mostafa Saleh
  2026-10-23 10:15 ` [PATCH v2 1/2] dmaengine: qcom: bam_dma: Take a PM ref at remove() Mostafa Saleh
  2026-10-23 10:15 ` [PATCH v2 2/2] dmaengine: qcom: bam_dma: Do not touch remote BAM in remove() Mostafa Saleh
  0 siblings, 2 replies; 3+ messages in thread
From: Mostafa Saleh @ 2026-10-23 10:15 UTC (permalink / raw)
  To: linux-kernel, dmaengine
  Cc: linux-arm-msm, vkoul, Frank.Li, bartosz.golaszewski, Mostafa Saleh

On Lenovo Mini-x Gen 10 (X1P42100 based) I am using VFIO-platform
to assign 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.

Changes in v2:
v1: https://lore.kernel.org/all/20261020180804.140766-1-smostafa@google.com/
- Collect Frank Rb
- Drop call to pm_runtime_dont_use_autosuspend()

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 | 17 ++++++++++++-----
 1 file changed, 12 insertions(+), 5 deletions(-)


base-commit: bd1ecbb61afefc6a8b876ccbc31e9228b44e9eab
-- 
2.56.0.307.g5fe7bd680c-goog


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH v2 1/2] dmaengine: qcom: bam_dma: Take a PM ref at remove()
  2026-10-23 10:15 [PATCH v2 0/2] dmaengine: qcom: bam_dma: Fixes for unbind Mostafa Saleh
@ 2026-10-23 10:15 ` Mostafa Saleh
  2026-10-23 10:15 ` [PATCH v2 2/2] dmaengine: qcom: bam_dma: Do not touch remote BAM in remove() Mostafa Saleh
  1 sibling, 0 replies; 3+ messages in thread
From: Mostafa Saleh @ 2026-10-23 10:15 UTC (permalink / raw)
  To: linux-kernel, dmaengine
  Cc: linux-arm-msm, vkoul, Frank.Li, bartosz.golaszewski, 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 | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

diff --git a/drivers/dma/qcom/bam_dma.c b/drivers/dma/qcom/bam_dma.c
index f67a93a37d48..8a1f4e5d24d1 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,8 @@ static void bam_dma_remove(struct platform_device *pdev)
 
 	tasklet_kill(&bdev->task);
 
+	pm_runtime_disable(&pdev->dev);
+	pm_runtime_put_noidle(&pdev->dev);
 	clk_disable_unprepare(bdev->bamclk);
 }
 
-- 
2.56.0.307.g5fe7bd680c-goog


^ permalink raw reply	[flat|nested] 3+ messages in thread

* [PATCH v2 2/2] dmaengine: qcom: bam_dma: Do not touch remote BAM in remove()
  2026-10-23 10:15 [PATCH v2 0/2] dmaengine: qcom: bam_dma: Fixes for unbind Mostafa Saleh
  2026-10-23 10:15 ` [PATCH v2 1/2] dmaengine: qcom: bam_dma: Take a PM ref at remove() Mostafa Saleh
@ 2026-10-23 10:15 ` Mostafa Saleh
  1 sibling, 0 replies; 3+ messages in thread
From: Mostafa Saleh @ 2026-10-23 10:15 UTC (permalink / raw)
  To: linux-kernel, dmaengine
  Cc: linux-arm-msm, vkoul, Frank.Li, bartosz.golaszewski,
	Mostafa Saleh, Frank Li

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")
Reviewed-by: Frank Li <Frank.Li@nxp.com>
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 8a1f4e5d24d1..e01f0fec1599 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.307.g5fe7bd680c-goog


^ permalink raw reply	[flat|nested] 3+ messages in thread

end of thread, other threads:[~2026-10-23 10:16 UTC | newest]

Thread overview: 3+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2026-10-23 10:15 [PATCH v2 0/2] dmaengine: qcom: bam_dma: Fixes for unbind Mostafa Saleh
2026-10-23 10:15 ` [PATCH v2 1/2] dmaengine: qcom: bam_dma: Take a PM ref at remove() Mostafa Saleh
2026-10-23 10:15 ` [PATCH v2 2/2] dmaengine: qcom: bam_dma: Do not touch remote BAM in remove() Mostafa Saleh

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®