Linux kernel mirror (for testing) git.kernel.org/pub/scm/linux/kernel/git/torvalds/linux.git
kernel os linux
1
fork

Configure Feed

Select the types of activity you want to include in your feed.

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.com

authored by

Frank Li and committed by
Bjorn Helgaas
4ff4252a c8223922

+41
+38
drivers/pci/endpoint/pci-epf-core.c
··· 477 477 } 478 478 EXPORT_SYMBOL_GPL(pci_epf_create); 479 479 480 + /** 481 + * pci_epf_align_inbound_addr() - Align the given address based on the BAR 482 + * alignment requirement 483 + * @epf: the EPF device 484 + * @addr: inbound address to be aligned 485 + * @bar: the BAR number corresponding to the given addr 486 + * @base: base address matching the @bar alignment requirement 487 + * @off: offset to be added to the @base address 488 + * 489 + * Helper function to align input @addr based on BAR's alignment requirement. 490 + * The aligned base address and offset are returned via @base and @off. 491 + * 492 + * NOTE: The pci_epf_alloc_space() function already accounts for alignment. 493 + * This API is primarily intended for use with other memory regions not 494 + * allocated by pci_epf_alloc_space(), such as peripheral register spaces or 495 + * the message address of a platform MSI controller. 496 + * 497 + * Return: 0 on success, errno otherwise. 498 + */ 499 + int pci_epf_align_inbound_addr(struct pci_epf *epf, enum pci_barno bar, 500 + u64 addr, dma_addr_t *base, size_t *off) 501 + { 502 + /* 503 + * Most EP controllers require the BAR start address to be aligned to 504 + * the BAR size, because they mask off the lower bits. 505 + * 506 + * Alignment to BAR size also works for controllers that support 507 + * unaligned addresses. 508 + */ 509 + u64 align = epf->bar[bar].size; 510 + 511 + *base = round_down(addr, align); 512 + *off = addr & (align - 1); 513 + 514 + return 0; 515 + } 516 + EXPORT_SYMBOL_GPL(pci_epf_align_inbound_addr); 517 + 480 518 static void pci_epf_dev_release(struct device *dev) 481 519 { 482 520 struct pci_epf *epf = to_pci_epf(dev);
+3
include/linux/pci-epf.h
··· 241 241 enum pci_epc_interface_type type); 242 242 void pci_epf_free_space(struct pci_epf *epf, void *addr, enum pci_barno bar, 243 243 enum pci_epc_interface_type type); 244 + 245 + int pci_epf_align_inbound_addr(struct pci_epf *epf, enum pci_barno bar, 246 + u64 addr, dma_addr_t *base, size_t *off); 244 247 int pci_epf_bind(struct pci_epf *epf); 245 248 void pci_epf_unbind(struct pci_epf *epf); 246 249 int pci_epf_add_vepf(struct pci_epf *epf_pf, struct pci_epf *epf_vf);