Loading arch/arm/mm/dma-mapping.c +4 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include <linux/vmalloc.h> #include <linux/sizes.h> #include <linux/cma.h> #include <linux/msm_dma_iommu_mapping.h> #include <asm/memory.h> #include <asm/highmem.h> Loading Loading @@ -2190,6 +2191,9 @@ static void __arm_iommu_detach_device(struct device *dev) return; } if (msm_dma_unmap_all_for_dev(dev)) dev_warn(dev, "IOMMU detach with outstanding mappings\n"); iommu_detach_device(mapping->domain, dev); kref_put(&mapping->kref, release_iommu_mapping); to_dma_iommu_mapping(dev) = NULL; Loading arch/arm64/mm/dma-mapping.c +4 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ #include <linux/io.h> #include <asm/dma-iommu.h> #include <linux/dma-mapping-fast.h> #include <linux/msm_dma_iommu_mapping.h> #include "mm.h" Loading Loading @@ -2164,6 +2165,9 @@ void arm_iommu_detach_device(struct device *dev) iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_S1_BYPASS, &s1_bypass); if (msm_dma_unmap_all_for_dev(dev)) dev_warn(dev, "IOMMU detach with outstanding mappings\n"); iommu_detach_device(mapping->domain, dev); kref_put(&mapping->kref, release_iommu_mapping); dev->archdata.mapping = NULL; Loading drivers/iommu/msm_dma_iommu_mapping.c +29 −0 Original line number Diff line number Diff line Loading @@ -346,6 +346,35 @@ out: } EXPORT_SYMBOL(msm_dma_unmap_sg); int msm_dma_unmap_all_for_dev(struct device *dev) { int ret = 0; struct msm_iommu_meta *meta; struct rb_root *root; struct rb_node *meta_node; mutex_lock(&msm_iommu_map_mutex); root = &iommu_root; meta_node = rb_first(root); while (meta_node) { struct msm_iommu_map *iommu_map; meta = rb_entry(meta_node, struct msm_iommu_meta, node); mutex_lock(&meta->lock); list_for_each_entry(iommu_map, &meta->iommu_maps, lnode) if (iommu_map->dev == dev) if (!kref_put(&iommu_map->ref, msm_iommu_map_release)) ret = -EINVAL; mutex_unlock(&meta->lock); meta_node = rb_next(meta_node); } mutex_unlock(&msm_iommu_map_mutex); return ret; } /* * Only to be called by ION code when a buffer is freed */ Loading include/linux/msm_dma_iommu_mapping.h +7 −1 Original line number Diff line number Diff line /* Copyright (c) 2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -50,6 +50,7 @@ static inline int msm_dma_map_sg(struct device *dev, struct scatterlist *sg, void msm_dma_unmap_sg(struct device *dev, struct scatterlist *sgl, int nents, enum dma_data_direction dir, struct dma_buf *dma_buf); int msm_dma_unmap_all_for_dev(struct device *dev); /* * Below is private function only to be called by framework (ION) and not by Loading Loading @@ -89,6 +90,11 @@ static inline void msm_dma_unmap_sg(struct device *dev, { } int msm_dma_unmap_all_for_dev(struct device *dev) { return 0; } static inline void msm_dma_buf_freed(void *buffer) {} #endif /*CONFIG_IOMMU_API*/ Loading Loading
arch/arm/mm/dma-mapping.c +4 −0 Original line number Diff line number Diff line Loading @@ -28,6 +28,7 @@ #include <linux/vmalloc.h> #include <linux/sizes.h> #include <linux/cma.h> #include <linux/msm_dma_iommu_mapping.h> #include <asm/memory.h> #include <asm/highmem.h> Loading Loading @@ -2190,6 +2191,9 @@ static void __arm_iommu_detach_device(struct device *dev) return; } if (msm_dma_unmap_all_for_dev(dev)) dev_warn(dev, "IOMMU detach with outstanding mappings\n"); iommu_detach_device(mapping->domain, dev); kref_put(&mapping->kref, release_iommu_mapping); to_dma_iommu_mapping(dev) = NULL; Loading
arch/arm64/mm/dma-mapping.c +4 −0 Original line number Diff line number Diff line Loading @@ -34,6 +34,7 @@ #include <linux/io.h> #include <asm/dma-iommu.h> #include <linux/dma-mapping-fast.h> #include <linux/msm_dma_iommu_mapping.h> #include "mm.h" Loading Loading @@ -2164,6 +2165,9 @@ void arm_iommu_detach_device(struct device *dev) iommu_domain_get_attr(mapping->domain, DOMAIN_ATTR_S1_BYPASS, &s1_bypass); if (msm_dma_unmap_all_for_dev(dev)) dev_warn(dev, "IOMMU detach with outstanding mappings\n"); iommu_detach_device(mapping->domain, dev); kref_put(&mapping->kref, release_iommu_mapping); dev->archdata.mapping = NULL; Loading
drivers/iommu/msm_dma_iommu_mapping.c +29 −0 Original line number Diff line number Diff line Loading @@ -346,6 +346,35 @@ out: } EXPORT_SYMBOL(msm_dma_unmap_sg); int msm_dma_unmap_all_for_dev(struct device *dev) { int ret = 0; struct msm_iommu_meta *meta; struct rb_root *root; struct rb_node *meta_node; mutex_lock(&msm_iommu_map_mutex); root = &iommu_root; meta_node = rb_first(root); while (meta_node) { struct msm_iommu_map *iommu_map; meta = rb_entry(meta_node, struct msm_iommu_meta, node); mutex_lock(&meta->lock); list_for_each_entry(iommu_map, &meta->iommu_maps, lnode) if (iommu_map->dev == dev) if (!kref_put(&iommu_map->ref, msm_iommu_map_release)) ret = -EINVAL; mutex_unlock(&meta->lock); meta_node = rb_next(meta_node); } mutex_unlock(&msm_iommu_map_mutex); return ret; } /* * Only to be called by ION code when a buffer is freed */ Loading
include/linux/msm_dma_iommu_mapping.h +7 −1 Original line number Diff line number Diff line /* Copyright (c) 2015, The Linux Foundation. All rights reserved. /* Copyright (c) 2015-2016, The Linux Foundation. All rights reserved. * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 and Loading Loading @@ -50,6 +50,7 @@ static inline int msm_dma_map_sg(struct device *dev, struct scatterlist *sg, void msm_dma_unmap_sg(struct device *dev, struct scatterlist *sgl, int nents, enum dma_data_direction dir, struct dma_buf *dma_buf); int msm_dma_unmap_all_for_dev(struct device *dev); /* * Below is private function only to be called by framework (ION) and not by Loading Loading @@ -89,6 +90,11 @@ static inline void msm_dma_unmap_sg(struct device *dev, { } int msm_dma_unmap_all_for_dev(struct device *dev) { return 0; } static inline void msm_dma_buf_freed(void *buffer) {} #endif /*CONFIG_IOMMU_API*/ Loading