Merge branches 'arm/exynos', 'arm/renesas', 'arm/rockchip', 'arm/omap', 'arm/mediatek...
[sfrench/cifs-2.6.git] / include / linux / iommu.h
index 2cb54adc4a334aa3f3a1732c35eaf9749d64b9e8..a7f2ac689d2917e2902e78604e8b6b33df1ee333 100644 (file)
@@ -167,6 +167,10 @@ struct iommu_resv_region {
  * @map: map a physically contiguous memory region to an iommu domain
  * @unmap: unmap a physically contiguous memory region from an iommu domain
  * @map_sg: map a scatter-gather list of physically contiguous memory chunks
+ * @flush_tlb_all: Synchronously flush all hardware TLBs for this domain
+ * @tlb_range_add: Add a given iova range to the flush queue for this domain
+ * @tlb_sync: Flush all queued ranges from the hardware TLBs and empty flush
+ *            queue
  * to an iommu domain
  * @iova_to_phys: translate iova to physical address
  * @add_device: add device to iommu grouping
@@ -199,6 +203,10 @@ struct iommu_ops {
                     size_t size);
        size_t (*map_sg)(struct iommu_domain *domain, unsigned long iova,
                         struct scatterlist *sg, unsigned int nents, int prot);
+       void (*flush_iotlb_all)(struct iommu_domain *domain);
+       void (*iotlb_range_add)(struct iommu_domain *domain,
+                               unsigned long iova, size_t size);
+       void (*iotlb_sync)(struct iommu_domain *domain);
        phys_addr_t (*iova_to_phys)(struct iommu_domain *domain, dma_addr_t iova);
        int (*add_device)(struct device *dev);
        void (*remove_device)(struct device *dev);
@@ -225,6 +233,7 @@ struct iommu_ops {
        u32 (*domain_get_windows)(struct iommu_domain *domain);
 
        int (*of_xlate)(struct device *dev, struct of_phandle_args *args);
+       bool (*is_attach_deferred)(struct iommu_domain *domain, struct device *dev);
 
        unsigned long pgsize_bitmap;
 };
@@ -240,7 +249,7 @@ struct iommu_device {
        struct list_head list;
        const struct iommu_ops *ops;
        struct fwnode_handle *fwnode;
-       struct device dev;
+       struct device *dev;
 };
 
 int  iommu_device_register(struct iommu_device *iommu);
@@ -265,6 +274,11 @@ static inline void iommu_device_set_fwnode(struct iommu_device *iommu,
        iommu->fwnode = fwnode;
 }
 
+static inline struct iommu_device *dev_to_iommu_device(struct device *dev)
+{
+       return (struct iommu_device *)dev_get_drvdata(dev);
+}
+
 #define IOMMU_GROUP_NOTIFY_ADD_DEVICE          1 /* Device added */
 #define IOMMU_GROUP_NOTIFY_DEL_DEVICE          2 /* Pre Device removed */
 #define IOMMU_GROUP_NOTIFY_BIND_DRIVER         3 /* Pre Driver bind */
@@ -286,7 +300,9 @@ extern struct iommu_domain *iommu_get_domain_for_dev(struct device *dev);
 extern int iommu_map(struct iommu_domain *domain, unsigned long iova,
                     phys_addr_t paddr, size_t size, int prot);
 extern size_t iommu_unmap(struct iommu_domain *domain, unsigned long iova,
-                      size_t size);
+                         size_t size);
+extern size_t iommu_unmap_fast(struct iommu_domain *domain,
+                              unsigned long iova, size_t size);
 extern size_t default_iommu_map_sg(struct iommu_domain *domain, unsigned long iova,
                                struct scatterlist *sg,unsigned int nents,
                                int prot);
@@ -343,6 +359,25 @@ extern void iommu_domain_window_disable(struct iommu_domain *domain, u32 wnd_nr)
 extern int report_iommu_fault(struct iommu_domain *domain, struct device *dev,
                              unsigned long iova, int flags);
 
+static inline void iommu_flush_tlb_all(struct iommu_domain *domain)
+{
+       if (domain->ops->flush_iotlb_all)
+               domain->ops->flush_iotlb_all(domain);
+}
+
+static inline void iommu_tlb_range_add(struct iommu_domain *domain,
+                                      unsigned long iova, size_t size)
+{
+       if (domain->ops->iotlb_range_add)
+               domain->ops->iotlb_range_add(domain, iova, size);
+}
+
+static inline void iommu_tlb_sync(struct iommu_domain *domain)
+{
+       if (domain->ops->iotlb_sync)
+               domain->ops->iotlb_sync(domain);
+}
+
 static inline size_t iommu_map_sg(struct iommu_domain *domain,
                                  unsigned long iova, struct scatterlist *sg,
                                  unsigned int nents, int prot)
@@ -425,13 +460,19 @@ static inline struct iommu_domain *iommu_get_domain_for_dev(struct device *dev)
 }
 
 static inline int iommu_map(struct iommu_domain *domain, unsigned long iova,
-                           phys_addr_t paddr, int gfp_order, int prot)
+                           phys_addr_t paddr, size_t size, int prot)
 {
        return -ENODEV;
 }
 
 static inline int iommu_unmap(struct iommu_domain *domain, unsigned long iova,
-                             int gfp_order)
+                             size_t size)
+{
+       return -ENODEV;
+}
+
+static inline int iommu_unmap_fast(struct iommu_domain *domain, unsigned long iova,
+                                  int gfp_order)
 {
        return -ENODEV;
 }
@@ -443,6 +484,19 @@ static inline size_t iommu_map_sg(struct iommu_domain *domain,
        return -ENODEV;
 }
 
+static inline void iommu_flush_tlb_all(struct iommu_domain *domain)
+{
+}
+
+static inline void iommu_tlb_range_add(struct iommu_domain *domain,
+                                      unsigned long iova, size_t size)
+{
+}
+
+static inline void iommu_tlb_sync(struct iommu_domain *domain)
+{
+}
+
 static inline int iommu_domain_window_enable(struct iommu_domain *domain,
                                             u32 wnd_nr, phys_addr_t paddr,
                                             u64 size, int prot)
@@ -589,6 +643,11 @@ static inline void iommu_device_set_fwnode(struct iommu_device *iommu,
 {
 }
 
+static inline struct iommu_device *dev_to_iommu_device(struct device *dev)
+{
+       return NULL;
+}
+
 static inline void iommu_device_unregister(struct iommu_device *iommu)
 {
 }