[PATCH v2 3/4] misc: fastrpc: add extended context bank support
From: Vinayak Katoch
Date: Wed Oct 07 2026 - 08:43:55 EST
Detect extended context banks by the presence of iommu-ranges on the
context bank node. Register them in a separate ext_cb array so the
mapping layer can direct large allocations into the wider IOVA window.
Signed-off-by: Vinayak Katoch <vinayak.katoch@xxxxxxxxxxxxxxxx>
---
drivers/misc/fastrpc.c | 46 ++++++++++++++++++++++++++++++++++++++++++++++
1 file changed, 46 insertions(+)
diff --git a/drivers/misc/fastrpc.c b/drivers/misc/fastrpc.c
index 5c7bb56cf46d..d40cdcd5dec3 100644
--- a/drivers/misc/fastrpc.c
+++ b/drivers/misc/fastrpc.c
@@ -307,6 +307,8 @@ struct fastrpc_channel_ctx {
struct qcom_scm_vmperm vmperms[FASTRPC_MAX_VMIDS];
struct rpmsg_device *rpdev;
struct fastrpc_session_ctx session[FASTRPC_MAX_SESSIONS];
+ struct fastrpc_session_ctx **ext_cb;
+ int ext_cb_count;
spinlock_t lock;
struct idr ctx_idr;
struct list_head users;
@@ -538,9 +540,13 @@ static int fastrpc_remote_heap_alloc(struct fastrpc_user *fl, struct device *dev
static void fastrpc_channel_ctx_free(struct kref *ref)
{
struct fastrpc_channel_ctx *cctx;
+ int i;
cctx = container_of(ref, struct fastrpc_channel_ctx, refcount);
+ for (i = 0; i < cctx->ext_cb_count; i++)
+ kfree(cctx->ext_cb[i]);
+ kfree(cctx->ext_cb);
idr_destroy(&cctx->ctx_idr);
kfree(cctx);
}
@@ -2343,6 +2349,7 @@ static int fastrpc_cb_init(struct platform_device *pdev)
u32 dma_bits;
u32 sid = 0;
int rc;
+ bool is_extended_cb = false;
cctx = dev_get_drvdata(dev->parent);
if (!cctx)
@@ -2352,6 +2359,43 @@ static int fastrpc_cb_init(struct platform_device *pdev)
of_n_addr_cells(dev->of_node) - 1, &sid))
dev_info(dev, "FastRPC Session ID not specified in DT\n");
+ if (of_property_present(dev->of_node, "iommu-ranges"))
+ is_extended_cb = true;
+
+ if (is_extended_cb) {
+ struct fastrpc_session_ctx **new_ext;
+
+ sess = kzalloc_obj(*sess);
+ if (!sess)
+ return -ENOMEM;
+
+ rc = dma_set_mask(dev, DMA_BIT_MASK(40));
+ if (rc) {
+ dev_err(dev, "40-bit DMA enable failed\n");
+ kfree(sess);
+ return rc;
+ }
+
+ new_ext = krealloc(cctx->ext_cb,
+ (cctx->ext_cb_count + 1) * sizeof(*cctx->ext_cb),
+ GFP_KERNEL);
+ if (!new_ext) {
+ kfree(sess);
+ return -ENOMEM;
+ }
+
+ spin_lock_irqsave(&cctx->lock, flags);
+ cctx->ext_cb = new_ext;
+ sess->valid = true;
+ sess->dev = dev;
+ sess->sid = sid;
+ dev_set_drvdata(dev, sess);
+ cctx->ext_cb[cctx->ext_cb_count++] = sess;
+ spin_unlock_irqrestore(&cctx->lock, flags);
+
+ return 0;
+ }
+
spin_lock_irqsave(&cctx->lock, flags);
if (cctx->sesscount >= FASTRPC_MAX_SESSIONS) {
spin_unlock_irqrestore(&cctx->lock, flags);
@@ -2391,6 +2435,8 @@ static void fastrpc_cb_devices_destroy(struct rpmsg_device *rpdev)
spin_lock_irqsave(&cctx->lock, flags);
for (i = 0; i < cctx->sesscount; i++)
cctx->session[i].valid = false;
+ for (i = 0; i < cctx->ext_cb_count; i++)
+ cctx->ext_cb[i]->valid = false;
spin_unlock_irqrestore(&cctx->lock, flags);
for_each_available_child_of_node(rdev->of_node, np) {
--
2.34.1