PCI: designware-ep: Pre-allocate memory for MSI in dw_pcie_ep_init
Certain SoCs need to map the MSI address in raise_irq. To map an address, you first need to call pci_epc_mem_alloc_addr(), however, pci_epc_mem_alloc_addr() calls ioremap() (which can sleep). Since raise_irq is only called from atomic context, we can't call pci_epc_mem_alloc_addr() from raise_irq. Pre-allocate a page in dw_pcie_ep_init(), so that this page can later be used to map/unmap the MSI address in raise_irq. Tested-by: Gustavo Pimentel <gustavo.pimentel@synopsys.com> Signed-off-by: Niklas Cassel <niklas.cassel@axis.com> Signed-off-by: Lorenzo Pieralisi <lorenzo.pieralisi@arm.com> Acked-by: Joao Pinto <jpinto@synopsys.com>
This commit is contained in:
parent
1cab826b30
commit
2fd0c9d966
2 changed files with 12 additions and 0 deletions
|
@ -286,6 +286,9 @@ void dw_pcie_ep_exit(struct dw_pcie_ep *ep)
|
||||||
{
|
{
|
||||||
struct pci_epc *epc = ep->epc;
|
struct pci_epc *epc = ep->epc;
|
||||||
|
|
||||||
|
pci_epc_mem_free_addr(epc, ep->msi_mem_phys, ep->msi_mem,
|
||||||
|
epc->mem->page_size);
|
||||||
|
|
||||||
pci_epc_mem_exit(epc);
|
pci_epc_mem_exit(epc);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -341,6 +344,13 @@ int dw_pcie_ep_init(struct dw_pcie_ep *ep)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
ep->msi_mem = pci_epc_mem_alloc_addr(epc, &ep->msi_mem_phys,
|
||||||
|
epc->mem->page_size);
|
||||||
|
if (!ep->msi_mem) {
|
||||||
|
dev_err(dev, "Failed to reserve memory for MSI\n");
|
||||||
|
return -ENOMEM;
|
||||||
|
}
|
||||||
|
|
||||||
ep->epc = epc;
|
ep->epc = epc;
|
||||||
epc_set_drvdata(epc, ep);
|
epc_set_drvdata(epc, ep);
|
||||||
dw_pcie_setup(pci);
|
dw_pcie_setup(pci);
|
||||||
|
|
|
@ -198,6 +198,8 @@ struct dw_pcie_ep {
|
||||||
unsigned long ob_window_map;
|
unsigned long ob_window_map;
|
||||||
u32 num_ib_windows;
|
u32 num_ib_windows;
|
||||||
u32 num_ob_windows;
|
u32 num_ob_windows;
|
||||||
|
void __iomem *msi_mem;
|
||||||
|
phys_addr_t msi_mem_phys;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct dw_pcie_ops {
|
struct dw_pcie_ops {
|
||||||
|
|
Loading…
Add table
Reference in a new issue