Commit ad78e05d authored by Philipp Stanner's avatar Philipp Stanner Committed by Bjorn Helgaas

PCI: Add managed pcim_iomap_range()

The only managed mapping function currently is pcim_iomap() which doesn't
allow for mapping an area starting at a certain offset, which many drivers
want.

Add pcim_iomap_range() as an exported function.

Link: https://lore.kernel.org/r/20240613115032.29098-13-pstanner@redhat.comSigned-off-by: default avatarPhilipp Stanner <pstanner@redhat.com>
Signed-off-by: default avatarKrzysztof Wilczyński <kwilczynski@kernel.org>
Signed-off-by: default avatarBjorn Helgaas <bhelgaas@google.com>
parent f748a07a
...@@ -1027,3 +1027,47 @@ void pcim_iounmap_regions(struct pci_dev *pdev, int mask) ...@@ -1027,3 +1027,47 @@ void pcim_iounmap_regions(struct pci_dev *pdev, int mask)
} }
} }
EXPORT_SYMBOL(pcim_iounmap_regions); EXPORT_SYMBOL(pcim_iounmap_regions);
/**
* pcim_iomap_range - Create a ranged __iomap mapping within a PCI BAR
* @pdev: PCI device to map IO resources for
* @bar: Index of the BAR
* @offset: Offset from the begin of the BAR
* @len: Length in bytes for the mapping
*
* Returns: __iomem pointer on success, an IOMEM_ERR_PTR on failure.
*
* Creates a new IO-Mapping within the specified @bar, ranging from @offset to
* @offset + @len.
*
* The mapping will automatically get unmapped on driver detach. If desired,
* release manually only with pcim_iounmap().
*/
void __iomem *pcim_iomap_range(struct pci_dev *pdev, int bar,
unsigned long offset, unsigned long len)
{
void __iomem *mapping;
struct pcim_addr_devres *res;
res = pcim_addr_devres_alloc(pdev);
if (!res)
return IOMEM_ERR_PTR(-ENOMEM);
mapping = pci_iomap_range(pdev, bar, offset, len);
if (!mapping) {
pcim_addr_devres_free(res);
return IOMEM_ERR_PTR(-EINVAL);
}
res->type = PCIM_ADDR_DEVRES_TYPE_MAPPING;
res->baseaddr = mapping;
/*
* Ranged mappings don't get added to the legacy-table, since the table
* only ever keeps track of whole BARs.
*/
devres_add(&pdev->dev, res);
return mapping;
}
EXPORT_SYMBOL(pcim_iomap_range);
...@@ -2303,6 +2303,8 @@ int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name); ...@@ -2303,6 +2303,8 @@ int pcim_iomap_regions(struct pci_dev *pdev, int mask, const char *name);
int pcim_iomap_regions_request_all(struct pci_dev *pdev, int mask, int pcim_iomap_regions_request_all(struct pci_dev *pdev, int mask,
const char *name); const char *name);
void pcim_iounmap_regions(struct pci_dev *pdev, int mask); void pcim_iounmap_regions(struct pci_dev *pdev, int mask);
void __iomem *pcim_iomap_range(struct pci_dev *pdev, int bar,
unsigned long offset, unsigned long len);
extern int pci_pci_problems; extern int pci_pci_problems;
#define PCIPCI_FAIL 1 /* No PCI PCI DMA */ #define PCIPCI_FAIL 1 /* No PCI PCI DMA */
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment