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: cadence: Implement ->msi_map_irq() ops

Implement ->msi_map_irq() ops in order to map physical address to MSI
address and return MSI data.

Link: https://lore.kernel.org/r/20210201195809.7342-12-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>
Reviewed-by: Tom Joseph <tjoseph@cadence.com>

authored by

Kishon Vijay Abraham I and committed by
Bjorn Helgaas
dbcc542f 38ad827e

+53
+53
drivers/pci/controller/cadence/pcie-cadence-ep.c
··· 382 382 return 0; 383 383 } 384 384 385 + static int cdns_pcie_ep_map_msi_irq(struct pci_epc *epc, u8 fn, 386 + phys_addr_t addr, u8 interrupt_num, 387 + u32 entry_size, u32 *msi_data, 388 + u32 *msi_addr_offset) 389 + { 390 + struct cdns_pcie_ep *ep = epc_get_drvdata(epc); 391 + u32 cap = CDNS_PCIE_EP_FUNC_MSI_CAP_OFFSET; 392 + struct cdns_pcie *pcie = &ep->pcie; 393 + u64 pci_addr, pci_addr_mask = 0xff; 394 + u16 flags, mme, data, data_mask; 395 + u8 msi_count; 396 + int ret; 397 + int i; 398 + 399 + /* Check whether the MSI feature has been enabled by the PCI host. */ 400 + flags = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_FLAGS); 401 + if (!(flags & PCI_MSI_FLAGS_ENABLE)) 402 + return -EINVAL; 403 + 404 + /* Get the number of enabled MSIs */ 405 + mme = (flags & PCI_MSI_FLAGS_QSIZE) >> 4; 406 + msi_count = 1 << mme; 407 + if (!interrupt_num || interrupt_num > msi_count) 408 + return -EINVAL; 409 + 410 + /* Compute the data value to be written. */ 411 + data_mask = msi_count - 1; 412 + data = cdns_pcie_ep_fn_readw(pcie, fn, cap + PCI_MSI_DATA_64); 413 + data = data & ~data_mask; 414 + 415 + /* Get the PCI address where to write the data into. */ 416 + pci_addr = cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_HI); 417 + pci_addr <<= 32; 418 + pci_addr |= cdns_pcie_ep_fn_readl(pcie, fn, cap + PCI_MSI_ADDRESS_LO); 419 + pci_addr &= GENMASK_ULL(63, 2); 420 + 421 + for (i = 0; i < interrupt_num; i++) { 422 + ret = cdns_pcie_ep_map_addr(epc, fn, addr, 423 + pci_addr & ~pci_addr_mask, 424 + entry_size); 425 + if (ret) 426 + return ret; 427 + addr = addr + entry_size; 428 + } 429 + 430 + *msi_data = data; 431 + *msi_addr_offset = pci_addr & pci_addr_mask; 432 + 433 + return 0; 434 + } 435 + 385 436 static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn, 386 437 u16 interrupt_num) 387 438 { ··· 532 481 .linkup_notifier = false, 533 482 .msi_capable = true, 534 483 .msix_capable = true, 484 + .align = 256, 535 485 }; 536 486 537 487 static const struct pci_epc_features* ··· 552 500 .set_msix = cdns_pcie_ep_set_msix, 553 501 .get_msix = cdns_pcie_ep_get_msix, 554 502 .raise_irq = cdns_pcie_ep_raise_irq, 503 + .map_msi_irq = cdns_pcie_ep_map_msi_irq, 555 504 .start = cdns_pcie_ep_start, 556 505 .get_features = cdns_pcie_ep_get_features, 557 506 };