1 // SPDX-License-Identifier: GPL-2.0 2 /* 3 * Generic PCI resource mmap helper 4 * 5 * Copyright © 2017 Amazon.com, Inc. or its affiliates. 6 * 7 * Author: David Woodhouse <dwmw2@infradead.org> 8 */ 9 10 #include <linux/kernel.h> 11 #include <linux/mm.h> 12 #include <linux/pci.h> 13 14 #ifdef ARCH_GENERIC_PCI_MMAP_RESOURCE 15 16 static const struct vm_operations_struct pci_phys_vm_ops = { 17 #ifdef CONFIG_HAVE_IOREMAP_PROT 18 .access = generic_access_phys, 19 #endif 20 }; 21 22 int pci_mmap_resource_range(struct pci_dev *pdev, int bar, 23 struct vm_area_struct *vma, 24 enum pci_mmap_state mmap_state, int write_combine) 25 { 26 unsigned long size; 27 int ret; 28 29 size = ((pci_resource_len(pdev, bar) - 1) >> PAGE_SHIFT) + 1; 30 if (vma->vm_pgoff + vma_pages(vma) > size) 31 return -EINVAL; 32 33 if (write_combine) 34 vma->vm_page_prot = pgprot_writecombine(vma->vm_page_prot); 35 else 36 vma->vm_page_prot = pgprot_device(vma->vm_page_prot); 37 38 if (mmap_state == pci_mmap_io) { 39 ret = pci_iobar_pfn(pdev, bar, vma); 40 if (ret) 41 return ret; 42 } else 43 vma->vm_pgoff += (pci_resource_start(pdev, bar) >> PAGE_SHIFT); 44 45 vma->vm_ops = &pci_phys_vm_ops; 46 47 return io_remap_pfn_range(vma, vma->vm_start, vma->vm_pgoff, 48 vma->vm_end - vma->vm_start, 49 vma->vm_page_prot); 50 } 51 52 #endif 53