iovad->granule = granule;
        iovad->start_pfn = start_pfn;
        iovad->dma_32bit_pfn = pfn_32bit + 1;
+       iovad->flush_cb = NULL;
+       iovad->fq = NULL;
        init_iova_rcaches(iovad);
 }
 EXPORT_SYMBOL_GPL(init_iova_domain);
 
+static void free_iova_flush_queue(struct iova_domain *iovad)
+{
+       if (!iovad->fq)
+               return;
+
+       free_percpu(iovad->fq);
+
+       iovad->fq         = NULL;
+       iovad->flush_cb   = NULL;
+       iovad->entry_dtor = NULL;
+}
+
+int init_iova_flush_queue(struct iova_domain *iovad,
+                         iova_flush_cb flush_cb, iova_entry_dtor entry_dtor)
+{
+       int cpu;
+
+       iovad->fq = alloc_percpu(struct iova_fq);
+       if (!iovad->fq)
+               return -ENOMEM;
+
+       iovad->flush_cb   = flush_cb;
+       iovad->entry_dtor = entry_dtor;
+
+       for_each_possible_cpu(cpu) {
+               struct iova_fq *fq;
+
+               fq = per_cpu_ptr(iovad->fq, cpu);
+               fq->head = 0;
+               fq->tail = 0;
+       }
+
+       return 0;
+}
+EXPORT_SYMBOL_GPL(init_iova_flush_queue);
+
 static struct rb_node *
 __get_cached_rbnode(struct iova_domain *iovad, unsigned long *limit_pfn)
 {
        struct rb_node *node;
        unsigned long flags;
 
+       free_iova_flush_queue(iovad);
        free_iova_rcaches(iovad);
        spin_lock_irqsave(&iovad->iova_rbtree_lock, flags);
        node = rb_first(&iovad->rbroot);
 
        struct iova_cpu_rcache __percpu *cpu_rcaches;
 };
 
+struct iova_domain;
+
+/* Call-Back from IOVA code into IOMMU drivers */
+typedef void (* iova_flush_cb)(struct iova_domain *domain);
+
+/* Destructor for per-entry data */
+typedef void (* iova_entry_dtor)(unsigned long data);
+
+/* Number of entries per Flush Queue */
+#define IOVA_FQ_SIZE   256
+
+/* Flush Queue entry for defered flushing */
+struct iova_fq_entry {
+       unsigned long iova_pfn;
+       unsigned long pages;
+       unsigned long data;
+};
+
+/* Per-CPU Flush Queue structure */
+struct iova_fq {
+       struct iova_fq_entry entries[IOVA_FQ_SIZE];
+       unsigned head, tail;
+};
+
 /* holds all the iova translations for a domain */
 struct iova_domain {
        spinlock_t      iova_rbtree_lock; /* Lock to protect update of rbtree */
        unsigned long   start_pfn;      /* Lower limit for this domain */
        unsigned long   dma_32bit_pfn;
        struct iova_rcache rcaches[IOVA_RANGE_CACHE_MAX_SIZE];  /* IOVA range caches */
+
+       iova_flush_cb   flush_cb;       /* Call-Back function to flush IOMMU
+                                          TLBs */
+
+       iova_entry_dtor entry_dtor;     /* IOMMU driver specific destructor for
+                                          iova entry */
+
+       struct iova_fq __percpu *fq;    /* Flush Queue */
 };
 
 static inline unsigned long iova_size(struct iova *iova)
 void copy_reserved_iova(struct iova_domain *from, struct iova_domain *to);
 void init_iova_domain(struct iova_domain *iovad, unsigned long granule,
        unsigned long start_pfn, unsigned long pfn_32bit);
+int init_iova_flush_queue(struct iova_domain *iovad,
+                         iova_flush_cb flush_cb, iova_entry_dtor entry_dtor);
 struct iova *find_iova(struct iova_domain *iovad, unsigned long pfn);
 void put_iova_domain(struct iova_domain *iovad);
 struct iova *split_and_remove_iova(struct iova_domain *iovad,
 {
 }
 
+static inline int init_iova_flush_queue(struct iova_domain *iovad,
+                                       iova_flush_cb flush_cb,
+                                       iova_entry_dtor entry_dtor)
+{
+       return -ENODEV;
+}
+
 static inline struct iova *find_iova(struct iova_domain *iovad,
                                     unsigned long pfn)
 {