Merge branch 'pci/host-probe-refactor'
- Use pci_host_bridge.windows list directly instead of splicing in a temporary list for cadence, mvebu, host-common (Rob Herring) - Use pci_host_probe() instead of open-coding all the pieces for altera, brcmstb, iproc, mobiveil, rcar, rockchip, tegra, v3, versatile, xgene, xilinx, xilinx-nwl (Rob Herring) - Convert to devm_platform_ioremap_resource_byname() instead of open-coding platform_get_resource_byname() and devm_ioremap_resource() for altera, cadence, mediatek, rockchip, tegra, xgene (Dejin Zheng) - Convert to devm_platform_ioremap_resource() instead of open-coding platform_get_resource() and devm_ioremap_resource() for aardvark, brcmstb, exynos, ftpci100, versatile (Dejin Zheng) - Remove redundant error messages from devm_pci_remap_cfg_resource() callers (Dejin Zheng) - Drop useless PCI_ENABLE_PROC_DOMAINS from versatile driver (Rob Herring) - Default host bridge parent device to the platform device (Rob Herring) - Drop unnecessary zeroing of host bridge fields (Rob Herring) - Use pci_is_root_bus() instead of tracking root bus number separately in aardvark, designware (imx6, keystone, designware-host), mobiveil, xilinx-nwl, xilinx, rockchip, rcar (Rob Herring) - Set host bridge bus number in pci_scan_root_bus_bridge() instead of each driver for aardvark, designware-host, host-common, mediatek, rcar, tegra, v3-semi (Rob Herring) - Use bridge resources instead of parsing DT 'ranges' again for cadence (Rob Herring) - Remove private bus number and range from cadence (Rob Herring) - Use devm_pci_alloc_host_bridge() to simplify rcar (Rob Herring) - Use struct pci_host_bridge.windows list directly rather than a temporary (Rob Herring) - Reduce OF "missing non-prefetchable window" from error to warning message (Rob Herring) - Convert rcar-gen2 from old Arm-specific pci_common_init_dev() to new arch-independent interfaces (Rob Herring) - Move DT resource setup into devm_pci_alloc_host_bridge() (Rob Herring) - Set bridge map_irq and swizzle_irq to default functions; drivers that don't support legacy IRQs (iproc) need to undo this (Rob Herring) * pci/host-probe-refactor: PCI: Set bridge map_irq and swizzle_irq to default functions PCI: Move DT resource setup into devm_pci_alloc_host_bridge() PCI: rcar-gen2: Convert to use modern host bridge probe functions PCI: of: Reduce missing non-prefetchable memory region to a warning PCI: rcar: Use struct pci_host_bridge.windows list directly PCI: rcar: Use devm_pci_alloc_host_bridge() PCI: cadence: Remove private bus number and range storage PCI: cadence: Use bridge resources for outbound window setup PCI: Move setting pci_host_bridge.busnr out of host drivers PCI: rcar: Use pci_is_root_bus() to check if bus is root bus PCI: rockchip: Use pci_is_root_bus() to check if bus is root bus PCI: xilinx: Use pci_is_root_bus() to check if bus is root bus PCI: xilinx-nwl: Use pci_is_root_bus() to check if bus is root bus PCI: mobiveil: Use pci_is_root_bus() to check if bus is root bus PCI: designware: Use pci_is_root_bus() to check if bus is root bus PCI: aardvark: Use pci_is_root_bus() to check if bus is root bus PCI: Drop unnecessary zeroing of bridge fields PCI: Set default bridge parent device PCI: versatile: Drop flag PCI_ENABLE_PROC_DOMAINS PCI: controller: Remove duplicate error message PCI: controller: Convert to devm_platform_ioremap_resource() PCI: controller: Convert to devm_platform_ioremap_resource_byname() PCI: xilinx: Use pci_host_probe() to register host PCI: xilinx-nwl: Use pci_host_probe() to register host PCI: rockchip: Use pci_host_probe() to register host PCI: rcar: Use pci_host_probe() to register host PCI: iproc: Use pci_host_probe() to register host PCI: altera: Use pci_host_probe() to register host PCI: xgene: Use pci_host_probe() to register host PCI: versatile: Use pci_host_probe() to register host PCI: v3: Use pci_host_probe() to register host PCI: tegra: Use pci_host_probe() to register host PCI: mobiveil: Use pci_host_probe() to register host PCI: brcmstb: Use pci_host_probe() to register host PCI: host-common: Use struct pci_host_bridge.windows list directly PCI: mvebu: Use struct pci_host_bridge.windows list directly PCI: cadence: Use struct pci_host_bridge.windows list directly # Conflicts: # drivers/pci/controller/cadence/pcie-cadence-host.c
This commit is contained in:
commit
49e427e6bd
43 changed files with 237 additions and 814 deletions
|
@ -245,11 +245,7 @@ static int j721e_pcie_ctrl_init(struct j721e_pcie *pcie)
|
||||||
static int cdns_ti_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
|
static int cdns_ti_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
|
||||||
int where, int size, u32 *value)
|
int where, int size, u32 *value)
|
||||||
{
|
{
|
||||||
struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
|
if (pci_is_root_bus(bus))
|
||||||
struct cdns_pcie_rc *rc = pci_host_bridge_priv(bridge);
|
|
||||||
unsigned int busn = bus->number;
|
|
||||||
|
|
||||||
if (busn == rc->bus_range->start)
|
|
||||||
return pci_generic_config_read32(bus, devfn, where, size,
|
return pci_generic_config_read32(bus, devfn, where, size,
|
||||||
value);
|
value);
|
||||||
|
|
||||||
|
@ -259,11 +255,7 @@ static int cdns_ti_pcie_config_read(struct pci_bus *bus, unsigned int devfn,
|
||||||
static int cdns_ti_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
|
static int cdns_ti_pcie_config_write(struct pci_bus *bus, unsigned int devfn,
|
||||||
int where, int size, u32 value)
|
int where, int size, u32 value)
|
||||||
{
|
{
|
||||||
struct pci_host_bridge *bridge = pci_find_host_bridge(bus);
|
if (pci_is_root_bus(bus))
|
||||||
struct cdns_pcie_rc *rc = pci_host_bridge_priv(bridge);
|
|
||||||
unsigned int busn = bus->number;
|
|
||||||
|
|
||||||
if (busn == rc->bus_range->start)
|
|
||||||
return pci_generic_config_write32(bus, devfn, where, size,
|
return pci_generic_config_write32(bus, devfn, where, size,
|
||||||
value);
|
value);
|
||||||
|
|
||||||
|
|
|
@ -161,7 +161,7 @@ static int cdns_pcie_ep_map_addr(struct pci_epc *epc, u8 fn, phys_addr_t addr,
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
cdns_pcie_set_outbound_region(pcie, fn, r, false, addr, pci_addr, size);
|
cdns_pcie_set_outbound_region(pcie, 0, fn, r, false, addr, pci_addr, size);
|
||||||
|
|
||||||
set_bit(r, &ep->ob_region_map);
|
set_bit(r, &ep->ob_region_map);
|
||||||
ep->ob_addr[r] = addr;
|
ep->ob_addr[r] = addr;
|
||||||
|
@ -289,7 +289,7 @@ static void cdns_pcie_ep_assert_intx(struct cdns_pcie_ep *ep, u8 fn,
|
||||||
if (unlikely(ep->irq_pci_addr != CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY ||
|
if (unlikely(ep->irq_pci_addr != CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY ||
|
||||||
ep->irq_pci_fn != fn)) {
|
ep->irq_pci_fn != fn)) {
|
||||||
/* First region was reserved for IRQ writes. */
|
/* First region was reserved for IRQ writes. */
|
||||||
cdns_pcie_set_outbound_region_for_normal_msg(pcie, fn, 0,
|
cdns_pcie_set_outbound_region_for_normal_msg(pcie, 0, fn, 0,
|
||||||
ep->irq_phys_addr);
|
ep->irq_phys_addr);
|
||||||
ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY;
|
ep->irq_pci_addr = CDNS_PCIE_EP_IRQ_PCI_ADDR_LEGACY;
|
||||||
ep->irq_pci_fn = fn;
|
ep->irq_pci_fn = fn;
|
||||||
|
@ -370,7 +370,7 @@ static int cdns_pcie_ep_send_msi_irq(struct cdns_pcie_ep *ep, u8 fn,
|
||||||
if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) ||
|
if (unlikely(ep->irq_pci_addr != (pci_addr & ~pci_addr_mask) ||
|
||||||
ep->irq_pci_fn != fn)) {
|
ep->irq_pci_fn != fn)) {
|
||||||
/* First region was reserved for IRQ writes. */
|
/* First region was reserved for IRQ writes. */
|
||||||
cdns_pcie_set_outbound_region(pcie, fn, 0,
|
cdns_pcie_set_outbound_region(pcie, 0, fn, 0,
|
||||||
false,
|
false,
|
||||||
ep->irq_phys_addr,
|
ep->irq_phys_addr,
|
||||||
pci_addr & ~pci_addr_mask,
|
pci_addr & ~pci_addr_mask,
|
||||||
|
@ -415,7 +415,7 @@ static int cdns_pcie_ep_send_msix_irq(struct cdns_pcie_ep *ep, u8 fn,
|
||||||
if (ep->irq_pci_addr != (msg_addr & ~pci_addr_mask) ||
|
if (ep->irq_pci_addr != (msg_addr & ~pci_addr_mask) ||
|
||||||
ep->irq_pci_fn != fn) {
|
ep->irq_pci_fn != fn) {
|
||||||
/* First region was reserved for IRQ writes. */
|
/* First region was reserved for IRQ writes. */
|
||||||
cdns_pcie_set_outbound_region(pcie, fn, 0,
|
cdns_pcie_set_outbound_region(pcie, 0, fn, 0,
|
||||||
false,
|
false,
|
||||||
ep->irq_phys_addr,
|
ep->irq_phys_addr,
|
||||||
msg_addr & ~pci_addr_mask,
|
msg_addr & ~pci_addr_mask,
|
||||||
|
@ -518,8 +518,7 @@ int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
|
||||||
|
|
||||||
pcie->is_rc = false;
|
pcie->is_rc = false;
|
||||||
|
|
||||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "reg");
|
pcie->reg_base = devm_platform_ioremap_resource_byname(pdev, "reg");
|
||||||
pcie->reg_base = devm_ioremap_resource(dev, res);
|
|
||||||
if (IS_ERR(pcie->reg_base)) {
|
if (IS_ERR(pcie->reg_base)) {
|
||||||
dev_err(dev, "missing \"reg\"\n");
|
dev_err(dev, "missing \"reg\"\n");
|
||||||
return PTR_ERR(pcie->reg_base);
|
return PTR_ERR(pcie->reg_base);
|
||||||
|
|
|
@ -32,7 +32,7 @@ void __iomem *cdns_pci_map_bus(struct pci_bus *bus, unsigned int devfn,
|
||||||
unsigned int busn = bus->number;
|
unsigned int busn = bus->number;
|
||||||
u32 addr0, desc0;
|
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.
|
* Only the root port (devfn == 0) is connected to this bus.
|
||||||
* All other PCI devices are behind some bridge hence on another
|
* 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
|
* The bus number was already set once for all in desc1 by
|
||||||
* cdns_pcie_host_init_address_translation().
|
* 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;
|
desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE0;
|
||||||
else
|
else
|
||||||
desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_TYPE_CONF_TYPE1;
|
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) {
|
resource_list_for_each_entry(entry, &bridge->dma_ranges) {
|
||||||
err = cdns_pcie_host_bar_config(rc, entry);
|
err = cdns_pcie_host_bar_config(rc, entry);
|
||||||
if (err) {
|
if (err)
|
||||||
dev_err(dev, "Fail to configure IB using dma-ranges\n");
|
dev_err(dev, "Fail to configure IB using dma-ranges\n");
|
||||||
return err;
|
return err;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
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)
|
static int cdns_pcie_host_init_address_translation(struct cdns_pcie_rc *rc)
|
||||||
{
|
{
|
||||||
struct cdns_pcie *pcie = &rc->pcie;
|
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 resource *cfg_res = rc->cfg_res;
|
||||||
struct device *dev = pcie->dev;
|
struct resource_entry *entry;
|
||||||
struct device_node *np = dev->of_node;
|
|
||||||
struct of_pci_range_parser parser;
|
|
||||||
u64 cpu_addr = cfg_res->start;
|
u64 cpu_addr = cfg_res->start;
|
||||||
struct of_pci_range range;
|
|
||||||
u32 addr0, addr1, desc1;
|
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:
|
* 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.
|
* cdns_pci_map_bus(), other region registers are set here once for all.
|
||||||
*/
|
*/
|
||||||
addr1 = 0; /* Should be programmed to zero. */
|
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_PCI_ADDR1(0), addr1);
|
||||||
cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_DESC1(0), desc1);
|
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_ADDR0(0), addr0);
|
||||||
cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(0), addr1);
|
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;
|
r = 1;
|
||||||
for_each_of_pci_range(&parser, &range) {
|
resource_list_for_each_entry(entry, &bridge->windows) {
|
||||||
bool is_io;
|
struct resource *res = entry->res;
|
||||||
|
u64 pci_addr = res->start - entry->offset;
|
||||||
|
|
||||||
if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_MEM)
|
if (resource_type(res) == IORESOURCE_IO)
|
||||||
is_io = false;
|
cdns_pcie_set_outbound_region(pcie, busnr, 0, r,
|
||||||
else if ((range.flags & IORESOURCE_TYPE_BITS) == IORESOURCE_IO)
|
true,
|
||||||
is_io = true;
|
pci_pio_to_address(res->start),
|
||||||
|
pci_addr,
|
||||||
|
resource_size(res));
|
||||||
else
|
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++;
|
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,
|
static int cdns_pcie_host_init(struct device *dev,
|
||||||
struct list_head *resources,
|
|
||||||
struct cdns_pcie_rc *rc)
|
struct cdns_pcie_rc *rc)
|
||||||
{
|
{
|
||||||
struct resource *bus_range = NULL;
|
|
||||||
struct pci_host_bridge *bridge;
|
|
||||||
int err;
|
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);
|
err = cdns_pcie_host_init_root_port(rc);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_out;
|
return err;
|
||||||
|
|
||||||
err = cdns_pcie_host_init_address_translation(rc);
|
return cdns_pcie_host_init_address_translation(rc);
|
||||||
if (err)
|
|
||||||
goto err_out;
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
err_out:
|
|
||||||
pci_free_resource_list(resources);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int cdns_pcie_host_wait_for_link(struct cdns_pcie *pcie)
|
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 platform_device *pdev = to_platform_device(dev);
|
||||||
struct device_node *np = dev->of_node;
|
struct device_node *np = dev->of_node;
|
||||||
struct pci_host_bridge *bridge;
|
struct pci_host_bridge *bridge;
|
||||||
struct list_head resources;
|
|
||||||
enum cdns_pcie_rp_bar bar;
|
enum cdns_pcie_rp_bar bar;
|
||||||
struct cdns_pcie *pcie;
|
struct cdns_pcie *pcie;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
|
@ -469,8 +443,7 @@ int cdns_pcie_host_setup(struct cdns_pcie_rc *rc)
|
||||||
rc->device_id = 0xffff;
|
rc->device_id = 0xffff;
|
||||||
of_property_read_u32(np, "device-id", &rc->device_id);
|
of_property_read_u32(np, "device-id", &rc->device_id);
|
||||||
|
|
||||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "reg");
|
pcie->reg_base = devm_platform_ioremap_resource_byname(pdev, "reg");
|
||||||
pcie->reg_base = devm_ioremap_resource(dev, res);
|
|
||||||
if (IS_ERR(pcie->reg_base)) {
|
if (IS_ERR(pcie->reg_base)) {
|
||||||
dev_err(dev, "missing \"reg\"\n");
|
dev_err(dev, "missing \"reg\"\n");
|
||||||
return PTR_ERR(pcie->reg_base);
|
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");
|
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
|
||||||
rc->cfg_base = devm_pci_remap_cfg_resource(dev, res);
|
rc->cfg_base = devm_pci_remap_cfg_resource(dev, res);
|
||||||
if (IS_ERR(rc->cfg_base)) {
|
if (IS_ERR(rc->cfg_base))
|
||||||
dev_err(dev, "missing \"cfg\"\n");
|
|
||||||
return PTR_ERR(rc->cfg_base);
|
return PTR_ERR(rc->cfg_base);
|
||||||
}
|
|
||||||
rc->cfg_res = res;
|
rc->cfg_res = res;
|
||||||
|
|
||||||
ret = cdns_pcie_start_link(pcie);
|
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++)
|
for (bar = RP_BAR0; bar <= RP_NO_BAR; bar++)
|
||||||
rc->avail_ib_bar[bar] = true;
|
rc->avail_ib_bar[bar] = true;
|
||||||
|
|
||||||
ret = cdns_pcie_host_init(dev, &resources, rc);
|
ret = cdns_pcie_host_init(dev, rc);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
list_splice_init(&resources, &bridge->windows);
|
|
||||||
bridge->dev.parent = dev;
|
|
||||||
bridge->busnr = pcie->bus;
|
|
||||||
if (!bridge->ops)
|
if (!bridge->ops)
|
||||||
bridge->ops = &cdns_pcie_host_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);
|
ret = pci_host_probe(bridge);
|
||||||
if (ret < 0)
|
if (ret < 0)
|
||||||
goto err_host_probe;
|
goto err_init;
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_host_probe:
|
err_init:
|
||||||
pci_free_resource_list(&resources);
|
pm_runtime_put_sync(dev);
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
#include "pcie-cadence.h"
|
#include "pcie-cadence.h"
|
||||||
|
|
||||||
void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 fn,
|
void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
|
||||||
u32 r, bool is_io,
|
u32 r, bool is_io,
|
||||||
u64 cpu_addr, u64 pci_addr, size_t size)
|
u64 cpu_addr, u64 pci_addr, size_t size)
|
||||||
{
|
{
|
||||||
|
@ -60,7 +60,7 @@ void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 fn,
|
||||||
/* The device and function numbers are always 0. */
|
/* The device and function numbers are always 0. */
|
||||||
desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID |
|
desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID |
|
||||||
CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0);
|
CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0);
|
||||||
desc1 |= CDNS_PCIE_AT_OB_REGION_DESC1_BUS(pcie->bus);
|
desc1 |= CDNS_PCIE_AT_OB_REGION_DESC1_BUS(busnr);
|
||||||
} else {
|
} else {
|
||||||
/*
|
/*
|
||||||
* Use captured values for bus and device numbers but still
|
* Use captured values for bus and device numbers but still
|
||||||
|
@ -84,7 +84,8 @@ void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 fn,
|
||||||
cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r), addr1);
|
cdns_pcie_writel(pcie, CDNS_PCIE_AT_OB_REGION_CPU_ADDR1(r), addr1);
|
||||||
}
|
}
|
||||||
|
|
||||||
void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, u8 fn,
|
void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie,
|
||||||
|
u8 busnr, u8 fn,
|
||||||
u32 r, u64 cpu_addr)
|
u32 r, u64 cpu_addr)
|
||||||
{
|
{
|
||||||
u32 addr0, addr1, desc0, desc1;
|
u32 addr0, addr1, desc0, desc1;
|
||||||
|
@ -96,7 +97,7 @@ void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, u8 fn,
|
||||||
if (pcie->is_rc) {
|
if (pcie->is_rc) {
|
||||||
desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID |
|
desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_HARDCODED_RID |
|
||||||
CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0);
|
CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(0);
|
||||||
desc1 |= CDNS_PCIE_AT_OB_REGION_DESC1_BUS(pcie->bus);
|
desc1 |= CDNS_PCIE_AT_OB_REGION_DESC1_BUS(busnr);
|
||||||
} else {
|
} else {
|
||||||
desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(fn);
|
desc0 |= CDNS_PCIE_AT_OB_REGION_DESC0_DEVFN(fn);
|
||||||
}
|
}
|
||||||
|
|
|
@ -272,7 +272,6 @@ struct cdns_pcie {
|
||||||
struct resource *mem_res;
|
struct resource *mem_res;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
bool is_rc;
|
bool is_rc;
|
||||||
u8 bus;
|
|
||||||
int phy_count;
|
int phy_count;
|
||||||
struct phy **phy;
|
struct phy **phy;
|
||||||
struct device_link **link;
|
struct device_link **link;
|
||||||
|
@ -285,7 +284,6 @@ struct cdns_pcie {
|
||||||
* @dev: pointer to PCIe device
|
* @dev: pointer to PCIe device
|
||||||
* @cfg_res: start/end offsets in the physical system memory to map PCI
|
* @cfg_res: start/end offsets in the physical system memory to map PCI
|
||||||
* configuration space accesses
|
* configuration space accesses
|
||||||
* @bus_range: first/last buses behind the PCIe host controller
|
|
||||||
* @cfg_base: IO mapped window to access the PCI configuration space of a
|
* @cfg_base: IO mapped window to access the PCI configuration space of a
|
||||||
* single function at a time
|
* single function at a time
|
||||||
* @vendor_id: PCI vendor ID
|
* @vendor_id: PCI vendor ID
|
||||||
|
@ -296,7 +294,6 @@ struct cdns_pcie {
|
||||||
struct cdns_pcie_rc {
|
struct cdns_pcie_rc {
|
||||||
struct cdns_pcie pcie;
|
struct cdns_pcie pcie;
|
||||||
struct resource *cfg_res;
|
struct resource *cfg_res;
|
||||||
struct resource *bus_range;
|
|
||||||
void __iomem *cfg_base;
|
void __iomem *cfg_base;
|
||||||
u32 vendor_id;
|
u32 vendor_id;
|
||||||
u32 device_id;
|
u32 device_id;
|
||||||
|
@ -498,11 +495,12 @@ static inline int cdns_pcie_ep_setup(struct cdns_pcie_ep *ep)
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 fn,
|
void cdns_pcie_set_outbound_region(struct cdns_pcie *pcie, u8 busnr, u8 fn,
|
||||||
u32 r, bool is_io,
|
u32 r, bool is_io,
|
||||||
u64 cpu_addr, u64 pci_addr, size_t size);
|
u64 cpu_addr, u64 pci_addr, size_t size);
|
||||||
|
|
||||||
void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie, u8 fn,
|
void cdns_pcie_set_outbound_region_for_normal_msg(struct cdns_pcie *pcie,
|
||||||
|
u8 busnr, u8 fn,
|
||||||
u32 r, u64 cpu_addr);
|
u32 r, u64 cpu_addr);
|
||||||
|
|
||||||
void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r);
|
void cdns_pcie_reset_outbound_region(struct cdns_pcie *pcie, u32 r);
|
||||||
|
|
|
@ -84,14 +84,12 @@ static int exynos5440_pcie_get_mem_resources(struct platform_device *pdev,
|
||||||
{
|
{
|
||||||
struct dw_pcie *pci = ep->pci;
|
struct dw_pcie *pci = ep->pci;
|
||||||
struct device *dev = pci->dev;
|
struct device *dev = pci->dev;
|
||||||
struct resource *res;
|
|
||||||
|
|
||||||
ep->mem_res = devm_kzalloc(dev, sizeof(*ep->mem_res), GFP_KERNEL);
|
ep->mem_res = devm_kzalloc(dev, sizeof(*ep->mem_res), GFP_KERNEL);
|
||||||
if (!ep->mem_res)
|
if (!ep->mem_res)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
ep->mem_res->elbi_base = devm_platform_ioremap_resource(pdev, 0);
|
||||||
ep->mem_res->elbi_base = devm_ioremap_resource(dev, res);
|
|
||||||
if (IS_ERR(ep->mem_res->elbi_base))
|
if (IS_ERR(ep->mem_res->elbi_base))
|
||||||
return PTR_ERR(ep->mem_res->elbi_base);
|
return PTR_ERR(ep->mem_res->elbi_base);
|
||||||
|
|
||||||
|
|
|
@ -1269,7 +1269,7 @@ static void imx6_pcie_quirk(struct pci_dev *dev)
|
||||||
if (bus->dev.parent->parent->driver != &imx6_pcie_driver.driver)
|
if (bus->dev.parent->parent->driver != &imx6_pcie_driver.driver)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (bus->number == pp->root_bus_nr) {
|
if (pci_is_root_bus(bus)) {
|
||||||
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
||||||
struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
|
struct imx6_pcie *imx6_pcie = to_imx6_pcie(pci);
|
||||||
|
|
||||||
|
|
|
@ -440,7 +440,7 @@ static int ks_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
|
||||||
|
|
||||||
reg = CFG_BUS(bus->number) | CFG_DEVICE(PCI_SLOT(devfn)) |
|
reg = CFG_BUS(bus->number) | CFG_DEVICE(PCI_SLOT(devfn)) |
|
||||||
CFG_FUNC(PCI_FUNC(devfn));
|
CFG_FUNC(PCI_FUNC(devfn));
|
||||||
if (bus->parent->number != pp->root_bus_nr)
|
if (!pci_is_root_bus(bus->parent))
|
||||||
reg |= CFG_TYPE1;
|
reg |= CFG_TYPE1;
|
||||||
ks_pcie_app_writel(ks_pcie, CFG_SETUP, reg);
|
ks_pcie_app_writel(ks_pcie, CFG_SETUP, reg);
|
||||||
|
|
||||||
|
@ -457,7 +457,7 @@ static int ks_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
|
||||||
|
|
||||||
reg = CFG_BUS(bus->number) | CFG_DEVICE(PCI_SLOT(devfn)) |
|
reg = CFG_BUS(bus->number) | CFG_DEVICE(PCI_SLOT(devfn)) |
|
||||||
CFG_FUNC(PCI_FUNC(devfn));
|
CFG_FUNC(PCI_FUNC(devfn));
|
||||||
if (bus->parent->number != pp->root_bus_nr)
|
if (!pci_is_root_bus(bus->parent))
|
||||||
reg |= CFG_TYPE1;
|
reg |= CFG_TYPE1;
|
||||||
ks_pcie_app_writel(ks_pcie, CFG_SETUP, reg);
|
ks_pcie_app_writel(ks_pcie, CFG_SETUP, reg);
|
||||||
|
|
||||||
|
|
|
@ -67,13 +67,8 @@ static int al_pcie_init(struct pci_config_window *cfg)
|
||||||
dev_dbg(dev, "Root port dbi res: %pR\n", res);
|
dev_dbg(dev, "Root port dbi res: %pR\n", res);
|
||||||
|
|
||||||
al_pcie->dbi_base = devm_pci_remap_cfg_resource(dev, res);
|
al_pcie->dbi_base = devm_pci_remap_cfg_resource(dev, res);
|
||||||
if (IS_ERR(al_pcie->dbi_base)) {
|
if (IS_ERR(al_pcie->dbi_base))
|
||||||
long err = PTR_ERR(al_pcie->dbi_base);
|
return PTR_ERR(al_pcie->dbi_base);
|
||||||
|
|
||||||
dev_err(dev, "couldn't remap dbi base %pR (err:%ld)\n",
|
|
||||||
res, err);
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
cfg->priv = al_pcie;
|
cfg->priv = al_pcie;
|
||||||
|
|
||||||
|
@ -408,10 +403,8 @@ static int al_pcie_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
dbi_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
|
dbi_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
|
||||||
pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_res);
|
pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_res);
|
||||||
if (IS_ERR(pci->dbi_base)) {
|
if (IS_ERR(pci->dbi_base))
|
||||||
dev_err(dev, "couldn't remap dbi base %pR\n", dbi_res);
|
|
||||||
return PTR_ERR(pci->dbi_base);
|
return PTR_ERR(pci->dbi_base);
|
||||||
}
|
|
||||||
|
|
||||||
ecam_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
|
ecam_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
|
||||||
if (!ecam_res) {
|
if (!ecam_res) {
|
||||||
|
|
|
@ -317,7 +317,6 @@ static int armada8k_pcie_probe(struct platform_device *pdev)
|
||||||
base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl");
|
base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "ctrl");
|
||||||
pci->dbi_base = devm_pci_remap_cfg_resource(dev, base);
|
pci->dbi_base = devm_pci_remap_cfg_resource(dev, base);
|
||||||
if (IS_ERR(pci->dbi_base)) {
|
if (IS_ERR(pci->dbi_base)) {
|
||||||
dev_err(dev, "couldn't remap regs base %p\n", base);
|
|
||||||
ret = PTR_ERR(pci->dbi_base);
|
ret = PTR_ERR(pci->dbi_base);
|
||||||
goto fail_clkreg;
|
goto fail_clkreg;
|
||||||
}
|
}
|
||||||
|
|
|
@ -346,11 +346,6 @@ int dw_pcie_host_init(struct pcie_port *pp)
|
||||||
if (!bridge)
|
if (!bridge)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
|
|
||||||
&bridge->dma_ranges, NULL);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
/* Get the I/O and memory ranges from DT */
|
/* Get the I/O and memory ranges from DT */
|
||||||
resource_list_for_each_entry(win, &bridge->windows) {
|
resource_list_for_each_entry(win, &bridge->windows) {
|
||||||
switch (resource_type(win->res)) {
|
switch (resource_type(win->res)) {
|
||||||
|
@ -473,14 +468,8 @@ int dw_pcie_host_init(struct pcie_port *pp)
|
||||||
goto err_free_msi;
|
goto err_free_msi;
|
||||||
}
|
}
|
||||||
|
|
||||||
pp->root_bus_nr = pp->busn->start;
|
|
||||||
|
|
||||||
bridge->dev.parent = dev;
|
|
||||||
bridge->sysdata = pp;
|
bridge->sysdata = pp;
|
||||||
bridge->busnr = pp->root_bus_nr;
|
|
||||||
bridge->ops = &dw_pcie_ops;
|
bridge->ops = &dw_pcie_ops;
|
||||||
bridge->map_irq = of_irq_parse_and_map_pci;
|
|
||||||
bridge->swizzle_irq = pci_common_swizzle;
|
|
||||||
|
|
||||||
ret = pci_scan_root_bus_bridge(bridge);
|
ret = pci_scan_root_bus_bridge(bridge);
|
||||||
if (ret)
|
if (ret)
|
||||||
|
@ -529,7 +518,7 @@ static int dw_pcie_access_other_conf(struct pcie_port *pp, struct pci_bus *bus,
|
||||||
busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
|
busdev = PCIE_ATU_BUS(bus->number) | PCIE_ATU_DEV(PCI_SLOT(devfn)) |
|
||||||
PCIE_ATU_FUNC(PCI_FUNC(devfn));
|
PCIE_ATU_FUNC(PCI_FUNC(devfn));
|
||||||
|
|
||||||
if (bus->parent->number == pp->root_bus_nr) {
|
if (pci_is_root_bus(bus->parent)) {
|
||||||
type = PCIE_ATU_TYPE_CFG0;
|
type = PCIE_ATU_TYPE_CFG0;
|
||||||
cpu_addr = pp->cfg0_base;
|
cpu_addr = pp->cfg0_base;
|
||||||
cfg_size = pp->cfg0_size;
|
cfg_size = pp->cfg0_size;
|
||||||
|
@ -585,13 +574,11 @@ static int dw_pcie_valid_device(struct pcie_port *pp, struct pci_bus *bus,
|
||||||
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
struct dw_pcie *pci = to_dw_pcie_from_pp(pp);
|
||||||
|
|
||||||
/* If there is no link, then there is no device */
|
/* If there is no link, then there is no device */
|
||||||
if (bus->number != pp->root_bus_nr) {
|
if (!pci_is_root_bus(bus)) {
|
||||||
if (!dw_pcie_link_up(pci))
|
if (!dw_pcie_link_up(pci))
|
||||||
return 0;
|
return 0;
|
||||||
}
|
} else if (dev > 0)
|
||||||
|
/* Access only one slot on each root port */
|
||||||
/* Access only one slot on each root port */
|
|
||||||
if (bus->number == pp->root_bus_nr && dev > 0)
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -607,7 +594,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bus->number == pp->root_bus_nr)
|
if (pci_is_root_bus(bus))
|
||||||
return dw_pcie_rd_own_conf(pp, where, size, val);
|
return dw_pcie_rd_own_conf(pp, where, size, val);
|
||||||
|
|
||||||
return dw_pcie_rd_other_conf(pp, bus, devfn, where, size, val);
|
return dw_pcie_rd_other_conf(pp, bus, devfn, where, size, val);
|
||||||
|
@ -621,7 +608,7 @@ static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
|
||||||
if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn)))
|
if (!dw_pcie_valid_device(pp, bus, PCI_SLOT(devfn)))
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
if (bus->number == pp->root_bus_nr)
|
if (pci_is_root_bus(bus))
|
||||||
return dw_pcie_wr_own_conf(pp, where, size, val);
|
return dw_pcie_wr_own_conf(pp, where, size, val);
|
||||||
|
|
||||||
return dw_pcie_wr_other_conf(pp, bus, devfn, where, size, val);
|
return dw_pcie_wr_other_conf(pp, bus, devfn, where, size, val);
|
||||||
|
|
|
@ -173,7 +173,6 @@ struct dw_pcie_host_ops {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct pcie_port {
|
struct pcie_port {
|
||||||
u8 root_bus_nr;
|
|
||||||
u64 cfg0_base;
|
u64 cfg0_base;
|
||||||
void __iomem *va_cfg0_base;
|
void __iomem *va_cfg0_base;
|
||||||
u32 cfg0_size;
|
u32 cfg0_size;
|
||||||
|
|
|
@ -273,7 +273,6 @@ static int spear13xx_pcie_probe(struct platform_device *pdev)
|
||||||
dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
|
dbi_base = platform_get_resource_byname(pdev, IORESOURCE_MEM, "dbi");
|
||||||
pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base);
|
pci->dbi_base = devm_pci_remap_cfg_resource(dev, dbi_base);
|
||||||
if (IS_ERR(pci->dbi_base)) {
|
if (IS_ERR(pci->dbi_base)) {
|
||||||
dev_err(dev, "couldn't remap dbi base %p\n", dbi_base);
|
|
||||||
ret = PTR_ERR(pci->dbi_base);
|
ret = PTR_ERR(pci->dbi_base);
|
||||||
goto fail_clk;
|
goto fail_clk;
|
||||||
}
|
}
|
||||||
|
|
|
@ -29,18 +29,15 @@
|
||||||
|
|
||||||
static bool mobiveil_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
|
static bool mobiveil_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
|
||||||
{
|
{
|
||||||
struct mobiveil_pcie *pcie = bus->sysdata;
|
|
||||||
struct mobiveil_root_port *rp = &pcie->rp;
|
|
||||||
|
|
||||||
/* Only one device down on each root port */
|
/* Only one device down on each root port */
|
||||||
if ((bus->number == rp->root_bus_nr) && (devfn > 0))
|
if (pci_is_root_bus(bus) && (devfn > 0))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* Do not read more than one device on the bus directly
|
* Do not read more than one device on the bus directly
|
||||||
* attached to RC
|
* attached to RC
|
||||||
*/
|
*/
|
||||||
if ((bus->primary == rp->root_bus_nr) && (PCI_SLOT(devfn) > 0))
|
if ((bus->primary == to_pci_host_bridge(bus->bridge)->busnr) && (PCI_SLOT(devfn) > 0))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -61,7 +58,7 @@ static void __iomem *mobiveil_pcie_map_bus(struct pci_bus *bus,
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* RC config access */
|
/* RC config access */
|
||||||
if (bus->number == rp->root_bus_nr)
|
if (pci_is_root_bus(bus))
|
||||||
return pcie->csr_axi_slave_base + where;
|
return pcie->csr_axi_slave_base + where;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -569,8 +566,6 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie)
|
||||||
struct mobiveil_root_port *rp = &pcie->rp;
|
struct mobiveil_root_port *rp = &pcie->rp;
|
||||||
struct pci_host_bridge *bridge = rp->bridge;
|
struct pci_host_bridge *bridge = rp->bridge;
|
||||||
struct device *dev = &pcie->pdev->dev;
|
struct device *dev = &pcie->pdev->dev;
|
||||||
struct pci_bus *bus;
|
|
||||||
struct pci_bus *child;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
ret = mobiveil_pcie_parse_dt(pcie);
|
ret = mobiveil_pcie_parse_dt(pcie);
|
||||||
|
@ -582,14 +577,6 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie)
|
||||||
if (!mobiveil_pcie_is_bridge(pcie))
|
if (!mobiveil_pcie_is_bridge(pcie))
|
||||||
return -ENODEV;
|
return -ENODEV;
|
||||||
|
|
||||||
/* parse the host bridge base addresses from the device tree file */
|
|
||||||
ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
|
|
||||||
&bridge->dma_ranges, NULL);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(dev, "Getting bridge resources failed\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* configure all inbound and outbound windows and prepare the RC for
|
* configure all inbound and outbound windows and prepare the RC for
|
||||||
* config access
|
* config access
|
||||||
|
@ -607,12 +594,8 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie)
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Initialize bridge */
|
/* Initialize bridge */
|
||||||
bridge->dev.parent = dev;
|
|
||||||
bridge->sysdata = pcie;
|
bridge->sysdata = pcie;
|
||||||
bridge->busnr = rp->root_bus_nr;
|
|
||||||
bridge->ops = &mobiveil_pcie_ops;
|
bridge->ops = &mobiveil_pcie_ops;
|
||||||
bridge->map_irq = of_irq_parse_and_map_pci;
|
|
||||||
bridge->swizzle_irq = pci_common_swizzle;
|
|
||||||
|
|
||||||
ret = mobiveil_bringup_link(pcie);
|
ret = mobiveil_bringup_link(pcie);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
|
@ -620,17 +603,5 @@ int mobiveil_pcie_host_probe(struct mobiveil_pcie *pcie)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* setup the kernel resources for the newly added PCIe root bus */
|
return pci_host_probe(bridge);
|
||||||
ret = pci_scan_root_bus_bridge(bridge);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
bus = bridge->bus;
|
|
||||||
|
|
||||||
pci_assign_unassigned_bus_resources(bus);
|
|
||||||
list_for_each_entry(child, &bus->children, node)
|
|
||||||
pcie_bus_configure_settings(child);
|
|
||||||
pci_bus_add_devices(bus);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -149,7 +149,6 @@ struct mobiveil_rp_ops {
|
||||||
};
|
};
|
||||||
|
|
||||||
struct mobiveil_root_port {
|
struct mobiveil_root_port {
|
||||||
char root_bus_nr;
|
|
||||||
void __iomem *config_axi_slave_base; /* endpoint config base */
|
void __iomem *config_axi_slave_base; /* endpoint config base */
|
||||||
struct resource *ob_io_res;
|
struct resource *ob_io_res;
|
||||||
struct mobiveil_rp_ops *ops;
|
struct mobiveil_rp_ops *ops;
|
||||||
|
|
|
@ -195,7 +195,6 @@ struct advk_pcie {
|
||||||
DECLARE_BITMAP(msi_used, MSI_IRQ_NUM);
|
DECLARE_BITMAP(msi_used, MSI_IRQ_NUM);
|
||||||
struct mutex msi_used_lock;
|
struct mutex msi_used_lock;
|
||||||
u16 msi_msg;
|
u16 msi_msg;
|
||||||
int root_bus_nr;
|
|
||||||
int link_gen;
|
int link_gen;
|
||||||
struct pci_bridge_emul bridge;
|
struct pci_bridge_emul bridge;
|
||||||
struct gpio_desc *reset_gpio;
|
struct gpio_desc *reset_gpio;
|
||||||
|
@ -641,14 +640,14 @@ static void advk_sw_pci_bridge_init(struct advk_pcie *pcie)
|
||||||
static bool advk_pcie_valid_device(struct advk_pcie *pcie, struct pci_bus *bus,
|
static bool advk_pcie_valid_device(struct advk_pcie *pcie, struct pci_bus *bus,
|
||||||
int devfn)
|
int devfn)
|
||||||
{
|
{
|
||||||
if ((bus->number == pcie->root_bus_nr) && PCI_SLOT(devfn) != 0)
|
if (pci_is_root_bus(bus) && PCI_SLOT(devfn) != 0)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* If the link goes down after we check for link-up, nothing bad
|
* If the link goes down after we check for link-up, nothing bad
|
||||||
* happens but the config access times out.
|
* happens but the config access times out.
|
||||||
*/
|
*/
|
||||||
if (bus->number != pcie->root_bus_nr && !advk_pcie_link_up(pcie))
|
if (!pci_is_root_bus(bus) && !advk_pcie_link_up(pcie))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -666,7 +665,7 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn,
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bus->number == pcie->root_bus_nr)
|
if (pci_is_root_bus(bus))
|
||||||
return pci_bridge_emul_conf_read(&pcie->bridge, where,
|
return pci_bridge_emul_conf_read(&pcie->bridge, where,
|
||||||
size, val);
|
size, val);
|
||||||
|
|
||||||
|
@ -677,7 +676,7 @@ static int advk_pcie_rd_conf(struct pci_bus *bus, u32 devfn,
|
||||||
/* Program the control register */
|
/* Program the control register */
|
||||||
reg = advk_readl(pcie, PIO_CTRL);
|
reg = advk_readl(pcie, PIO_CTRL);
|
||||||
reg &= ~PIO_CTRL_TYPE_MASK;
|
reg &= ~PIO_CTRL_TYPE_MASK;
|
||||||
if (bus->primary == pcie->root_bus_nr)
|
if (pci_is_root_bus(bus->parent))
|
||||||
reg |= PCIE_CONFIG_RD_TYPE0;
|
reg |= PCIE_CONFIG_RD_TYPE0;
|
||||||
else
|
else
|
||||||
reg |= PCIE_CONFIG_RD_TYPE1;
|
reg |= PCIE_CONFIG_RD_TYPE1;
|
||||||
|
@ -724,7 +723,7 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
|
||||||
if (!advk_pcie_valid_device(pcie, bus, devfn))
|
if (!advk_pcie_valid_device(pcie, bus, devfn))
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
if (bus->number == pcie->root_bus_nr)
|
if (pci_is_root_bus(bus))
|
||||||
return pci_bridge_emul_conf_write(&pcie->bridge, where,
|
return pci_bridge_emul_conf_write(&pcie->bridge, where,
|
||||||
size, val);
|
size, val);
|
||||||
|
|
||||||
|
@ -738,7 +737,7 @@ static int advk_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
|
||||||
/* Program the control register */
|
/* Program the control register */
|
||||||
reg = advk_readl(pcie, PIO_CTRL);
|
reg = advk_readl(pcie, PIO_CTRL);
|
||||||
reg &= ~PIO_CTRL_TYPE_MASK;
|
reg &= ~PIO_CTRL_TYPE_MASK;
|
||||||
if (bus->primary == pcie->root_bus_nr)
|
if (pci_is_root_bus(bus->parent))
|
||||||
reg |= PCIE_CONFIG_WR_TYPE0;
|
reg |= PCIE_CONFIG_WR_TYPE0;
|
||||||
else
|
else
|
||||||
reg |= PCIE_CONFIG_WR_TYPE1;
|
reg |= PCIE_CONFIG_WR_TYPE1;
|
||||||
|
@ -1114,7 +1113,6 @@ static int advk_pcie_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct advk_pcie *pcie;
|
struct advk_pcie *pcie;
|
||||||
struct resource *res, *bus;
|
|
||||||
struct pci_host_bridge *bridge;
|
struct pci_host_bridge *bridge;
|
||||||
int ret, irq;
|
int ret, irq;
|
||||||
|
|
||||||
|
@ -1125,8 +1123,7 @@ static int advk_pcie_probe(struct platform_device *pdev)
|
||||||
pcie = pci_host_bridge_priv(bridge);
|
pcie = pci_host_bridge_priv(bridge);
|
||||||
pcie->pdev = pdev;
|
pcie->pdev = pdev;
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
pcie->base = devm_platform_ioremap_resource(pdev, 0);
|
||||||
pcie->base = devm_ioremap_resource(dev, res);
|
|
||||||
if (IS_ERR(pcie->base))
|
if (IS_ERR(pcie->base))
|
||||||
return PTR_ERR(pcie->base);
|
return PTR_ERR(pcie->base);
|
||||||
|
|
||||||
|
@ -1142,14 +1139,6 @@ static int advk_pcie_probe(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
|
|
||||||
&bridge->dma_ranges, &bus);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(dev, "Failed to parse resources\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
pcie->root_bus_nr = bus->start;
|
|
||||||
|
|
||||||
pcie->reset_gpio = devm_gpiod_get_from_of_node(dev, dev->of_node,
|
pcie->reset_gpio = devm_gpiod_get_from_of_node(dev, dev->of_node,
|
||||||
"reset-gpios", 0,
|
"reset-gpios", 0,
|
||||||
GPIOD_OUT_LOW,
|
GPIOD_OUT_LOW,
|
||||||
|
@ -1193,12 +1182,8 @@ static int advk_pcie_probe(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
bridge->dev.parent = dev;
|
|
||||||
bridge->sysdata = pcie;
|
bridge->sysdata = pcie;
|
||||||
bridge->busnr = 0;
|
|
||||||
bridge->ops = &advk_pcie_ops;
|
bridge->ops = &advk_pcie_ops;
|
||||||
bridge->map_irq = of_irq_parse_and_map_pci;
|
|
||||||
bridge->swizzle_irq = pci_common_swizzle;
|
|
||||||
|
|
||||||
ret = pci_host_probe(bridge);
|
ret = pci_host_probe(bridge);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
|
|
|
@ -422,7 +422,6 @@ static int faraday_pci_probe(struct platform_device *pdev)
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
const struct faraday_pci_variant *variant =
|
const struct faraday_pci_variant *variant =
|
||||||
of_device_get_match_data(dev);
|
of_device_get_match_data(dev);
|
||||||
struct resource *regs;
|
|
||||||
struct resource_entry *win;
|
struct resource_entry *win;
|
||||||
struct faraday_pci *p;
|
struct faraday_pci *p;
|
||||||
struct resource *io;
|
struct resource *io;
|
||||||
|
@ -437,12 +436,7 @@ static int faraday_pci_probe(struct platform_device *pdev)
|
||||||
if (!host)
|
if (!host)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
host->dev.parent = dev;
|
|
||||||
host->ops = &faraday_pci_ops;
|
host->ops = &faraday_pci_ops;
|
||||||
host->busnr = 0;
|
|
||||||
host->msi = NULL;
|
|
||||||
host->map_irq = of_irq_parse_and_map_pci;
|
|
||||||
host->swizzle_irq = pci_common_swizzle;
|
|
||||||
p = pci_host_bridge_priv(host);
|
p = pci_host_bridge_priv(host);
|
||||||
host->sysdata = p;
|
host->sysdata = p;
|
||||||
p->dev = dev;
|
p->dev = dev;
|
||||||
|
@ -465,16 +459,10 @@ static int faraday_pci_probe(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
regs = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
p->base = devm_platform_ioremap_resource(pdev, 0);
|
||||||
p->base = devm_ioremap_resource(dev, regs);
|
|
||||||
if (IS_ERR(p->base))
|
if (IS_ERR(p->base))
|
||||||
return PTR_ERR(p->base);
|
return PTR_ERR(p->base);
|
||||||
|
|
||||||
ret = pci_parse_request_of_pci_ranges(dev, &host->windows,
|
|
||||||
&host->dma_ranges, NULL);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
win = resource_list_first_type(&host->windows, IORESOURCE_IO);
|
win = resource_list_first_type(&host->windows, IORESOURCE_IO);
|
||||||
if (win) {
|
if (win) {
|
||||||
io = win->res;
|
io = win->res;
|
||||||
|
|
|
@ -21,39 +21,32 @@ static void gen_pci_unmap_cfg(void *ptr)
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pci_config_window *gen_pci_init(struct device *dev,
|
static struct pci_config_window *gen_pci_init(struct device *dev,
|
||||||
struct list_head *resources, const struct pci_ecam_ops *ops)
|
struct pci_host_bridge *bridge, const struct pci_ecam_ops *ops)
|
||||||
{
|
{
|
||||||
int err;
|
int err;
|
||||||
struct resource cfgres;
|
struct resource cfgres;
|
||||||
struct resource *bus_range = NULL;
|
struct resource_entry *bus;
|
||||||
struct pci_config_window *cfg;
|
struct pci_config_window *cfg;
|
||||||
|
|
||||||
/* Parse our PCI ranges and request their resources */
|
|
||||||
err = pci_parse_request_of_pci_ranges(dev, resources, NULL, &bus_range);
|
|
||||||
if (err)
|
|
||||||
return ERR_PTR(err);
|
|
||||||
|
|
||||||
err = of_address_to_resource(dev->of_node, 0, &cfgres);
|
err = of_address_to_resource(dev->of_node, 0, &cfgres);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(dev, "missing \"reg\" property\n");
|
dev_err(dev, "missing \"reg\" property\n");
|
||||||
goto err_out;
|
return ERR_PTR(err);
|
||||||
}
|
}
|
||||||
|
|
||||||
cfg = pci_ecam_create(dev, &cfgres, bus_range, ops);
|
bus = resource_list_first_type(&bridge->windows, IORESOURCE_BUS);
|
||||||
if (IS_ERR(cfg)) {
|
if (!bus)
|
||||||
err = PTR_ERR(cfg);
|
return ERR_PTR(-ENODEV);
|
||||||
goto err_out;
|
|
||||||
}
|
cfg = pci_ecam_create(dev, &cfgres, bus->res, ops);
|
||||||
|
if (IS_ERR(cfg))
|
||||||
|
return cfg;
|
||||||
|
|
||||||
err = devm_add_action_or_reset(dev, gen_pci_unmap_cfg, cfg);
|
err = devm_add_action_or_reset(dev, gen_pci_unmap_cfg, cfg);
|
||||||
if (err) {
|
if (err)
|
||||||
goto err_out;
|
return ERR_PTR(err);
|
||||||
}
|
|
||||||
return cfg;
|
|
||||||
|
|
||||||
err_out:
|
return cfg;
|
||||||
pci_free_resource_list(resources);
|
|
||||||
return ERR_PTR(err);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
int pci_host_common_probe(struct platform_device *pdev)
|
int pci_host_common_probe(struct platform_device *pdev)
|
||||||
|
@ -61,9 +54,7 @@ int pci_host_common_probe(struct platform_device *pdev)
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct pci_host_bridge *bridge;
|
struct pci_host_bridge *bridge;
|
||||||
struct pci_config_window *cfg;
|
struct pci_config_window *cfg;
|
||||||
struct list_head resources;
|
|
||||||
const struct pci_ecam_ops *ops;
|
const struct pci_ecam_ops *ops;
|
||||||
int ret;
|
|
||||||
|
|
||||||
ops = of_device_get_match_data(&pdev->dev);
|
ops = of_device_get_match_data(&pdev->dev);
|
||||||
if (!ops)
|
if (!ops)
|
||||||
|
@ -76,7 +67,7 @@ int pci_host_common_probe(struct platform_device *pdev)
|
||||||
of_pci_check_probe_only();
|
of_pci_check_probe_only();
|
||||||
|
|
||||||
/* Parse and map our Configuration Space windows */
|
/* Parse and map our Configuration Space windows */
|
||||||
cfg = gen_pci_init(dev, &resources, ops);
|
cfg = gen_pci_init(dev, bridge, ops);
|
||||||
if (IS_ERR(cfg))
|
if (IS_ERR(cfg))
|
||||||
return PTR_ERR(cfg);
|
return PTR_ERR(cfg);
|
||||||
|
|
||||||
|
@ -84,32 +75,22 @@ int pci_host_common_probe(struct platform_device *pdev)
|
||||||
if (!pci_has_flag(PCI_PROBE_ONLY))
|
if (!pci_has_flag(PCI_PROBE_ONLY))
|
||||||
pci_add_flags(PCI_REASSIGN_ALL_BUS);
|
pci_add_flags(PCI_REASSIGN_ALL_BUS);
|
||||||
|
|
||||||
list_splice_init(&resources, &bridge->windows);
|
|
||||||
bridge->dev.parent = dev;
|
|
||||||
bridge->sysdata = cfg;
|
bridge->sysdata = cfg;
|
||||||
bridge->busnr = cfg->busr.start;
|
|
||||||
bridge->ops = (struct pci_ops *)&ops->pci_ops;
|
bridge->ops = (struct pci_ops *)&ops->pci_ops;
|
||||||
bridge->map_irq = of_irq_parse_and_map_pci;
|
|
||||||
bridge->swizzle_irq = pci_common_swizzle;
|
|
||||||
|
|
||||||
ret = pci_host_probe(bridge);
|
platform_set_drvdata(pdev, bridge);
|
||||||
if (ret < 0) {
|
|
||||||
pci_free_resource_list(&resources);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
platform_set_drvdata(pdev, bridge->bus);
|
return pci_host_probe(bridge);
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pci_host_common_probe);
|
EXPORT_SYMBOL_GPL(pci_host_common_probe);
|
||||||
|
|
||||||
int pci_host_common_remove(struct platform_device *pdev)
|
int pci_host_common_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct pci_bus *bus = platform_get_drvdata(pdev);
|
struct pci_host_bridge *bridge = platform_get_drvdata(pdev);
|
||||||
|
|
||||||
pci_lock_rescan_remove();
|
pci_lock_rescan_remove();
|
||||||
pci_stop_root_bus(bus);
|
pci_stop_root_bus(bridge->bus);
|
||||||
pci_remove_root_bus(bus);
|
pci_remove_root_bus(bridge->bus);
|
||||||
pci_unlock_rescan_remove();
|
pci_unlock_rescan_remove();
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
|
@ -218,14 +218,6 @@ static int loongson_pci_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
|
|
||||||
&bridge->dma_ranges, NULL);
|
|
||||||
if (err) {
|
|
||||||
dev_err(dev, "failed to get bridge resources\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
bridge->dev.parent = dev;
|
|
||||||
bridge->sysdata = priv;
|
bridge->sysdata = priv;
|
||||||
bridge->ops = &loongson_pci_ops;
|
bridge->ops = &loongson_pci_ops;
|
||||||
bridge->map_irq = loongson_map_irq;
|
bridge->map_irq = loongson_map_irq;
|
||||||
|
|
|
@ -71,7 +71,6 @@ struct mvebu_pcie {
|
||||||
struct platform_device *pdev;
|
struct platform_device *pdev;
|
||||||
struct mvebu_pcie_port *ports;
|
struct mvebu_pcie_port *ports;
|
||||||
struct msi_controller *msi;
|
struct msi_controller *msi;
|
||||||
struct list_head resources;
|
|
||||||
struct resource io;
|
struct resource io;
|
||||||
struct resource realio;
|
struct resource realio;
|
||||||
struct resource mem;
|
struct resource mem;
|
||||||
|
@ -969,17 +968,16 @@ static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie)
|
||||||
{
|
{
|
||||||
struct device *dev = &pcie->pdev->dev;
|
struct device *dev = &pcie->pdev->dev;
|
||||||
struct device_node *np = dev->of_node;
|
struct device_node *np = dev->of_node;
|
||||||
|
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
INIT_LIST_HEAD(&pcie->resources);
|
|
||||||
|
|
||||||
/* Get the bus range */
|
/* Get the bus range */
|
||||||
ret = of_pci_parse_bus_range(np, &pcie->busn);
|
ret = of_pci_parse_bus_range(np, &pcie->busn);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "failed to parse bus-range property: %d\n", ret);
|
dev_err(dev, "failed to parse bus-range property: %d\n", ret);
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
pci_add_resource(&pcie->resources, &pcie->busn);
|
pci_add_resource(&bridge->windows, &pcie->busn);
|
||||||
|
|
||||||
/* Get the PCIe memory aperture */
|
/* Get the PCIe memory aperture */
|
||||||
mvebu_mbus_get_pcie_mem_aperture(&pcie->mem);
|
mvebu_mbus_get_pcie_mem_aperture(&pcie->mem);
|
||||||
|
@ -989,7 +987,7 @@ static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie)
|
||||||
}
|
}
|
||||||
|
|
||||||
pcie->mem.name = "PCI MEM";
|
pcie->mem.name = "PCI MEM";
|
||||||
pci_add_resource(&pcie->resources, &pcie->mem);
|
pci_add_resource(&bridge->windows, &pcie->mem);
|
||||||
|
|
||||||
/* Get the PCIe IO aperture */
|
/* Get the PCIe IO aperture */
|
||||||
mvebu_mbus_get_pcie_io_aperture(&pcie->io);
|
mvebu_mbus_get_pcie_io_aperture(&pcie->io);
|
||||||
|
@ -1002,10 +1000,10 @@ static int mvebu_pcie_parse_request_resources(struct mvebu_pcie *pcie)
|
||||||
resource_size(&pcie->io) - 1);
|
resource_size(&pcie->io) - 1);
|
||||||
pcie->realio.name = "PCI I/O";
|
pcie->realio.name = "PCI I/O";
|
||||||
|
|
||||||
pci_add_resource(&pcie->resources, &pcie->realio);
|
pci_add_resource(&bridge->windows, &pcie->realio);
|
||||||
}
|
}
|
||||||
|
|
||||||
return devm_request_pci_bus_resources(dev, &pcie->resources);
|
return devm_request_pci_bus_resources(dev, &bridge->windows);
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -1126,13 +1124,8 @@ static int mvebu_pcie_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
pcie->nports = i;
|
pcie->nports = i;
|
||||||
|
|
||||||
list_splice_init(&pcie->resources, &bridge->windows);
|
|
||||||
bridge->dev.parent = dev;
|
|
||||||
bridge->sysdata = pcie;
|
bridge->sysdata = pcie;
|
||||||
bridge->busnr = 0;
|
|
||||||
bridge->ops = &mvebu_pcie_ops;
|
bridge->ops = &mvebu_pcie_ops;
|
||||||
bridge->map_irq = of_irq_parse_and_map_pci;
|
|
||||||
bridge->swizzle_irq = pci_common_swizzle;
|
|
||||||
bridge->align_resource = mvebu_pcie_align_resource;
|
bridge->align_resource = mvebu_pcie_align_resource;
|
||||||
bridge->msi = pcie->msi;
|
bridge->msi = pcie->msi;
|
||||||
|
|
||||||
|
|
|
@ -98,22 +98,17 @@ struct rcar_pci_priv {
|
||||||
void __iomem *reg;
|
void __iomem *reg;
|
||||||
struct resource mem_res;
|
struct resource mem_res;
|
||||||
struct resource *cfg_res;
|
struct resource *cfg_res;
|
||||||
unsigned busnr;
|
|
||||||
int irq;
|
int irq;
|
||||||
unsigned long window_size;
|
|
||||||
unsigned long window_addr;
|
|
||||||
unsigned long window_pci;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
/* PCI configuration space operations */
|
/* PCI configuration space operations */
|
||||||
static void __iomem *rcar_pci_cfg_base(struct pci_bus *bus, unsigned int devfn,
|
static void __iomem *rcar_pci_cfg_base(struct pci_bus *bus, unsigned int devfn,
|
||||||
int where)
|
int where)
|
||||||
{
|
{
|
||||||
struct pci_sys_data *sys = bus->sysdata;
|
struct rcar_pci_priv *priv = bus->sysdata;
|
||||||
struct rcar_pci_priv *priv = sys->private_data;
|
|
||||||
int slot, val;
|
int slot, val;
|
||||||
|
|
||||||
if (sys->busnr != bus->number || PCI_FUNC(devfn))
|
if (!pci_is_root_bus(bus) || PCI_FUNC(devfn))
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
/* Only one EHCI/OHCI device built-in */
|
/* Only one EHCI/OHCI device built-in */
|
||||||
|
@ -132,20 +127,6 @@ static void __iomem *rcar_pci_cfg_base(struct pci_bus *bus, unsigned int devfn,
|
||||||
return priv->reg + (slot >> 1) * 0x100 + where;
|
return priv->reg + (slot >> 1) * 0x100 + where;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* PCI interrupt mapping */
|
|
||||||
static int rcar_pci_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
|
|
||||||
{
|
|
||||||
struct pci_sys_data *sys = dev->bus->sysdata;
|
|
||||||
struct rcar_pci_priv *priv = sys->private_data;
|
|
||||||
int irq;
|
|
||||||
|
|
||||||
irq = of_irq_parse_and_map_pci(dev, slot, pin);
|
|
||||||
if (!irq)
|
|
||||||
irq = priv->irq;
|
|
||||||
|
|
||||||
return irq;
|
|
||||||
}
|
|
||||||
|
|
||||||
#ifdef CONFIG_PCI_DEBUG
|
#ifdef CONFIG_PCI_DEBUG
|
||||||
/* if debug enabled, then attach an error handler irq to the bridge */
|
/* if debug enabled, then attach an error handler irq to the bridge */
|
||||||
|
|
||||||
|
@ -189,19 +170,33 @@ static inline void rcar_pci_setup_errirq(struct rcar_pci_priv *priv) { }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* PCI host controller setup */
|
/* PCI host controller setup */
|
||||||
static int rcar_pci_setup(int nr, struct pci_sys_data *sys)
|
static void rcar_pci_setup(struct rcar_pci_priv *priv)
|
||||||
{
|
{
|
||||||
struct rcar_pci_priv *priv = sys->private_data;
|
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(priv);
|
||||||
struct device *dev = priv->dev;
|
struct device *dev = priv->dev;
|
||||||
void __iomem *reg = priv->reg;
|
void __iomem *reg = priv->reg;
|
||||||
|
struct resource_entry *entry;
|
||||||
|
unsigned long window_size;
|
||||||
|
unsigned long window_addr;
|
||||||
|
unsigned long window_pci;
|
||||||
u32 val;
|
u32 val;
|
||||||
int ret;
|
|
||||||
|
entry = resource_list_first_type(&bridge->dma_ranges, IORESOURCE_MEM);
|
||||||
|
if (!entry) {
|
||||||
|
window_addr = 0x40000000;
|
||||||
|
window_pci = 0x40000000;
|
||||||
|
window_size = SZ_1G;
|
||||||
|
} else {
|
||||||
|
window_addr = entry->res->start;
|
||||||
|
window_pci = entry->res->start - entry->offset;
|
||||||
|
window_size = resource_size(entry->res);
|
||||||
|
}
|
||||||
|
|
||||||
pm_runtime_enable(dev);
|
pm_runtime_enable(dev);
|
||||||
pm_runtime_get_sync(dev);
|
pm_runtime_get_sync(dev);
|
||||||
|
|
||||||
val = ioread32(reg + RCAR_PCI_UNIT_REV_REG);
|
val = ioread32(reg + RCAR_PCI_UNIT_REV_REG);
|
||||||
dev_info(dev, "PCI: bus%u revision %x\n", sys->busnr, val);
|
dev_info(dev, "PCI: revision %x\n", val);
|
||||||
|
|
||||||
/* Disable Direct Power Down State and assert reset */
|
/* Disable Direct Power Down State and assert reset */
|
||||||
val = ioread32(reg + RCAR_USBCTR_REG) & ~RCAR_USBCTR_DIRPD;
|
val = ioread32(reg + RCAR_USBCTR_REG) & ~RCAR_USBCTR_DIRPD;
|
||||||
|
@ -214,7 +209,7 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys)
|
||||||
RCAR_USBCTR_USBH_RST | RCAR_USBCTR_PLL_RST);
|
RCAR_USBCTR_USBH_RST | RCAR_USBCTR_PLL_RST);
|
||||||
|
|
||||||
/* Setup PCIAHB window1 size */
|
/* Setup PCIAHB window1 size */
|
||||||
switch (priv->window_size) {
|
switch (window_size) {
|
||||||
case SZ_2G:
|
case SZ_2G:
|
||||||
val |= RCAR_USBCTR_PCIAHB_WIN1_2G;
|
val |= RCAR_USBCTR_PCIAHB_WIN1_2G;
|
||||||
break;
|
break;
|
||||||
|
@ -226,8 +221,8 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys)
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pr_warn("unknown window size %ld - defaulting to 256M\n",
|
pr_warn("unknown window size %ld - defaulting to 256M\n",
|
||||||
priv->window_size);
|
window_size);
|
||||||
priv->window_size = SZ_256M;
|
window_size = SZ_256M;
|
||||||
/* fall-through */
|
/* fall-through */
|
||||||
case SZ_256M:
|
case SZ_256M:
|
||||||
val |= RCAR_USBCTR_PCIAHB_WIN1_256M;
|
val |= RCAR_USBCTR_PCIAHB_WIN1_256M;
|
||||||
|
@ -245,7 +240,7 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys)
|
||||||
iowrite32(val, reg + RCAR_PCI_ARBITER_CTR_REG);
|
iowrite32(val, reg + RCAR_PCI_ARBITER_CTR_REG);
|
||||||
|
|
||||||
/* PCI-AHB mapping */
|
/* PCI-AHB mapping */
|
||||||
iowrite32(priv->window_addr | RCAR_PCIAHB_PREFETCH16,
|
iowrite32(window_addr | RCAR_PCIAHB_PREFETCH16,
|
||||||
reg + RCAR_PCIAHB_WIN1_CTR_REG);
|
reg + RCAR_PCIAHB_WIN1_CTR_REG);
|
||||||
|
|
||||||
/* AHB-PCI mapping: OHCI/EHCI registers */
|
/* AHB-PCI mapping: OHCI/EHCI registers */
|
||||||
|
@ -256,7 +251,7 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys)
|
||||||
iowrite32(RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG,
|
iowrite32(RCAR_AHBPCI_WIN1_HOST | RCAR_AHBPCI_WIN_CTR_CFG,
|
||||||
reg + RCAR_AHBPCI_WIN1_CTR_REG);
|
reg + RCAR_AHBPCI_WIN1_CTR_REG);
|
||||||
/* Set PCI-AHB Window1 address */
|
/* Set PCI-AHB Window1 address */
|
||||||
iowrite32(priv->window_pci | PCI_BASE_ADDRESS_MEM_PREFETCH,
|
iowrite32(window_pci | PCI_BASE_ADDRESS_MEM_PREFETCH,
|
||||||
reg + PCI_BASE_ADDRESS_1);
|
reg + PCI_BASE_ADDRESS_1);
|
||||||
/* Set AHB-PCI bridge PCI communication area address */
|
/* Set AHB-PCI bridge PCI communication area address */
|
||||||
val = priv->cfg_res->start + RCAR_AHBPCI_PCICOM_OFFSET;
|
val = priv->cfg_res->start + RCAR_AHBPCI_PCICOM_OFFSET;
|
||||||
|
@ -271,18 +266,7 @@ static int rcar_pci_setup(int nr, struct pci_sys_data *sys)
|
||||||
iowrite32(RCAR_PCI_INT_A | RCAR_PCI_INT_B | RCAR_PCI_INT_PME,
|
iowrite32(RCAR_PCI_INT_A | RCAR_PCI_INT_B | RCAR_PCI_INT_PME,
|
||||||
reg + RCAR_PCI_INT_ENABLE_REG);
|
reg + RCAR_PCI_INT_ENABLE_REG);
|
||||||
|
|
||||||
if (priv->irq > 0)
|
rcar_pci_setup_errirq(priv);
|
||||||
rcar_pci_setup_errirq(priv);
|
|
||||||
|
|
||||||
/* Add PCI resources */
|
|
||||||
pci_add_resource(&sys->resources, &priv->mem_res);
|
|
||||||
ret = devm_request_pci_bus_resources(dev, &sys->resources);
|
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
/* Setup bus number based on platform device id / of bus-range */
|
|
||||||
sys->busnr = priv->busnr;
|
|
||||||
return 1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct pci_ops rcar_pci_ops = {
|
static struct pci_ops rcar_pci_ops = {
|
||||||
|
@ -291,55 +275,20 @@ static struct pci_ops rcar_pci_ops = {
|
||||||
.write = pci_generic_config_write,
|
.write = pci_generic_config_write,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int rcar_pci_parse_map_dma_ranges(struct rcar_pci_priv *pci,
|
|
||||||
struct device_node *np)
|
|
||||||
{
|
|
||||||
struct device *dev = pci->dev;
|
|
||||||
struct of_pci_range range;
|
|
||||||
struct of_pci_range_parser parser;
|
|
||||||
int index = 0;
|
|
||||||
|
|
||||||
/* Failure to parse is ok as we fall back to defaults */
|
|
||||||
if (of_pci_dma_range_parser_init(&parser, np))
|
|
||||||
return 0;
|
|
||||||
|
|
||||||
/* Get the dma-ranges from DT */
|
|
||||||
for_each_of_pci_range(&parser, &range) {
|
|
||||||
/* Hardware only allows one inbound 32-bit range */
|
|
||||||
if (index)
|
|
||||||
return -EINVAL;
|
|
||||||
|
|
||||||
pci->window_addr = (unsigned long)range.cpu_addr;
|
|
||||||
pci->window_pci = (unsigned long)range.pci_addr;
|
|
||||||
pci->window_size = (unsigned long)range.size;
|
|
||||||
|
|
||||||
/* Catch HW limitations */
|
|
||||||
if (!(range.flags & IORESOURCE_PREFETCH)) {
|
|
||||||
dev_err(dev, "window must be prefetchable\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
if (pci->window_addr) {
|
|
||||||
u32 lowaddr = 1 << (ffs(pci->window_addr) - 1);
|
|
||||||
|
|
||||||
if (lowaddr < pci->window_size) {
|
|
||||||
dev_err(dev, "invalid window size/addr\n");
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
index++;
|
|
||||||
}
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
static int rcar_pci_probe(struct platform_device *pdev)
|
static int rcar_pci_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct resource *cfg_res, *mem_res;
|
struct resource *cfg_res, *mem_res;
|
||||||
struct rcar_pci_priv *priv;
|
struct rcar_pci_priv *priv;
|
||||||
|
struct pci_host_bridge *bridge;
|
||||||
void __iomem *reg;
|
void __iomem *reg;
|
||||||
struct hw_pci hw;
|
|
||||||
void *hw_private[1];
|
bridge = devm_pci_alloc_host_bridge(dev, sizeof(*priv));
|
||||||
|
if (!bridge)
|
||||||
|
return -ENOMEM;
|
||||||
|
|
||||||
|
priv = pci_host_bridge_priv(bridge);
|
||||||
|
bridge->sysdata = priv;
|
||||||
|
|
||||||
cfg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
cfg_res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
||||||
reg = devm_ioremap_resource(dev, cfg_res);
|
reg = devm_ioremap_resource(dev, cfg_res);
|
||||||
|
@ -353,10 +302,6 @@ static int rcar_pci_probe(struct platform_device *pdev)
|
||||||
if (mem_res->start & 0xFFFF)
|
if (mem_res->start & 0xFFFF)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
|
|
||||||
priv = devm_kzalloc(dev, sizeof(struct rcar_pci_priv), GFP_KERNEL);
|
|
||||||
if (!priv)
|
|
||||||
return -ENOMEM;
|
|
||||||
|
|
||||||
priv->mem_res = *mem_res;
|
priv->mem_res = *mem_res;
|
||||||
priv->cfg_res = cfg_res;
|
priv->cfg_res = cfg_res;
|
||||||
|
|
||||||
|
@ -369,44 +314,13 @@ static int rcar_pci_probe(struct platform_device *pdev)
|
||||||
return priv->irq;
|
return priv->irq;
|
||||||
}
|
}
|
||||||
|
|
||||||
/* default window addr and size if not specified in DT */
|
bridge->ops = &rcar_pci_ops;
|
||||||
priv->window_addr = 0x40000000;
|
|
||||||
priv->window_pci = 0x40000000;
|
|
||||||
priv->window_size = SZ_1G;
|
|
||||||
|
|
||||||
if (dev->of_node) {
|
pci_add_flags(PCI_REASSIGN_ALL_BUS);
|
||||||
struct resource busnr;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
ret = of_pci_parse_bus_range(dev->of_node, &busnr);
|
rcar_pci_setup(priv);
|
||||||
if (ret < 0) {
|
|
||||||
dev_err(dev, "failed to parse bus-range\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
priv->busnr = busnr.start;
|
return pci_host_probe(bridge);
|
||||||
if (busnr.end != busnr.start)
|
|
||||||
dev_warn(dev, "only one bus number supported\n");
|
|
||||||
|
|
||||||
ret = rcar_pci_parse_map_dma_ranges(priv, dev->of_node);
|
|
||||||
if (ret < 0) {
|
|
||||||
dev_err(dev, "failed to parse dma-range\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
priv->busnr = pdev->id;
|
|
||||||
}
|
|
||||||
|
|
||||||
hw_private[0] = priv;
|
|
||||||
memset(&hw, 0, sizeof(hw));
|
|
||||||
hw.nr_controllers = ARRAY_SIZE(hw_private);
|
|
||||||
hw.io_optional = 1;
|
|
||||||
hw.private_data = hw_private;
|
|
||||||
hw.map_irq = rcar_pci_map_irq;
|
|
||||||
hw.ops = &rcar_pci_ops;
|
|
||||||
hw.setup = rcar_pci_setup;
|
|
||||||
pci_common_init_dev(dev, &hw);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id rcar_pci_of_match[] = {
|
static const struct of_device_id rcar_pci_of_match[] = {
|
||||||
|
|
|
@ -1437,7 +1437,7 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
|
||||||
{
|
{
|
||||||
struct device *dev = pcie->dev;
|
struct device *dev = pcie->dev;
|
||||||
struct platform_device *pdev = to_platform_device(dev);
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
struct resource *pads, *afi, *res;
|
struct resource *res;
|
||||||
const struct tegra_pcie_soc *soc = pcie->soc;
|
const struct tegra_pcie_soc *soc = pcie->soc;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -1461,15 +1461,13 @@ static int tegra_pcie_get_resources(struct tegra_pcie *pcie)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pads = platform_get_resource_byname(pdev, IORESOURCE_MEM, "pads");
|
pcie->pads = devm_platform_ioremap_resource_byname(pdev, "pads");
|
||||||
pcie->pads = devm_ioremap_resource(dev, pads);
|
|
||||||
if (IS_ERR(pcie->pads)) {
|
if (IS_ERR(pcie->pads)) {
|
||||||
err = PTR_ERR(pcie->pads);
|
err = PTR_ERR(pcie->pads);
|
||||||
goto phys_put;
|
goto phys_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
afi = platform_get_resource_byname(pdev, IORESOURCE_MEM, "afi");
|
pcie->afi = devm_platform_ioremap_resource_byname(pdev, "afi");
|
||||||
pcie->afi = devm_ioremap_resource(dev, afi);
|
|
||||||
if (IS_ERR(pcie->afi)) {
|
if (IS_ERR(pcie->afi)) {
|
||||||
err = PTR_ERR(pcie->afi);
|
err = PTR_ERR(pcie->afi);
|
||||||
goto phys_put;
|
goto phys_put;
|
||||||
|
@ -2632,8 +2630,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct pci_host_bridge *host;
|
struct pci_host_bridge *host;
|
||||||
struct tegra_pcie *pcie;
|
struct tegra_pcie *pcie;
|
||||||
struct pci_bus *child;
|
|
||||||
struct resource *bus;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
|
host = devm_pci_alloc_host_bridge(dev, sizeof(*pcie));
|
||||||
|
@ -2648,12 +2644,6 @@ static int tegra_pcie_probe(struct platform_device *pdev)
|
||||||
INIT_LIST_HEAD(&pcie->ports);
|
INIT_LIST_HEAD(&pcie->ports);
|
||||||
pcie->dev = dev;
|
pcie->dev = dev;
|
||||||
|
|
||||||
err = pci_parse_request_of_pci_ranges(dev, &host->windows, NULL, &bus);
|
|
||||||
if (err) {
|
|
||||||
dev_err(dev, "Getting bridge resources failed\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = tegra_pcie_parse_dt(pcie);
|
err = tegra_pcie_parse_dt(pcie);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
return err;
|
return err;
|
||||||
|
@ -2677,26 +2667,15 @@ static int tegra_pcie_probe(struct platform_device *pdev)
|
||||||
goto pm_runtime_put;
|
goto pm_runtime_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
host->busnr = bus->start;
|
|
||||||
host->dev.parent = &pdev->dev;
|
|
||||||
host->ops = &tegra_pcie_ops;
|
host->ops = &tegra_pcie_ops;
|
||||||
host->map_irq = tegra_pcie_map_irq;
|
host->map_irq = tegra_pcie_map_irq;
|
||||||
host->swizzle_irq = pci_common_swizzle;
|
|
||||||
|
|
||||||
err = pci_scan_root_bus_bridge(host);
|
err = pci_host_probe(host);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
dev_err(dev, "failed to register host: %d\n", err);
|
dev_err(dev, "failed to register host: %d\n", err);
|
||||||
goto pm_runtime_put;
|
goto pm_runtime_put;
|
||||||
}
|
}
|
||||||
|
|
||||||
pci_bus_size_bridges(host->bus);
|
|
||||||
pci_bus_assign_resources(host->bus);
|
|
||||||
|
|
||||||
list_for_each_entry(child, &host->bus->children, node)
|
|
||||||
pcie_bus_configure_settings(child);
|
|
||||||
|
|
||||||
pci_bus_add_devices(host->bus);
|
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_DEBUG_FS)) {
|
if (IS_ENABLED(CONFIG_DEBUG_FS)) {
|
||||||
err = tegra_pcie_debugfs_init(pcie);
|
err = tegra_pcie_debugfs_init(pcie);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
|
|
|
@ -239,7 +239,6 @@ struct v3_pci {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
void __iomem *config_base;
|
void __iomem *config_base;
|
||||||
struct pci_bus *bus;
|
|
||||||
u32 config_mem;
|
u32 config_mem;
|
||||||
u32 non_pre_mem;
|
u32 non_pre_mem;
|
||||||
u32 pre_mem;
|
u32 pre_mem;
|
||||||
|
@ -585,8 +584,6 @@ static int v3_pci_setup_resource(struct v3_pci *v3,
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case IORESOURCE_BUS:
|
case IORESOURCE_BUS:
|
||||||
dev_dbg(dev, "BUS %pR\n", win->res);
|
|
||||||
host->busnr = win->res->start;
|
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
dev_info(dev, "Unknown resource type %lu\n",
|
dev_info(dev, "Unknown resource type %lu\n",
|
||||||
|
@ -724,12 +721,7 @@ static int v3_pci_probe(struct platform_device *pdev)
|
||||||
if (!host)
|
if (!host)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
host->dev.parent = dev;
|
|
||||||
host->ops = &v3_pci_ops;
|
host->ops = &v3_pci_ops;
|
||||||
host->busnr = 0;
|
|
||||||
host->msi = NULL;
|
|
||||||
host->map_irq = of_irq_parse_and_map_pci;
|
|
||||||
host->swizzle_irq = pci_common_swizzle;
|
|
||||||
v3 = pci_host_bridge_priv(host);
|
v3 = pci_host_bridge_priv(host);
|
||||||
host->sysdata = v3;
|
host->sysdata = v3;
|
||||||
v3->dev = dev;
|
v3->dev = dev;
|
||||||
|
@ -770,11 +762,6 @@ static int v3_pci_probe(struct platform_device *pdev)
|
||||||
if (IS_ERR(v3->config_base))
|
if (IS_ERR(v3->config_base))
|
||||||
return PTR_ERR(v3->config_base);
|
return PTR_ERR(v3->config_base);
|
||||||
|
|
||||||
ret = pci_parse_request_of_pci_ranges(dev, &host->windows,
|
|
||||||
&host->dma_ranges, NULL);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
/* Get and request error IRQ resource */
|
/* Get and request error IRQ resource */
|
||||||
irq = platform_get_irq(pdev, 0);
|
irq = platform_get_irq(pdev, 0);
|
||||||
if (irq < 0) {
|
if (irq < 0) {
|
||||||
|
@ -904,17 +891,7 @@ static int v3_pci_probe(struct platform_device *pdev)
|
||||||
val |= V3_SYSTEM_M_LOCK;
|
val |= V3_SYSTEM_M_LOCK;
|
||||||
writew(val, v3->base + V3_SYSTEM);
|
writew(val, v3->base + V3_SYSTEM);
|
||||||
|
|
||||||
ret = pci_scan_root_bus_bridge(host);
|
return pci_host_probe(host);
|
||||||
if (ret) {
|
|
||||||
dev_err(dev, "failed to register host: %d\n", ret);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
v3->bus = host->bus;
|
|
||||||
|
|
||||||
pci_bus_assign_resources(v3->bus);
|
|
||||||
pci_bus_add_devices(v3->bus);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id v3_pci_of_match[] = {
|
static const struct of_device_id v3_pci_of_match[] = {
|
||||||
|
|
|
@ -67,23 +67,20 @@ static int versatile_pci_probe(struct platform_device *pdev)
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct resource *res;
|
struct resource *res;
|
||||||
struct resource_entry *entry;
|
struct resource_entry *entry;
|
||||||
int ret, i, myslot = -1, mem = 1;
|
int i, myslot = -1, mem = 1;
|
||||||
u32 val;
|
u32 val;
|
||||||
void __iomem *local_pci_cfg_base;
|
void __iomem *local_pci_cfg_base;
|
||||||
struct pci_bus *bus, *child;
|
|
||||||
struct pci_host_bridge *bridge;
|
struct pci_host_bridge *bridge;
|
||||||
|
|
||||||
bridge = devm_pci_alloc_host_bridge(dev, 0);
|
bridge = devm_pci_alloc_host_bridge(dev, 0);
|
||||||
if (!bridge)
|
if (!bridge)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
versatile_pci_base = devm_platform_ioremap_resource(pdev, 0);
|
||||||
versatile_pci_base = devm_ioremap_resource(dev, res);
|
|
||||||
if (IS_ERR(versatile_pci_base))
|
if (IS_ERR(versatile_pci_base))
|
||||||
return PTR_ERR(versatile_pci_base);
|
return PTR_ERR(versatile_pci_base);
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 1);
|
versatile_cfg_base[0] = devm_platform_ioremap_resource(pdev, 1);
|
||||||
versatile_cfg_base[0] = devm_ioremap_resource(dev, res);
|
|
||||||
if (IS_ERR(versatile_cfg_base[0]))
|
if (IS_ERR(versatile_cfg_base[0]))
|
||||||
return PTR_ERR(versatile_cfg_base[0]);
|
return PTR_ERR(versatile_cfg_base[0]);
|
||||||
|
|
||||||
|
@ -92,11 +89,6 @@ static int versatile_pci_probe(struct platform_device *pdev)
|
||||||
if (IS_ERR(versatile_cfg_base[1]))
|
if (IS_ERR(versatile_cfg_base[1]))
|
||||||
return PTR_ERR(versatile_cfg_base[1]);
|
return PTR_ERR(versatile_cfg_base[1]);
|
||||||
|
|
||||||
ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
|
|
||||||
NULL, NULL);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
resource_list_for_each_entry(entry, &bridge->windows) {
|
resource_list_for_each_entry(entry, &bridge->windows) {
|
||||||
if (resource_type(entry->res) == IORESOURCE_MEM) {
|
if (resource_type(entry->res) == IORESOURCE_MEM) {
|
||||||
writel(entry->res->start >> 28, PCI_IMAP(mem));
|
writel(entry->res->start >> 28, PCI_IMAP(mem));
|
||||||
|
@ -154,28 +146,11 @@ static int versatile_pci_probe(struct platform_device *pdev)
|
||||||
*/
|
*/
|
||||||
writel(0, versatile_cfg_base[0] + PCI_INTERRUPT_LINE);
|
writel(0, versatile_cfg_base[0] + PCI_INTERRUPT_LINE);
|
||||||
|
|
||||||
pci_add_flags(PCI_ENABLE_PROC_DOMAINS);
|
|
||||||
pci_add_flags(PCI_REASSIGN_ALL_BUS);
|
pci_add_flags(PCI_REASSIGN_ALL_BUS);
|
||||||
|
|
||||||
bridge->dev.parent = dev;
|
|
||||||
bridge->sysdata = NULL;
|
|
||||||
bridge->busnr = 0;
|
|
||||||
bridge->ops = &pci_versatile_ops;
|
bridge->ops = &pci_versatile_ops;
|
||||||
bridge->map_irq = of_irq_parse_and_map_pci;
|
|
||||||
bridge->swizzle_irq = pci_common_swizzle;
|
|
||||||
|
|
||||||
ret = pci_scan_root_bus_bridge(bridge);
|
return pci_host_probe(bridge);
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
bus = bridge->bus;
|
|
||||||
|
|
||||||
pci_assign_unassigned_bus_resources(bus);
|
|
||||||
list_for_each_entry(child, &bus->children, node)
|
|
||||||
pcie_bus_configure_settings(child);
|
|
||||||
pci_bus_add_devices(bus);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id versatile_pci_of_match[] = {
|
static const struct of_device_id versatile_pci_of_match[] = {
|
||||||
|
|
|
@ -355,8 +355,7 @@ static int xgene_pcie_map_reg(struct xgene_pcie_port *port,
|
||||||
if (IS_ERR(port->csr_base))
|
if (IS_ERR(port->csr_base))
|
||||||
return PTR_ERR(port->csr_base);
|
return PTR_ERR(port->csr_base);
|
||||||
|
|
||||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "cfg");
|
port->cfg_base = devm_platform_ioremap_resource_byname(pdev, "cfg");
|
||||||
port->cfg_base = devm_ioremap_resource(dev, res);
|
|
||||||
if (IS_ERR(port->cfg_base))
|
if (IS_ERR(port->cfg_base))
|
||||||
return PTR_ERR(port->cfg_base);
|
return PTR_ERR(port->cfg_base);
|
||||||
port->cfg_addr = res->start;
|
port->cfg_addr = res->start;
|
||||||
|
@ -591,7 +590,6 @@ static int xgene_pcie_probe(struct platform_device *pdev)
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct device_node *dn = dev->of_node;
|
struct device_node *dn = dev->of_node;
|
||||||
struct xgene_pcie_port *port;
|
struct xgene_pcie_port *port;
|
||||||
struct pci_bus *bus, *child;
|
|
||||||
struct pci_host_bridge *bridge;
|
struct pci_host_bridge *bridge;
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
|
@ -616,33 +614,14 @@ static int xgene_pcie_probe(struct platform_device *pdev)
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
|
|
||||||
&bridge->dma_ranges, NULL);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = xgene_pcie_setup(port);
|
ret = xgene_pcie_setup(port);
|
||||||
if (ret)
|
if (ret)
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
bridge->dev.parent = dev;
|
|
||||||
bridge->sysdata = port;
|
bridge->sysdata = port;
|
||||||
bridge->busnr = 0;
|
|
||||||
bridge->ops = &xgene_pcie_ops;
|
bridge->ops = &xgene_pcie_ops;
|
||||||
bridge->map_irq = of_irq_parse_and_map_pci;
|
|
||||||
bridge->swizzle_irq = pci_common_swizzle;
|
|
||||||
|
|
||||||
ret = pci_scan_root_bus_bridge(bridge);
|
return pci_host_probe(bridge);
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
bus = bridge->bus;
|
|
||||||
|
|
||||||
pci_assign_unassigned_bus_resources(bus);
|
|
||||||
list_for_each_entry(child, &bus->children, node)
|
|
||||||
pcie_bus_configure_settings(child);
|
|
||||||
pci_bus_add_devices(bus);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id xgene_pcie_match_table[] = {
|
static const struct of_device_id xgene_pcie_match_table[] = {
|
||||||
|
|
|
@ -228,8 +228,7 @@ static int altera_msi_probe(struct platform_device *pdev)
|
||||||
mutex_init(&msi->lock);
|
mutex_init(&msi->lock);
|
||||||
msi->pdev = pdev;
|
msi->pdev = pdev;
|
||||||
|
|
||||||
res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "csr");
|
msi->csr_base = devm_platform_ioremap_resource_byname(pdev, "csr");
|
||||||
msi->csr_base = devm_ioremap_resource(&pdev->dev, res);
|
|
||||||
if (IS_ERR(msi->csr_base)) {
|
if (IS_ERR(msi->csr_base)) {
|
||||||
dev_err(&pdev->dev, "failed to map csr memory\n");
|
dev_err(&pdev->dev, "failed to map csr memory\n");
|
||||||
return PTR_ERR(msi->csr_base);
|
return PTR_ERR(msi->csr_base);
|
||||||
|
|
|
@ -696,17 +696,14 @@ static int altera_pcie_parse_dt(struct altera_pcie *pcie)
|
||||||
{
|
{
|
||||||
struct device *dev = &pcie->pdev->dev;
|
struct device *dev = &pcie->pdev->dev;
|
||||||
struct platform_device *pdev = pcie->pdev;
|
struct platform_device *pdev = pcie->pdev;
|
||||||
struct resource *cra;
|
|
||||||
struct resource *hip;
|
|
||||||
|
|
||||||
cra = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Cra");
|
pcie->cra_base = devm_platform_ioremap_resource_byname(pdev, "Cra");
|
||||||
pcie->cra_base = devm_ioremap_resource(dev, cra);
|
|
||||||
if (IS_ERR(pcie->cra_base))
|
if (IS_ERR(pcie->cra_base))
|
||||||
return PTR_ERR(pcie->cra_base);
|
return PTR_ERR(pcie->cra_base);
|
||||||
|
|
||||||
if (pcie->pcie_data->version == ALTERA_PCIE_V2) {
|
if (pcie->pcie_data->version == ALTERA_PCIE_V2) {
|
||||||
hip = platform_get_resource_byname(pdev, IORESOURCE_MEM, "Hip");
|
pcie->hip_base =
|
||||||
pcie->hip_base = devm_ioremap_resource(&pdev->dev, hip);
|
devm_platform_ioremap_resource_byname(pdev, "Hip");
|
||||||
if (IS_ERR(pcie->hip_base))
|
if (IS_ERR(pcie->hip_base))
|
||||||
return PTR_ERR(pcie->hip_base);
|
return PTR_ERR(pcie->hip_base);
|
||||||
}
|
}
|
||||||
|
@ -773,8 +770,6 @@ static int altera_pcie_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct altera_pcie *pcie;
|
struct altera_pcie *pcie;
|
||||||
struct pci_bus *bus;
|
|
||||||
struct pci_bus *child;
|
|
||||||
struct pci_host_bridge *bridge;
|
struct pci_host_bridge *bridge;
|
||||||
int ret;
|
int ret;
|
||||||
const struct of_device_id *match;
|
const struct of_device_id *match;
|
||||||
|
@ -799,13 +794,6 @@ static int altera_pcie_probe(struct platform_device *pdev)
|
||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
|
|
||||||
&bridge->dma_ranges, NULL);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(dev, "Failed add resources\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
ret = altera_pcie_init_irq_domain(pcie);
|
ret = altera_pcie_init_irq_domain(pcie);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(dev, "Failed creating IRQ Domain\n");
|
dev_err(dev, "Failed creating IRQ Domain\n");
|
||||||
|
@ -818,27 +806,11 @@ static int altera_pcie_probe(struct platform_device *pdev)
|
||||||
cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE);
|
cra_writel(pcie, P2A_INT_ENA_ALL, P2A_INT_ENABLE);
|
||||||
altera_pcie_host_init(pcie);
|
altera_pcie_host_init(pcie);
|
||||||
|
|
||||||
bridge->dev.parent = dev;
|
|
||||||
bridge->sysdata = pcie;
|
bridge->sysdata = pcie;
|
||||||
bridge->busnr = pcie->root_bus_nr;
|
bridge->busnr = pcie->root_bus_nr;
|
||||||
bridge->ops = &altera_pcie_ops;
|
bridge->ops = &altera_pcie_ops;
|
||||||
bridge->map_irq = of_irq_parse_and_map_pci;
|
|
||||||
bridge->swizzle_irq = pci_common_swizzle;
|
|
||||||
|
|
||||||
ret = pci_scan_root_bus_bridge(bridge);
|
return pci_host_probe(bridge);
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
bus = bridge->bus;
|
|
||||||
|
|
||||||
pci_assign_unassigned_bus_resources(bus);
|
|
||||||
|
|
||||||
/* Configure PCI Express setting. */
|
|
||||||
list_for_each_entry(child, &bus->children, node)
|
|
||||||
pcie_bus_configure_settings(child);
|
|
||||||
|
|
||||||
pci_bus_add_devices(bus);
|
|
||||||
return ret;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int altera_pcie_remove(struct platform_device *pdev)
|
static int altera_pcie_remove(struct platform_device *pdev)
|
||||||
|
|
|
@ -172,7 +172,6 @@ struct brcm_pcie {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
struct clk *clk;
|
struct clk *clk;
|
||||||
struct pci_bus *root_bus;
|
|
||||||
struct device_node *np;
|
struct device_node *np;
|
||||||
bool ssc;
|
bool ssc;
|
||||||
int gen;
|
int gen;
|
||||||
|
@ -919,9 +918,10 @@ static void __brcm_pcie_remove(struct brcm_pcie *pcie)
|
||||||
static int brcm_pcie_remove(struct platform_device *pdev)
|
static int brcm_pcie_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct brcm_pcie *pcie = platform_get_drvdata(pdev);
|
struct brcm_pcie *pcie = platform_get_drvdata(pdev);
|
||||||
|
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(pcie);
|
||||||
|
|
||||||
pci_stop_root_bus(pcie->root_bus);
|
pci_stop_root_bus(bridge->bus);
|
||||||
pci_remove_root_bus(pcie->root_bus);
|
pci_remove_root_bus(bridge->bus);
|
||||||
__brcm_pcie_remove(pcie);
|
__brcm_pcie_remove(pcie);
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
@ -933,8 +933,6 @@ static int brcm_pcie_probe(struct platform_device *pdev)
|
||||||
struct pci_host_bridge *bridge;
|
struct pci_host_bridge *bridge;
|
||||||
struct device_node *fw_np;
|
struct device_node *fw_np;
|
||||||
struct brcm_pcie *pcie;
|
struct brcm_pcie *pcie;
|
||||||
struct pci_bus *child;
|
|
||||||
struct resource *res;
|
|
||||||
int ret;
|
int ret;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -959,8 +957,7 @@ static int brcm_pcie_probe(struct platform_device *pdev)
|
||||||
pcie->dev = &pdev->dev;
|
pcie->dev = &pdev->dev;
|
||||||
pcie->np = np;
|
pcie->np = np;
|
||||||
|
|
||||||
res = platform_get_resource(pdev, IORESOURCE_MEM, 0);
|
pcie->base = devm_platform_ioremap_resource(pdev, 0);
|
||||||
pcie->base = devm_ioremap_resource(&pdev->dev, res);
|
|
||||||
if (IS_ERR(pcie->base))
|
if (IS_ERR(pcie->base))
|
||||||
return PTR_ERR(pcie->base);
|
return PTR_ERR(pcie->base);
|
||||||
|
|
||||||
|
@ -973,11 +970,6 @@ static int brcm_pcie_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
pcie->ssc = of_property_read_bool(np, "brcm,enable-ssc");
|
pcie->ssc = of_property_read_bool(np, "brcm,enable-ssc");
|
||||||
|
|
||||||
ret = pci_parse_request_of_pci_ranges(pcie->dev, &bridge->windows,
|
|
||||||
&bridge->dma_ranges, NULL);
|
|
||||||
if (ret)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
ret = clk_prepare_enable(pcie->clk);
|
ret = clk_prepare_enable(pcie->clk);
|
||||||
if (ret) {
|
if (ret) {
|
||||||
dev_err(&pdev->dev, "could not enable clock\n");
|
dev_err(&pdev->dev, "could not enable clock\n");
|
||||||
|
@ -997,27 +989,12 @@ static int brcm_pcie_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
bridge->dev.parent = &pdev->dev;
|
|
||||||
bridge->busnr = 0;
|
|
||||||
bridge->ops = &brcm_pcie_ops;
|
bridge->ops = &brcm_pcie_ops;
|
||||||
bridge->sysdata = pcie;
|
bridge->sysdata = pcie;
|
||||||
bridge->map_irq = of_irq_parse_and_map_pci;
|
|
||||||
bridge->swizzle_irq = pci_common_swizzle;
|
|
||||||
|
|
||||||
ret = pci_scan_root_bus_bridge(bridge);
|
|
||||||
if (ret < 0) {
|
|
||||||
dev_err(pcie->dev, "Scanning root bridge failed\n");
|
|
||||||
goto fail;
|
|
||||||
}
|
|
||||||
|
|
||||||
pci_assign_unassigned_bus_resources(bridge->bus);
|
|
||||||
list_for_each_entry(child, &bridge->bus->children, node)
|
|
||||||
pcie_bus_configure_settings(child);
|
|
||||||
pci_bus_add_devices(bridge->bus);
|
|
||||||
platform_set_drvdata(pdev, pcie);
|
platform_set_drvdata(pdev, pcie);
|
||||||
pcie->root_bus = bridge->bus;
|
|
||||||
|
|
||||||
return 0;
|
return pci_host_probe(bridge);
|
||||||
fail:
|
fail:
|
||||||
__brcm_pcie_remove(pcie);
|
__brcm_pcie_remove(pcie);
|
||||||
return ret;
|
return ret;
|
||||||
|
|
|
@ -95,20 +95,14 @@ static int iproc_pcie_pltfm_probe(struct platform_device *pdev)
|
||||||
if (IS_ERR(pcie->phy))
|
if (IS_ERR(pcie->phy))
|
||||||
return PTR_ERR(pcie->phy);
|
return PTR_ERR(pcie->phy);
|
||||||
|
|
||||||
ret = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
|
|
||||||
&bridge->dma_ranges, NULL);
|
|
||||||
if (ret) {
|
|
||||||
dev_err(dev, "unable to get PCI host bridge resources\n");
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
/* PAXC doesn't support legacy IRQs, skip mapping */
|
/* PAXC doesn't support legacy IRQs, skip mapping */
|
||||||
switch (pcie->type) {
|
switch (pcie->type) {
|
||||||
case IPROC_PCIE_PAXC:
|
case IPROC_PCIE_PAXC:
|
||||||
case IPROC_PCIE_PAXC_V2:
|
case IPROC_PCIE_PAXC_V2:
|
||||||
|
pcie->map_irq = 0;
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
pcie->map_irq = of_irq_parse_and_map_pci;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
ret = iproc_pcie_setup(pcie, &bridge->windows);
|
ret = iproc_pcie_setup(pcie, &bridge->windows);
|
||||||
|
|
|
@ -1470,7 +1470,6 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
|
||||||
{
|
{
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
int ret;
|
int ret;
|
||||||
struct pci_bus *child;
|
|
||||||
struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
|
struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
|
||||||
|
|
||||||
dev = pcie->dev;
|
dev = pcie->dev;
|
||||||
|
@ -1524,28 +1523,16 @@ int iproc_pcie_setup(struct iproc_pcie *pcie, struct list_head *res)
|
||||||
if (iproc_pcie_msi_enable(pcie))
|
if (iproc_pcie_msi_enable(pcie))
|
||||||
dev_info(dev, "not using iProc MSI\n");
|
dev_info(dev, "not using iProc MSI\n");
|
||||||
|
|
||||||
host->busnr = 0;
|
|
||||||
host->dev.parent = dev;
|
|
||||||
host->ops = &iproc_pcie_ops;
|
host->ops = &iproc_pcie_ops;
|
||||||
host->sysdata = pcie;
|
host->sysdata = pcie;
|
||||||
host->map_irq = pcie->map_irq;
|
host->map_irq = pcie->map_irq;
|
||||||
host->swizzle_irq = pci_common_swizzle;
|
|
||||||
|
|
||||||
ret = pci_scan_root_bus_bridge(host);
|
ret = pci_host_probe(host);
|
||||||
if (ret < 0) {
|
if (ret < 0) {
|
||||||
dev_err(dev, "failed to scan host: %d\n", ret);
|
dev_err(dev, "failed to scan host: %d\n", ret);
|
||||||
goto err_power_off_phy;
|
goto err_power_off_phy;
|
||||||
}
|
}
|
||||||
|
|
||||||
pci_assign_unassigned_bus_resources(host->bus);
|
|
||||||
|
|
||||||
pcie->root_bus = host->bus;
|
|
||||||
|
|
||||||
list_for_each_entry(child, &host->bus->children, node)
|
|
||||||
pcie_bus_configure_settings(child);
|
|
||||||
|
|
||||||
pci_bus_add_devices(host->bus);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_power_off_phy:
|
err_power_off_phy:
|
||||||
|
@ -1558,8 +1545,10 @@ EXPORT_SYMBOL(iproc_pcie_setup);
|
||||||
|
|
||||||
int iproc_pcie_remove(struct iproc_pcie *pcie)
|
int iproc_pcie_remove(struct iproc_pcie *pcie)
|
||||||
{
|
{
|
||||||
pci_stop_root_bus(pcie->root_bus);
|
struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
|
||||||
pci_remove_root_bus(pcie->root_bus);
|
|
||||||
|
pci_stop_root_bus(host->bus);
|
||||||
|
pci_remove_root_bus(host->bus);
|
||||||
|
|
||||||
iproc_pcie_msi_disable(pcie);
|
iproc_pcie_msi_disable(pcie);
|
||||||
|
|
||||||
|
|
|
@ -54,7 +54,6 @@ struct iproc_msi;
|
||||||
* @reg_offsets: register offsets
|
* @reg_offsets: register offsets
|
||||||
* @base: PCIe host controller I/O register base
|
* @base: PCIe host controller I/O register base
|
||||||
* @base_addr: PCIe host controller register base physical address
|
* @base_addr: PCIe host controller register base physical address
|
||||||
* @root_bus: pointer to root bus
|
|
||||||
* @phy: optional PHY device that controls the Serdes
|
* @phy: optional PHY device that controls the Serdes
|
||||||
* @map_irq: function callback to map interrupts
|
* @map_irq: function callback to map interrupts
|
||||||
* @ep_is_internal: indicates an internal emulated endpoint device is connected
|
* @ep_is_internal: indicates an internal emulated endpoint device is connected
|
||||||
|
@ -85,7 +84,6 @@ struct iproc_pcie {
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
phys_addr_t base_addr;
|
phys_addr_t base_addr;
|
||||||
struct resource mem;
|
struct resource mem;
|
||||||
struct pci_bus *root_bus;
|
|
||||||
struct phy *phy;
|
struct phy *phy;
|
||||||
int (*map_irq)(const struct pci_dev *, u8, u8);
|
int (*map_irq)(const struct pci_dev *, u8, u8);
|
||||||
bool ep_is_internal;
|
bool ep_is_internal;
|
||||||
|
|
|
@ -209,7 +209,6 @@ struct mtk_pcie_port {
|
||||||
* @mem: non-prefetchable memory resource
|
* @mem: non-prefetchable memory resource
|
||||||
* @ports: pointer to PCIe port information
|
* @ports: pointer to PCIe port information
|
||||||
* @soc: pointer to SoC-dependent operations
|
* @soc: pointer to SoC-dependent operations
|
||||||
* @busnr: root bus number
|
|
||||||
*/
|
*/
|
||||||
struct mtk_pcie {
|
struct mtk_pcie {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
|
@ -218,7 +217,6 @@ struct mtk_pcie {
|
||||||
|
|
||||||
struct list_head ports;
|
struct list_head ports;
|
||||||
const struct mtk_pcie_soc *soc;
|
const struct mtk_pcie_soc *soc;
|
||||||
unsigned int busnr;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
static void mtk_pcie_subsys_powerdown(struct mtk_pcie *pcie)
|
static void mtk_pcie_subsys_powerdown(struct mtk_pcie *pcie)
|
||||||
|
@ -905,7 +903,6 @@ static int mtk_pcie_parse_port(struct mtk_pcie *pcie,
|
||||||
int slot)
|
int slot)
|
||||||
{
|
{
|
||||||
struct mtk_pcie_port *port;
|
struct mtk_pcie_port *port;
|
||||||
struct resource *regs;
|
|
||||||
struct device *dev = pcie->dev;
|
struct device *dev = pcie->dev;
|
||||||
struct platform_device *pdev = to_platform_device(dev);
|
struct platform_device *pdev = to_platform_device(dev);
|
||||||
char name[10];
|
char name[10];
|
||||||
|
@ -916,8 +913,7 @@ static int mtk_pcie_parse_port(struct mtk_pcie *pcie,
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
snprintf(name, sizeof(name), "port%d", slot);
|
snprintf(name, sizeof(name), "port%d", slot);
|
||||||
regs = platform_get_resource_byname(pdev, IORESOURCE_MEM, name);
|
port->base = devm_platform_ioremap_resource_byname(pdev, name);
|
||||||
port->base = devm_ioremap_resource(dev, regs);
|
|
||||||
if (IS_ERR(port->base)) {
|
if (IS_ERR(port->base)) {
|
||||||
dev_err(dev, "failed to map port%d base\n", slot);
|
dev_err(dev, "failed to map port%d base\n", slot);
|
||||||
return PTR_ERR(port->base);
|
return PTR_ERR(port->base);
|
||||||
|
@ -1031,18 +1027,8 @@ static int mtk_pcie_setup(struct mtk_pcie *pcie)
|
||||||
struct device *dev = pcie->dev;
|
struct device *dev = pcie->dev;
|
||||||
struct device_node *node = dev->of_node, *child;
|
struct device_node *node = dev->of_node, *child;
|
||||||
struct mtk_pcie_port *port, *tmp;
|
struct mtk_pcie_port *port, *tmp;
|
||||||
struct pci_host_bridge *host = pci_host_bridge_from_priv(pcie);
|
|
||||||
struct list_head *windows = &host->windows;
|
|
||||||
struct resource *bus;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
err = pci_parse_request_of_pci_ranges(dev, windows,
|
|
||||||
&host->dma_ranges, &bus);
|
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
pcie->busnr = bus->start;
|
|
||||||
|
|
||||||
for_each_available_child_of_node(node, child) {
|
for_each_available_child_of_node(node, child) {
|
||||||
int slot;
|
int slot;
|
||||||
|
|
||||||
|
@ -1096,11 +1082,7 @@ static int mtk_pcie_probe(struct platform_device *pdev)
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
host->busnr = pcie->busnr;
|
|
||||||
host->dev.parent = pcie->dev;
|
|
||||||
host->ops = pcie->soc->ops;
|
host->ops = pcie->soc->ops;
|
||||||
host->map_irq = of_irq_parse_and_map_pci;
|
|
||||||
host->swizzle_irq = pci_common_swizzle;
|
|
||||||
host->sysdata = pcie;
|
host->sysdata = pcie;
|
||||||
|
|
||||||
err = pci_host_probe(host);
|
err = pci_host_probe(host);
|
||||||
|
|
|
@ -53,8 +53,6 @@ struct rcar_pcie_host {
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct phy *phy;
|
struct phy *phy;
|
||||||
void __iomem *base;
|
void __iomem *base;
|
||||||
struct list_head resources;
|
|
||||||
int root_bus_nr;
|
|
||||||
struct clk *bus_clk;
|
struct clk *bus_clk;
|
||||||
struct rcar_msi msi;
|
struct rcar_msi msi;
|
||||||
int (*phy_init_fn)(struct rcar_pcie_host *host);
|
int (*phy_init_fn)(struct rcar_pcie_host *host);
|
||||||
|
@ -100,22 +98,14 @@ static int rcar_pcie_config_access(struct rcar_pcie_host *host,
|
||||||
if (dev != 0)
|
if (dev != 0)
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
if (access_type == RCAR_PCI_ACCESS_READ) {
|
if (access_type == RCAR_PCI_ACCESS_READ)
|
||||||
*data = rcar_pci_read_reg(pcie, PCICONF(index));
|
*data = rcar_pci_read_reg(pcie, PCICONF(index));
|
||||||
} else {
|
else
|
||||||
/* Keep an eye out for changes to the root bus number */
|
|
||||||
if (pci_is_root_bus(bus) && (reg == PCI_PRIMARY_BUS))
|
|
||||||
host->root_bus_nr = *data & 0xff;
|
|
||||||
|
|
||||||
rcar_pci_write_reg(pcie, *data, PCICONF(index));
|
rcar_pci_write_reg(pcie, *data, PCICONF(index));
|
||||||
}
|
|
||||||
|
|
||||||
return PCIBIOS_SUCCESSFUL;
|
return PCIBIOS_SUCCESSFUL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (host->root_bus_nr < 0)
|
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
|
||||||
|
|
||||||
/* Clear errors */
|
/* Clear errors */
|
||||||
rcar_pci_write_reg(pcie, rcar_pci_read_reg(pcie, PCIEERRFR), PCIEERRFR);
|
rcar_pci_write_reg(pcie, rcar_pci_read_reg(pcie, PCIEERRFR), PCIEERRFR);
|
||||||
|
|
||||||
|
@ -124,7 +114,7 @@ static int rcar_pcie_config_access(struct rcar_pcie_host *host,
|
||||||
PCIE_CONF_DEV(dev) | PCIE_CONF_FUNC(func) | reg, PCIECAR);
|
PCIE_CONF_DEV(dev) | PCIE_CONF_FUNC(func) | reg, PCIECAR);
|
||||||
|
|
||||||
/* Enable the configuration access */
|
/* Enable the configuration access */
|
||||||
if (bus->parent->number == host->root_bus_nr)
|
if (pci_is_root_bus(bus->parent))
|
||||||
rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE0, PCIECCTLR);
|
rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE0, PCIECCTLR);
|
||||||
else
|
else
|
||||||
rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE1, PCIECCTLR);
|
rcar_pci_write_reg(pcie, CONFIG_SEND_ENABLE | TYPE1, PCIECCTLR);
|
||||||
|
@ -212,38 +202,6 @@ static struct pci_ops rcar_pcie_ops = {
|
||||||
.write = rcar_pcie_write_conf,
|
.write = rcar_pcie_write_conf,
|
||||||
};
|
};
|
||||||
|
|
||||||
static int rcar_pcie_setup(struct list_head *resource,
|
|
||||||
struct rcar_pcie_host *host)
|
|
||||||
{
|
|
||||||
struct resource_entry *win;
|
|
||||||
int i = 0;
|
|
||||||
|
|
||||||
/* Setup PCI resources */
|
|
||||||
resource_list_for_each_entry(win, &host->resources) {
|
|
||||||
struct resource *res = win->res;
|
|
||||||
|
|
||||||
if (!res->flags)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
switch (resource_type(res)) {
|
|
||||||
case IORESOURCE_IO:
|
|
||||||
case IORESOURCE_MEM:
|
|
||||||
rcar_pcie_set_outbound(&host->pcie, i, win);
|
|
||||||
i++;
|
|
||||||
break;
|
|
||||||
case IORESOURCE_BUS:
|
|
||||||
host->root_bus_nr = res->start;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
|
|
||||||
pci_add_resource(resource, res);
|
|
||||||
}
|
|
||||||
|
|
||||||
return 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
static void rcar_pcie_force_speedup(struct rcar_pcie *pcie)
|
static void rcar_pcie_force_speedup(struct rcar_pcie *pcie)
|
||||||
{
|
{
|
||||||
struct device *dev = pcie->dev;
|
struct device *dev = pcie->dev;
|
||||||
|
@ -301,6 +259,7 @@ done:
|
||||||
static void rcar_pcie_hw_enable(struct rcar_pcie_host *host)
|
static void rcar_pcie_hw_enable(struct rcar_pcie_host *host)
|
||||||
{
|
{
|
||||||
struct rcar_pcie *pcie = &host->pcie;
|
struct rcar_pcie *pcie = &host->pcie;
|
||||||
|
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(host);
|
||||||
struct resource_entry *win;
|
struct resource_entry *win;
|
||||||
LIST_HEAD(res);
|
LIST_HEAD(res);
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
@ -309,7 +268,7 @@ static void rcar_pcie_hw_enable(struct rcar_pcie_host *host)
|
||||||
rcar_pcie_force_speedup(pcie);
|
rcar_pcie_force_speedup(pcie);
|
||||||
|
|
||||||
/* Setup PCI resources */
|
/* Setup PCI resources */
|
||||||
resource_list_for_each_entry(win, &host->resources) {
|
resource_list_for_each_entry(win, &bridge->windows) {
|
||||||
struct resource *res = win->res;
|
struct resource *res = win->res;
|
||||||
|
|
||||||
if (!res->flags)
|
if (!res->flags)
|
||||||
|
@ -328,42 +287,17 @@ static void rcar_pcie_hw_enable(struct rcar_pcie_host *host)
|
||||||
static int rcar_pcie_enable(struct rcar_pcie_host *host)
|
static int rcar_pcie_enable(struct rcar_pcie_host *host)
|
||||||
{
|
{
|
||||||
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(host);
|
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(host);
|
||||||
struct rcar_pcie *pcie = &host->pcie;
|
|
||||||
struct device *dev = pcie->dev;
|
|
||||||
struct pci_bus *bus, *child;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
/* Try setting 5 GT/s link speed */
|
rcar_pcie_hw_enable(host);
|
||||||
rcar_pcie_force_speedup(pcie);
|
|
||||||
|
|
||||||
rcar_pcie_setup(&bridge->windows, host);
|
|
||||||
|
|
||||||
pci_add_flags(PCI_REASSIGN_ALL_BUS);
|
pci_add_flags(PCI_REASSIGN_ALL_BUS);
|
||||||
|
|
||||||
bridge->dev.parent = dev;
|
|
||||||
bridge->sysdata = host;
|
bridge->sysdata = host;
|
||||||
bridge->busnr = host->root_bus_nr;
|
|
||||||
bridge->ops = &rcar_pcie_ops;
|
bridge->ops = &rcar_pcie_ops;
|
||||||
bridge->map_irq = of_irq_parse_and_map_pci;
|
|
||||||
bridge->swizzle_irq = pci_common_swizzle;
|
|
||||||
if (IS_ENABLED(CONFIG_PCI_MSI))
|
if (IS_ENABLED(CONFIG_PCI_MSI))
|
||||||
bridge->msi = &host->msi.chip;
|
bridge->msi = &host->msi.chip;
|
||||||
|
|
||||||
ret = pci_scan_root_bus_bridge(bridge);
|
return pci_host_probe(bridge);
|
||||||
if (ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
bus = bridge->bus;
|
|
||||||
|
|
||||||
pci_bus_size_bridges(bus);
|
|
||||||
pci_bus_assign_resources(bus);
|
|
||||||
|
|
||||||
list_for_each_entry(child, &bus->children, node)
|
|
||||||
pcie_bus_configure_settings(child);
|
|
||||||
|
|
||||||
pci_bus_add_devices(bus);
|
|
||||||
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static int phy_wait_for_ack(struct rcar_pcie *pcie)
|
static int phy_wait_for_ack(struct rcar_pcie *pcie)
|
||||||
|
@ -968,7 +902,7 @@ static int rcar_pcie_probe(struct platform_device *pdev)
|
||||||
int err;
|
int err;
|
||||||
struct pci_host_bridge *bridge;
|
struct pci_host_bridge *bridge;
|
||||||
|
|
||||||
bridge = pci_alloc_host_bridge(sizeof(*host));
|
bridge = devm_pci_alloc_host_bridge(dev, sizeof(*host));
|
||||||
if (!bridge)
|
if (!bridge)
|
||||||
return -ENOMEM;
|
return -ENOMEM;
|
||||||
|
|
||||||
|
@ -977,11 +911,6 @@ static int rcar_pcie_probe(struct platform_device *pdev)
|
||||||
pcie->dev = dev;
|
pcie->dev = dev;
|
||||||
platform_set_drvdata(pdev, host);
|
platform_set_drvdata(pdev, host);
|
||||||
|
|
||||||
err = pci_parse_request_of_pci_ranges(dev, &host->resources,
|
|
||||||
&bridge->dma_ranges, NULL);
|
|
||||||
if (err)
|
|
||||||
goto err_free_bridge;
|
|
||||||
|
|
||||||
pm_runtime_enable(pcie->dev);
|
pm_runtime_enable(pcie->dev);
|
||||||
err = pm_runtime_get_sync(pcie->dev);
|
err = pm_runtime_get_sync(pcie->dev);
|
||||||
if (err < 0) {
|
if (err < 0) {
|
||||||
|
@ -1058,10 +987,6 @@ err_unmap_msi_irqs:
|
||||||
err_pm_put:
|
err_pm_put:
|
||||||
pm_runtime_put(dev);
|
pm_runtime_put(dev);
|
||||||
pm_runtime_disable(dev);
|
pm_runtime_disable(dev);
|
||||||
pci_free_resource_list(&host->resources);
|
|
||||||
|
|
||||||
err_free_bridge:
|
|
||||||
pci_free_host_bridge(bridge);
|
|
||||||
|
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
|
@ -72,14 +72,14 @@ static int rockchip_pcie_valid_device(struct rockchip_pcie *rockchip,
|
||||||
struct pci_bus *bus, int dev)
|
struct pci_bus *bus, int dev)
|
||||||
{
|
{
|
||||||
/* access only one slot on each root port */
|
/* access only one slot on each root port */
|
||||||
if (bus->number == rockchip->root_bus_nr && dev > 0)
|
if (pci_is_root_bus(bus) && dev > 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
/*
|
/*
|
||||||
* do not read more than one device on the bus directly attached
|
* do not read more than one device on the bus directly attached
|
||||||
* to RC's downstream side.
|
* to RC's downstream side.
|
||||||
*/
|
*/
|
||||||
if (bus->primary == rockchip->root_bus_nr && dev > 0)
|
if (pci_is_root_bus(bus->parent) && dev > 0)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
@ -170,7 +170,7 @@ static int rockchip_pcie_rd_other_conf(struct rockchip_pcie *rockchip,
|
||||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bus->parent->number == rockchip->root_bus_nr)
|
if (pci_is_root_bus(bus->parent))
|
||||||
rockchip_pcie_cfg_configuration_accesses(rockchip,
|
rockchip_pcie_cfg_configuration_accesses(rockchip,
|
||||||
AXI_WRAPPER_TYPE0_CFG);
|
AXI_WRAPPER_TYPE0_CFG);
|
||||||
else
|
else
|
||||||
|
@ -201,7 +201,7 @@ static int rockchip_pcie_wr_other_conf(struct rockchip_pcie *rockchip,
|
||||||
if (!IS_ALIGNED(busdev, size))
|
if (!IS_ALIGNED(busdev, size))
|
||||||
return PCIBIOS_BAD_REGISTER_NUMBER;
|
return PCIBIOS_BAD_REGISTER_NUMBER;
|
||||||
|
|
||||||
if (bus->parent->number == rockchip->root_bus_nr)
|
if (pci_is_root_bus(bus->parent))
|
||||||
rockchip_pcie_cfg_configuration_accesses(rockchip,
|
rockchip_pcie_cfg_configuration_accesses(rockchip,
|
||||||
AXI_WRAPPER_TYPE0_CFG);
|
AXI_WRAPPER_TYPE0_CFG);
|
||||||
else
|
else
|
||||||
|
@ -230,7 +230,7 @@ static int rockchip_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (bus->number == rockchip->root_bus_nr)
|
if (pci_is_root_bus(bus))
|
||||||
return rockchip_pcie_rd_own_conf(rockchip, where, size, val);
|
return rockchip_pcie_rd_own_conf(rockchip, where, size, val);
|
||||||
|
|
||||||
return rockchip_pcie_rd_other_conf(rockchip, bus, devfn, where, size,
|
return rockchip_pcie_rd_other_conf(rockchip, bus, devfn, where, size,
|
||||||
|
@ -245,7 +245,7 @@ static int rockchip_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
|
||||||
if (!rockchip_pcie_valid_device(rockchip, bus, PCI_SLOT(devfn)))
|
if (!rockchip_pcie_valid_device(rockchip, bus, PCI_SLOT(devfn)))
|
||||||
return PCIBIOS_DEVICE_NOT_FOUND;
|
return PCIBIOS_DEVICE_NOT_FOUND;
|
||||||
|
|
||||||
if (bus->number == rockchip->root_bus_nr)
|
if (pci_is_root_bus(bus))
|
||||||
return rockchip_pcie_wr_own_conf(rockchip, where, size, val);
|
return rockchip_pcie_wr_own_conf(rockchip, where, size, val);
|
||||||
|
|
||||||
return rockchip_pcie_wr_other_conf(rockchip, bus, devfn, where, size,
|
return rockchip_pcie_wr_other_conf(rockchip, bus, devfn, where, size,
|
||||||
|
@ -949,9 +949,7 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct rockchip_pcie *rockchip;
|
struct rockchip_pcie *rockchip;
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct pci_bus *bus, *child;
|
|
||||||
struct pci_host_bridge *bridge;
|
struct pci_host_bridge *bridge;
|
||||||
struct resource *bus_res;
|
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
if (!dev->of_node)
|
if (!dev->of_node)
|
||||||
|
@ -991,13 +989,6 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto err_deinit_port;
|
goto err_deinit_port;
|
||||||
|
|
||||||
err = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
|
|
||||||
&bridge->dma_ranges, &bus_res);
|
|
||||||
if (err)
|
|
||||||
goto err_remove_irq_domain;
|
|
||||||
|
|
||||||
rockchip->root_bus_nr = bus_res->start;
|
|
||||||
|
|
||||||
err = rockchip_pcie_cfg_atu(rockchip);
|
err = rockchip_pcie_cfg_atu(rockchip);
|
||||||
if (err)
|
if (err)
|
||||||
goto err_remove_irq_domain;
|
goto err_remove_irq_domain;
|
||||||
|
@ -1008,27 +999,13 @@ static int rockchip_pcie_probe(struct platform_device *pdev)
|
||||||
goto err_remove_irq_domain;
|
goto err_remove_irq_domain;
|
||||||
}
|
}
|
||||||
|
|
||||||
bridge->dev.parent = dev;
|
|
||||||
bridge->sysdata = rockchip;
|
bridge->sysdata = rockchip;
|
||||||
bridge->busnr = 0;
|
|
||||||
bridge->ops = &rockchip_pcie_ops;
|
bridge->ops = &rockchip_pcie_ops;
|
||||||
bridge->map_irq = of_irq_parse_and_map_pci;
|
|
||||||
bridge->swizzle_irq = pci_common_swizzle;
|
|
||||||
|
|
||||||
err = pci_scan_root_bus_bridge(bridge);
|
err = pci_host_probe(bridge);
|
||||||
if (err < 0)
|
if (err < 0)
|
||||||
goto err_remove_irq_domain;
|
goto err_remove_irq_domain;
|
||||||
|
|
||||||
bus = bridge->bus;
|
|
||||||
|
|
||||||
rockchip->root_bus = bus;
|
|
||||||
|
|
||||||
pci_bus_size_bridges(bus);
|
|
||||||
pci_bus_assign_resources(bus);
|
|
||||||
list_for_each_entry(child, &bus->children, node)
|
|
||||||
pcie_bus_configure_settings(child);
|
|
||||||
|
|
||||||
pci_bus_add_devices(bus);
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
err_remove_irq_domain:
|
err_remove_irq_domain:
|
||||||
|
@ -1051,9 +1028,10 @@ static int rockchip_pcie_remove(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct rockchip_pcie *rockchip = dev_get_drvdata(dev);
|
struct rockchip_pcie *rockchip = dev_get_drvdata(dev);
|
||||||
|
struct pci_host_bridge *bridge = pci_host_bridge_from_priv(rockchip);
|
||||||
|
|
||||||
pci_stop_root_bus(rockchip->root_bus);
|
pci_stop_root_bus(bridge->bus);
|
||||||
pci_remove_root_bus(rockchip->root_bus);
|
pci_remove_root_bus(bridge->bus);
|
||||||
irq_domain_remove(rockchip->irq_domain);
|
irq_domain_remove(rockchip->irq_domain);
|
||||||
|
|
||||||
rockchip_pcie_deinit_phys(rockchip);
|
rockchip_pcie_deinit_phys(rockchip);
|
||||||
|
|
|
@ -45,9 +45,8 @@ int rockchip_pcie_parse_dt(struct rockchip_pcie *rockchip)
|
||||||
return -EINVAL;
|
return -EINVAL;
|
||||||
}
|
}
|
||||||
|
|
||||||
regs = platform_get_resource_byname(pdev, IORESOURCE_MEM,
|
rockchip->apb_base =
|
||||||
"apb-base");
|
devm_platform_ioremap_resource_byname(pdev, "apb-base");
|
||||||
rockchip->apb_base = devm_ioremap_resource(dev, regs);
|
|
||||||
if (IS_ERR(rockchip->apb_base))
|
if (IS_ERR(rockchip->apb_base))
|
||||||
return PTR_ERR(rockchip->apb_base);
|
return PTR_ERR(rockchip->apb_base);
|
||||||
|
|
||||||
|
|
|
@ -298,12 +298,10 @@ struct rockchip_pcie {
|
||||||
struct gpio_desc *ep_gpio;
|
struct gpio_desc *ep_gpio;
|
||||||
u32 lanes;
|
u32 lanes;
|
||||||
u8 lanes_map;
|
u8 lanes_map;
|
||||||
u8 root_bus_nr;
|
|
||||||
int link_gen;
|
int link_gen;
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct irq_domain *irq_domain;
|
struct irq_domain *irq_domain;
|
||||||
int offset;
|
int offset;
|
||||||
struct pci_bus *root_bus;
|
|
||||||
void __iomem *msg_region;
|
void __iomem *msg_region;
|
||||||
phys_addr_t msg_bus_addr;
|
phys_addr_t msg_bus_addr;
|
||||||
bool is_rc;
|
bool is_rc;
|
||||||
|
|
|
@ -539,7 +539,7 @@ static int xilinx_cpm_pcie_probe(struct platform_device *pdev)
|
||||||
struct xilinx_cpm_pcie_port *port;
|
struct xilinx_cpm_pcie_port *port;
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct pci_host_bridge *bridge;
|
struct pci_host_bridge *bridge;
|
||||||
struct resource *bus_range;
|
struct resource_entry *bus;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
bridge = devm_pci_alloc_host_bridge(dev, sizeof(*port));
|
bridge = devm_pci_alloc_host_bridge(dev, sizeof(*port));
|
||||||
|
@ -550,18 +550,15 @@ static int xilinx_cpm_pcie_probe(struct platform_device *pdev)
|
||||||
|
|
||||||
port->dev = dev;
|
port->dev = dev;
|
||||||
|
|
||||||
err = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
|
|
||||||
&bridge->dma_ranges, &bus_range);
|
|
||||||
if (err) {
|
|
||||||
dev_err(dev, "Getting bridge resources failed\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = xilinx_cpm_pcie_init_irq_domain(port);
|
err = xilinx_cpm_pcie_init_irq_domain(port);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = xilinx_cpm_pcie_parse_dt(port, bus_range);
|
bus = resource_list_first_type(&bridge->windows, IORESOURCE_BUS);
|
||||||
|
if (!bus)
|
||||||
|
return -ENODEV;
|
||||||
|
|
||||||
|
err = xilinx_cpm_pcie_parse_dt(port, bus->res);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(dev, "Parsing DT failed\n");
|
dev_err(dev, "Parsing DT failed\n");
|
||||||
goto err_parse_dt;
|
goto err_parse_dt;
|
||||||
|
|
|
@ -166,7 +166,6 @@ struct nwl_pcie {
|
||||||
int irq_misc;
|
int irq_misc;
|
||||||
u32 ecam_value;
|
u32 ecam_value;
|
||||||
u8 last_busno;
|
u8 last_busno;
|
||||||
u8 root_busno;
|
|
||||||
struct nwl_msi msi;
|
struct nwl_msi msi;
|
||||||
struct irq_domain *legacy_irq_domain;
|
struct irq_domain *legacy_irq_domain;
|
||||||
raw_spinlock_t leg_mask_lock;
|
raw_spinlock_t leg_mask_lock;
|
||||||
|
@ -217,13 +216,11 @@ static bool nwl_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
|
||||||
struct nwl_pcie *pcie = bus->sysdata;
|
struct nwl_pcie *pcie = bus->sysdata;
|
||||||
|
|
||||||
/* Check link before accessing downstream ports */
|
/* Check link before accessing downstream ports */
|
||||||
if (bus->number != pcie->root_busno) {
|
if (!pci_is_root_bus(bus)) {
|
||||||
if (!nwl_pcie_link_up(pcie))
|
if (!nwl_pcie_link_up(pcie))
|
||||||
return false;
|
return false;
|
||||||
}
|
} else if (devfn > 0)
|
||||||
|
/* Only one device down on each root port */
|
||||||
/* Only one device down on each root port */
|
|
||||||
if (bus->number == pcie->root_busno && devfn > 0)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
@ -817,8 +814,6 @@ static int nwl_pcie_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct nwl_pcie *pcie;
|
struct nwl_pcie *pcie;
|
||||||
struct pci_bus *bus;
|
|
||||||
struct pci_bus *child;
|
|
||||||
struct pci_host_bridge *bridge;
|
struct pci_host_bridge *bridge;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -843,25 +838,14 @@ static int nwl_pcie_probe(struct platform_device *pdev)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
|
|
||||||
&bridge->dma_ranges, NULL);
|
|
||||||
if (err) {
|
|
||||||
dev_err(dev, "Getting bridge resources failed\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
err = nwl_pcie_init_irq_domain(pcie);
|
err = nwl_pcie_init_irq_domain(pcie);
|
||||||
if (err) {
|
if (err) {
|
||||||
dev_err(dev, "Failed creating IRQ Domain\n");
|
dev_err(dev, "Failed creating IRQ Domain\n");
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
bridge->dev.parent = dev;
|
|
||||||
bridge->sysdata = pcie;
|
bridge->sysdata = pcie;
|
||||||
bridge->busnr = pcie->root_busno;
|
|
||||||
bridge->ops = &nwl_pcie_ops;
|
bridge->ops = &nwl_pcie_ops;
|
||||||
bridge->map_irq = of_irq_parse_and_map_pci;
|
|
||||||
bridge->swizzle_irq = pci_common_swizzle;
|
|
||||||
|
|
||||||
if (IS_ENABLED(CONFIG_PCI_MSI)) {
|
if (IS_ENABLED(CONFIG_PCI_MSI)) {
|
||||||
err = nwl_pcie_enable_msi(pcie);
|
err = nwl_pcie_enable_msi(pcie);
|
||||||
|
@ -871,17 +855,7 @@ static int nwl_pcie_probe(struct platform_device *pdev)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pci_scan_root_bus_bridge(bridge);
|
return pci_host_probe(bridge);
|
||||||
if (err)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
bus = bridge->bus;
|
|
||||||
|
|
||||||
pci_assign_unassigned_bus_resources(bus);
|
|
||||||
list_for_each_entry(child, &bus->children, node)
|
|
||||||
pcie_bus_configure_settings(child);
|
|
||||||
pci_bus_add_devices(bus);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static struct platform_driver nwl_pcie_driver = {
|
static struct platform_driver nwl_pcie_driver = {
|
||||||
|
|
|
@ -98,7 +98,6 @@
|
||||||
* @reg_base: IO Mapped Register Base
|
* @reg_base: IO Mapped Register Base
|
||||||
* @irq: Interrupt number
|
* @irq: Interrupt number
|
||||||
* @msi_pages: MSI pages
|
* @msi_pages: MSI pages
|
||||||
* @root_busno: Root Bus number
|
|
||||||
* @dev: Device pointer
|
* @dev: Device pointer
|
||||||
* @msi_domain: MSI IRQ domain pointer
|
* @msi_domain: MSI IRQ domain pointer
|
||||||
* @leg_domain: Legacy IRQ domain pointer
|
* @leg_domain: Legacy IRQ domain pointer
|
||||||
|
@ -108,7 +107,6 @@ struct xilinx_pcie_port {
|
||||||
void __iomem *reg_base;
|
void __iomem *reg_base;
|
||||||
u32 irq;
|
u32 irq;
|
||||||
unsigned long msi_pages;
|
unsigned long msi_pages;
|
||||||
u8 root_busno;
|
|
||||||
struct device *dev;
|
struct device *dev;
|
||||||
struct irq_domain *msi_domain;
|
struct irq_domain *msi_domain;
|
||||||
struct irq_domain *leg_domain;
|
struct irq_domain *leg_domain;
|
||||||
|
@ -162,14 +160,13 @@ static bool xilinx_pcie_valid_device(struct pci_bus *bus, unsigned int devfn)
|
||||||
struct xilinx_pcie_port *port = bus->sysdata;
|
struct xilinx_pcie_port *port = bus->sysdata;
|
||||||
|
|
||||||
/* Check if link is up when trying to access downstream ports */
|
/* Check if link is up when trying to access downstream ports */
|
||||||
if (bus->number != port->root_busno)
|
if (!pci_is_root_bus(bus)) {
|
||||||
if (!xilinx_pcie_link_up(port))
|
if (!xilinx_pcie_link_up(port))
|
||||||
return false;
|
return false;
|
||||||
|
} else if (devfn > 0) {
|
||||||
/* Only one device down on each root port */
|
/* Only one device down on each root port */
|
||||||
if (bus->number == port->root_busno && devfn > 0)
|
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -616,7 +613,6 @@ static int xilinx_pcie_probe(struct platform_device *pdev)
|
||||||
{
|
{
|
||||||
struct device *dev = &pdev->dev;
|
struct device *dev = &pdev->dev;
|
||||||
struct xilinx_pcie_port *port;
|
struct xilinx_pcie_port *port;
|
||||||
struct pci_bus *bus, *child;
|
|
||||||
struct pci_host_bridge *bridge;
|
struct pci_host_bridge *bridge;
|
||||||
int err;
|
int err;
|
||||||
|
|
||||||
|
@ -645,35 +641,14 @@ static int xilinx_pcie_probe(struct platform_device *pdev)
|
||||||
return err;
|
return err;
|
||||||
}
|
}
|
||||||
|
|
||||||
err = pci_parse_request_of_pci_ranges(dev, &bridge->windows,
|
|
||||||
&bridge->dma_ranges, NULL);
|
|
||||||
if (err) {
|
|
||||||
dev_err(dev, "Getting bridge resources failed\n");
|
|
||||||
return err;
|
|
||||||
}
|
|
||||||
|
|
||||||
bridge->dev.parent = dev;
|
|
||||||
bridge->sysdata = port;
|
bridge->sysdata = port;
|
||||||
bridge->busnr = 0;
|
|
||||||
bridge->ops = &xilinx_pcie_ops;
|
bridge->ops = &xilinx_pcie_ops;
|
||||||
bridge->map_irq = of_irq_parse_and_map_pci;
|
|
||||||
bridge->swizzle_irq = pci_common_swizzle;
|
|
||||||
|
|
||||||
#ifdef CONFIG_PCI_MSI
|
#ifdef CONFIG_PCI_MSI
|
||||||
xilinx_pcie_msi_chip.dev = dev;
|
xilinx_pcie_msi_chip.dev = dev;
|
||||||
bridge->msi = &xilinx_pcie_msi_chip;
|
bridge->msi = &xilinx_pcie_msi_chip;
|
||||||
#endif
|
#endif
|
||||||
err = pci_scan_root_bus_bridge(bridge);
|
return pci_host_probe(bridge);
|
||||||
if (err < 0)
|
|
||||||
return err;
|
|
||||||
|
|
||||||
bus = bridge->bus;
|
|
||||||
|
|
||||||
pci_assign_unassigned_bus_resources(bus);
|
|
||||||
list_for_each_entry(child, &bus->children, node)
|
|
||||||
pcie_bus_configure_settings(child);
|
|
||||||
pci_bus_add_devices(bus);
|
|
||||||
return 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static const struct of_device_id xilinx_pcie_of_match[] = {
|
static const struct of_device_id xilinx_pcie_of_match[] = {
|
||||||
|
|
|
@ -521,28 +521,26 @@ int of_irq_parse_and_map_pci(const struct pci_dev *dev, u8 slot, u8 pin)
|
||||||
EXPORT_SYMBOL_GPL(of_irq_parse_and_map_pci);
|
EXPORT_SYMBOL_GPL(of_irq_parse_and_map_pci);
|
||||||
#endif /* CONFIG_OF_IRQ */
|
#endif /* CONFIG_OF_IRQ */
|
||||||
|
|
||||||
int pci_parse_request_of_pci_ranges(struct device *dev,
|
static int pci_parse_request_of_pci_ranges(struct device *dev,
|
||||||
struct list_head *resources,
|
struct pci_host_bridge *bridge)
|
||||||
struct list_head *ib_resources,
|
|
||||||
struct resource **bus_range)
|
|
||||||
{
|
{
|
||||||
int err, res_valid = 0;
|
int err, res_valid = 0;
|
||||||
resource_size_t iobase;
|
resource_size_t iobase;
|
||||||
struct resource_entry *win, *tmp;
|
struct resource_entry *win, *tmp;
|
||||||
|
|
||||||
INIT_LIST_HEAD(resources);
|
INIT_LIST_HEAD(&bridge->windows);
|
||||||
if (ib_resources)
|
INIT_LIST_HEAD(&bridge->dma_ranges);
|
||||||
INIT_LIST_HEAD(ib_resources);
|
|
||||||
err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, resources,
|
err = devm_of_pci_get_host_bridge_resources(dev, 0, 0xff, &bridge->windows,
|
||||||
ib_resources, &iobase);
|
&bridge->dma_ranges, &iobase);
|
||||||
if (err)
|
if (err)
|
||||||
return err;
|
return err;
|
||||||
|
|
||||||
err = devm_request_pci_bus_resources(dev, resources);
|
err = devm_request_pci_bus_resources(dev, &bridge->windows);
|
||||||
if (err)
|
if (err)
|
||||||
goto out_release_res;
|
return err;
|
||||||
|
|
||||||
resource_list_for_each_entry_safe(win, tmp, resources) {
|
resource_list_for_each_entry_safe(win, tmp, &bridge->windows) {
|
||||||
struct resource *res = win->res;
|
struct resource *res = win->res;
|
||||||
|
|
||||||
switch (resource_type(res)) {
|
switch (resource_type(res)) {
|
||||||
|
@ -557,24 +555,25 @@ int pci_parse_request_of_pci_ranges(struct device *dev,
|
||||||
case IORESOURCE_MEM:
|
case IORESOURCE_MEM:
|
||||||
res_valid |= !(res->flags & IORESOURCE_PREFETCH);
|
res_valid |= !(res->flags & IORESOURCE_PREFETCH);
|
||||||
break;
|
break;
|
||||||
case IORESOURCE_BUS:
|
|
||||||
if (bus_range)
|
|
||||||
*bus_range = res;
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (res_valid)
|
if (!res_valid)
|
||||||
|
dev_warn(dev, "non-prefetchable memory resource required\n");
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge *bridge)
|
||||||
|
{
|
||||||
|
if (!dev->of_node)
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
dev_err(dev, "non-prefetchable memory resource required\n");
|
bridge->swizzle_irq = pci_common_swizzle;
|
||||||
err = -EINVAL;
|
bridge->map_irq = of_irq_parse_and_map_pci;
|
||||||
|
|
||||||
out_release_res:
|
return pci_parse_request_of_pci_ranges(dev, bridge);
|
||||||
pci_free_resource_list(resources);
|
|
||||||
return err;
|
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL_GPL(pci_parse_request_of_pci_ranges);
|
|
||||||
|
|
||||||
#endif /* CONFIG_PCI */
|
#endif /* CONFIG_PCI */
|
||||||
|
|
||||||
|
|
|
@ -628,6 +628,8 @@ void pci_release_of_node(struct pci_dev *dev);
|
||||||
void pci_set_bus_of_node(struct pci_bus *bus);
|
void pci_set_bus_of_node(struct pci_bus *bus);
|
||||||
void pci_release_bus_of_node(struct pci_bus *bus);
|
void pci_release_bus_of_node(struct pci_bus *bus);
|
||||||
|
|
||||||
|
int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge *bridge);
|
||||||
|
|
||||||
#else
|
#else
|
||||||
static inline int
|
static inline int
|
||||||
of_pci_parse_bus_range(struct device_node *node, struct resource *res)
|
of_pci_parse_bus_range(struct device_node *node, struct resource *res)
|
||||||
|
@ -651,6 +653,12 @@ static inline void pci_set_of_node(struct pci_dev *dev) { }
|
||||||
static inline void pci_release_of_node(struct pci_dev *dev) { }
|
static inline void pci_release_of_node(struct pci_dev *dev) { }
|
||||||
static inline void pci_set_bus_of_node(struct pci_bus *bus) { }
|
static inline void pci_set_bus_of_node(struct pci_bus *bus) { }
|
||||||
static inline void pci_release_bus_of_node(struct pci_bus *bus) { }
|
static inline void pci_release_bus_of_node(struct pci_bus *bus) { }
|
||||||
|
|
||||||
|
static inline int devm_of_pci_bridge_init(struct device *dev, struct pci_host_bridge *bridge)
|
||||||
|
{
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
#endif /* CONFIG_OF */
|
#endif /* CONFIG_OF */
|
||||||
|
|
||||||
#ifdef CONFIG_PCIEAER
|
#ifdef CONFIG_PCIEAER
|
||||||
|
|
|
@ -628,11 +628,17 @@ struct pci_host_bridge *devm_pci_alloc_host_bridge(struct device *dev,
|
||||||
if (!bridge)
|
if (!bridge)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
bridge->dev.parent = dev;
|
||||||
|
|
||||||
ret = devm_add_action_or_reset(dev, devm_pci_alloc_host_bridge_release,
|
ret = devm_add_action_or_reset(dev, devm_pci_alloc_host_bridge_release,
|
||||||
bridge);
|
bridge);
|
||||||
if (ret)
|
if (ret)
|
||||||
return NULL;
|
return NULL;
|
||||||
|
|
||||||
|
ret = devm_of_pci_bridge_init(dev, bridge);
|
||||||
|
if (ret)
|
||||||
|
return NULL;
|
||||||
|
|
||||||
return bridge;
|
return bridge;
|
||||||
}
|
}
|
||||||
EXPORT_SYMBOL(devm_pci_alloc_host_bridge);
|
EXPORT_SYMBOL(devm_pci_alloc_host_bridge);
|
||||||
|
@ -3086,6 +3092,7 @@ int pci_scan_root_bus_bridge(struct pci_host_bridge *bridge)
|
||||||
|
|
||||||
resource_list_for_each_entry(window, &bridge->windows)
|
resource_list_for_each_entry(window, &bridge->windows)
|
||||||
if (window->res->flags & IORESOURCE_BUS) {
|
if (window->res->flags & IORESOURCE_BUS) {
|
||||||
|
bridge->busnr = window->res->start;
|
||||||
found = true;
|
found = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
|
@ -2303,10 +2303,6 @@ int pci_vpd_find_info_keyword(const u8 *buf, unsigned int off,
|
||||||
struct device_node;
|
struct device_node;
|
||||||
struct irq_domain;
|
struct irq_domain;
|
||||||
struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus);
|
struct irq_domain *pci_host_bridge_of_msi_domain(struct pci_bus *bus);
|
||||||
int pci_parse_request_of_pci_ranges(struct device *dev,
|
|
||||||
struct list_head *resources,
|
|
||||||
struct list_head *ib_resources,
|
|
||||||
struct resource **bus_range);
|
|
||||||
|
|
||||||
/* Arch may override this (weak) */
|
/* Arch may override this (weak) */
|
||||||
struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus);
|
struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus);
|
||||||
|
@ -2314,14 +2310,6 @@ struct device_node *pcibios_get_phb_of_node(struct pci_bus *bus);
|
||||||
#else /* CONFIG_OF */
|
#else /* CONFIG_OF */
|
||||||
static inline struct irq_domain *
|
static inline struct irq_domain *
|
||||||
pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
|
pci_host_bridge_of_msi_domain(struct pci_bus *bus) { return NULL; }
|
||||||
static inline int
|
|
||||||
pci_parse_request_of_pci_ranges(struct device *dev,
|
|
||||||
struct list_head *resources,
|
|
||||||
struct list_head *ib_resources,
|
|
||||||
struct resource **bus_range)
|
|
||||||
{
|
|
||||||
return -EINVAL;
|
|
||||||
}
|
|
||||||
#endif /* CONFIG_OF */
|
#endif /* CONFIG_OF */
|
||||||
|
|
||||||
static inline struct device_node *
|
static inline struct device_node *
|
||||||
|
|
Loading…
Add table
Reference in a new issue