}
 EXPORT_SYMBOL(dmam_alloc_attrs);
 
-static inline bool dma_is_direct(const struct dma_map_ops *ops)
+static bool dma_go_direct(struct device *dev, dma_addr_t mask,
+               const struct dma_map_ops *ops)
 {
-       return likely(!ops);
+       if (likely(!ops))
+               return true;
+#ifdef CONFIG_DMA_OPS_BYPASS
+       if (dev->dma_ops_bypass)
+               return min_not_zero(mask, dev->bus_dma_limit) >=
+                           dma_direct_get_required_mask(dev);
+#endif
+       return false;
+}
+
+
+/*
+ * Check if the devices uses a direct mapping for streaming DMA operations.
+ * This allows IOMMU drivers to set a bypass mode if the DMA mask is large
+ * enough.
+ */
+static inline bool dma_alloc_direct(struct device *dev,
+               const struct dma_map_ops *ops)
+{
+       return dma_go_direct(dev, dev->coherent_dma_mask, ops);
+}
+
+static inline bool dma_map_direct(struct device *dev,
+               const struct dma_map_ops *ops)
+{
+       return dma_go_direct(dev, *dev->dma_mask, ops);
 }
 
 dma_addr_t dma_map_page_attrs(struct device *dev, struct page *page,
        dma_addr_t addr;
 
        BUG_ON(!valid_dma_direction(dir));
-       if (dma_is_direct(ops))
+       if (dma_map_direct(dev, ops))
                addr = dma_direct_map_page(dev, page, offset, size, dir, attrs);
        else
                addr = ops->map_page(dev, page, offset, size, dir, attrs);
        const struct dma_map_ops *ops = get_dma_ops(dev);
 
        BUG_ON(!valid_dma_direction(dir));
-       if (dma_is_direct(ops))
+       if (dma_map_direct(dev, ops))
                dma_direct_unmap_page(dev, addr, size, dir, attrs);
        else if (ops->unmap_page)
                ops->unmap_page(dev, addr, size, dir, attrs);
        int ents;
 
        BUG_ON(!valid_dma_direction(dir));
-       if (dma_is_direct(ops))
+       if (dma_map_direct(dev, ops))
                ents = dma_direct_map_sg(dev, sg, nents, dir, attrs);
        else
                ents = ops->map_sg(dev, sg, nents, dir, attrs);
 
        BUG_ON(!valid_dma_direction(dir));
        debug_dma_unmap_sg(dev, sg, nents, dir);
-       if (dma_is_direct(ops))
+       if (dma_map_direct(dev, ops))
                dma_direct_unmap_sg(dev, sg, nents, dir, attrs);
        else if (ops->unmap_sg)
                ops->unmap_sg(dev, sg, nents, dir, attrs);
        if (WARN_ON_ONCE(pfn_valid(PHYS_PFN(phys_addr))))
                return DMA_MAPPING_ERROR;
 
-       if (dma_is_direct(ops))
+       if (dma_map_direct(dev, ops))
                addr = dma_direct_map_resource(dev, phys_addr, size, dir, attrs);
        else if (ops->map_resource)
                addr = ops->map_resource(dev, phys_addr, size, dir, attrs);
        const struct dma_map_ops *ops = get_dma_ops(dev);
 
        BUG_ON(!valid_dma_direction(dir));
-       if (!dma_is_direct(ops) && ops->unmap_resource)
+       if (!dma_map_direct(dev, ops) && ops->unmap_resource)
                ops->unmap_resource(dev, addr, size, dir, attrs);
        debug_dma_unmap_resource(dev, addr, size, dir);
 }
        const struct dma_map_ops *ops = get_dma_ops(dev);
 
        BUG_ON(!valid_dma_direction(dir));
-       if (dma_is_direct(ops))
+       if (dma_map_direct(dev, ops))
                dma_direct_sync_single_for_cpu(dev, addr, size, dir);
        else if (ops->sync_single_for_cpu)
                ops->sync_single_for_cpu(dev, addr, size, dir);
        const struct dma_map_ops *ops = get_dma_ops(dev);
 
        BUG_ON(!valid_dma_direction(dir));
-       if (dma_is_direct(ops))
+       if (dma_map_direct(dev, ops))
                dma_direct_sync_single_for_device(dev, addr, size, dir);
        else if (ops->sync_single_for_device)
                ops->sync_single_for_device(dev, addr, size, dir);
        const struct dma_map_ops *ops = get_dma_ops(dev);
 
        BUG_ON(!valid_dma_direction(dir));
-       if (dma_is_direct(ops))
+       if (dma_map_direct(dev, ops))
                dma_direct_sync_sg_for_cpu(dev, sg, nelems, dir);
        else if (ops->sync_sg_for_cpu)
                ops->sync_sg_for_cpu(dev, sg, nelems, dir);
        const struct dma_map_ops *ops = get_dma_ops(dev);
 
        BUG_ON(!valid_dma_direction(dir));
-       if (dma_is_direct(ops))
+       if (dma_map_direct(dev, ops))
                dma_direct_sync_sg_for_device(dev, sg, nelems, dir);
        else if (ops->sync_sg_for_device)
                ops->sync_sg_for_device(dev, sg, nelems, dir);
 {
        const struct dma_map_ops *ops = get_dma_ops(dev);
 
-       if (dma_is_direct(ops))
+       if (dma_alloc_direct(dev, ops))
                return dma_direct_get_sgtable(dev, sgt, cpu_addr, dma_addr,
                                size, attrs);
        if (!ops->get_sgtable)
 {
        const struct dma_map_ops *ops = get_dma_ops(dev);
 
-       if (dma_is_direct(ops))
+       if (dma_alloc_direct(dev, ops))
                return dma_direct_can_mmap(dev);
        return ops->mmap != NULL;
 }
 {
        const struct dma_map_ops *ops = get_dma_ops(dev);
 
-       if (dma_is_direct(ops))
+       if (dma_alloc_direct(dev, ops))
                return dma_direct_mmap(dev, vma, cpu_addr, dma_addr, size,
                                attrs);
        if (!ops->mmap)
 {
        const struct dma_map_ops *ops = get_dma_ops(dev);
 
-       if (dma_is_direct(ops))
+       if (dma_alloc_direct(dev, ops))
                return dma_direct_get_required_mask(dev);
        if (ops->get_required_mask)
                return ops->get_required_mask(dev);
        /* let the implementation decide on the zone to allocate from: */
        flag &= ~(__GFP_DMA | __GFP_DMA32 | __GFP_HIGHMEM);
 
-       if (dma_is_direct(ops))
+       if (dma_alloc_direct(dev, ops))
                cpu_addr = dma_direct_alloc(dev, size, dma_handle, flag, attrs);
        else if (ops->alloc)
                cpu_addr = ops->alloc(dev, size, dma_handle, flag, attrs);
                return;
 
        debug_dma_free_coherent(dev, size, cpu_addr, dma_handle);
-       if (dma_is_direct(ops))
+       if (dma_alloc_direct(dev, ops))
                dma_direct_free(dev, size, cpu_addr, dma_handle, attrs);
        else if (ops->free)
                ops->free(dev, size, cpu_addr, dma_handle, attrs);
 {
        const struct dma_map_ops *ops = get_dma_ops(dev);
 
-       if (dma_is_direct(ops))
+       /*
+        * ->dma_supported sets the bypass flag, so we must always call
+        * into the method here unless the device is truly direct mapped.
+        */
+       if (!ops)
                return dma_direct_supported(dev, mask);
        if (!ops->dma_supported)
                return 1;
 
        BUG_ON(!valid_dma_direction(dir));
 
-       if (dma_is_direct(ops))
+       if (dma_alloc_direct(dev, ops))
                arch_dma_cache_sync(dev, vaddr, size, dir);
        else if (ops->cache_sync)
                ops->cache_sync(dev, vaddr, size, dir);
        const struct dma_map_ops *ops = get_dma_ops(dev);
        size_t size = SIZE_MAX;
 
-       if (dma_is_direct(ops))
+       if (dma_map_direct(dev, ops))
                size = dma_direct_max_mapping_size(dev);
        else if (ops && ops->max_mapping_size)
                size = ops->max_mapping_size(dev);
 {
        const struct dma_map_ops *ops = get_dma_ops(dev);
 
-       if (dma_is_direct(ops))
+       if (dma_map_direct(dev, ops))
                return dma_direct_need_sync(dev, dma_addr);
        return ops->sync_single_for_cpu || ops->sync_single_for_device;
 }