PCI: endpoint: Add pci_epf_align_inbound_addr() helper for inbound address alignment
Add pci_epf_align_inbound_addr() to align the inbound addresses according to PCI BAR alignment requirements. The aligned base address and offset are returned via 'base' and 'off' parameters. Signed-off-by: Frank Li <Frank.Li@nxp.com> [mani: reworded kernel-doc and commit message] Signed-off-by: Manivannan Sadhasivam <mani@kernel.org> Signed-off-by: Bjorn Helgaas <bhelgaas@google.com> Tested-by: Niklas Cassel <cassel@kernel.org> Link: https://patch.msgid.link/20250710-ep-msi-v21-5-57683fc7fb25@nxp.compull/1320/head
parent
c822392280
commit
4ff4252a23
|
|
@ -477,6 +477,44 @@ struct pci_epf *pci_epf_create(const char *name)
|
|||
}
|
||||
EXPORT_SYMBOL_GPL(pci_epf_create);
|
||||
|
||||
/**
|
||||
* pci_epf_align_inbound_addr() - Align the given address based on the BAR
|
||||
* alignment requirement
|
||||
* @epf: the EPF device
|
||||
* @addr: inbound address to be aligned
|
||||
* @bar: the BAR number corresponding to the given addr
|
||||
* @base: base address matching the @bar alignment requirement
|
||||
* @off: offset to be added to the @base address
|
||||
*
|
||||
* Helper function to align input @addr based on BAR's alignment requirement.
|
||||
* The aligned base address and offset are returned via @base and @off.
|
||||
*
|
||||
* NOTE: The pci_epf_alloc_space() function already accounts for alignment.
|
||||
* This API is primarily intended for use with other memory regions not
|
||||
* allocated by pci_epf_alloc_space(), such as peripheral register spaces or
|
||||
* the message address of a platform MSI controller.
|
||||
*
|
||||
* Return: 0 on success, errno otherwise.
|
||||
*/
|
||||
int pci_epf_align_inbound_addr(struct pci_epf *epf, enum pci_barno bar,
|
||||
u64 addr, dma_addr_t *base, size_t *off)
|
||||
{
|
||||
/*
|
||||
* Most EP controllers require the BAR start address to be aligned to
|
||||
* the BAR size, because they mask off the lower bits.
|
||||
*
|
||||
* Alignment to BAR size also works for controllers that support
|
||||
* unaligned addresses.
|
||||
*/
|
||||
u64 align = epf->bar[bar].size;
|
||||
|
||||
*base = round_down(addr, align);
|
||||
*off = addr & (align - 1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
EXPORT_SYMBOL_GPL(pci_epf_align_inbound_addr);
|
||||
|
||||
static void pci_epf_dev_release(struct device *dev)
|
||||
{
|
||||
struct pci_epf *epf = to_pci_epf(dev);
|
||||
|
|
|
|||
|
|
@ -241,6 +241,9 @@ void *pci_epf_alloc_space(struct pci_epf *epf, size_t size, enum pci_barno bar,
|
|||
enum pci_epc_interface_type type);
|
||||
void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar,
|
||||
enum pci_epc_interface_type type);
|
||||
|
||||
int pci_epf_align_inbound_addr(struct pci_epf *epf, enum pci_barno bar,
|
||||
u64 addr, dma_addr_t *base, size_t *off);
|
||||
int pci_epf_bind(struct pci_epf *epf);
|
||||
void pci_epf_unbind(struct pci_epf *epf);
|
||||
int pci_epf_add_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf);
|
||||
|
|
|
|||
Loading…
Reference in New Issue