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 <jonathanh@nvidia.com>
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 <svcacv@nvidia.com>
Reviewed-by: svc_kernel_abi <svc_kernel_abi@nvidia.com>
Reviewed-by: Mikko Perttunen <mperttunen@nvidia.com>
GVS: Gerrit_Virtual_Submit <buildbot_gerritrpt@nvidia.com>
This commit is contained in:
Jon Hunter
2022-10-31 15:34:20 +00:00
committed by Laxman Dewangan
parent 968b6f758f
commit 6cd2f00c46

View File

@@ -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);