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 <[email protected]> --- 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
