void dw_pcie_ep_exit(struct dw_pcie_ep *ep) { 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); }
static int cdns_pcie_ep_probe(struct platform_device *pdev) { struct device *dev = &pdev->dev; struct device_node *np = dev->of_node; struct cdns_pcie_ep *ep; struct cdns_pcie *pcie; struct pci_epc *epc; struct resource *res; int ret; ep = devm_kzalloc(dev, sizeof(*ep), GFP_KERNEL); if (!ep) return -ENOMEM; pcie = &ep->pcie; pcie->is_rc = false; res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "reg"); pcie->reg_base = devm_ioremap_resource(dev, res); if (IS_ERR(pcie->reg_base)) { dev_err(dev, "missing \"reg\"\n"); return PTR_ERR(pcie->reg_base); } res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "mem"); if (!res) { dev_err(dev, "missing \"mem\"\n"); return -EINVAL; } pcie->mem_res = res; ret = of_property_read_u32(np, "cdns,max-outbound-regions", &ep->max_regions); if (ret < 0) { dev_err(dev, "missing \"cdns,max-outbound-regions\"\n"); return ret; } ep->ob_addr = devm_kzalloc(dev, ep->max_regions * sizeof(*ep->ob_addr), GFP_KERNEL); if (!ep->ob_addr) return -ENOMEM; pm_runtime_enable(dev); ret = pm_runtime_get_sync(dev); if (ret < 0) { dev_err(dev, "pm_runtime_get_sync() failed\n"); goto err_get_sync; } /* Disable all but function 0 (anyway BIT(0) is hardwired to 1). */ cdns_pcie_writel(pcie, CDNS_PCIE_LM_EP_FUNC_CFG, BIT(0)); epc = devm_pci_epc_create(dev, &cdns_pcie_epc_ops); if (IS_ERR(epc)) { dev_err(dev, "failed to create epc device\n"); ret = PTR_ERR(epc); goto err_init; } epc_set_drvdata(epc, ep); if (of_property_read_u8(np, "max-functions", &epc->max_functions) < 0) epc->max_functions = 1; ret = pci_epc_mem_init(epc, pcie->mem_res->start, resource_size(pcie->mem_res)); if (ret < 0) { dev_err(dev, "failed to initialize the memory space\n"); goto err_init; } ep->irq_cpu_addr = pci_epc_mem_alloc_addr(epc, &ep->irq_phys_addr, SZ_128K); if (!ep->irq_cpu_addr) { dev_err(dev, "failed to reserve memory space for MSI\n"); ret = -ENOMEM; goto free_epc_mem; } ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_NONE; return 0; free_epc_mem: pci_epc_mem_exit(epc); err_init: pm_runtime_put_sync(dev); err_get_sync: pm_runtime_disable(dev); return ret; }
void dw_pcie_ep_exit(struct dw_pcie_ep *ep) { struct pci_epc *epc = ep->epc; pci_epc_mem_exit(epc); }