--- zzzz-none-000/linux-3.10.107/drivers/gpu/drm/exynos/exynos_drm_iommu.c 2017-06-27 09:49:32.000000000 +0000 +++ scorpion-7490-727/linux-3.10.107/drivers/gpu/drm/exynos/exynos_drm_iommu.c 2021-02-04 17:41:59.000000000 +0000 @@ -36,21 +36,25 @@ priv->da_start = EXYNOS_DEV_ADDR_START; if (!priv->da_space_size) priv->da_space_size = EXYNOS_DEV_ADDR_SIZE; - if (!priv->da_space_order) - priv->da_space_order = EXYNOS_DEV_ADDR_ORDER; mapping = arm_iommu_create_mapping(&platform_bus_type, priv->da_start, - priv->da_space_size, - priv->da_space_order); + priv->da_space_size); + if (IS_ERR(mapping)) return PTR_ERR(mapping); dev->dma_parms = devm_kzalloc(dev, sizeof(*dev->dma_parms), GFP_KERNEL); + if (!dev->dma_parms) + goto error; + dma_set_max_seg_size(dev, 0xffffffffu); dev->archdata.mapping = mapping; return 0; +error: + arm_iommu_release_mapping(mapping); + return -ENOMEM; } /* @@ -83,16 +87,20 @@ struct device *dev = drm_dev->dev; int ret; - if (!dev->archdata.mapping) { - DRM_ERROR("iommu_mapping is null.\n"); - return -EFAULT; - } + if (!dev->archdata.mapping) + return 0; subdrv_dev->dma_parms = devm_kzalloc(subdrv_dev, sizeof(*subdrv_dev->dma_parms), GFP_KERNEL); + if (!subdrv_dev->dma_parms) + return -ENOMEM; + dma_set_max_seg_size(subdrv_dev, 0xffffffffu); + if (subdrv_dev->archdata.mapping) + arm_iommu_detach_device(subdrv_dev); + ret = arm_iommu_attach_device(subdrv_dev, dev->archdata.mapping); if (ret < 0) { DRM_DEBUG_KMS("failed iommu attach.\n"); @@ -107,8 +115,8 @@ * If iommu attach succeeded, the sub driver would have dma_ops * for iommu and also all sub drivers have same dma_ops. */ - if (!dev->archdata.dma_ops) - dev->archdata.dma_ops = subdrv_dev->archdata.dma_ops; + if (get_dma_ops(dev) == get_dma_ops(NULL)) + set_dma_ops(dev, get_dma_ops(subdrv_dev)); return 0; } @@ -131,6 +139,5 @@ if (!mapping || !mapping->domain) return; - iommu_detach_device(mapping->domain, subdrv_dev); - drm_release_iommu_mapping(drm_dev); + arm_iommu_detach_device(subdrv_dev); }