]> git.karo-electronics.de Git - karo-tx-linux.git/blobdiff - drivers/iommu/iommu.c
Merge branch 'for_linus' of git://git.kernel.org/pub/scm/linux/kernel/git/jack/linux-fs
[karo-tx-linux.git] / drivers / iommu / iommu.c
index ddbdacad7768e4c530a2e12657dc953a763325cc..b972d430d92b946eb16e98a41a2e23441b17f93e 100644 (file)
@@ -734,7 +734,8 @@ int iommu_map(struct iommu_domain *domain, unsigned long iova,
        size_t orig_size = size;
        int ret = 0;
 
-       if (unlikely(domain->ops->map == NULL))
+       if (unlikely(domain->ops->unmap == NULL ||
+                    domain->ops->pgsize_bitmap == 0UL))
                return -ENODEV;
 
        /* 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)
        size_t unmapped_page, unmapped = 0;
        unsigned int min_pagesz;
 
-       if (unlikely(domain->ops->unmap == NULL))
+       if (unlikely(domain->ops->unmap == NULL ||
+                    domain->ops->pgsize_bitmap == 0UL))
                return -ENODEV;
 
        /* 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)
 }
 EXPORT_SYMBOL_GPL(iommu_unmap);
 
+
+int iommu_domain_window_enable(struct iommu_domain *domain, u32 wnd_nr,
+                              phys_addr_t paddr, u64 size)
+{
+       if (unlikely(domain->ops->domain_window_enable == NULL))
+               return -ENODEV;
+
+       return domain->ops->domain_window_enable(domain, wnd_nr, paddr, size);
+}
+EXPORT_SYMBOL_GPL(iommu_domain_window_enable);
+
+void iommu_domain_window_disable(struct iommu_domain *domain, u32 wnd_nr)
+{
+       if (unlikely(domain->ops->domain_window_disable == NULL))
+               return;
+
+       return domain->ops->domain_window_disable(domain, wnd_nr);
+}
+EXPORT_SYMBOL_GPL(iommu_domain_window_disable);
+
 static int __init iommu_init(void)
 {
        iommu_group_kset = kset_create_and_add("iommu_groups",
@@ -861,19 +883,34 @@ static int __init iommu_init(void)
 
        return 0;
 }
-subsys_initcall(iommu_init);
+arch_initcall(iommu_init);
 
 int iommu_domain_get_attr(struct iommu_domain *domain,
                          enum iommu_attr attr, void *data)
 {
        struct iommu_domain_geometry *geometry;
+       bool *paging;
        int ret = 0;
+       u32 *count;
 
        switch (attr) {
        case DOMAIN_ATTR_GEOMETRY:
                geometry  = data;
                *geometry = domain->geometry;
 
+               break;
+       case DOMAIN_ATTR_PAGING:
+               paging  = data;
+               *paging = (domain->ops->pgsize_bitmap != 0UL);
+               break;
+       case DOMAIN_ATTR_WINDOWS:
+               count = data;
+
+               if (domain->ops->domain_get_windows != NULL)
+                       *count = domain->ops->domain_get_windows(domain);
+               else
+                       ret = -ENODEV;
+
                break;
        default:
                if (!domain->ops->domain_get_attr)
@@ -889,9 +926,26 @@ EXPORT_SYMBOL_GPL(iommu_domain_get_attr);
 int iommu_domain_set_attr(struct iommu_domain *domain,
                          enum iommu_attr attr, void *data)
 {
-       if (!domain->ops->domain_set_attr)
-               return -EINVAL;
+       int ret = 0;
+       u32 *count;
 
-       return domain->ops->domain_set_attr(domain, attr, data);
+       switch (attr) {
+       case DOMAIN_ATTR_WINDOWS:
+               count = data;
+
+               if (domain->ops->domain_set_windows != NULL)
+                       ret = domain->ops->domain_set_windows(domain, *count);
+               else
+                       ret = -ENODEV;
+
+               break;
+       default:
+               if (domain->ops->domain_set_attr == NULL)
+                       return -EINVAL;
+
+               ret = domain->ops->domain_set_attr(domain, attr, data);
+       }
+
+       return ret;
 }
 EXPORT_SYMBOL_GPL(iommu_domain_set_attr);