{
bool coherent = dev_is_dma_coherent(dev);
int ioprot = dma_info_to_prot(DMA_BIDIRECTIONAL, coherent, attrs);
- pgprot_t prot = arch_dma_mmap_pgprot(dev, PAGE_KERNEL, attrs);
size_t iosize = size;
struct page *page;
void *addr;
if (*handle == DMA_MAPPING_ERROR)
goto out_free_pages;
- addr = dma_common_contiguous_remap(page, size, VM_USERMAP, prot,
- __builtin_return_address(0));
- if (!addr)
- goto out_unmap;
+ if (!coherent || PageHighMem(page)) {
+ pgprot_t prot = arch_dma_mmap_pgprot(dev, PAGE_KERNEL, attrs);
- if (!coherent)
- arch_dma_prep_coherent(page, iosize);
+ addr = dma_common_contiguous_remap(page, size, VM_USERMAP, prot,
+ __builtin_return_address(0));
+ if (!addr)
+ goto out_unmap;
+
+ if (!coherent)
+ arch_dma_prep_coherent(page, iosize);
+ } else {
+ addr = page_address(page);
+ }
memset(addr, 0, size);
return addr;
out_unmap: