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.com Signed-off-by: Philipp Stanner <pstanner@redhat.com> Signed-off-by: Krzysztof Wilczyński <kwilczynski@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>
This commit is contained in:
parent
f748a07a0b
commit
ad78e05d65
@ -1027,3 +1027,47 @@ void pcim_iounmap_regions(struct pci_dev *pdev, int mask)
|
||||
}
|
||||
}
|
||||
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);
|
||||
int pcim_iomap_regions_request_all(struct pci_dev *pdev, int mask,
|
||||
const char *name);
|
||||
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;
|
||||
#define PCIPCI_FAIL 1 /* No PCI PCI DMA */
|
||||
|
Loading…
Reference in New Issue
Block a user