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_epc_ops to map MSI IRQ

Add pci_epc_ops to map physical address to MSI address and return MSI data.
The physical address is an address in the outbound region. This is required
to implement doorbell functionality of NTB (non-transparent bridge) wherein
EPC on either side of the interface (primary and secondary) can directly
write to the physical address (in outbound region) of the other interface
to ring doorbell using MSI.

Link: https://lore.kernel.org/r/20210201195809.7342-9-kishon@ti.com
Signed-off-by: Kishon Vijay Abraham I <kishon@ti.com>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Signed-off-by: Bjorn Helgaas <bhelgaas@google.com>

authored by

Kishon Vijay Abraham I and committed by
Bjorn Helgaas
87d5972e e85a2d78

+49
+41
drivers/pci/endpoint/pci-epc-core.c
··· 231 231 EXPORT_SYMBOL_GPL(pci_epc_raise_irq); 232 232 233 233 /** 234 + * pci_epc_map_msi_irq() - Map physical address to MSI address and return 235 + * MSI data 236 + * @epc: the EPC device which has the MSI capability 237 + * @func_no: the physical endpoint function number in the EPC device 238 + * @phys_addr: the physical address of the outbound region 239 + * @interrupt_num: the MSI interrupt number 240 + * @entry_size: Size of Outbound address region for each interrupt 241 + * @msi_data: the data that should be written in order to raise MSI interrupt 242 + * with interrupt number as 'interrupt num' 243 + * @msi_addr_offset: Offset of MSI address from the aligned outbound address 244 + * to which the MSI address is mapped 245 + * 246 + * Invoke to map physical address to MSI address and return MSI data. The 247 + * physical address should be an address in the outbound region. This is 248 + * required to implement doorbell functionality of NTB wherein EPC on either 249 + * side of the interface (primary and secondary) can directly write to the 250 + * physical address (in outbound region) of the other interface to ring 251 + * doorbell. 252 + */ 253 + int pci_epc_map_msi_irq(struct pci_epc *epc, u8 func_no, phys_addr_t phys_addr, 254 + u8 interrupt_num, u32 entry_size, u32 *msi_data, 255 + u32 *msi_addr_offset) 256 + { 257 + int ret; 258 + 259 + if (IS_ERR_OR_NULL(epc)) 260 + return -EINVAL; 261 + 262 + if (!epc->ops->map_msi_irq) 263 + return -EINVAL; 264 + 265 + mutex_lock(&epc->lock); 266 + ret = epc->ops->map_msi_irq(epc, func_no, phys_addr, interrupt_num, 267 + entry_size, msi_data, msi_addr_offset); 268 + mutex_unlock(&epc->lock); 269 + 270 + return ret; 271 + } 272 + EXPORT_SYMBOL_GPL(pci_epc_map_msi_irq); 273 + 274 + /** 234 275 * pci_epc_get_msi() - get the number of MSI interrupt numbers allocated 235 276 * @epc: the EPC device to which MSI interrupts was requested 236 277 * @func_no: the endpoint function number in the EPC device
+8
include/linux/pci-epc.h
··· 55 55 * @get_msix: ops to get the number of MSI-X interrupts allocated by the RC 56 56 * from the MSI-X capability register 57 57 * @raise_irq: ops to raise a legacy, MSI or MSI-X interrupt 58 + * @map_msi_irq: ops to map physical address to MSI address and return MSI data 58 59 * @start: ops to start the PCI link 59 60 * @stop: ops to stop the PCI link 60 61 * @owner: the module owner containing the ops ··· 78 77 int (*get_msix)(struct pci_epc *epc, u8 func_no); 79 78 int (*raise_irq)(struct pci_epc *epc, u8 func_no, 80 79 enum pci_epc_irq_type type, u16 interrupt_num); 80 + int (*map_msi_irq)(struct pci_epc *epc, u8 func_no, 81 + phys_addr_t phys_addr, u8 interrupt_num, 82 + u32 entry_size, u32 *msi_data, 83 + u32 *msi_addr_offset); 81 84 int (*start)(struct pci_epc *epc); 82 85 void (*stop)(struct pci_epc *epc); 83 86 const struct pci_epc_features* (*get_features)(struct pci_epc *epc, ··· 221 216 int pci_epc_set_msix(struct pci_epc *epc, u8 func_no, u16 interrupts, 222 217 enum pci_barno, u32 offset); 223 218 int pci_epc_get_msix(struct pci_epc *epc, u8 func_no); 219 + int pci_epc_map_msi_irq(struct pci_epc *epc, u8 func_no, 220 + phys_addr_t phys_addr, u8 interrupt_num, 221 + u32 entry_size, u32 *msi_data, u32 *msi_addr_offset); 224 222 int pci_epc_raise_irq(struct pci_epc *epc, u8 func_no, 225 223 enum pci_epc_irq_type type, u16 interrupt_num); 226 224 int pci_epc_start(struct pci_epc *epc);