diff options
Diffstat (limited to 'drivers/pci/controller/cadence/pcie-cadence-host.c')
-rw-r--r-- | drivers/pci/controller/cadence/pcie-cadence-host.c | 104 |
1 files changed, 35 insertions, 69 deletions
diff --git a/drivers/pci/controller/cadence/pcie-cadence-host.c b/drivers/pci/controller/cadence/pcie-cadence-host.c index 8d86560196aa..4550e0d469ca 100644 --- a/drivers/pci/controller/cadence/pcie-cadence-host.c +++ b/drivers/pci/controller/cadence/pcie-cadence-host.c @@ -32,7 +32,7 @@ void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn, unsigned int busn = bus->number; u32 addr0, desc0; - if (busn == rc->bus_range->start) { + if (pci_is_root_bus(bus)) { /* * Only the root port (devfn == 0) is connected to this bus. * All other PCI devices are behind some bridge hence on another @@ -62,7 +62,7 @@ void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn, * The bus number was already set once for all in desc1 by * cdns_pcie_host_init_address_translation(). */ - if (busn == rc->bus_range->start + 1) + if (busn == bridge->busnr + 1) desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE0; else desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1; @@ -321,10 +321,9 @@ static int cdns_pcie_host_map_dma_ranges(struct cdns_pcie_rc *rc) resource_list_for_each_entry(entry, &bridge->dma_ranges) { err = cdns_pcie_host_bar_config(rc, entry); - if (err) { + if (err) dev_err(dev, "Fail to configure IB using dma-ranges\n"); - return err; - } + return err; } return 0; @@ -333,15 +332,16 @@ static int cdns_pcie_host_map_dma_ranges(struct cdns_pcie_rc *rc) static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc) { struct cdns_pcie *pcie = &rc->pcie; - struct resource *bus_range = rc->bus_range; + struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rc); struct resource *cfg_res = rc->cfg_res; - struct device *dev = pcie->dev; - struct device_node *np = dev->of_node; - struct of_pci_range_parser parser; + struct resource_entry *entry; u64 cpu_addr = cfg_res->start; - struct of_pci_range range; u32 addr0, addr1, desc1; - int r, err; + int r, err, busnr = 0; + + entry = resource_list_first_type(&bridge->windows, IORESOURCE_BUS); + if (entry) + busnr = entry->res->start; /* * Reserve region 0 for PCI configure space accesses: @@ -349,7 +349,7 @@ static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc) * cdns_pci_map_bus(), other region registers are set here once for all. */ addr1 = 0; /* Should be programmed to zero. */ - desc1 = CDNS_PCIE_AT_OB_REGION_DESC1_BUS(bus_range->start); + desc1 = CDNS_PCIE_AT_OB_REGION_DESC1_BUS(busnr); cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_PCI_ADDR1(0), addr1); cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(0), desc1); @@ -362,25 +362,24 @@ static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc) cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR0(0), addr0); cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(0), addr1); - err = of_pci_range_parser_init(&parser, np); - if (err) - return err; - r = 1; - for_each_of_pci_range(&parser, &range) { - bool is_io; - - if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM) - is_io = false; - else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO) - is_io = true; + resource_list_for_each_entry(entry, &bridge->windows) { + struct resource *res = entry->res; + u64 pci_addr = res->start - entry->offset; + + if (resource_type(res) == IORESOURCE_IO) + cdns_pcie_set_outbound_region(pcie, busnr, 0, r, + true, + pci_pio_to_address(res->start), + pci_addr, + resource_size(res)); else - continue; + cdns_pcie_set_outbound_region(pcie, busnr, 0, r, + false, + res->start, + pci_addr, + resource_size(res)); - cdns_pcie_set_outbound_region(pcie, 0, r, is_io, - range.cpu_addr, - range.pci_addr, - range.size); r++; } @@ -392,39 +391,15 @@ static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc) } static int cdns_pcie_host_init(struct device *dev, - struct list_head *resources, struct cdns_pcie_rc *rc) { - struct resource *bus_range = NULL; - struct pci_host_bridge *bridge; int err; - bridge = pci_host_bridge_from_priv(rc); - if (!bridge) - return -ENOMEM; - - /* Parse our PCI ranges and request their resources */ - err = pci_parse_request_of_pci_ranges(dev, resources, - &bridge->dma_ranges, &bus_range); - if (err) - return err; - - rc->bus_range = bus_range; - rc->pcie.bus = bus_range->start; - err = cdns_pcie_host_init_root_port(rc); if (err) - goto err_out; - - err = cdns_pcie_host_init_address_translation(rc); - if (err) - goto err_out; - - return 0; + return err; - err_out: - pci_free_resource_list(resources); - return err; + return cdns_pcie_host_init_address_translation(rc); } static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie) @@ -450,7 +425,6 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc) struct platform_device *pdev = to_platform_device(dev); struct device_node *np = dev->of_node; struct pci_host_bridge *bridge; - struct list_head resources; enum cdns_pcie_rp_bar bar; struct cdns_pcie *pcie; struct resource *res; @@ -469,8 +443,7 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc) rc->device_id = 0xffff; of_property_read_u32(np, "device-id", &rc->device_id); - res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "reg"); - pcie->reg_base = devm_ioremap_resource(dev, res); + pcie->reg_base = devm_platform_ioremap_resource_byname(pdev, "reg"); if (IS_ERR(pcie->reg_base)) { dev_err(dev, "missing \"reg\"\n"); return PTR_ERR(pcie->reg_base); @@ -478,10 +451,8 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc) res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg"); rc->cfg_base = devm_pci_remap_cfg_resource(dev, res); - if (IS_ERR(rc->cfg_base)) { - dev_err(dev, "missing \"cfg\"\n"); + if (IS_ERR(rc->cfg_base)) return PTR_ERR(rc->cfg_base); - } rc->cfg_res = res; ret = cdns_pcie_start_link(pcie); @@ -497,26 +468,21 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc) for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++) rc->avail_ib_bar[bar] = true; - ret = cdns_pcie_host_init(dev, &resources, rc); + ret = cdns_pcie_host_init(dev, rc); if (ret) return ret; - list_splice_init(&resources, &bridge->windows); - bridge->dev.parent = dev; - bridge->busnr = pcie->bus; if (!bridge->ops) bridge->ops = &cdns_pcie_host_ops; - bridge->map_irq = of_irq_parse_and_map_pci; - bridge->swizzle_irq = pci_common_swizzle; ret = pci_host_probe(bridge); if (ret < 0) - goto err_host_probe; + goto err_init; return 0; - err_host_probe: - pci_free_resource_list(&resources); + err_init: + pm_runtime_put_sync(dev); return ret; } |