Devicetree
 help / color / mirror / Atom feed
* [PATCH 0/2] net: wwan: qcom_bam_dmux: Alloc RX buffers as a single coherent block
@ 2026-07-14  5:32 Vishnu Santhosh
  2026-07-14  5:32 ` [PATCH 1/2] dt-bindings: net: qcom,bam-dmux: Add qcom,shikra-bam-dmux compatible Vishnu Santhosh
                   ` (2 more replies)
  0 siblings, 3 replies; 7+ messages in thread
From: Vishnu Santhosh @ 2026-07-14  5:32 UTC (permalink / raw)
  To: Stephan Gerhold, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Loic Poulain, Sergey Ryazanov, Johannes Berg
  Cc: linux-arm-msm, netdev, devicetree, linux-kernel, Vishnu Santhosh,
	chris.lew, Deepak Kumar Singh

On platforms where the modem DMAs into the BAM-DMUX RX data buffers and
the XPU (eXternal Protection Unit) enforces per-region access control,
each individually DMA-mapped RX buffer consumes an XPU resource group.
With only ~16 groups available on Shikra (mDSP, VMID 43 / NAV), the
per-buffer mappings exhaust the table and inbound transfers fault.

This series adds a qcom,shikra-bam-dmux compatible and have the driver
select QCOM_SCM_VMID_NAV internally via that compatible's match data.
When matched, the driver allocates all RX buffers as a single
contiguous coherent block and SCM-assigns it to HLOS plus the VMID
once at probe, consuming one XPU resource group instead of many.

Platforms that do not use the qcom,shikra-bam-dmux compatible are
unaffected: the existing per-buffer dma_map_single() path is
unchanged.

Signed-off-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
---
Vishnu Santhosh (2):
      dt-bindings: net: qcom,bam-dmux: Add qcom,shikra-bam-dmux compatible
      net: wwan: qcom_bam_dmux: Alloc RX buffers as a single coherent block

 .../devicetree/bindings/net/qcom,bam-dmux.yaml     |   8 +-
 drivers/net/wwan/Kconfig                           |   1 +
 drivers/net/wwan/qcom_bam_dmux.c                   | 134 +++++++++++++++++++--
 3 files changed, 132 insertions(+), 11 deletions(-)
---
base-commit: 3b029c035b34bbc693405ddf759f0e9b920c27f1
change-id: 20260714-qcom-bam-dmux-vmid-ext-d9289db310c1

Best regards,
-- 
Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>


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

* [PATCH 1/2] dt-bindings: net: qcom,bam-dmux: Add qcom,shikra-bam-dmux compatible
  2026-07-14  5:32 [PATCH 0/2] net: wwan: qcom_bam_dmux: Alloc RX buffers as a single coherent block Vishnu Santhosh
@ 2026-07-14  5:32 ` Vishnu Santhosh
  2026-07-14  7:11   ` Stephan Gerhold
  2026-07-14  5:32 ` [PATCH 2/2] net: wwan: qcom_bam_dmux: Alloc RX buffers as a single coherent block Vishnu Santhosh
  2026-07-14  7:53 ` [PATCH 0/2] " Jagielski, Jedrzej
  2 siblings, 1 reply; 7+ messages in thread
From: Vishnu Santhosh @ 2026-07-14  5:32 UTC (permalink / raw)
  To: Stephan Gerhold, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Loic Poulain, Sergey Ryazanov, Johannes Berg
  Cc: linux-arm-msm, netdev, devicetree, linux-kernel, Vishnu Santhosh,
	chris.lew, Deepak Kumar Singh

On platforms where the modem DMAs into the BAM-DMUX RX data buffers and
the XPU enforces per-region access control, each individually
DMA-mapped RX buffer consumes an XPU resource group. With only ~16
groups available, the per-buffer mappings exhaust the table and inbound
transfers fault.

Add qcom,shikra-bam-dmux as an additional compatible for the Shikra SoC,
paired with the generic qcom,bam-dmux fallback, so the driver can match
on it via its of_device_id table.

Co-developed-by: Deepak Kumar Singh <deepak.singh@oss.qualcomm.com>
Signed-off-by: Deepak Kumar Singh <deepak.singh@oss.qualcomm.com>
Signed-off-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
---
 Documentation/devicetree/bindings/net/qcom,bam-dmux.yaml | 8 +++++++-
 1 file changed, 7 insertions(+), 1 deletion(-)

diff --git a/Documentation/devicetree/bindings/net/qcom,bam-dmux.yaml b/Documentation/devicetree/bindings/net/qcom,bam-dmux.yaml
index 33746c238513d72366bc52359fb10f275475b331..27f0fdf285c17d6bfdecd5e59cad09912a5e821b 100644
--- a/Documentation/devicetree/bindings/net/qcom,bam-dmux.yaml
+++ b/Documentation/devicetree/bindings/net/qcom,bam-dmux.yaml
@@ -22,7 +22,13 @@ description: |
 
 properties:
   compatible:
-    const: qcom,bam-dmux
+    oneOf:
+      - const: qcom,bam-dmux
+      - items:
+          - enum:
+              # Shikra
+              - qcom,shikra-bam-dmux
+          - const: qcom,bam-dmux
 
   interrupts:
     description:

-- 
2.34.1


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

* [PATCH 2/2] net: wwan: qcom_bam_dmux: Alloc RX buffers as a single coherent block
  2026-07-14  5:32 [PATCH 0/2] net: wwan: qcom_bam_dmux: Alloc RX buffers as a single coherent block Vishnu Santhosh
  2026-07-14  5:32 ` [PATCH 1/2] dt-bindings: net: qcom,bam-dmux: Add qcom,shikra-bam-dmux compatible Vishnu Santhosh
@ 2026-07-14  5:32 ` Vishnu Santhosh
  2026-07-14  7:35   ` Stephan Gerhold
  2026-07-14  7:55   ` Jagielski, Jedrzej
  2026-07-14  7:53 ` [PATCH 0/2] " Jagielski, Jedrzej
  2 siblings, 2 replies; 7+ messages in thread
From: Vishnu Santhosh @ 2026-07-14  5:32 UTC (permalink / raw)
  To: Stephan Gerhold, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Loic Poulain, Sergey Ryazanov, Johannes Berg
  Cc: linux-arm-msm, netdev, devicetree, linux-kernel, Vishnu Santhosh,
	chris.lew, Deepak Kumar Singh

On Qualcomm SoCs where the modem (e.g. the mDSP on Shikra, VMID 43 /
NAV) is the AXI master for BAM-DMUX RX transfers and the XPU enforces
per-region access control, each individually DMA-mapped RX buffer
requires its own XPU resource group (RG). With ~16 RGs available, the
32 per-buffer dma_map_single() calls exhaust the table and the first
inbound transfer faults with an XPU violation.

BAM-DMUX is a singleton (exactly one instance per SoC), so the
destination VMID does not need to be a DT property; it is looked up
from the compatible string's match data instead. Add struct
bam_dmux_data with a single vmid field, and a shikra_data instance
hardcoding QCOM_SCM_VMID_NAV for qcom,shikra-bam-dmux.

When match data is present, allocate all BAM_DMUX_NUM_SKB RX buffers as
a single contiguous dma_alloc_coherent() block and SCM-assign that
block to HLOS plus the VMID once at probe. This reduces RG consumption
from 32 to 1. The block is never reclaimed across a modem power cycle
(bam_dmux_power_off() does not touch it), so the probe-time assignment
covers every subsequent restart without re-assigning or reclaiming. It
is reclaimed to HLOS only once, at remove or on a probe error, and if
that reclaim fails it is leaked rather than returned to the page
allocator.

Each rx_skbs[] slot is pre-assigned its virtual and DMA address from
the block, so no per-buffer mapping is needed at power-on. Because the
coherent block is not page-backed, received payload is copied into a
regular netdev skb before handoff to the network stack; this is an
unavoidable extra copy on the XPU-enforced RX path.

Platforms without match data are unaffected: rx_virt stays NULL, no
coherent memory is allocated, and the per-buffer dma_map_single() path
is unchanged.

Co-developed-by: Deepak Kumar Singh <deepak.singh@oss.qualcomm.com>
Signed-off-by: Deepak Kumar Singh <deepak.singh@oss.qualcomm.com>
Signed-off-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
---
 drivers/net/wwan/Kconfig         |   1 +
 drivers/net/wwan/qcom_bam_dmux.c | 134 ++++++++++++++++++++++++++++++++++++---
 2 files changed, 125 insertions(+), 10 deletions(-)

diff --git a/drivers/net/wwan/Kconfig b/drivers/net/wwan/Kconfig
index 958dbc7347fa84ee869439bf8b503037faab8bef..1b133c56231615269698140187ca3141dfe48dbf 100644
--- a/drivers/net/wwan/Kconfig
+++ b/drivers/net/wwan/Kconfig
@@ -65,6 +65,7 @@ config MHI_WWAN_MBIM
 config QCOM_BAM_DMUX
 	tristate "Qualcomm BAM-DMUX WWAN network driver"
 	depends on (DMA_ENGINE && PM && QCOM_SMEM_STATE) || COMPILE_TEST
+	select QCOM_SCM
 	help
 	  The BAM Data Multiplexer provides access to the network data channels
 	  of modems integrated into many older Qualcomm SoCs, e.g. Qualcomm
diff --git a/drivers/net/wwan/qcom_bam_dmux.c b/drivers/net/wwan/qcom_bam_dmux.c
index cc6ace8d64371eb8d00c638a39b234ee540b83c9..247230b720e6011876d5c429badbb5a1f34fc576 100644
--- a/drivers/net/wwan/qcom_bam_dmux.c
+++ b/drivers/net/wwan/qcom_bam_dmux.c
@@ -9,10 +9,12 @@
 #include <linux/completion.h>
 #include <linux/dma-mapping.h>
 #include <linux/dmaengine.h>
+#include <linux/firmware/qcom/qcom_scm.h>
 #include <linux/if_arp.h>
 #include <linux/interrupt.h>
 #include <linux/module.h>
 #include <linux/netdevice.h>
+#include <linux/of.h>
 #include <linux/platform_device.h>
 #include <linux/pm_runtime.h>
 #include <linux/soc/qcom/smem_state.h>
@@ -62,6 +64,7 @@ struct bam_dmux_skb_dma {
 	struct bam_dmux *dmux;
 	struct sk_buff *skb;
 	dma_addr_t addr;
+	void *rx_virt; /* non-NULL: slot in the coherent RX block */
 };
 
 struct bam_dmux {
@@ -75,6 +78,10 @@ struct bam_dmux {
 	struct completion pc_ack_completion;
 
 	struct dma_chan *rx, *tx;
+	/* Single coherent block backing all RX buffers, NULL if unused */
+	void *rx_buf;
+	dma_addr_t rx_buf_dma;
+	u64 rx_buf_perms; /* SCM source-VMID bitmask of rx_buf */
 	struct bam_dmux_skb_dma rx_skbs[BAM_DMUX_NUM_SKB];
 	struct bam_dmux_skb_dma tx_skbs[BAM_DMUX_NUM_SKB];
 	spinlock_t tx_lock; /* Protect tx_skbs, tx_next_skb */
@@ -92,6 +99,10 @@ struct bam_dmux_netdev {
 	u8 ch;
 };
 
+struct bam_dmux_data {
+	u32 vmid;
+};
+
 static void bam_dmux_pc_vote(struct bam_dmux *dmux, bool enable)
 {
 	reinit_completion(&dmux->pc_ack_completion);
@@ -111,6 +122,9 @@ static bool bam_dmux_skb_dma_map(struct bam_dmux_skb_dma *skb_dma,
 {
 	struct device *dev = skb_dma->dmux->dev;
 
+	if (skb_dma->rx_virt) /* coherent RX slot: addr pre-assigned */
+		return true;
+
 	skb_dma->addr = dma_map_single(dev, skb_dma->skb->data, skb_dma->skb->len, dir);
 	if (dma_mapping_error(dev, skb_dma->addr)) {
 		dev_err(dev, "Failed to DMA map buffer\n");
@@ -124,6 +138,9 @@ static bool bam_dmux_skb_dma_map(struct bam_dmux_skb_dma *skb_dma,
 static void bam_dmux_skb_dma_unmap(struct bam_dmux_skb_dma *skb_dma,
 				   enum dma_data_direction dir)
 {
+	if (skb_dma->rx_virt) /* coherent RX slot: nothing to unmap */
+		return;
+
 	dma_unmap_single(skb_dma->dmux->dev, skb_dma->addr, skb_dma->skb->len, dir);
 	skb_dma->addr = 0;
 }
@@ -468,9 +485,10 @@ static bool bam_dmux_skb_dma_submit_rx(struct bam_dmux_skb_dma *skb_dma)
 {
 	struct bam_dmux *dmux = skb_dma->dmux;
 	struct dma_async_tx_descriptor *desc;
+	size_t len = skb_dma->rx_virt ? BAM_DMUX_BUFFER_SIZE : skb_dma->skb->len;
 
 	desc = dmaengine_prep_slave_single(dmux->rx, skb_dma->addr,
-					   skb_dma->skb->len, DMA_DEV_TO_MEM,
+					   len, DMA_DEV_TO_MEM,
 					   DMA_PREP_INTERRUPT);
 	if (!desc) {
 		dev_err(dmux->dev, "Failed to prepare RX DMA buffer\n");
@@ -485,6 +503,10 @@ static bool bam_dmux_skb_dma_submit_rx(struct bam_dmux_skb_dma *skb_dma)
 
 static bool bam_dmux_skb_dma_queue_rx(struct bam_dmux_skb_dma *skb_dma, gfp_t gfp)
 {
+	/* Coherent RX slots have rx_virt and addr pre-assigned at probe. */
+	if (skb_dma->rx_virt)
+		return bam_dmux_skb_dma_submit_rx(skb_dma);
+
 	if (!skb_dma->skb) {
 		skb_dma->skb = __netdev_alloc_skb(NULL, BAM_DMUX_BUFFER_SIZE, gfp);
 		if (!skb_dma->skb)
@@ -499,9 +521,10 @@ static bool bam_dmux_skb_dma_queue_rx(struct bam_dmux_skb_dma *skb_dma, gfp_t gf
 static void bam_dmux_cmd_data(struct bam_dmux_skb_dma *skb_dma)
 {
 	struct bam_dmux *dmux = skb_dma->dmux;
-	struct sk_buff *skb = skb_dma->skb;
-	struct bam_dmux_hdr *hdr = (struct bam_dmux_hdr *)skb->data;
+	struct bam_dmux_hdr *hdr = skb_dma->rx_virt ? skb_dma->rx_virt :
+				   (struct bam_dmux_hdr *)skb_dma->skb->data;
 	struct net_device *netdev = dmux->netdevs[hdr->ch];
+	struct sk_buff *skb;
 
 	if (!netdev || !netif_running(netdev)) {
 		dev_warn(dmux->dev, "Data for inactive channel %u\n", hdr->ch);
@@ -514,10 +537,18 @@ static void bam_dmux_cmd_data(struct bam_dmux_skb_dma *skb_dma)
 		return;
 	}
 
-	skb_dma->skb = NULL; /* Hand over to network stack */
-
-	skb_pull(skb, sizeof(*hdr));
-	skb_trim(skb, hdr->len);
+	if (skb_dma->rx_virt) {
+		/* Coherent block is not page-backed: copy out to a real skb */
+		skb = netdev_alloc_skb(netdev, hdr->len);
+		if (!skb)
+			return;
+		skb_put_data(skb, (u8 *)skb_dma->rx_virt + sizeof(*hdr), hdr->len);
+	} else {
+		skb = skb_dma->skb;
+		skb_dma->skb = NULL; /* Hand over to network stack */
+		skb_pull(skb, sizeof(*hdr));
+		skb_trim(skb, hdr->len);
+	}
 	skb->dev = netdev;
 
 	/* Only Raw-IP/QMAP is supported by this driver */
@@ -574,10 +605,14 @@ static void bam_dmux_rx_callback(void *data)
 {
 	struct bam_dmux_skb_dma *skb_dma = data;
 	struct bam_dmux *dmux = skb_dma->dmux;
-	struct sk_buff *skb = skb_dma->skb;
-	struct bam_dmux_hdr *hdr = (struct bam_dmux_hdr *)skb->data;
+	struct bam_dmux_hdr *hdr;
 
-	bam_dmux_skb_dma_unmap(skb_dma, DMA_FROM_DEVICE);
+	if (skb_dma->rx_virt) {
+		hdr = skb_dma->rx_virt; /* coherent RX: no skb to unmap */
+	} else {
+		bam_dmux_skb_dma_unmap(skb_dma, DMA_FROM_DEVICE);
+		hdr = (struct bam_dmux_hdr *)skb_dma->skb->data;
+	}
 
 	if (hdr->magic != BAM_DMUX_HDR_MAGIC) {
 		dev_err(dmux->dev, "Invalid magic in header: %#x\n", hdr->magic);
@@ -644,6 +679,9 @@ static void bam_dmux_free_skbs(struct bam_dmux_skb_dma skbs[],
 	for (i = 0; i < BAM_DMUX_NUM_SKB; i++) {
 		struct bam_dmux_skb_dma *skb_dma = &skbs[i];
 
+		if (skb_dma->rx_virt) /* coherent block freed at remove */
+			continue;
+
 		if (skb_dma->addr)
 			bam_dmux_skb_dma_unmap(skb_dma, dir);
 		if (skb_dma->skb) {
@@ -762,6 +800,71 @@ static int __maybe_unused bam_dmux_runtime_resume(struct device *dev)
 	return 0;
 }
 
+static int bam_dmux_alloc_coherent_rx(struct bam_dmux *dmux)
+{
+	struct device *dev = dmux->dev;
+	const struct bam_dmux_data *data = of_device_get_match_data(dev);
+	size_t size = BAM_DMUX_NUM_SKB * BAM_DMUX_BUFFER_SIZE;
+	u64 src = BIT_ULL(QCOM_SCM_VMID_HLOS);
+	struct qcom_scm_vmperm dst[2];
+	int i, ret;
+
+	if (!data)
+		return 0;
+
+	if (!qcom_scm_is_available())
+		return -EPROBE_DEFER;
+
+	dst[0].vmid = QCOM_SCM_VMID_HLOS;
+	dst[0].perm = QCOM_SCM_PERM_RW;
+	dst[1].vmid = data->vmid;
+	dst[1].perm = QCOM_SCM_PERM_RW;
+
+	dmux->rx_buf = dma_alloc_coherent(dev, size, &dmux->rx_buf_dma, GFP_KERNEL);
+	if (!dmux->rx_buf)
+		return -ENOMEM;
+
+	for (i = 0; i < BAM_DMUX_NUM_SKB; i++) {
+		dmux->rx_skbs[i].rx_virt = dmux->rx_buf + i * BAM_DMUX_BUFFER_SIZE;
+		dmux->rx_skbs[i].addr = dmux->rx_buf_dma + i * BAM_DMUX_BUFFER_SIZE;
+	}
+
+	ret = qcom_scm_assign_mem(dmux->rx_buf_dma, size, &src, dst, ARRAY_SIZE(dst));
+	if (ret) {
+		dev_err(dev, "SCM assign RX block failed: %d\n", ret);
+		dma_free_coherent(dev, size, dmux->rx_buf, dmux->rx_buf_dma);
+		dmux->rx_buf = NULL;
+		return ret;
+	}
+	dmux->rx_buf_perms = src;
+
+	return 0;
+}
+
+static void bam_dmux_free_coherent_rx(struct bam_dmux *dmux)
+{
+	struct qcom_scm_vmperm hlos = {
+		.vmid = QCOM_SCM_VMID_HLOS,
+		.perm = QCOM_SCM_PERM_RW,
+	};
+	size_t size = BAM_DMUX_NUM_SKB * BAM_DMUX_BUFFER_SIZE;
+
+	if (!dmux->rx_buf)
+		return;
+
+	if (dmux->rx_buf_perms) {
+		if (qcom_scm_assign_mem(dmux->rx_buf_dma, size, &dmux->rx_buf_perms,
+					&hlos, 1)) {
+			dev_err(dmux->dev, "SCM reclaim RX block failed; leaking\n");
+			return;
+		}
+		dmux->rx_buf_perms = 0;
+	}
+
+	dma_free_coherent(dmux->dev, size, dmux->rx_buf, dmux->rx_buf_dma);
+	dmux->rx_buf = NULL;
+}
+
 static int bam_dmux_probe(struct platform_device *pdev)
 {
 	struct device *dev = &pdev->dev;
@@ -809,6 +912,10 @@ static int bam_dmux_probe(struct platform_device *pdev)
 		dmux->tx_skbs[i].dmux = dmux;
 	}
 
+	ret = bam_dmux_alloc_coherent_rx(dmux);
+	if (ret)
+		return ret;
+
 	/* Runtime PM manages our own power vote.
 	 * Note that the RX path may be active even if we are runtime suspended,
 	 * since it is controlled by the remote side.
@@ -845,6 +952,7 @@ static int bam_dmux_probe(struct platform_device *pdev)
 err_disable_pm:
 	pm_runtime_disable(dev);
 	pm_runtime_dont_use_autosuspend(dev);
+	bam_dmux_free_coherent_rx(dmux);
 	return ret;
 }
 
@@ -879,13 +987,19 @@ static void bam_dmux_remove(struct platform_device *pdev)
 	disable_irq(dmux->pc_irq);
 	bam_dmux_power_off(dmux);
 	bam_dmux_free_skbs(dmux->tx_skbs, DMA_TO_DEVICE);
+	bam_dmux_free_coherent_rx(dmux);
 }
 
 static const struct dev_pm_ops bam_dmux_pm_ops = {
 	SET_RUNTIME_PM_OPS(bam_dmux_runtime_suspend, bam_dmux_runtime_resume, NULL)
 };
 
+static const struct bam_dmux_data shikra_data = {
+	.vmid = QCOM_SCM_VMID_NAV,
+};
+
 static const struct of_device_id bam_dmux_of_match[] = {
+	{ .compatible = "qcom,shikra-bam-dmux", .data = &shikra_data },
 	{ .compatible = "qcom,bam-dmux" },
 	{ /* sentinel */ }
 };

-- 
2.34.1


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

* Re: [PATCH 1/2] dt-bindings: net: qcom,bam-dmux: Add qcom,shikra-bam-dmux compatible
  2026-07-14  5:32 ` [PATCH 1/2] dt-bindings: net: qcom,bam-dmux: Add qcom,shikra-bam-dmux compatible Vishnu Santhosh
@ 2026-07-14  7:11   ` Stephan Gerhold
  0 siblings, 0 replies; 7+ messages in thread
From: Stephan Gerhold @ 2026-07-14  7:11 UTC (permalink / raw)
  To: Vishnu Santhosh
  Cc: Stephan Gerhold, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Loic Poulain, Sergey Ryazanov, Johannes Berg,
	linux-arm-msm, netdev, devicetree, linux-kernel, chris.lew,
	Deepak Kumar Singh

On Tue, Jul 14, 2026 at 11:02:31AM +0530, Vishnu Santhosh wrote:
> On platforms where the modem DMAs into the BAM-DMUX RX data buffers and
> the XPU enforces per-region access control, each individually
> DMA-mapped RX buffer consumes an XPU resource group. With only ~16
> groups available, the per-buffer mappings exhaust the table and inbound
> transfers fault.
> 
> Add qcom,shikra-bam-dmux as an additional compatible for the Shikra SoC,
> paired with the generic qcom,bam-dmux fallback, so the driver can match
> on it via its of_device_id table.
> 
> Co-developed-by: Deepak Kumar Singh <deepak.singh@oss.qualcomm.com>
> Signed-off-by: Deepak Kumar Singh <deepak.singh@oss.qualcomm.com>
> Signed-off-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>

IMHO (the DT maintainers might disagree) this is not a different
BAM DMUX hardware block on Shikra, just a different firmware
configuration. I'm sure the existing SoCs also have those XPU blocks,
they just don't make use of it.

Personally, I would rather describe this with an optional "qcom,vmid"
property similar to your bam-dma patch, allowed for all SoCs.

Thanks,
Stephan

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

* Re: [PATCH 2/2] net: wwan: qcom_bam_dmux: Alloc RX buffers as a single coherent block
  2026-07-14  5:32 ` [PATCH 2/2] net: wwan: qcom_bam_dmux: Alloc RX buffers as a single coherent block Vishnu Santhosh
@ 2026-07-14  7:35   ` Stephan Gerhold
  2026-07-14  7:55   ` Jagielski, Jedrzej
  1 sibling, 0 replies; 7+ messages in thread
From: Stephan Gerhold @ 2026-07-14  7:35 UTC (permalink / raw)
  To: Vishnu Santhosh
  Cc: Stephan Gerhold, Andrew Lunn, David S. Miller, Eric Dumazet,
	Jakub Kicinski, Paolo Abeni, Rob Herring, Krzysztof Kozlowski,
	Conor Dooley, Loic Poulain, Sergey Ryazanov, Johannes Berg,
	linux-arm-msm, netdev, devicetree, linux-kernel, chris.lew,
	Deepak Kumar Singh

On Tue, Jul 14, 2026 at 11:02:32AM +0530, Vishnu Santhosh wrote:
> On Qualcomm SoCs where the modem (e.g. the mDSP on Shikra, VMID 43 /
> NAV) is the AXI master for BAM-DMUX RX transfers and the XPU enforces
> per-region access control, each individually DMA-mapped RX buffer
> requires its own XPU resource group (RG). With ~16 RGs available, the
> 32 per-buffer dma_map_single() calls exhaust the table and the first
> inbound transfer faults with an XPU violation.
> 
> BAM-DMUX is a singleton (exactly one instance per SoC), so the
> destination VMID does not need to be a DT property; it is looked up
> from the compatible string's match data instead. Add struct
> bam_dmux_data with a single vmid field, and a shikra_data instance
> hardcoding QCOM_SCM_VMID_NAV for qcom,shikra-bam-dmux.
> 
> When match data is present, allocate all BAM_DMUX_NUM_SKB RX buffers as
> a single contiguous dma_alloc_coherent() block and SCM-assign that
> block to HLOS plus the VMID once at probe. This reduces RG consumption
> from 32 to 1. The block is never reclaimed across a modem power cycle
> (bam_dmux_power_off() does not touch it), so the probe-time assignment
> covers every subsequent restart without re-assigning or reclaiming. It
> is reclaimed to HLOS only once, at remove or on a probe error, and if
> that reclaim fails it is leaked rather than returned to the page
> allocator.
> 
> Each rx_skbs[] slot is pre-assigned its virtual and DMA address from
> the block, so no per-buffer mapping is needed at power-on. Because the
> coherent block is not page-backed, received payload is copied into a
> regular netdev skb before handoff to the network stack; this is an
> unavoidable extra copy on the XPU-enforced RX path.
> 
> Platforms without match data are unaffected: rx_virt stays NULL, no
> coherent memory is allocated, and the per-buffer dma_map_single() path
> is unchanged.
> 
> Co-developed-by: Deepak Kumar Singh <deepak.singh@oss.qualcomm.com>
> Signed-off-by: Deepak Kumar Singh <deepak.singh@oss.qualcomm.com>
> Signed-off-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>

So how do you handle TX buffers? Right now, they are just passed on from
the net subsystem. There can be up to 32 TX buffers in progress as well.

Overall, I have mixed feelings about this patch. It looks reasonably
simple, but fundamentally I don't understand why we need to go back to
the old days of implementing protection using a highly limited MPU (in
your case: the xPU).

Why does the setup of BAM-DMUX differ e.g. from the setup for the crypto
engine? Crypto is also using bam-dma, but it avoids this inflexibility
by making use of the &apps_smmu. Is BAM-DMUX not covered by the SMMU? Or
did you just decide to bypass the SMMU in this case? (If so: Why?)

If you had BAM-DMUX mapped using the SMMU you would get all of this for
free. No changes would be needed in the BAM-DMUX driver ...

Thanks,
Stephan

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

* RE: [PATCH 0/2] net: wwan: qcom_bam_dmux: Alloc RX buffers as a single coherent block
  2026-07-14  5:32 [PATCH 0/2] net: wwan: qcom_bam_dmux: Alloc RX buffers as a single coherent block Vishnu Santhosh
  2026-07-14  5:32 ` [PATCH 1/2] dt-bindings: net: qcom,bam-dmux: Add qcom,shikra-bam-dmux compatible Vishnu Santhosh
  2026-07-14  5:32 ` [PATCH 2/2] net: wwan: qcom_bam_dmux: Alloc RX buffers as a single coherent block Vishnu Santhosh
@ 2026-07-14  7:53 ` Jagielski, Jedrzej
  2 siblings, 0 replies; 7+ messages in thread
From: Jagielski, Jedrzej @ 2026-07-14  7:53 UTC (permalink / raw)
  To: Vishnu Santhosh, Stephan Gerhold, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Loic Poulain, Sergey Ryazanov,
	Johannes Berg
  Cc: linux-arm-msm@vger.kernel.org, netdev@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	chris.lew@oss.qualcomm.com, Deepak Kumar Singh

From: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com> 
Sent: Tuesday, July 14, 2026 7:33 AM

>On platforms where the modem DMAs into the BAM-DMUX RX data buffers and
>the XPU (eXternal Protection Unit) enforces per-region access control,
>each individually DMA-mapped RX buffer consumes an XPU resource group.
>With only ~16 groups available on Shikra (mDSP, VMID 43 / NAV), the
>per-buffer mappings exhaust the table and inbound transfers fault.
>
>This series adds a qcom,shikra-bam-dmux compatible and have the driver
>select QCOM_SCM_VMID_NAV internally via that compatible's match data.
>When matched, the driver allocates all RX buffers as a single
>contiguous coherent block and SCM-assigns it to HLOS plus the VMID
>once at probe, consuming one XPU resource group instead of many.
>
>Platforms that do not use the qcom,shikra-bam-dmux compatible are
>unaffected: the existing per-buffer dma_map_single() path is
>unchanged.
>
>Signed-off-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
>---
>Vishnu Santhosh (2):
>      dt-bindings: net: qcom,bam-dmux: Add qcom,shikra-bam-dmux compatible
>      net: wwan: qcom_bam_dmux: Alloc RX buffers as a single coherent block
>
> .../devicetree/bindings/net/qcom,bam-dmux.yaml     |   8 +-
> drivers/net/wwan/Kconfig                           |   1 +
> drivers/net/wwan/qcom_bam_dmux.c                   | 134 +++++++++++++++++++--
> 3 files changed, 132 insertions(+), 11 deletions(-)
>---
>base-commit: 3b029c035b34bbc693405ddf759f0e9b920c27f1
>change-id: 20260714-qcom-bam-dmux-vmid-ext-d9289db310c1
>
>Best regards,
>-- 
>Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>

Hi Vishnu
you need to specify target tree, net-next for this series i believe
please refer to[1]

[1]
https://docs.kernel.org/process/maintainer-netdev.html#indicating-target-tree



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

* RE: [PATCH 2/2] net: wwan: qcom_bam_dmux: Alloc RX buffers as a single coherent block
  2026-07-14  5:32 ` [PATCH 2/2] net: wwan: qcom_bam_dmux: Alloc RX buffers as a single coherent block Vishnu Santhosh
  2026-07-14  7:35   ` Stephan Gerhold
@ 2026-07-14  7:55   ` Jagielski, Jedrzej
  1 sibling, 0 replies; 7+ messages in thread
From: Jagielski, Jedrzej @ 2026-07-14  7:55 UTC (permalink / raw)
  To: Vishnu Santhosh, Stephan Gerhold, Andrew Lunn, David S. Miller,
	Eric Dumazet, Jakub Kicinski, Paolo Abeni, Rob Herring,
	Krzysztof Kozlowski, Conor Dooley, Loic Poulain, Sergey Ryazanov,
	Johannes Berg
  Cc: linux-arm-msm@vger.kernel.org, netdev@vger.kernel.org,
	devicetree@vger.kernel.org, linux-kernel@vger.kernel.org,
	chris.lew@oss.qualcomm.com, Deepak Kumar Singh

From: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com> 
Sent: Tuesday, July 14, 2026 7:33 AM

>On Qualcomm SoCs where the modem (e.g. the mDSP on Shikra, VMID 43 /
>NAV) is the AXI master for BAM-DMUX RX transfers and the XPU enforces
>per-region access control, each individually DMA-mapped RX buffer
>requires its own XPU resource group (RG). With ~16 RGs available, the
>32 per-buffer dma_map_single() calls exhaust the table and the first
>inbound transfer faults with an XPU violation.
>
>BAM-DMUX is a singleton (exactly one instance per SoC), so the
>destination VMID does not need to be a DT property; it is looked up
>from the compatible string's match data instead. Add struct
>bam_dmux_data with a single vmid field, and a shikra_data instance
>hardcoding QCOM_SCM_VMID_NAV for qcom,shikra-bam-dmux.
>
>When match data is present, allocate all BAM_DMUX_NUM_SKB RX buffers as
>a single contiguous dma_alloc_coherent() block and SCM-assign that
>block to HLOS plus the VMID once at probe. This reduces RG consumption
>from 32 to 1. The block is never reclaimed across a modem power cycle
>(bam_dmux_power_off() does not touch it), so the probe-time assignment
>covers every subsequent restart without re-assigning or reclaiming. It
>is reclaimed to HLOS only once, at remove or on a probe error, and if
>that reclaim fails it is leaked rather than returned to the page
>allocator.
>
>Each rx_skbs[] slot is pre-assigned its virtual and DMA address from
>the block, so no per-buffer mapping is needed at power-on. Because the
>coherent block is not page-backed, received payload is copied into a
>regular netdev skb before handoff to the network stack; this is an
>unavoidable extra copy on the XPU-enforced RX path.
>
>Platforms without match data are unaffected: rx_virt stays NULL, no
>coherent memory is allocated, and the per-buffer dma_map_single() path
>is unchanged.
>
>Co-developed-by: Deepak Kumar Singh <deepak.singh@oss.qualcomm.com>
>Signed-off-by: Deepak Kumar Singh <deepak.singh@oss.qualcomm.com>
>Signed-off-by: Vishnu Santhosh <vishnu.santhosh@oss.qualcomm.com>
>---
> drivers/net/wwan/Kconfig         |   1 +
> drivers/net/wwan/qcom_bam_dmux.c | 134 ++++++++++++++++++++++++++++++++++++---
> 2 files changed, 125 insertions(+), 10 deletions(-)
>
>diff --git a/drivers/net/wwan/Kconfig b/drivers/net/wwan/Kconfig
>index 958dbc7347fa84ee869439bf8b503037faab8bef..1b133c56231615269698140187ca3141dfe48dbf 100644
>--- a/drivers/net/wwan/Kconfig
>+++ b/drivers/net/wwan/Kconfig
>@@ -65,6 +65,7 @@ config MHI_WWAN_MBIM
> config QCOM_BAM_DMUX
> 	tristate "Qualcomm BAM-DMUX WWAN network driver"
> 	depends on (DMA_ENGINE && PM && QCOM_SMEM_STATE) || COMPILE_TEST
>+	select QCOM_SCM
> 	help
> 	  The BAM Data Multiplexer provides access to the network data channels
> 	  of modems integrated into many older Qualcomm SoCs, e.g. Qualcomm
>diff --git a/drivers/net/wwan/qcom_bam_dmux.c b/drivers/net/wwan/qcom_bam_dmux.c
>index cc6ace8d64371eb8d00c638a39b234ee540b83c9..247230b720e6011876d5c429badbb5a1f34fc576 100644
>--- a/drivers/net/wwan/qcom_bam_dmux.c
>+++ b/drivers/net/wwan/qcom_bam_dmux.c
>@@ -9,10 +9,12 @@
> #include <linux/completion.h>
> #include <linux/dma-mapping.h>
> #include <linux/dmaengine.h>
>+#include <linux/firmware/qcom/qcom_scm.h>
> #include <linux/if_arp.h>
> #include <linux/interrupt.h>
> #include <linux/module.h>
> #include <linux/netdevice.h>
>+#include <linux/of.h>
> #include <linux/platform_device.h>
> #include <linux/pm_runtime.h>
> #include <linux/soc/qcom/smem_state.h>
>@@ -62,6 +64,7 @@ struct bam_dmux_skb_dma {
> 	struct bam_dmux *dmux;
> 	struct sk_buff *skb;
> 	dma_addr_t addr;
>+	void *rx_virt; /* non-NULL: slot in the coherent RX block */
> };
> 
> struct bam_dmux {
>@@ -75,6 +78,10 @@ struct bam_dmux {
> 	struct completion pc_ack_completion;
> 
> 	struct dma_chan *rx, *tx;
>+	/* Single coherent block backing all RX buffers, NULL if unused */
>+	void *rx_buf;
>+	dma_addr_t rx_buf_dma;
>+	u64 rx_buf_perms; /* SCM source-VMID bitmask of rx_buf */
> 	struct bam_dmux_skb_dma rx_skbs[BAM_DMUX_NUM_SKB];
> 	struct bam_dmux_skb_dma tx_skbs[BAM_DMUX_NUM_SKB];
> 	spinlock_t tx_lock; /* Protect tx_skbs, tx_next_skb */
>@@ -92,6 +99,10 @@ struct bam_dmux_netdev {
> 	u8 ch;
> };
> 
>+struct bam_dmux_data {
>+	u32 vmid;
>+};
>+

do we need to introduce dedicated struct just to cover u32?

> static void bam_dmux_pc_vote(struct bam_dmux *dmux, bool enable)
> {
> 	reinit_completion(&dmux->pc_ack_completion);
>@@ -111,6 +122,9 @@ static bool bam_dmux_skb_dma_map(struct bam_dmux_skb_dma *skb_dma,
> {
> 	struct device *dev = skb_dma->dmux->dev;
> 
>+	if (skb_dma->rx_virt) /* coherent RX slot: addr pre-assigned */
>+		return true;
>+
> 	skb_dma->addr = dma_map_single(dev, skb_dma->skb->data, skb_dma->skb->len, dir);
> 	if (dma_mapping_error(dev, skb_dma->addr)) {
> 		dev_err(dev, "Failed to DMA map buffer\n");
>@@ -124,6 +138,9 @@ static bool bam_dmux_skb_dma_map(struct bam_dmux_skb_dma *skb_dma,
> static void bam_dmux_skb_dma_unmap(struct bam_dmux_skb_dma *skb_dma,
> 				   enum dma_data_direction dir)
> {
>+	if (skb_dma->rx_virt) /* coherent RX slot: nothing to unmap */
>+		return;
>+
> 	dma_unmap_single(skb_dma->dmux->dev, skb_dma->addr, skb_dma->skb->len, dir);
> 	skb_dma->addr = 0;
> }
>@@ -468,9 +485,10 @@ static bool bam_dmux_skb_dma_submit_rx(struct bam_dmux_skb_dma *skb_dma)
> {
> 	struct bam_dmux *dmux = skb_dma->dmux;
> 	struct dma_async_tx_descriptor *desc;
>+	size_t len = skb_dma->rx_virt ? BAM_DMUX_BUFFER_SIZE : skb_dma->skb->len;

please stick to RCT
please fix it here and for the following where RCT is violated

> 
> 	desc = dmaengine_prep_slave_single(dmux->rx, skb_dma->addr,
>-					   skb_dma->skb->len, DMA_DEV_TO_MEM,
>+					   len, DMA_DEV_TO_MEM,
> 					   DMA_PREP_INTERRUPT);
> 	if (!desc) {
> 		dev_err(dmux->dev, "Failed to prepare RX DMA buffer\n");
>@@ -485,6 +503,10 @@ static bool bam_dmux_skb_dma_submit_rx(struct bam_dmux_skb_dma *skb_dma)
> 
> static bool bam_dmux_skb_dma_queue_rx(struct bam_dmux_skb_dma *skb_dma, gfp_t gfp)
> {
>+	/* Coherent RX slots have rx_virt and addr pre-assigned at probe. */
>+	if (skb_dma->rx_virt)
>+		return bam_dmux_skb_dma_submit_rx(skb_dma);
>+
> 	if (!skb_dma->skb) {
> 		skb_dma->skb = __netdev_alloc_skb(NULL, BAM_DMUX_BUFFER_SIZE, gfp);
> 		if (!skb_dma->skb)
>@@ -499,9 +521,10 @@ static bool bam_dmux_skb_dma_queue_rx(struct bam_dmux_skb_dma *skb_dma, gfp_t gf
> static void bam_dmux_cmd_data(struct bam_dmux_skb_dma *skb_dma)
> {
> 	struct bam_dmux *dmux = skb_dma->dmux;
>-	struct sk_buff *skb = skb_dma->skb;
>-	struct bam_dmux_hdr *hdr = (struct bam_dmux_hdr *)skb->data;
>+	struct bam_dmux_hdr *hdr = skb_dma->rx_virt ? skb_dma->rx_virt :
>+				   (struct bam_dmux_hdr *)skb_dma->skb->data;
> 	struct net_device *netdev = dmux->netdevs[hdr->ch];
>+	struct sk_buff *skb;
> 
> 	if (!netdev || !netif_running(netdev)) {
> 		dev_warn(dmux->dev, "Data for inactive channel %u\n", hdr->ch);
>@@ -514,10 +537,18 @@ static void bam_dmux_cmd_data(struct bam_dmux_skb_dma *skb_dma)
> 		return;
> 	}
> 
>-	skb_dma->skb = NULL; /* Hand over to network stack */
>-
>-	skb_pull(skb, sizeof(*hdr));
>-	skb_trim(skb, hdr->len);
>+	if (skb_dma->rx_virt) {
>+		/* Coherent block is not page-backed: copy out to a real skb */
>+		skb = netdev_alloc_skb(netdev, hdr->len);
>+		if (!skb)
>+			return;
>+		skb_put_data(skb, (u8 *)skb_dma->rx_virt + sizeof(*hdr), hdr->len);
>+	} else {
>+		skb = skb_dma->skb;
>+		skb_dma->skb = NULL; /* Hand over to network stack */
>+		skb_pull(skb, sizeof(*hdr));
>+		skb_trim(skb, hdr->len);
>+	}
> 	skb->dev = netdev;
> 
> 	/* Only Raw-IP/QMAP is supported by this driver */
>@@ -574,10 +605,14 @@ static void bam_dmux_rx_callback(void *data)
> {
> 	struct bam_dmux_skb_dma *skb_dma = data;
> 	struct bam_dmux *dmux = skb_dma->dmux;
>-	struct sk_buff *skb = skb_dma->skb;
>-	struct bam_dmux_hdr *hdr = (struct bam_dmux_hdr *)skb->data;
>+	struct bam_dmux_hdr *hdr;
> 
>-	bam_dmux_skb_dma_unmap(skb_dma, DMA_FROM_DEVICE);
>+	if (skb_dma->rx_virt) {
>+		hdr = skb_dma->rx_virt; /* coherent RX: no skb to unmap */
>+	} else {
>+		bam_dmux_skb_dma_unmap(skb_dma, DMA_FROM_DEVICE);
>+		hdr = (struct bam_dmux_hdr *)skb_dma->skb->data;
>+	}
> 
> 	if (hdr->magic != BAM_DMUX_HDR_MAGIC) {
> 		dev_err(dmux->dev, "Invalid magic in header: %#x\n", hdr->magic);
>@@ -644,6 +679,9 @@ static void bam_dmux_free_skbs(struct bam_dmux_skb_dma skbs[],
> 	for (i = 0; i < BAM_DMUX_NUM_SKB; i++) {
> 		struct bam_dmux_skb_dma *skb_dma = &skbs[i];
> 
>+		if (skb_dma->rx_virt) /* coherent block freed at remove */
>+			continue;
>+
> 		if (skb_dma->addr)
> 			bam_dmux_skb_dma_unmap(skb_dma, dir);
> 		if (skb_dma->skb) {
>@@ -762,6 +800,71 @@ static int __maybe_unused bam_dmux_runtime_resume(struct device *dev)
> 	return 0;
> }
> 
>+static int bam_dmux_alloc_coherent_rx(struct bam_dmux *dmux)
>+{
>+	struct device *dev = dmux->dev;
>+	const struct bam_dmux_data *data = of_device_get_match_data(dev);
>+	size_t size = BAM_DMUX_NUM_SKB * BAM_DMUX_BUFFER_SIZE;
>+	u64 src = BIT_ULL(QCOM_SCM_VMID_HLOS);
>+	struct qcom_scm_vmperm dst[2];
>+	int i, ret;
>+
>+	if (!data)
>+		return 0;

is there actually any chance to really trigger that check?
or just theoretical case?

>+
>+	if (!qcom_scm_is_available())
>+		return -EPROBE_DEFER;
>+
>+	dst[0].vmid = QCOM_SCM_VMID_HLOS;
>+	dst[0].perm = QCOM_SCM_PERM_RW;
>+	dst[1].vmid = data->vmid;
>+	dst[1].perm = QCOM_SCM_PERM_RW;
>+
>+	dmux->rx_buf = dma_alloc_coherent(dev, size, &dmux->rx_buf_dma, GFP_KERNEL);
>+	if (!dmux->rx_buf)
>+		return -ENOMEM;
>+
>+	for (i = 0; i < BAM_DMUX_NUM_SKB; i++) {
>+		dmux->rx_skbs[i].rx_virt = dmux->rx_buf + i * BAM_DMUX_BUFFER_SIZE;
>+		dmux->rx_skbs[i].addr = dmux->rx_buf_dma + i * BAM_DMUX_BUFFER_SIZE;
>+	}
>+
>+	ret = qcom_scm_assign_mem(dmux->rx_buf_dma, size, &src, dst, ARRAY_SIZE(dst));
>+	if (ret) {
>+		dev_err(dev, "SCM assign RX block failed: %d\n", ret);
>+		dma_free_coherent(dev, size, dmux->rx_buf, dmux->rx_buf_dma);
>+		dmux->rx_buf = NULL;
>+		return ret;
>+	}
>+	dmux->rx_buf_perms = src;
>+
>+	return 0;
>+}
>+
>+static void bam_dmux_free_coherent_rx(struct bam_dmux *dmux)
>+{
>+	struct qcom_scm_vmperm hlos = {
>+		.vmid = QCOM_SCM_VMID_HLOS,
>+		.perm = QCOM_SCM_PERM_RW,
>+	};
>+	size_t size = BAM_DMUX_NUM_SKB * BAM_DMUX_BUFFER_SIZE;
>+
>+	if (!dmux->rx_buf)
>+		return;
>+
>+	if (dmux->rx_buf_perms) {
>+		if (qcom_scm_assign_mem(dmux->rx_buf_dma, size, &dmux->rx_buf_perms,
>+					&hlos, 1)) {
>+			dev_err(dmux->dev, "SCM reclaim RX block failed; leaking\n");
>+			return;
>+		}
>+		dmux->rx_buf_perms = 0;
>+	}
>+
>+	dma_free_coherent(dmux->dev, size, dmux->rx_buf, dmux->rx_buf_dma);
>+	dmux->rx_buf = NULL;
>+}
>+
> static int bam_dmux_probe(struct platform_device *pdev)
> {
> 	struct device *dev = &pdev->dev;
>@@ -809,6 +912,10 @@ static int bam_dmux_probe(struct platform_device *pdev)
> 		dmux->tx_skbs[i].dmux = dmux;
> 	}
> 
>+	ret = bam_dmux_alloc_coherent_rx(dmux);
>+	if (ret)
>+		return ret;
>+
> 	/* Runtime PM manages our own power vote.
> 	 * Note that the RX path may be active even if we are runtime suspended,
> 	 * since it is controlled by the remote side.
>@@ -845,6 +952,7 @@ static int bam_dmux_probe(struct platform_device *pdev)
> err_disable_pm:
> 	pm_runtime_disable(dev);
> 	pm_runtime_dont_use_autosuspend(dev);
>+	bam_dmux_free_coherent_rx(dmux);
> 	return ret;
> }
> 
>@@ -879,13 +987,19 @@ static void bam_dmux_remove(struct platform_device *pdev)
> 	disable_irq(dmux->pc_irq);
> 	bam_dmux_power_off(dmux);
> 	bam_dmux_free_skbs(dmux->tx_skbs, DMA_TO_DEVICE);
>+	bam_dmux_free_coherent_rx(dmux);
> }
> 
> static const struct dev_pm_ops bam_dmux_pm_ops = {
> 	SET_RUNTIME_PM_OPS(bam_dmux_runtime_suspend, bam_dmux_runtime_resume, NULL)
> };
> 
>+static const struct bam_dmux_data shikra_data = {
>+	.vmid = QCOM_SCM_VMID_NAV,
>+};
>+
> static const struct of_device_id bam_dmux_of_match[] = {
>+	{ .compatible = "qcom,shikra-bam-dmux", .data = &shikra_data },
> 	{ .compatible = "qcom,bam-dmux" },
> 	{ /* sentinel */ }
> };
>
>-- 
>2.34.1



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

end of thread, other threads:[~2026-07-14  7:55 UTC | newest]

Thread overview: 7+ messages (download: mbox.gz follow: Atom feed
-- links below jump to the message on this page --
2026-07-14  5:32 [PATCH 0/2] net: wwan: qcom_bam_dmux: Alloc RX buffers as a single coherent block Vishnu Santhosh
2026-07-14  5:32 ` [PATCH 1/2] dt-bindings: net: qcom,bam-dmux: Add qcom,shikra-bam-dmux compatible Vishnu Santhosh
2026-07-14  7:11   ` Stephan Gerhold
2026-07-14  5:32 ` [PATCH 2/2] net: wwan: qcom_bam_dmux: Alloc RX buffers as a single coherent block Vishnu Santhosh
2026-07-14  7:35   ` Stephan Gerhold
2026-07-14  7:55   ` Jagielski, Jedrzej
2026-07-14  7:53 ` [PATCH 0/2] " Jagielski, Jedrzej

This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox