From 6cd2f00c4637640efeff4e6a0a2bef3e63992be4 Mon Sep 17 00:00:00 2001 From: Jon Hunter Date: Mon, 31 Oct 2022 15:34:20 +0000 Subject: [PATCH] nvhost: Add clean up function for syncpt interface Drivers, such as the PVA and DLA driver, that call nvhost_syncpt_unit_interface_init() during probe are missing a call to clean-up the DMA mappings this function may create if the driver probe fails or if the driver is removed. The function nvhost_syncpt_unit_interface_init() may make a call to dma_map_sg_attrs() and we need to ensure that dma_unmap_sg_attrs() is called if the probe of the driver fails or if the driver is unloaded. Add a new function, nvhost_syncpt_unit_interface_deinit(), that calls dma_unmap_sg_attrs() if needed for drivers to call. Bug 3800349 Change-Id: I62a4e19cd42878dac54fa623509440596ffdf17f Signed-off-by: Jon Hunter Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2801280 (cherry picked from commit cee12fb989186611aa9deb5ada45831ab5f783aa) Reviewed-on: https://git-master.nvidia.com/r/c/linux-nvidia/+/2801934 Reviewed-by: svcacv Reviewed-by: svc_kernel_abi Reviewed-by: Mikko Perttunen GVS: Gerrit_Virtual_Submit --- drivers/gpu/host1x-nvhost/nvhost.c | 26 ++++++++++++++++++++------ 1 file changed, 20 insertions(+), 6 deletions(-) diff --git a/drivers/gpu/host1x-nvhost/nvhost.c b/drivers/gpu/host1x-nvhost/nvhost.c index 933aedd5..bd1fc6cd 100644 --- a/drivers/gpu/host1x-nvhost/nvhost.c +++ b/drivers/gpu/host1x-nvhost/nvhost.c @@ -34,6 +34,7 @@ #define NVHOST_NUM_CDEV 1 struct nvhost_syncpt_interface { + struct scatterlist sg; dma_addr_t base; uint32_t page_size; }; @@ -439,12 +440,10 @@ int nvhost_syncpt_unit_interface_init(struct platform_device *pdev) /* If IOMMU is enabled, map it into the device memory */ if (iommu_get_domain_for_dev(&pdev->dev)) { - struct scatterlist sg; + sg_init_table(&syncpt_if->sg, 1); + sg_set_page(&syncpt_if->sg, phys_to_page(base), size, 0); - sg_init_table(&sg, 1); - sg_set_page(&sg, phys_to_page(base), size, 0); - - err = dma_map_sg_attrs(&pdev->dev, &sg, 1, + err = dma_map_sg_attrs(&pdev->dev, &syncpt_if->sg, 1, DMA_BIDIRECTIONAL, DMA_ATTR_SKIP_CPU_SYNC); if (err == 0) { @@ -452,7 +451,7 @@ int nvhost_syncpt_unit_interface_init(struct platform_device *pdev) return err; } - syncpt_if->base = sg_dma_address(&sg); + syncpt_if->base = sg_dma_address(&syncpt_if->sg); } else { syncpt_if->base = base; } @@ -467,6 +466,21 @@ int nvhost_syncpt_unit_interface_init(struct platform_device *pdev) } EXPORT_SYMBOL(nvhost_syncpt_unit_interface_init); +void nvhost_syncpt_unit_interface_deinit(struct platform_device *pdev) +{ + struct nvhost_syncpt_interface *syncpt_if; + struct nvhost_device_data *pdata; + + if (iommu_get_domain_for_dev(&pdev->dev)) { + pdata = platform_get_drvdata(pdev); + syncpt_if = pdata->syncpt_unit_interface; + + dma_unmap_sg_attrs(&pdev->dev, &syncpt_if->sg, 1, + DMA_BIDIRECTIONAL, DMA_ATTR_SKIP_CPU_SYNC); + } +} +EXPORT_SYMBOL(nvhost_syncpt_unit_interface_deinit); + dma_addr_t nvhost_syncpt_address(struct platform_device *pdev, u32 id) { struct nvhost_device_data *pdata = platform_get_drvdata(pdev);