Line data Source code
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 0 : 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 0 : size = ((pci_resource_len(pdev, bar) - 1) >> PAGE_SHIFT) + 1; 30 0 : 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 0 : if (mmap_state == pci_mmap_io) { 39 : ret = pci_iobar_pfn(pdev, bar, vma); 40 : if (ret) 41 : return ret; 42 : } else 43 0 : vma->vm_pgoff += (pci_resource_start(pdev, bar) >> PAGE_SHIFT); 44 : 45 0 : vma->vm_ops = &pci_phys_vm_ops; 46 : 47 0 : 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