18c2ecf20Sopenharmony_ci// SPDX-License-Identifier: GPL-2.0 28c2ecf20Sopenharmony_ci/* 38c2ecf20Sopenharmony_ci * Implement the default iomap interfaces 48c2ecf20Sopenharmony_ci * 58c2ecf20Sopenharmony_ci * (C) Copyright 2004 Linus Torvalds 68c2ecf20Sopenharmony_ci */ 78c2ecf20Sopenharmony_ci#include <linux/pci.h> 88c2ecf20Sopenharmony_ci#include <linux/io.h> 98c2ecf20Sopenharmony_ci 108c2ecf20Sopenharmony_ci#include <linux/export.h> 118c2ecf20Sopenharmony_ci 128c2ecf20Sopenharmony_ci#ifdef CONFIG_PCI 138c2ecf20Sopenharmony_ci/** 148c2ecf20Sopenharmony_ci * pci_iomap_range - create a virtual mapping cookie for a PCI BAR 158c2ecf20Sopenharmony_ci * @dev: PCI device that owns the BAR 168c2ecf20Sopenharmony_ci * @bar: BAR number 178c2ecf20Sopenharmony_ci * @offset: map memory at the given offset in BAR 188c2ecf20Sopenharmony_ci * @maxlen: max length of the memory to map 198c2ecf20Sopenharmony_ci * 208c2ecf20Sopenharmony_ci * Using this function you will get a __iomem address to your device BAR. 218c2ecf20Sopenharmony_ci * You can access it using ioread*() and iowrite*(). These functions hide 228c2ecf20Sopenharmony_ci * the details if this is a MMIO or PIO address space and will just do what 238c2ecf20Sopenharmony_ci * you expect from them in the correct way. 248c2ecf20Sopenharmony_ci * 258c2ecf20Sopenharmony_ci * @maxlen specifies the maximum length to map. If you want to get access to 268c2ecf20Sopenharmony_ci * the complete BAR from offset to the end, pass %0 here. 278c2ecf20Sopenharmony_ci * */ 288c2ecf20Sopenharmony_civoid __iomem *pci_iomap_range(struct pci_dev *dev, 298c2ecf20Sopenharmony_ci int bar, 308c2ecf20Sopenharmony_ci unsigned long offset, 318c2ecf20Sopenharmony_ci unsigned long maxlen) 328c2ecf20Sopenharmony_ci{ 338c2ecf20Sopenharmony_ci resource_size_t start = pci_resource_start(dev, bar); 348c2ecf20Sopenharmony_ci resource_size_t len = pci_resource_len(dev, bar); 358c2ecf20Sopenharmony_ci unsigned long flags = pci_resource_flags(dev, bar); 368c2ecf20Sopenharmony_ci 378c2ecf20Sopenharmony_ci if (len <= offset || !start) 388c2ecf20Sopenharmony_ci return NULL; 398c2ecf20Sopenharmony_ci len -= offset; 408c2ecf20Sopenharmony_ci start += offset; 418c2ecf20Sopenharmony_ci if (maxlen && len > maxlen) 428c2ecf20Sopenharmony_ci len = maxlen; 438c2ecf20Sopenharmony_ci if (flags & IORESOURCE_IO) 448c2ecf20Sopenharmony_ci return __pci_ioport_map(dev, start, len); 458c2ecf20Sopenharmony_ci if (flags & IORESOURCE_MEM) 468c2ecf20Sopenharmony_ci return ioremap(start, len); 478c2ecf20Sopenharmony_ci /* What? */ 488c2ecf20Sopenharmony_ci return NULL; 498c2ecf20Sopenharmony_ci} 508c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pci_iomap_range); 518c2ecf20Sopenharmony_ci 528c2ecf20Sopenharmony_ci/** 538c2ecf20Sopenharmony_ci * pci_iomap_wc_range - create a virtual WC mapping cookie for a PCI BAR 548c2ecf20Sopenharmony_ci * @dev: PCI device that owns the BAR 558c2ecf20Sopenharmony_ci * @bar: BAR number 568c2ecf20Sopenharmony_ci * @offset: map memory at the given offset in BAR 578c2ecf20Sopenharmony_ci * @maxlen: max length of the memory to map 588c2ecf20Sopenharmony_ci * 598c2ecf20Sopenharmony_ci * Using this function you will get a __iomem address to your device BAR. 608c2ecf20Sopenharmony_ci * You can access it using ioread*() and iowrite*(). These functions hide 618c2ecf20Sopenharmony_ci * the details if this is a MMIO or PIO address space and will just do what 628c2ecf20Sopenharmony_ci * you expect from them in the correct way. When possible write combining 638c2ecf20Sopenharmony_ci * is used. 648c2ecf20Sopenharmony_ci * 658c2ecf20Sopenharmony_ci * @maxlen specifies the maximum length to map. If you want to get access to 668c2ecf20Sopenharmony_ci * the complete BAR from offset to the end, pass %0 here. 678c2ecf20Sopenharmony_ci * */ 688c2ecf20Sopenharmony_civoid __iomem *pci_iomap_wc_range(struct pci_dev *dev, 698c2ecf20Sopenharmony_ci int bar, 708c2ecf20Sopenharmony_ci unsigned long offset, 718c2ecf20Sopenharmony_ci unsigned long maxlen) 728c2ecf20Sopenharmony_ci{ 738c2ecf20Sopenharmony_ci resource_size_t start = pci_resource_start(dev, bar); 748c2ecf20Sopenharmony_ci resource_size_t len = pci_resource_len(dev, bar); 758c2ecf20Sopenharmony_ci unsigned long flags = pci_resource_flags(dev, bar); 768c2ecf20Sopenharmony_ci 778c2ecf20Sopenharmony_ci 788c2ecf20Sopenharmony_ci if (flags & IORESOURCE_IO) 798c2ecf20Sopenharmony_ci return NULL; 808c2ecf20Sopenharmony_ci 818c2ecf20Sopenharmony_ci if (len <= offset || !start) 828c2ecf20Sopenharmony_ci return NULL; 838c2ecf20Sopenharmony_ci 848c2ecf20Sopenharmony_ci len -= offset; 858c2ecf20Sopenharmony_ci start += offset; 868c2ecf20Sopenharmony_ci if (maxlen && len > maxlen) 878c2ecf20Sopenharmony_ci len = maxlen; 888c2ecf20Sopenharmony_ci 898c2ecf20Sopenharmony_ci if (flags & IORESOURCE_MEM) 908c2ecf20Sopenharmony_ci return ioremap_wc(start, len); 918c2ecf20Sopenharmony_ci 928c2ecf20Sopenharmony_ci /* What? */ 938c2ecf20Sopenharmony_ci return NULL; 948c2ecf20Sopenharmony_ci} 958c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_iomap_wc_range); 968c2ecf20Sopenharmony_ci 978c2ecf20Sopenharmony_ci/** 988c2ecf20Sopenharmony_ci * pci_iomap - create a virtual mapping cookie for a PCI BAR 998c2ecf20Sopenharmony_ci * @dev: PCI device that owns the BAR 1008c2ecf20Sopenharmony_ci * @bar: BAR number 1018c2ecf20Sopenharmony_ci * @maxlen: length of the memory to map 1028c2ecf20Sopenharmony_ci * 1038c2ecf20Sopenharmony_ci * Using this function you will get a __iomem address to your device BAR. 1048c2ecf20Sopenharmony_ci * You can access it using ioread*() and iowrite*(). These functions hide 1058c2ecf20Sopenharmony_ci * the details if this is a MMIO or PIO address space and will just do what 1068c2ecf20Sopenharmony_ci * you expect from them in the correct way. 1078c2ecf20Sopenharmony_ci * 1088c2ecf20Sopenharmony_ci * @maxlen specifies the maximum length to map. If you want to get access to 1098c2ecf20Sopenharmony_ci * the complete BAR without checking for its length first, pass %0 here. 1108c2ecf20Sopenharmony_ci * */ 1118c2ecf20Sopenharmony_civoid __iomem *pci_iomap(struct pci_dev *dev, int bar, unsigned long maxlen) 1128c2ecf20Sopenharmony_ci{ 1138c2ecf20Sopenharmony_ci return pci_iomap_range(dev, bar, 0, maxlen); 1148c2ecf20Sopenharmony_ci} 1158c2ecf20Sopenharmony_ciEXPORT_SYMBOL(pci_iomap); 1168c2ecf20Sopenharmony_ci 1178c2ecf20Sopenharmony_ci/** 1188c2ecf20Sopenharmony_ci * pci_iomap_wc - create a virtual WC mapping cookie for a PCI BAR 1198c2ecf20Sopenharmony_ci * @dev: PCI device that owns the BAR 1208c2ecf20Sopenharmony_ci * @bar: BAR number 1218c2ecf20Sopenharmony_ci * @maxlen: length of the memory to map 1228c2ecf20Sopenharmony_ci * 1238c2ecf20Sopenharmony_ci * Using this function you will get a __iomem address to your device BAR. 1248c2ecf20Sopenharmony_ci * You can access it using ioread*() and iowrite*(). These functions hide 1258c2ecf20Sopenharmony_ci * the details if this is a MMIO or PIO address space and will just do what 1268c2ecf20Sopenharmony_ci * you expect from them in the correct way. When possible write combining 1278c2ecf20Sopenharmony_ci * is used. 1288c2ecf20Sopenharmony_ci * 1298c2ecf20Sopenharmony_ci * @maxlen specifies the maximum length to map. If you want to get access to 1308c2ecf20Sopenharmony_ci * the complete BAR without checking for its length first, pass %0 here. 1318c2ecf20Sopenharmony_ci * */ 1328c2ecf20Sopenharmony_civoid __iomem *pci_iomap_wc(struct pci_dev *dev, int bar, unsigned long maxlen) 1338c2ecf20Sopenharmony_ci{ 1348c2ecf20Sopenharmony_ci return pci_iomap_wc_range(dev, bar, 0, maxlen); 1358c2ecf20Sopenharmony_ci} 1368c2ecf20Sopenharmony_ciEXPORT_SYMBOL_GPL(pci_iomap_wc); 1378c2ecf20Sopenharmony_ci#endif /* CONFIG_PCI */ 138