summaryrefslogtreecommitdiffstats
path: root/drivers/pci
diff options
context:
space:
mode:
authorMarc Zyngier <maz@kernel.org>2021-03-30 17:11:35 +0200
committerLorenzo Pieralisi <lorenzo.pieralisi@arm.com>2021-04-20 15:11:21 +0200
commit161260e7f7bc58d6a0972eb41a6072e82d0b58a5 (patch)
treec41a541a0d86ba776fe8cd3c6c66ab8758401135 /drivers/pci
parentPCI: rcar: Convert to MSI domains (diff)
downloadlinux-161260e7f7bc58d6a0972eb41a6072e82d0b58a5.tar.xz
linux-161260e7f7bc58d6a0972eb41a6072e82d0b58a5.zip
PCI: xilinx: Don't allocate extra memory for the MSI capture address
A long cargo-culted behaviour of PCI drivers is to allocate memory to obtain an address that is fed to the controller as the MSI capture address (i.e. the MSI doorbell). But there is no actual requirement for this address to be RAM. All it needs to be is a suitable aligned address that will *not* be DMA'd to. Use the physical address of the 'port' data structure as the MSI capture address, aligned on a 4K boundary. Link: https://lore.kernel.org/r/20210330151145.997953-5-maz@kernel.org Tested-by: Bharat Kumar Gogada <bharatku@xilinx.com> Signed-off-by: Marc Zyngier <maz@kernel.org> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Diffstat (limited to 'drivers/pci')
-rw-r--r--drivers/pci/controller/pcie-xilinx.c18
1 files changed, 6 insertions, 12 deletions
diff --git a/drivers/pci/controller/pcie-xilinx.c b/drivers/pci/controller/pcie-xilinx.c
index fa5baeb82653..e127a7b6e535 100644
--- a/drivers/pci/controller/pcie-xilinx.c
+++ b/drivers/pci/controller/pcie-xilinx.c
@@ -94,7 +94,6 @@
* struct xilinx_pcie_port - PCIe port information
* @reg_base: IO Mapped Register Base
* @irq: Interrupt number
- * @msi_pages: MSI pages
* @dev: Device pointer
* @msi_domain: MSI IRQ domain pointer
* @leg_domain: Legacy IRQ domain pointer
@@ -103,7 +102,6 @@
struct xilinx_pcie_port {
void __iomem *reg_base;
u32 irq;
- unsigned long msi_pages;
struct device *dev;
struct irq_domain *msi_domain;
struct irq_domain *leg_domain;
@@ -274,10 +272,10 @@ static int xilinx_pcie_msi_setup_irq(struct msi_controller *chip,
irq_set_msi_desc(irq, desc);
- msg_addr = virt_to_phys((void *)port->msi_pages);
+ msg_addr = ALIGN_DOWN(virt_to_phys(port), SZ_4K);
- msg.address_hi = 0;
- msg.address_lo = msg_addr;
+ msg.address_hi = upper_32_bits(msg_addr);
+ msg.address_lo = lower_32_bits(msg_addr);
msg.data = irq;
pci_write_msi_msg(irq, &msg);
@@ -330,13 +328,9 @@ static int xilinx_pcie_enable_msi(struct xilinx_pcie_port *port)
{
phys_addr_t msg_addr;
- port->msi_pages = __get_free_pages(GFP_KERNEL, 0);
- if (!port->msi_pages)
- return -ENOMEM;
-
- msg_addr = virt_to_phys((void *)port->msi_pages);
- pcie_write(port, 0x0, XILINX_PCIE_REG_MSIBASE1);
- pcie_write(port, msg_addr, XILINX_PCIE_REG_MSIBASE2);
+ msg_addr = ALIGN_DOWN(virt_to_phys(port), SZ_4K);
+ pcie_write(port, upper_32_bits(msg_addr), XILINX_PCIE_REG_MSIBASE1);
+ pcie_write(port, lower_32_bits(msg_addr), XILINX_PCIE_REG_MSIBASE2);
return 0;
}