PCI: rcar: 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.

Since the rcar platform already has a requirement that this
address should be in the first 4GB of the physical address space,
use the controller's own base address as the capture address.

Link: https://lore.kernel.org/r/20210330151145.997953-3-maz@kernel.org
Tested-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
Signed-off-by: Marc Zyngier <maz@kernel.org>
Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com>
Reviewed-by: Yoshihiro Shimoda <yoshihiro.shimoda.uh@renesas.com>
This commit is contained in:
Marc Zyngier 2021-03-30 16:11:33 +01:00 committed by Lorenzo Pieralisi
parent 2c99e55f79
commit 93cd1bb486

View file

@ -36,7 +36,6 @@ struct rcar_msi {
DECLARE_BITMAP(used, INT_PCI_MSI_NR); DECLARE_BITMAP(used, INT_PCI_MSI_NR);
struct irq_domain *domain; struct irq_domain *domain;
struct msi_controller chip; struct msi_controller chip;
unsigned long pages;
struct mutex lock; struct mutex lock;
int irq1; int irq1;
int irq2; int irq2;
@ -680,14 +679,15 @@ static void rcar_pcie_unmap_msi(struct rcar_pcie_host *host)
static void rcar_pcie_hw_enable_msi(struct rcar_pcie_host *host) static void rcar_pcie_hw_enable_msi(struct rcar_pcie_host *host)
{ {
struct rcar_pcie *pcie = &host->pcie; struct rcar_pcie *pcie = &host->pcie;
struct rcar_msi *msi = &host->msi; struct device *dev = pcie->dev;
unsigned long base; struct resource res;
if (WARN_ON(of_address_to_resource(dev->of_node, 0, &res)))
return;
/* setup MSI data target */ /* setup MSI data target */
base = virt_to_phys((void *)msi->pages); rcar_pci_write_reg(pcie, lower_32_bits(res.start) | MSIFE, PCIEMSIALR);
rcar_pci_write_reg(pcie, upper_32_bits(res.start), PCIEMSIAUR);
rcar_pci_write_reg(pcie, lower_32_bits(base) | MSIFE, PCIEMSIALR);
rcar_pci_write_reg(pcie, upper_32_bits(base), PCIEMSIAUR);
/* enable all MSI interrupts */ /* enable all MSI interrupts */
rcar_pci_write_reg(pcie, 0xffffffff, PCIEMSIIER); rcar_pci_write_reg(pcie, 0xffffffff, PCIEMSIIER);
@ -735,7 +735,6 @@ static int rcar_pcie_enable_msi(struct rcar_pcie_host *host)
} }
/* setup MSI data target */ /* setup MSI data target */
msi->pages = __get_free_pages(GFP_KERNEL | GFP_DMA32, 0);
rcar_pcie_hw_enable_msi(host); rcar_pcie_hw_enable_msi(host);
return 0; return 0;
@ -748,7 +747,6 @@ err:
static void rcar_pcie_teardown_msi(struct rcar_pcie_host *host) static void rcar_pcie_teardown_msi(struct rcar_pcie_host *host)
{ {
struct rcar_pcie *pcie = &host->pcie; struct rcar_pcie *pcie = &host->pcie;
struct rcar_msi *msi = &host->msi;
/* Disable all MSI interrupts */ /* Disable all MSI interrupts */
rcar_pci_write_reg(pcie, 0, PCIEMSIIER); rcar_pci_write_reg(pcie, 0, PCIEMSIIER);
@ -756,8 +754,6 @@ static void rcar_pcie_teardown_msi(struct rcar_pcie_host *host)
/* Disable address decoding of the MSI interrupt, MSIFE */ /* Disable address decoding of the MSI interrupt, MSIFE */
rcar_pci_write_reg(pcie, 0, PCIEMSIALR); rcar_pci_write_reg(pcie, 0, PCIEMSIALR);
free_pages(msi->pages, 0);
rcar_pcie_unmap_msi(host); rcar_pcie_unmap_msi(host);
} }