aboutsummaryrefslogtreecommitdiffstats
path: root/drivers/iommu/iommu.c
diff options
context:
space:
mode:
Diffstat (limited to 'drivers/iommu/iommu.c')
-rw-r--r--drivers/iommu/iommu.c66
1 files changed, 60 insertions, 6 deletions
diff --git a/drivers/iommu/iommu.c b/drivers/iommu/iommu.c
index ddbdacad7768..b972d430d92b 100644
--- a/drivers/iommu/iommu.c
+++ b/drivers/iommu/iommu.c
@@ -734,7 +734,8 @@ int iommu_map(struct iommu_domain *domain, unsigned long iova,
734 size_t orig_size = size; 734 size_t orig_size = size;
735 int ret = 0; 735 int ret = 0;
736 736
737 if (unlikely(domain->ops->map == NULL)) 737 if (unlikely(domain->ops->unmap == NULL ||
738 domain->ops->pgsize_bitmap == 0UL))
738 return -ENODEV; 739 return -ENODEV;
739 740
740 /* find out the minimum page size supported */ 741 /* find out the minimum page size supported */
@@ -808,7 +809,8 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)
808 size_t unmapped_page, unmapped = 0; 809 size_t unmapped_page, unmapped = 0;
809 unsigned int min_pagesz; 810 unsigned int min_pagesz;
810 811
811 if (unlikely(domain->ops->unmap == NULL)) 812 if (unlikely(domain->ops->unmap == NULL ||
813 domain->ops->pgsize_bitmap == 0UL))
812 return -ENODEV; 814 return -ENODEV;
813 815
814 /* find out the minimum page size supported */ 816 /* find out the minimum page size supported */
@@ -850,6 +852,26 @@ size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova, size_t size)
850} 852}
851EXPORT_SYMBOL_GPL(iommu_unmap); 853EXPORT_SYMBOL_GPL(iommu_unmap);
852 854
855
856int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr,
857 phys_addr_t paddr, u64 size)
858{
859 if (unlikely(domain->ops->domain_window_enable == NULL))
860 return -ENODEV;
861
862 return domain->ops->domain_window_enable(domain, wnd_nr, paddr, size);
863}
864EXPORT_SYMBOL_GPL(iommu_domain_window_enable);
865
866void iommu_domain_window_disable(struct iommu_domain *domain, u32 wnd_nr)
867{
868 if (unlikely(domain->ops->domain_window_disable == NULL))
869 return;
870
871 return domain->ops->domain_window_disable(domain, wnd_nr);
872}
873EXPORT_SYMBOL_GPL(iommu_domain_window_disable);
874
853static int __init iommu_init(void) 875static int __init iommu_init(void)
854{ 876{
855 iommu_group_kset = kset_create_and_add("iommu_groups", 877 iommu_group_kset = kset_create_and_add("iommu_groups",
@@ -861,13 +883,15 @@ static int __init iommu_init(void)
861 883
862 return 0; 884 return 0;
863} 885}
864subsys_initcall(iommu_init); 886arch_initcall(iommu_init);
865 887
866int iommu_domain_get_attr(struct iommu_domain *domain, 888int iommu_domain_get_attr(struct iommu_domain *domain,
867 enum iommu_attr attr, void *data) 889 enum iommu_attr attr, void *data)
868{ 890{
869 struct iommu_domain_geometry *geometry; 891 struct iommu_domain_geometry *geometry;
892 bool *paging;
870 int ret = 0; 893 int ret = 0;
894 u32 *count;
871 895
872 switch (attr) { 896 switch (attr) {
873 case DOMAIN_ATTR_GEOMETRY: 897 case DOMAIN_ATTR_GEOMETRY:
@@ -875,6 +899,19 @@ int iommu_domain_get_attr(struct iommu_domain *domain,
875 *geometry = domain->geometry; 899 *geometry = domain->geometry;
876 900
877 break; 901 break;
902 case DOMAIN_ATTR_PAGING:
903 paging = data;
904 *paging = (domain->ops->pgsize_bitmap != 0UL);
905 break;
906 case DOMAIN_ATTR_WINDOWS:
907 count = data;
908
909 if (domain->ops->domain_get_windows != NULL)
910 *count = domain->ops->domain_get_windows(domain);
911 else
912 ret = -ENODEV;
913
914 break;
878 default: 915 default:
879 if (!domain->ops->domain_get_attr) 916 if (!domain->ops->domain_get_attr)
880 return -EINVAL; 917 return -EINVAL;
@@ -889,9 +926,26 @@ EXPORT_SYMBOL_GPL(iommu_domain_get_attr);
889int iommu_domain_set_attr(struct iommu_domain *domain, 926int iommu_domain_set_attr(struct iommu_domain *domain,
890 enum iommu_attr attr, void *data) 927 enum iommu_attr attr, void *data)
891{ 928{
892 if (!domain->ops->domain_set_attr) 929 int ret = 0;
893 return -EINVAL; 930 u32 *count;
894 931
895 return domain->ops->domain_set_attr(domain, attr, data); 932 switch (attr) {
933 case DOMAIN_ATTR_WINDOWS:
934 count = data;
935
936 if (domain->ops->domain_set_windows != NULL)
937 ret = domain->ops->domain_set_windows(domain, *count);
938 else
939 ret = -ENODEV;
940
941 break;
942 default:
943 if (domain->ops->domain_set_attr == NULL)
944 return -EINVAL;
945
946 ret = domain->ops->domain_set_attr(domain, attr, data);
947 }
948
949 return ret;
896} 950}
897EXPORT_SYMBOL_GPL(iommu_domain_set_attr); 951EXPORT_SYMBOL_GPL(iommu_domain_set_attr);