diff --git a/drivers/gpu/drm/msm/msm_iommu.c b/drivers/gpu/drm/msm/msm_iommu.c index 897e42c8d5c8..da6782fca6bd 100644 --- a/drivers/gpu/drm/msm/msm_iommu.c +++ b/drivers/gpu/drm/msm/msm_iommu.c @@ -7,6 +7,15 @@ #include #include #include + +#if defined(CONFIG_ARM_DMA_USE_IOMMU) +#include +#else +#define arm_iommu_detach_device(...) ({ }) +#define arm_iommu_release_mapping(...) ({ }) +#define to_dma_iommu_mapping(dev) NULL +#endif + #include "msm_drv.h" #include "msm_gpu_trace.h" #include "msm_mmu.h" @@ -749,6 +758,19 @@ struct msm_mmu *msm_iommu_new(struct device *dev, unsigned long quirks) mutex_init(&iommu->init_lock); + /* + * ARM32 attaches a DMA mapping domain to every IOMMU-backed device, + * which would make attaching our own domain fail with -EBUSY. + */ + if (IS_ENABLED(CONFIG_ARM_DMA_USE_IOMMU)) { + struct dma_iommu_mapping *mapping = to_dma_iommu_mapping(dev); + + if (mapping) { + arm_iommu_detach_device(dev); + arm_iommu_release_mapping(mapping); + } + } + ret = iommu_attach_device(iommu->domain, dev); if (ret) { iommu_domain_free(domain);