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