diff mbox

[v7,3/6] PCI: designware: Add ARM64 support

Message ID 1439812554-180426-4-git-send-email-wangzhou1@hisilicon.com (mailing list archive)
State New, archived
Delegated to: Bjorn Helgaas
Headers show

Commit Message

Zhou Wang Aug. 17, 2015, 11:55 a.m. UTC
This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
move related operations to dw_pcie_host_init.

In past, we use:
pci_common_init_dev
	-> pcibios_init_hw
		-> hw->scan (dw_pcie_scan_bus)
to pass 0 to root_bus_nr in struct pcie_port. This patch set pp->root_bus_nr = 0
in each PCIe host driver which is based on pcie-designware.

This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
according to the suggestion for Gabriele[1]

Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
with untranslated address" based on 1/6 in this series. we delete *_mod_base in
pcie-designware. This was discussed in [2]

I have compiled the driver with multi_v7_defconfig. However, I don't have
ARM32 PCIe related board to do test. It will be appreciated if someone could
help to test it.

Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
Signed-off-by: Arnd Bergmann <arnd@arndb.de>
Tested-By: James Morse <james.morse@arm.com>

[1] http://www.spinics.net/lists/linux-pci/msg42194.html
[2] http://www.spinics.net/lists/arm-kernel/msg436779.html
---
 drivers/pci/host/pci-dra7xx.c      |  15 +--
 drivers/pci/host/pci-exynos.c      |   2 +-
 drivers/pci/host/pci-imx6.c        |   2 +-
 drivers/pci/host/pci-keystone-dw.c |   2 +-
 drivers/pci/host/pci-keystone.c    |   2 +-
 drivers/pci/host/pci-layerscape.c  |   2 +-
 drivers/pci/host/pcie-designware.c | 229 ++++++++++++-------------------------
 drivers/pci/host/pcie-designware.h |  14 +--
 drivers/pci/host/pcie-spear13xx.c  |   2 +-
 9 files changed, 95 insertions(+), 175 deletions(-)

Comments

Zhou Wang Aug. 19, 2015, 12:20 p.m. UTC | #1
Hi Pratyush and Jingoo,

what is your opinion about this patch? It will be very appreciated if you
could take a look at it.

Thanks,
Zhou

On 2015/8/17 19:55, Zhou Wang wrote:
> This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
> function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
> move related operations to dw_pcie_host_init.
> 
> In past, we use:
> pci_common_init_dev
> 	-> pcibios_init_hw
> 		-> hw->scan (dw_pcie_scan_bus)
> to pass 0 to root_bus_nr in struct pcie_port. This patch set pp->root_bus_nr = 0
> in each PCIe host driver which is based on pcie-designware.
> 
> This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
> according to the suggestion for Gabriele[1]
> 
> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
> with untranslated address" based on 1/6 in this series. we delete *_mod_base in
> pcie-designware. This was discussed in [2]
> 
> I have compiled the driver with multi_v7_defconfig. However, I don't have
> ARM32 PCIe related board to do test. It will be appreciated if someone could
> help to test it.
> 
> Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
> Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Tested-By: James Morse <james.morse@arm.com>
> 
> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
> ---
>  drivers/pci/host/pci-dra7xx.c      |  15 +--
>  drivers/pci/host/pci-exynos.c      |   2 +-
>  drivers/pci/host/pci-imx6.c        |   2 +-
>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>  drivers/pci/host/pci-keystone.c    |   2 +-
>  drivers/pci/host/pci-layerscape.c  |   2 +-
>  drivers/pci/host/pcie-designware.c | 229 ++++++++++++-------------------------
>  drivers/pci/host/pcie-designware.h |  14 +--
>  drivers/pci/host/pcie-spear13xx.c  |   2 +-
>  9 files changed, 95 insertions(+), 175 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> index 18ae7ff..1268c69 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
>  {
>  	dw_pcie_setup_rc(pp);
>  
> -	if (pp->io_mod_base)
> -		pp->io_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->io_base)
> +		pp->io_base &= CPU_TO_BUS_ADDR;
>  
> -	if (pp->mem_mod_base)
> -		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->mem_base)
> +		pp->mem_base &= CPU_TO_BUS_ADDR;
>  
> -	if (pp->cfg0_mod_base) {
> -		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> -		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->cfg0_base) {
> +		pp->cfg0_base &= CPU_TO_BUS_ADDR;
> +		pp->cfg1_base &= CPU_TO_BUS_ADDR;
>  	}
>  
>  	dra7xx_pcie_establish_link(pp);
> @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
>  
>  	pp = &dra7xx->pp;
>  	pp->dev = dev;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &dra7xx_pcie_host_ops;
>  
>  	pp->irq = platform_get_irq(pdev, 1);
> diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
> index f9f468d..9771bb0 100644
> --- a/drivers/pci/host/pci-exynos.c
> +++ b/drivers/pci/host/pci-exynos.c
> @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp,
>  		}
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &exynos_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
> index 233a196..bec256c 100644
> --- a/drivers/pci/host/pci-imx6.c
> +++ b/drivers/pci/host/pci-imx6.c
> @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp,
>  		}
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &imx6_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
> index f34892e..b1e4135 100644
> --- a/drivers/pci/host/pci-keystone-dw.c
> +++ b/drivers/pci/host/pci-keystone-dw.c
> @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt)
>  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
>  {
>  	struct pcie_port *pp = &ks_pcie->pp;
> -	u32 start = pp->mem.start, end = pp->mem.end;
> +	u32 start = pp->mem->start, end = pp->mem->end;
>  	int i, tr_size;
>  
>  	/* Disable BARs for inbound access */
> diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c
> index 734da58..8113832 100644
> --- a/drivers/pci/host/pci-keystone.c
> +++ b/drivers/pci/host/pci-keystone.c
> @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie,
>  			return ret;
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &keystone_pcie_host_ops;
>  	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
>  	if (ret) {
> diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
> index b2328ea1..79ff08c 100644
> --- a/drivers/pci/host/pci-layerscape.c
> +++ b/drivers/pci/host/pci-layerscape.c
> @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)
>  	pp = &pcie->pp;
>  	pp->dev = pcie->dev;
>  	pp->dbi_base = pcie->dbi;
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &ls_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index c5d407c..e71a88e 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -11,6 +11,7 @@
>   * published by the Free Software Foundation.
>   */
>  
> +#include <linux/hardirq.h>
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/kernel.h>
> @@ -69,16 +70,7 @@
>  #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
>  #define PCIE_ATU_UPPER_TARGET		0x91C
>  
> -static struct hw_pci dw_pci;
> -
> -static unsigned long global_io_offset;
> -
> -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
> -{
> -	BUG_ON(!sys->private_data);
> -
> -	return sys->private_data;
> -}
> +static struct pci_ops dw_pcie_ops;
>  
>  int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
>  {
> @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
>  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
>  {
>  	int irq, pos0, i;
> -	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
> +	struct pcie_port *pp = desc->dev->bus->sysdata;
>  
>  	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
>  				       order_base_2(no_irqs));
> @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
>  {
>  	int irq, pos;
>  	struct msi_msg msg;
> -	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
> +	struct pcie_port *pp = pdev->bus->sysdata;
>  
>  	if (desc->msi_attrib.is_msix)
>  		return -EINVAL;
> @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
>  {
>  	struct irq_data *data = irq_get_irq_data(irq);
>  	struct msi_desc *msi = irq_data_get_msi(data);
> -	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
> +	struct pcie_port *pp = msi->dev->bus->sysdata;
>  
>  	clear_irq_range(pp, irq, 1, data->hwirq);
>  }
> @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  {
>  	struct device_node *np = pp->dev->of_node;
>  	struct platform_device *pdev = to_platform_device(pp->dev);
> -	struct of_pci_range range;
> -	struct of_pci_range_parser parser;
> +	struct pci_bus *bus;
>  	struct resource *cfg_res;
> -	u32 val, ns;
> -	const __be32 *addrp;
> -	int i, index, ret;
> -
> -	ns = of_n_size_cells(np);
> +	LIST_HEAD(res);
> +	u32 val;
> +	int i, ret;
> +	struct resource_entry *win;
>  
>  	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
>  	if (cfg_res) {
> @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  		pp->cfg1_size = resource_size(cfg_res)/2;
>  		pp->cfg0_base = cfg_res->start;
>  		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> -
> -		/* Find the untranslated configuration space address */
> -		index = of_property_match_string(np, "reg-names", "config");
> -		addrp = of_get_address(np, index, NULL, NULL);
> -		pp->cfg0_mod_base = of_read_number(addrp, ns);
> -		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
>  	} else {
>  		dev_err(pp->dev, "missing *config* reg space\n");
>  	}
>  
> -	if (of_pci_range_parser_init(&parser, np)) {
> -		dev_err(pp->dev, "missing ranges property\n");
> -		return -EINVAL;
> -	}
> +	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base);
> +	if (ret)
> +		return ret;
>  
>  	/* Get the I/O and memory ranges from DT */
> -	for_each_of_pci_range(&parser, &range) {
> -		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
> -
> -		if (restype == IORESOURCE_IO) {
> -			of_pci_range_to_resource(&range, np, &pp->io);
> -			pp->io.name = "I/O";
> -			pp->io.start = max_t(resource_size_t,
> -					     PCIBIOS_MIN_IO,
> -					     range.pci_addr + global_io_offset);
> -			pp->io.end = min_t(resource_size_t,
> -					   IO_SPACE_LIMIT,
> -					   range.pci_addr + range.size
> -					   + global_io_offset - 1);
> -			pp->io_size = resource_size(&pp->io);
> -			pp->io_bus_addr = range.pci_addr;
> -			pp->io_base = range.cpu_addr;
> -
> -			/* Find the untranslated IO space address */
> -			pp->io_mod_base = range.cpu_addr;
> -		}
> -		if (restype == IORESOURCE_MEM) {
> -			of_pci_range_to_resource(&range, np, &pp->mem);
> -			pp->mem.name = "MEM";
> -			pp->mem_size = resource_size(&pp->mem);
> -			pp->mem_bus_addr = range.pci_addr;
> -
> -			/* Find the untranslated MEM space address */
> -			pp->mem_mod_base = range.cpu_addr;
> -		}
> -		if (restype == 0) {
> -			of_pci_range_to_resource(&range, np, &pp->cfg);
> -			pp->cfg0_size = resource_size(&pp->cfg)/2;
> -			pp->cfg1_size = resource_size(&pp->cfg)/2;
> -			pp->cfg0_base = pp->cfg.start;
> -			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> -
> -			/* Find the untranslated configuration space address */
> -			pp->cfg0_mod_base = range.cpu_addr;
> -			pp->cfg1_mod_base = pp->cfg0_mod_base +
> -					    pp->cfg0_size;
> +	resource_list_for_each_entry(win, &res) {
> +		switch (resource_type(win->res)) {
> +		case IORESOURCE_IO:
> +			pp->io = win->res;
> +			pp->io->name = "I/O";
> +			pp->io_size = resource_size(pp->io);
> +			pp->io_bus_addr = pp->io->start - win->offset;
> +			ret = pci_remap_iospace(pp->io, pp->io_base);
> +			if (ret) {
> +				dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
> +					 ret, pp->io);
> +				continue;
> +			}
> +			break;
> +		case IORESOURCE_MEM:
> +			pp->mem = win->res;
> +			pp->mem->name = "MEM";
> +			pp->mem_size = resource_size(pp->mem);
> +			pp->mem_bus_addr = pp->mem->start - win->offset;
> +			break;
> +		case 0:
> +			pp->cfg = win->res;
> +			pp->cfg0_size = resource_size(pp->cfg)/2;
> +			pp->cfg1_size = resource_size(pp->cfg)/2;
> +			pp->cfg0_base = pp->cfg->start;
> +			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
> +			break;
> +		case IORESOURCE_BUS:
> +			pp->busn = win->res;
> +			break;
> +		default:
> +			continue;
>  		}
>  	}
>  
> -	ret = of_pci_parse_bus_range(np, &pp->busn);
> -	if (ret < 0) {
> -		pp->busn.name = np->name;
> -		pp->busn.start = 0;
> -		pp->busn.end = 0xff;
> -		pp->busn.flags = IORESOURCE_BUS;
> -		dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n",
> -			ret, &pp->busn);
> -	}
> -
>  	if (!pp->dbi_base) {
> -		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
> -					resource_size(&pp->cfg));
> +		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
> +					resource_size(pp->cfg));
>  		if (!pp->dbi_base) {
>  			dev_err(pp->dev, "error with ioremap\n");
>  			return -ENOMEM;
>  		}
>  	}
>  
> -	pp->mem_base = pp->mem.start;
> +	pp->mem_base = pp->mem->start;
>  
>  	if (!pp->va_cfg0_base) {
>  		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
> @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  
>  	if (!pp->ops->rd_other_conf)
>  		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> -					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
> +					  PCIE_ATU_TYPE_MEM, pp->mem_base,
>  					  pp->mem_bus_addr, pp->mem_size);
>  
>  	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> @@ -517,15 +482,29 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  	val |= PORT_LOGIC_SPEED_CHANGE;
>  	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
>  
> -#ifdef CONFIG_PCI_MSI
> +	bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
> +				  pp, &res);
> +	if (!bus)
> +		return -ENOMEM;
> +
> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> +	bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain);
> +#else
>  	dw_pcie_msi_chip.dev = pp->dev;
> -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> +	bus->msi = &dw_pcie_msi_chip;
>  #endif
>  
> -	dw_pci.nr_controllers = 1;
> -	dw_pci.private_data = (void **)&pp;
> +	pci_scan_child_bus(bus);
> +	if (pp->ops->scan_bus)
> +		pp->ops->scan_bus(pp);
> +
> +#ifdef CONFIG_ARM
> +	/* support old dtbs that incorrectly describe IRQs */
> +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +#endif
>  
> -	pci_common_init_dev(pp->dev, &dw_pci);
> +	pci_assign_unassigned_bus_resources(bus);
> +	pci_bus_add_devices(bus);
>  
>  	return 0;
>  }
> @@ -544,12 +523,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  
>  	if (bus->parent->number == pp->root_bus_nr) {
>  		type = PCIE_ATU_TYPE_CFG0;
> -		cpu_addr = pp->cfg0_mod_base;
> +		cpu_addr = pp->cfg0_base;
>  		cfg_size = pp->cfg0_size;
>  		va_cfg_base = pp->va_cfg0_base;
>  	} else {
>  		type = PCIE_ATU_TYPE_CFG1;
> -		cpu_addr = pp->cfg1_mod_base;
> +		cpu_addr = pp->cfg1_base;
>  		cfg_size = pp->cfg1_size;
>  		va_cfg_base = pp->va_cfg1_base;
>  	}
> @@ -559,7 +538,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  				  busdev, cfg_size);
>  	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
>  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +				  PCIE_ATU_TYPE_IO, pp->io_base,
>  				  pp->io_bus_addr, pp->io_size);
>  
>  	return ret;
> @@ -579,12 +558,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  
>  	if (bus->parent->number == pp->root_bus_nr) {
>  		type = PCIE_ATU_TYPE_CFG0;
> -		cpu_addr = pp->cfg0_mod_base;
> +		cpu_addr = pp->cfg0_base;
>  		cfg_size = pp->cfg0_size;
>  		va_cfg_base = pp->va_cfg0_base;
>  	} else {
>  		type = PCIE_ATU_TYPE_CFG1;
> -		cpu_addr = pp->cfg1_mod_base;
> +		cpu_addr = pp->cfg1_base;
>  		cfg_size = pp->cfg1_size;
>  		va_cfg_base = pp->va_cfg1_base;
>  	}
> @@ -594,7 +573,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  				  busdev, cfg_size);
>  	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
>  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +				  PCIE_ATU_TYPE_IO, pp->io_base,
>  				  pp->io_bus_addr, pp->io_size);
>  
>  	return ret;
> @@ -626,7 +605,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,
>  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>  			int size, u32 *val)
>  {
> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +	struct pcie_port *pp = bus->sysdata;
>  	int ret;
>  
>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
> @@ -650,7 +629,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
>  			int where, int size, u32 val)
>  {
> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +	struct pcie_port *pp = bus->sysdata;
>  	int ret;
>  
>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
> @@ -674,62 +653,6 @@ static struct pci_ops dw_pcie_ops = {
>  	.write = dw_pcie_wr_conf,
>  };
>  
> -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
> -{
> -	struct pcie_port *pp;
> -
> -	pp = sys_to_pcie(sys);
> -
> -	if (global_io_offset < SZ_1M && pp->io_size > 0) {
> -		sys->io_offset = global_io_offset - pp->io_bus_addr;
> -		pci_ioremap_io(global_io_offset, pp->io_base);
> -		global_io_offset += SZ_64K;
> -		pci_add_resource_offset(&sys->resources, &pp->io,
> -					sys->io_offset);
> -	}
> -
> -	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
> -	pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
> -	pci_add_resource(&sys->resources, &pp->busn);
> -
> -	return 1;
> -}
> -
> -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
> -{
> -	struct pci_bus *bus;
> -	struct pcie_port *pp = sys_to_pcie(sys);
> -
> -	pp->root_bus_nr = sys->busnr;
> -	bus = pci_scan_root_bus(pp->dev, sys->busnr,
> -				  &dw_pcie_ops, sys, &sys->resources);
> -	if (!bus)
> -		return NULL;
> -
> -	if (bus && pp->ops->scan_bus)
> -		pp->ops->scan_bus(pp);
> -
> -	return bus;
> -}
> -
> -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> -{
> -	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
> -	int irq;
> -
> -	irq = of_irq_parse_and_map_pci(dev, slot, pin);
> -	if (!irq)
> -		irq = pp->irq;
> -
> -	return irq;
> -}
> -
> -static struct hw_pci dw_pci = {
> -	.setup		= dw_pcie_setup,
> -	.scan		= dw_pcie_scan_bus,
> -	.map_irq	= dw_pcie_map_irq,
> -};
> -
>  void dw_pcie_setup_rc(struct pcie_port *pp)
>  {
>  	u32 val;
> diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
> index d0bbd27..264c969 100644
> --- a/drivers/pci/host/pcie-designware.h
> +++ b/drivers/pci/host/pcie-designware.h
> @@ -27,25 +27,21 @@ struct pcie_port {
>  	u8			root_bus_nr;
>  	void __iomem		*dbi_base;
>  	u64			cfg0_base;
> -	u64			cfg0_mod_base;
>  	void __iomem		*va_cfg0_base;
>  	u32			cfg0_size;
>  	u64			cfg1_base;
> -	u64			cfg1_mod_base;
>  	void __iomem		*va_cfg1_base;
>  	u32			cfg1_size;
> -	u64			io_base;
> -	u64			io_mod_base;
> +	resource_size_t		io_base;
>  	phys_addr_t		io_bus_addr;
>  	u32			io_size;
>  	u64			mem_base;
> -	u64			mem_mod_base;
>  	phys_addr_t		mem_bus_addr;
>  	u32			mem_size;
> -	struct resource		cfg;
> -	struct resource		io;
> -	struct resource		mem;
> -	struct resource		busn;
> +	struct resource		*cfg;
> +	struct resource		*io;
> +	struct resource		*mem;
> +	struct resource		*busn;
>  	int			irq;
>  	u32			lanes;
>  	struct pcie_host_ops	*ops;
> diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
> index c49fbdc..03eb204 100644
> --- a/drivers/pci/host/pcie-spear13xx.c
> +++ b/drivers/pci/host/pcie-spear13xx.c
> @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,
>  		return ret;
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &spear13xx_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> 


--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Lucas Stach Aug. 19, 2015, 12:54 p.m. UTC | #2
Am Montag, den 17.08.2015, 19:55 +0800 schrieb Zhou Wang:
> This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
> function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
> move related operations to dw_pcie_host_init.
> 
> In past, we use:
> pci_common_init_dev
> 	-> pcibios_init_hw
> 		-> hw->scan (dw_pcie_scan_bus)
> to pass 0 to root_bus_nr in struct pcie_port. This patch set pp->root_bus_nr = 0
> in each PCIe host driver which is based on pcie-designware.
> 
This is incorrect at least if there are 2 instances of DW PCIe host in
the same SoC without using PCI domains. In that the case the bus range
determines the range of valid bus numbers per instance and the first
number is the root bus. Please look at the "bus-range" DT property in
the DW PCIe bindings.

Also we should finally remove this root-bus setup from the glue drivers
altogether. It's something that entirely belongs into the DW core code.

Regards,
Lucas

> This patch also try to use of_pci_get_host_bridge_resources for ARM32 and ARM64
> according to the suggestion for Gabriele[1]
> 
> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware: Program ATU
> with untranslated address" based on 1/6 in this series. we delete *_mod_base in
> pcie-designware. This was discussed in [2]
> 
> I have compiled the driver with multi_v7_defconfig. However, I don't have
> ARM32 PCIe related board to do test. It will be appreciated if someone could
> help to test it.
> 
> Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
> Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Tested-By: James Morse <james.morse@arm.com>
> 
> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
> ---
>  drivers/pci/host/pci-dra7xx.c      |  15 +--
>  drivers/pci/host/pci-exynos.c      |   2 +-
>  drivers/pci/host/pci-imx6.c        |   2 +-
>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>  drivers/pci/host/pci-keystone.c    |   2 +-
>  drivers/pci/host/pci-layerscape.c  |   2 +-
>  drivers/pci/host/pcie-designware.c | 229 ++++++++++++-------------------------
>  drivers/pci/host/pcie-designware.h |  14 +--
>  drivers/pci/host/pcie-spear13xx.c  |   2 +-
>  9 files changed, 95 insertions(+), 175 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> index 18ae7ff..1268c69 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
>  {
>  	dw_pcie_setup_rc(pp);
>  
> -	if (pp->io_mod_base)
> -		pp->io_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->io_base)
> +		pp->io_base &= CPU_TO_BUS_ADDR;
>  
> -	if (pp->mem_mod_base)
> -		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->mem_base)
> +		pp->mem_base &= CPU_TO_BUS_ADDR;
>  
> -	if (pp->cfg0_mod_base) {
> -		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> -		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->cfg0_base) {
> +		pp->cfg0_base &= CPU_TO_BUS_ADDR;
> +		pp->cfg1_base &= CPU_TO_BUS_ADDR;
>  	}
>  
>  	dra7xx_pcie_establish_link(pp);
> @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
>  
>  	pp = &dra7xx->pp;
>  	pp->dev = dev;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &dra7xx_pcie_host_ops;
>  
>  	pp->irq = platform_get_irq(pdev, 1);
> diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
> index f9f468d..9771bb0 100644
> --- a/drivers/pci/host/pci-exynos.c
> +++ b/drivers/pci/host/pci-exynos.c
> @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp,
>  		}
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &exynos_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
> index 233a196..bec256c 100644
> --- a/drivers/pci/host/pci-imx6.c
> +++ b/drivers/pci/host/pci-imx6.c
> @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp,
>  		}
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &imx6_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
> index f34892e..b1e4135 100644
> --- a/drivers/pci/host/pci-keystone-dw.c
> +++ b/drivers/pci/host/pci-keystone-dw.c
> @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt)
>  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
>  {
>  	struct pcie_port *pp = &ks_pcie->pp;
> -	u32 start = pp->mem.start, end = pp->mem.end;
> +	u32 start = pp->mem->start, end = pp->mem->end;
>  	int i, tr_size;
>  
>  	/* Disable BARs for inbound access */
> diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c
> index 734da58..8113832 100644
> --- a/drivers/pci/host/pci-keystone.c
> +++ b/drivers/pci/host/pci-keystone.c
> @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie,
>  			return ret;
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &keystone_pcie_host_ops;
>  	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
>  	if (ret) {
> diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
> index b2328ea1..79ff08c 100644
> --- a/drivers/pci/host/pci-layerscape.c
> +++ b/drivers/pci/host/pci-layerscape.c
> @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)
>  	pp = &pcie->pp;
>  	pp->dev = pcie->dev;
>  	pp->dbi_base = pcie->dbi;
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &ls_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index c5d407c..e71a88e 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -11,6 +11,7 @@
>   * published by the Free Software Foundation.
>   */
>  
> +#include <linux/hardirq.h>
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/kernel.h>
> @@ -69,16 +70,7 @@
>  #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
>  #define PCIE_ATU_UPPER_TARGET		0x91C
>  
> -static struct hw_pci dw_pci;
> -
> -static unsigned long global_io_offset;
> -
> -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
> -{
> -	BUG_ON(!sys->private_data);
> -
> -	return sys->private_data;
> -}
> +static struct pci_ops dw_pcie_ops;
>  
>  int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
>  {
> @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
>  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
>  {
>  	int irq, pos0, i;
> -	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
> +	struct pcie_port *pp = desc->dev->bus->sysdata;
>  
>  	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
>  				       order_base_2(no_irqs));
> @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
>  {
>  	int irq, pos;
>  	struct msi_msg msg;
> -	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
> +	struct pcie_port *pp = pdev->bus->sysdata;
>  
>  	if (desc->msi_attrib.is_msix)
>  		return -EINVAL;
> @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
>  {
>  	struct irq_data *data = irq_get_irq_data(irq);
>  	struct msi_desc *msi = irq_data_get_msi(data);
> -	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
> +	struct pcie_port *pp = msi->dev->bus->sysdata;
>  
>  	clear_irq_range(pp, irq, 1, data->hwirq);
>  }
> @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  {
>  	struct device_node *np = pp->dev->of_node;
>  	struct platform_device *pdev = to_platform_device(pp->dev);
> -	struct of_pci_range range;
> -	struct of_pci_range_parser parser;
> +	struct pci_bus *bus;
>  	struct resource *cfg_res;
> -	u32 val, ns;
> -	const __be32 *addrp;
> -	int i, index, ret;
> -
> -	ns = of_n_size_cells(np);
> +	LIST_HEAD(res);
> +	u32 val;
> +	int i, ret;
> +	struct resource_entry *win;
>  
>  	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
>  	if (cfg_res) {
> @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  		pp->cfg1_size = resource_size(cfg_res)/2;
>  		pp->cfg0_base = cfg_res->start;
>  		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> -
> -		/* Find the untranslated configuration space address */
> -		index = of_property_match_string(np, "reg-names", "config");
> -		addrp = of_get_address(np, index, NULL, NULL);
> -		pp->cfg0_mod_base = of_read_number(addrp, ns);
> -		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
>  	} else {
>  		dev_err(pp->dev, "missing *config* reg space\n");
>  	}
>  
> -	if (of_pci_range_parser_init(&parser, np)) {
> -		dev_err(pp->dev, "missing ranges property\n");
> -		return -EINVAL;
> -	}
> +	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base);
> +	if (ret)
> +		return ret;
>  
>  	/* Get the I/O and memory ranges from DT */
> -	for_each_of_pci_range(&parser, &range) {
> -		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
> -
> -		if (restype == IORESOURCE_IO) {
> -			of_pci_range_to_resource(&range, np, &pp->io);
> -			pp->io.name = "I/O";
> -			pp->io.start = max_t(resource_size_t,
> -					     PCIBIOS_MIN_IO,
> -					     range.pci_addr + global_io_offset);
> -			pp->io.end = min_t(resource_size_t,
> -					   IO_SPACE_LIMIT,
> -					   range.pci_addr + range.size
> -					   + global_io_offset - 1);
> -			pp->io_size = resource_size(&pp->io);
> -			pp->io_bus_addr = range.pci_addr;
> -			pp->io_base = range.cpu_addr;
> -
> -			/* Find the untranslated IO space address */
> -			pp->io_mod_base = range.cpu_addr;
> -		}
> -		if (restype == IORESOURCE_MEM) {
> -			of_pci_range_to_resource(&range, np, &pp->mem);
> -			pp->mem.name = "MEM";
> -			pp->mem_size = resource_size(&pp->mem);
> -			pp->mem_bus_addr = range.pci_addr;
> -
> -			/* Find the untranslated MEM space address */
> -			pp->mem_mod_base = range.cpu_addr;
> -		}
> -		if (restype == 0) {
> -			of_pci_range_to_resource(&range, np, &pp->cfg);
> -			pp->cfg0_size = resource_size(&pp->cfg)/2;
> -			pp->cfg1_size = resource_size(&pp->cfg)/2;
> -			pp->cfg0_base = pp->cfg.start;
> -			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> -
> -			/* Find the untranslated configuration space address */
> -			pp->cfg0_mod_base = range.cpu_addr;
> -			pp->cfg1_mod_base = pp->cfg0_mod_base +
> -					    pp->cfg0_size;
> +	resource_list_for_each_entry(win, &res) {
> +		switch (resource_type(win->res)) {
> +		case IORESOURCE_IO:
> +			pp->io = win->res;
> +			pp->io->name = "I/O";
> +			pp->io_size = resource_size(pp->io);
> +			pp->io_bus_addr = pp->io->start - win->offset;
> +			ret = pci_remap_iospace(pp->io, pp->io_base);
> +			if (ret) {
> +				dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
> +					 ret, pp->io);
> +				continue;
> +			}
> +			break;
> +		case IORESOURCE_MEM:
> +			pp->mem = win->res;
> +			pp->mem->name = "MEM";
> +			pp->mem_size = resource_size(pp->mem);
> +			pp->mem_bus_addr = pp->mem->start - win->offset;
> +			break;
> +		case 0:
> +			pp->cfg = win->res;
> +			pp->cfg0_size = resource_size(pp->cfg)/2;
> +			pp->cfg1_size = resource_size(pp->cfg)/2;
> +			pp->cfg0_base = pp->cfg->start;
> +			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
> +			break;
> +		case IORESOURCE_BUS:
> +			pp->busn = win->res;
> +			break;
> +		default:
> +			continue;
>  		}
>  	}
>  
> -	ret = of_pci_parse_bus_range(np, &pp->busn);
> -	if (ret < 0) {
> -		pp->busn.name = np->name;
> -		pp->busn.start = 0;
> -		pp->busn.end = 0xff;
> -		pp->busn.flags = IORESOURCE_BUS;
> -		dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n",
> -			ret, &pp->busn);
> -	}
> -
>  	if (!pp->dbi_base) {
> -		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
> -					resource_size(&pp->cfg));
> +		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
> +					resource_size(pp->cfg));
>  		if (!pp->dbi_base) {
>  			dev_err(pp->dev, "error with ioremap\n");
>  			return -ENOMEM;
>  		}
>  	}
>  
> -	pp->mem_base = pp->mem.start;
> +	pp->mem_base = pp->mem->start;
>  
>  	if (!pp->va_cfg0_base) {
>  		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
> @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  
>  	if (!pp->ops->rd_other_conf)
>  		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> -					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
> +					  PCIE_ATU_TYPE_MEM, pp->mem_base,
>  					  pp->mem_bus_addr, pp->mem_size);
>  
>  	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> @@ -517,15 +482,29 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  	val |= PORT_LOGIC_SPEED_CHANGE;
>  	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
>  
> -#ifdef CONFIG_PCI_MSI
> +	bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
> +				  pp, &res);
> +	if (!bus)
> +		return -ENOMEM;
> +
> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> +	bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain);
> +#else
>  	dw_pcie_msi_chip.dev = pp->dev;
> -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> +	bus->msi = &dw_pcie_msi_chip;
>  #endif
>  
> -	dw_pci.nr_controllers = 1;
> -	dw_pci.private_data = (void **)&pp;
> +	pci_scan_child_bus(bus);
> +	if (pp->ops->scan_bus)
> +		pp->ops->scan_bus(pp);
> +
> +#ifdef CONFIG_ARM
> +	/* support old dtbs that incorrectly describe IRQs */
> +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +#endif
>  
> -	pci_common_init_dev(pp->dev, &dw_pci);
> +	pci_assign_unassigned_bus_resources(bus);
> +	pci_bus_add_devices(bus);
>  
>  	return 0;
>  }
> @@ -544,12 +523,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  
>  	if (bus->parent->number == pp->root_bus_nr) {
>  		type = PCIE_ATU_TYPE_CFG0;
> -		cpu_addr = pp->cfg0_mod_base;
> +		cpu_addr = pp->cfg0_base;
>  		cfg_size = pp->cfg0_size;
>  		va_cfg_base = pp->va_cfg0_base;
>  	} else {
>  		type = PCIE_ATU_TYPE_CFG1;
> -		cpu_addr = pp->cfg1_mod_base;
> +		cpu_addr = pp->cfg1_base;
>  		cfg_size = pp->cfg1_size;
>  		va_cfg_base = pp->va_cfg1_base;
>  	}
> @@ -559,7 +538,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  				  busdev, cfg_size);
>  	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
>  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +				  PCIE_ATU_TYPE_IO, pp->io_base,
>  				  pp->io_bus_addr, pp->io_size);
>  
>  	return ret;
> @@ -579,12 +558,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  
>  	if (bus->parent->number == pp->root_bus_nr) {
>  		type = PCIE_ATU_TYPE_CFG0;
> -		cpu_addr = pp->cfg0_mod_base;
> +		cpu_addr = pp->cfg0_base;
>  		cfg_size = pp->cfg0_size;
>  		va_cfg_base = pp->va_cfg0_base;
>  	} else {
>  		type = PCIE_ATU_TYPE_CFG1;
> -		cpu_addr = pp->cfg1_mod_base;
> +		cpu_addr = pp->cfg1_base;
>  		cfg_size = pp->cfg1_size;
>  		va_cfg_base = pp->va_cfg1_base;
>  	}
> @@ -594,7 +573,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  				  busdev, cfg_size);
>  	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
>  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +				  PCIE_ATU_TYPE_IO, pp->io_base,
>  				  pp->io_bus_addr, pp->io_size);
>  
>  	return ret;
> @@ -626,7 +605,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,
>  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>  			int size, u32 *val)
>  {
> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +	struct pcie_port *pp = bus->sysdata;
>  	int ret;
>  
>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
> @@ -650,7 +629,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
>  			int where, int size, u32 val)
>  {
> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +	struct pcie_port *pp = bus->sysdata;
>  	int ret;
>  
>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
> @@ -674,62 +653,6 @@ static struct pci_ops dw_pcie_ops = {
>  	.write = dw_pcie_wr_conf,
>  };
>  
> -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
> -{
> -	struct pcie_port *pp;
> -
> -	pp = sys_to_pcie(sys);
> -
> -	if (global_io_offset < SZ_1M && pp->io_size > 0) {
> -		sys->io_offset = global_io_offset - pp->io_bus_addr;
> -		pci_ioremap_io(global_io_offset, pp->io_base);
> -		global_io_offset += SZ_64K;
> -		pci_add_resource_offset(&sys->resources, &pp->io,
> -					sys->io_offset);
> -	}
> -
> -	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
> -	pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
> -	pci_add_resource(&sys->resources, &pp->busn);
> -
> -	return 1;
> -}
> -
> -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
> -{
> -	struct pci_bus *bus;
> -	struct pcie_port *pp = sys_to_pcie(sys);
> -
> -	pp->root_bus_nr = sys->busnr;
> -	bus = pci_scan_root_bus(pp->dev, sys->busnr,
> -				  &dw_pcie_ops, sys, &sys->resources);
> -	if (!bus)
> -		return NULL;
> -
> -	if (bus && pp->ops->scan_bus)
> -		pp->ops->scan_bus(pp);
> -
> -	return bus;
> -}
> -
> -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> -{
> -	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
> -	int irq;
> -
> -	irq = of_irq_parse_and_map_pci(dev, slot, pin);
> -	if (!irq)
> -		irq = pp->irq;
> -
> -	return irq;
> -}
> -
> -static struct hw_pci dw_pci = {
> -	.setup		= dw_pcie_setup,
> -	.scan		= dw_pcie_scan_bus,
> -	.map_irq	= dw_pcie_map_irq,
> -};
> -
>  void dw_pcie_setup_rc(struct pcie_port *pp)
>  {
>  	u32 val;
> diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
> index d0bbd27..264c969 100644
> --- a/drivers/pci/host/pcie-designware.h
> +++ b/drivers/pci/host/pcie-designware.h
> @@ -27,25 +27,21 @@ struct pcie_port {
>  	u8			root_bus_nr;
>  	void __iomem		*dbi_base;
>  	u64			cfg0_base;
> -	u64			cfg0_mod_base;
>  	void __iomem		*va_cfg0_base;
>  	u32			cfg0_size;
>  	u64			cfg1_base;
> -	u64			cfg1_mod_base;
>  	void __iomem		*va_cfg1_base;
>  	u32			cfg1_size;
> -	u64			io_base;
> -	u64			io_mod_base;
> +	resource_size_t		io_base;
>  	phys_addr_t		io_bus_addr;
>  	u32			io_size;
>  	u64			mem_base;
> -	u64			mem_mod_base;
>  	phys_addr_t		mem_bus_addr;
>  	u32			mem_size;
> -	struct resource		cfg;
> -	struct resource		io;
> -	struct resource		mem;
> -	struct resource		busn;
> +	struct resource		*cfg;
> +	struct resource		*io;
> +	struct resource		*mem;
> +	struct resource		*busn;
>  	int			irq;
>  	u32			lanes;
>  	struct pcie_host_ops	*ops;
> diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
> index c49fbdc..03eb204 100644
> --- a/drivers/pci/host/pcie-spear13xx.c
> +++ b/drivers/pci/host/pcie-spear13xx.c
> @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,
>  		return ret;
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = 0;
>  	pp->ops = &spear13xx_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
Gabriele Paoloni Aug. 19, 2015, 3:16 p.m. UTC | #3
SGkgTHVjYXMNCg0KSSBoYXZlIHJld3JpdHRlbiB0aGUgcGF0Y2ggdG8gdGFrZSBpbnRvIGFjY291
bnQgbXVsdGlwbGUgY29udHJvbGxlcnMuDQoNCkFzIHlvdSBjYW4gc2VlIG5vdyB0aGVyZSBpcyBh
IHN0YXRpYyB2YXIgaW4gZHdfcGNpZV9ob3N0X2luaXQoKSB0aGF0IHRyYWNrcw0KdGhlIGJ1cyBu
dW1iZXJzIHVzZWQuDQpEcml2ZXJzIHRoYXQgZG8gbm90IHNwZWNpZnkgdGhlIGJ1cyByYW5nZSBp
biB0aGUgRFRCIHNldCBwcC0+cm9vdF9idXNfbnIgPSBEV19ST09UX05SX1VOREVGSU5FRC4NCkRl
c2lnbndhcmUgd2lsbCBjaGVjayBpZiB0aGUgZmxhZyBpcyBzZXQgYW5kIHdpbGwgdXNlIHRoZSBh
dXRvbWF0aWMgYnVzIHJhbmdlDQphc3NpZ25tZW50Lg0KSW5zdGVhZCBpZiB0aGUgZHJpdmVyIGFz
c2lnbnMgcHAtPnJvb3RfYnVzX25yIGFjY29yZGluZyB0byB0aGUgZHRiLCBkZXNpZ253d2FyZQ0K
d2lsbCB1c2UgdGhlIHZhbHVlIHBhc3NlZCBpbiBieSB0aGUgZHJpdmVyLg0KQmVsb3cgdGhlIHJl
bGV2YW50IHNlY3Rpb246DQoNCg0KKwlzdGF0aWMgaW50IHJvb3RfYnVzX25yID0gMDsNCi4uLg0K
KwltdXRleF9sb2NrKCZyb290X2J1c19ucl9tdXgpOw0KKw0KKwlpZiAocHAtPnJvb3RfYnVzX25y
ICE9IERXX1JPT1RfTlJfVU5ERUZJTkVEKQ0KKwkJcm9vdF9idXNfbnIgPSBwcC0+cm9vdF9idXNf
bnI7DQorDQorCWJ1cyA9IHBjaV9jcmVhdGVfcm9vdF9idXMocHAtPmRldiwgcm9vdF9idXNfbnIs
ICZkd19wY2llX29wcywNCisJCQkgICAgICBwcCwgJnJlcyk7DQorCWlmICghYnVzKSB7DQorCQlt
dXRleF91bmxvY2soJnJvb3RfYnVzX25yX211eCk7DQorCQlyZXR1cm4gLUVOT01FTTsNCisJfQ0K
Kw0KKwlyb290X2J1c19uciArPSBidXMtPmJ1c25fcmVzLmVuZCArIDE7DQorCW11dGV4X3VubG9j
aygmcm9vdF9idXNfbnJfbXV4KTsNCg0KUGxlYXNlIGxldCBtZSBrbm93IHdoYXQgeW91IHRoaW5r
Li4uDQoNCk1hbnkgVGhhbmtzDQoNCkdhYg0KLS0tLS0tLS0tLQ0KDQpGcm9tOiBnYWJyaWVsZSBw
YW9sb25pIDxnYWJyaWVsZS5wYW9sb25pQGh1YXdlaS5jb20+DQoNClRoaXMgcGF0Y2ggdHJpZXMg
dG8gdW5pZnkgQVJNMzIgYW5kIEFSTTY0IFBDSWUgaW4gZGVzaWdud2FyZSBkcml2ZXIuIERlbGV0
ZQ0KZnVuY3Rpb24gZHdfcGNpZV9zZXR1cCwgZHdfcGNpZV9zY2FuX2J1cywgZHdfcGNpZV9tYXBf
aXJxIGFuZCBzdHJ1Y3QgaHdfcGNpLA0KbW92ZSByZWxhdGVkIG9wZXJhdGlvbnMgdG8gZHdfcGNp
ZV9ob3N0X2luaXQuDQpBbHNvIHNldCBwcC0+cm9vdF9idXNfbnIgPSBEV19ST09UX05SX1VOREVG
SU5FRCBpbiBhbGwgdGhlIGRyaXZlcnMgdGhhdA0KYXJlIGJhc2VkIG9uIGRlc2lnbndhcmUgdG8g
ZmxhZyB0aGF0IHRoZSBkcml2ZXJzIGRvIG5vdCByZWFkIHRoZSBidXMNCnJhbmdlcyBmcm9tIERU
Lg0KVGhpcyBwYXRjaCBhbHNvIGFkZHMgaGFuZGxpbmcgb2YgbXVsdGlwbGUgUENJIGRvbWFpbnMg
aW4gZGVzaWdud2FyZS4NCmlmIHRoZSBQQ0kgaG9zdCBicmlkZ2UgZHJpdmVyIGRvZXMgbm90IHNw
ZWNpZnkgYSByb290IGJ1cyBudW1iZXIsIGluIGNhc2UNCm9mIG11bHRpcGxlIGRvbWFpbnMsIGRl
c2lnbndhcmUgd2lsbCBhdXRvbWF0aWxsYXkgc2V0IHRoZSBuZXh0IGRvbWFpbiByb290DQpidXMg
bnVtYmVyIHRvIHRoZSBsYXN0IGJ1cyBudW1iZXIgdXNlZCBpbiB0aGUgbGFzdCBkb21haW4gKyAx
Lg0KDQpUaGlzIHBhdGNoIGFsc28gdHJ5IHRvIHVzZSBvZl9wY2lfZ2V0X2hvc3RfYnJpZGdlX3Jl
c291cmNlcyBmb3IgQVJNMzIgYW5kDQpBUk02NCBhY2NvcmRpbmcgdG8gdGhlIHN1Z2dlc3Rpb24g
Zm9yIEdhYnJpZWxlWzFdDQoNClRoaXMgcGF0Y2ggaXMgYmFzZWQgb24gR2FicmllbGUncyBwYXRj
aCBhYm91dCBvZl9wY2lfcmFuZ2UgZml4WzJdDQoNCkZpbmFsbHkgdGhpcyBwYXRjaCByZXZlcnRz
IGNvbW1pdCBmNGM1NWM1YTNmN2YgIlBDSTogZGVzaWdud2FyZToNClByb2dyYW0gQVRVIHdpdGgg
dW50cmFuc2xhdGVkIGFkZHJlc3MiLiBUaGlzIHdhcyBkaXNjdXNzZWQgaW4gWzNdDQoNCkkgaGF2
ZSBjb21waWxlZCB0aGUgZHJpdmVyIHdpdGggbXVsdGlfdjdfZGVmY29uZmlnLiBIb3dldmVyLCBJ
IGRvbid0IGhhdmUNCkFSTTMyIFBDSWUgcmVsYXRlZCBib2FyZCB0byBkbyB0ZXN0LiBJdCB3aWxs
IGJlIGFwcHJlY2lhdGVkIGlmIHNvbWVvbmUgY291bGQNCmhlbHAgdG8gdGVzdCBpdC4NCg0KU2ln
bmVkLW9mZi1ieTogWmhvdSBXYW5nIDx3YW5nemhvdTFAaGlzaWxpY29uLmNvbT4NClNpZ25lZC1v
ZmYtYnk6IEFybmQgQmVyZ21hbm4gPGFybmRAYXJuZGIuZGU+DQpTaWduZWQtb2ZmLWJ5OiBHYWJy
aWVsZSBQYW9sb25pIDxnYWJyaWVsZS5wYW9sb25pQGh1YXdlaS5jb20+DQoNClsxXSBodHRwOi8v
d3d3LnNwaW5pY3MubmV0L2xpc3RzL2xpbnV4LXBjaS9tc2c0MjE5NC5odG1sDQpbMl0gaHR0cHM6
Ly9wYXRjaHdvcmsub3psYWJzLm9yZy9wYXRjaC80OTUwMTgvDQpbM10gaHR0cDovL3d3dy5zcGlu
aWNzLm5ldC9saXN0cy9hcm0ta2VybmVsL21zZzQzNjc3OS5odG1sDQotLS0NCiBkcml2ZXJzL3Bj
aS9ob3N0L3BjaS1kcmE3eHguYyAgICAgIHwgIDE1ICstLQ0KIGRyaXZlcnMvcGNpL2hvc3QvcGNp
LWV4eW5vcy5jICAgICAgfCAgIDIgKy0NCiBkcml2ZXJzL3BjaS9ob3N0L3BjaS1pbXg2LmMgICAg
ICAgIHwgICAyICstDQogZHJpdmVycy9wY2kvaG9zdC9wY2kta2V5c3RvbmUtZHcuYyB8ICAgMiAr
LQ0KIGRyaXZlcnMvcGNpL2hvc3QvcGNpLWtleXN0b25lLmMgICAgfCAgIDIgKy0NCiBkcml2ZXJz
L3BjaS9ob3N0L3BjaS1sYXllcnNjYXBlLmMgIHwgICAyICstDQogZHJpdmVycy9wY2kvaG9zdC9w
Y2llLWRlc2lnbndhcmUuYyB8IDI0NyArKysrKysrKysrKysrKy0tLS0tLS0tLS0tLS0tLS0tLS0t
LS0tDQogZHJpdmVycy9wY2kvaG9zdC9wY2llLWRlc2lnbndhcmUuaCB8ICAxNSArLS0NCiBkcml2
ZXJzL3BjaS9ob3N0L3BjaWUtc3BlYXIxM3h4LmMgIHwgICAyICstDQogOSBmaWxlcyBjaGFuZ2Vk
LCAxMTAgaW5zZXJ0aW9ucygrKSwgMTc5IGRlbGV0aW9ucygtKQ0KDQpkaWZmIC0tZ2l0IGEvZHJp
dmVycy9wY2kvaG9zdC9wY2ktZHJhN3h4LmMgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaS1kcmE3eHgu
Yw0KaW5kZXggNTY3OGI1Ny4uOGQ1OThmYiAxMDA2NDQNCi0tLSBhL2RyaXZlcnMvcGNpL2hvc3Qv
cGNpLWRyYTd4eC5jDQorKysgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaS1kcmE3eHguYw0KQEAgLTE0
MSwxNSArMTQxLDE1IEBAIHN0YXRpYyB2b2lkIGRyYTd4eF9wY2llX2hvc3RfaW5pdChzdHJ1Y3Qg
cGNpZV9wb3J0ICpwcCkNCiB7DQogCWR3X3BjaWVfc2V0dXBfcmMocHApOw0KIA0KLQlpZiAocHAt
PmlvX21vZF9iYXNlKQ0KLQkJcHAtPmlvX21vZF9iYXNlICY9IENQVV9UT19CVVNfQUREUjsNCisJ
aWYgKHBwLT5pb19iYXNlKQ0KKwkJcHAtPmlvX2Jhc2UgJj0gQ1BVX1RPX0JVU19BRERSOw0KIA0K
LQlpZiAocHAtPm1lbV9tb2RfYmFzZSkNCi0JCXBwLT5tZW1fbW9kX2Jhc2UgJj0gQ1BVX1RPX0JV
U19BRERSOw0KKwlpZiAocHAtPm1lbV9iYXNlKQ0KKwkJcHAtPm1lbV9iYXNlICY9IENQVV9UT19C
VVNfQUREUjsNCiANCi0JaWYgKHBwLT5jZmcwX21vZF9iYXNlKSB7DQotCQlwcC0+Y2ZnMF9tb2Rf
YmFzZSAmPSBDUFVfVE9fQlVTX0FERFI7DQotCQlwcC0+Y2ZnMV9tb2RfYmFzZSAmPSBDUFVfVE9f
QlVTX0FERFI7DQorCWlmIChwcC0+Y2ZnMF9iYXNlKSB7DQorCQlwcC0+Y2ZnMF9iYXNlICY9IENQ
VV9UT19CVVNfQUREUjsNCisJCXBwLT5jZmcxX2Jhc2UgJj0gQ1BVX1RPX0JVU19BRERSOw0KIAl9
DQogDQogCWRyYTd4eF9wY2llX2VzdGFibGlzaF9saW5rKHBwKTsNCkBAIC0yODgsNiArMjg4LDcg
QEAgc3RhdGljIGludCBfX2luaXQgZHJhN3h4X2FkZF9wY2llX3BvcnQoc3RydWN0IGRyYTd4eF9w
Y2llICpkcmE3eHgsDQogDQogCXBwID0gJmRyYTd4eC0+cHA7DQogCXBwLT5kZXYgPSBkZXY7DQor
CXBwLT5yb290X2J1c19uciA9IERXX1JPT1RfTlJfVU5ERUZJTkVEOw0KIAlwcC0+b3BzID0gJmRy
YTd4eF9wY2llX2hvc3Rfb3BzOw0KIA0KIAlwcC0+aXJxID0gcGxhdGZvcm1fZ2V0X2lycShwZGV2
LCAxKTsNCmRpZmYgLS1naXQgYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1leHlub3MuYyBiL2RyaXZl
cnMvcGNpL2hvc3QvcGNpLWV4eW5vcy5jDQppbmRleCBmOWY0NjhkLi5lZDAzYThmIDEwMDY0NA0K
LS0tIGEvZHJpdmVycy9wY2kvaG9zdC9wY2ktZXh5bm9zLmMNCisrKyBiL2RyaXZlcnMvcGNpL2hv
c3QvcGNpLWV4eW5vcy5jDQpAQCAtNTMwLDcgKzUzMCw3IEBAIHN0YXRpYyBpbnQgX19pbml0IGV4
eW5vc19hZGRfcGNpZV9wb3J0KHN0cnVjdCBwY2llX3BvcnQgKnBwLA0KIAkJfQ0KIAl9DQogDQot
CXBwLT5yb290X2J1c19uciA9IC0xOw0KKwlwcC0+cm9vdF9idXNfbnIgPSBEV19ST09UX05SX1VO
REVGSU5FRDsNCiAJcHAtPm9wcyA9ICZleHlub3NfcGNpZV9ob3N0X29wczsNCiANCiAJcmV0ID0g
ZHdfcGNpZV9ob3N0X2luaXQocHApOw0KZGlmZiAtLWdpdCBhL2RyaXZlcnMvcGNpL2hvc3QvcGNp
LWlteDYuYyBiL2RyaXZlcnMvcGNpL2hvc3QvcGNpLWlteDYuYw0KaW5kZXggMjMzYTE5Ni4uMGVm
YWM4NSAxMDA2NDQNCi0tLSBhL2RyaXZlcnMvcGNpL2hvc3QvcGNpLWlteDYuYw0KKysrIGIvZHJp
dmVycy9wY2kvaG9zdC9wY2ktaW14Ni5jDQpAQCAtNTUxLDcgKzU1MSw3IEBAIHN0YXRpYyBpbnQg
X19pbml0IGlteDZfYWRkX3BjaWVfcG9ydChzdHJ1Y3QgcGNpZV9wb3J0ICpwcCwNCiAJCX0NCiAJ
fQ0KIA0KLQlwcC0+cm9vdF9idXNfbnIgPSAtMTsNCisJcHAtPnJvb3RfYnVzX25yID0gRFdfUk9P
VF9OUl9VTkRFRklORUQ7DQogCXBwLT5vcHMgPSAmaW14Nl9wY2llX2hvc3Rfb3BzOw0KIA0KIAly
ZXQgPSBkd19wY2llX2hvc3RfaW5pdChwcCk7DQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9wY2kvaG9z
dC9wY2kta2V5c3RvbmUtZHcuYyBiL2RyaXZlcnMvcGNpL2hvc3QvcGNpLWtleXN0b25lLWR3LmMN
CmluZGV4IGYzNDg5MmUuLmIxZTQxMzUgMTAwNjQ0DQotLS0gYS9kcml2ZXJzL3BjaS9ob3N0L3Bj
aS1rZXlzdG9uZS1kdy5jDQorKysgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaS1rZXlzdG9uZS1kdy5j
DQpAQCAtMzI3LDcgKzMyNyw3IEBAIHN0YXRpYyB2b2lkIGtzX2R3X3BjaWVfY2xlYXJfZGJpX21v
ZGUodm9pZCBfX2lvbWVtICpyZWdfdmlydCkNCiB2b2lkIGtzX2R3X3BjaWVfc2V0dXBfcmNfYXBw
X3JlZ3Moc3RydWN0IGtleXN0b25lX3BjaWUgKmtzX3BjaWUpDQogew0KIAlzdHJ1Y3QgcGNpZV9w
b3J0ICpwcCA9ICZrc19wY2llLT5wcDsNCi0JdTMyIHN0YXJ0ID0gcHAtPm1lbS5zdGFydCwgZW5k
ID0gcHAtPm1lbS5lbmQ7DQorCXUzMiBzdGFydCA9IHBwLT5tZW0tPnN0YXJ0LCBlbmQgPSBwcC0+
bWVtLT5lbmQ7DQogCWludCBpLCB0cl9zaXplOw0KIA0KIAkvKiBEaXNhYmxlIEJBUnMgZm9yIGlu
Ym91bmQgYWNjZXNzICovDQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9wY2kvaG9zdC9wY2kta2V5c3Rv
bmUuYyBiL2RyaXZlcnMvcGNpL2hvc3QvcGNpLWtleXN0b25lLmMNCmluZGV4IDczNGRhNTguLmI1
MjI5NTYgMTAwNjQ0DQotLS0gYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1rZXlzdG9uZS5jDQorKysg
Yi9kcml2ZXJzL3BjaS9ob3N0L3BjaS1rZXlzdG9uZS5jDQpAQCAtMzA5LDcgKzMwOSw3IEBAIHN0
YXRpYyBpbnQgX19pbml0IGtzX2FkZF9wY2llX3BvcnQoc3RydWN0IGtleXN0b25lX3BjaWUgKmtz
X3BjaWUsDQogCQkJcmV0dXJuIHJldDsNCiAJfQ0KIA0KLQlwcC0+cm9vdF9idXNfbnIgPSAtMTsN
CisJcHAtPnJvb3RfYnVzX25yID0gRFdfUk9PVF9OUl9VTkRFRklORUQ7DQogCXBwLT5vcHMgPSAm
a2V5c3RvbmVfcGNpZV9ob3N0X29wczsNCiAJcmV0ID0ga3NfZHdfcGNpZV9ob3N0X2luaXQoa3Nf
cGNpZSwga3NfcGNpZS0+bXNpX2ludGNfbnApOw0KIAlpZiAocmV0KSB7DQpkaWZmIC0tZ2l0IGEv
ZHJpdmVycy9wY2kvaG9zdC9wY2ktbGF5ZXJzY2FwZS5jIGIvZHJpdmVycy9wY2kvaG9zdC9wY2kt
bGF5ZXJzY2FwZS5jDQppbmRleCBiMjMyOGVhMS4uZGQ5MmZmYSAxMDA2NDQNCi0tLSBhL2RyaXZl
cnMvcGNpL2hvc3QvcGNpLWxheWVyc2NhcGUuYw0KKysrIGIvZHJpdmVycy9wY2kvaG9zdC9wY2kt
bGF5ZXJzY2FwZS5jDQpAQCAtMTA2LDcgKzEwNiw3IEBAIHN0YXRpYyBpbnQgbHNfYWRkX3BjaWVf
cG9ydChzdHJ1Y3QgbHNfcGNpZSAqcGNpZSkNCiAJcHAgPSAmcGNpZS0+cHA7DQogCXBwLT5kZXYg
PSBwY2llLT5kZXY7DQogCXBwLT5kYmlfYmFzZSA9IHBjaWUtPmRiaTsNCi0JcHAtPnJvb3RfYnVz
X25yID0gLTE7DQorCXBwLT5yb290X2J1c19uciA9IERXX1JPT1RfTlJfVU5ERUZJTkVEOw0KIAlw
cC0+b3BzID0gJmxzX3BjaWVfaG9zdF9vcHM7DQogDQogCXJldCA9IGR3X3BjaWVfaG9zdF9pbml0
KHBwKTsNCmRpZmYgLS1naXQgYS9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtZGVzaWdud2FyZS5jIGIv
ZHJpdmVycy9wY2kvaG9zdC9wY2llLWRlc2lnbndhcmUuYw0KaW5kZXggNTMwN2IzNS4uYmQyNjA2
YiAxMDA2NDQNCi0tLSBhL2RyaXZlcnMvcGNpL2hvc3QvcGNpZS1kZXNpZ253YXJlLmMNCisrKyBi
L2RyaXZlcnMvcGNpL2hvc3QvcGNpZS1kZXNpZ253YXJlLmMNCkBAIC0xMSw2ICsxMSw3IEBADQog
ICogcHVibGlzaGVkIGJ5IHRoZSBGcmVlIFNvZnR3YXJlIEZvdW5kYXRpb24uDQogICovDQogDQor
I2luY2x1ZGUgPGxpbnV4L2hhcmRpcnEuaD4NCiAjaW5jbHVkZSA8bGludXgvaXJxLmg+DQogI2lu
Y2x1ZGUgPGxpbnV4L2lycWRvbWFpbi5oPg0KICNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4NCkBA
IC02OSwxNiArNzAsOSBAQA0KICNkZWZpbmUgUENJRV9BVFVfRlVOQyh4KQkJKCgoeCkgJiAweDcp
IDw8IDE2KQ0KICNkZWZpbmUgUENJRV9BVFVfVVBQRVJfVEFSR0VUCQkweDkxQw0KIA0KLXN0YXRp
YyBzdHJ1Y3QgaHdfcGNpIGR3X3BjaTsNCitzdGF0aWMgc3RydWN0IHBjaV9vcHMgZHdfcGNpZV9v
cHM7DQogDQotc3RhdGljIHVuc2lnbmVkIGxvbmcgZ2xvYmFsX2lvX29mZnNldDsNCi0NCi1zdGF0
aWMgaW5saW5lIHN0cnVjdCBwY2llX3BvcnQgKnN5c190b19wY2llKHN0cnVjdCBwY2lfc3lzX2Rh
dGEgKnN5cykNCi17DQotCUJVR19PTighc3lzLT5wcml2YXRlX2RhdGEpOw0KLQ0KLQlyZXR1cm4g
c3lzLT5wcml2YXRlX2RhdGE7DQotfQ0KK0RFRklORV9NVVRFWChyb290X2J1c19ucl9tdXgpOw0K
IA0KIGludCBkd19wY2llX2NmZ19yZWFkKHZvaWQgX19pb21lbSAqYWRkciwgaW50IHdoZXJlLCBp
bnQgc2l6ZSwgdTMyICp2YWwpDQogew0KQEAgLTI1NSw3ICsyNDksNyBAQCBzdGF0aWMgdm9pZCBk
d19wY2llX21zaV9zZXRfaXJxKHN0cnVjdCBwY2llX3BvcnQgKnBwLCBpbnQgaXJxKQ0KIHN0YXRp
YyBpbnQgYXNzaWduX2lycShpbnQgbm9faXJxcywgc3RydWN0IG1zaV9kZXNjICpkZXNjLCBpbnQg
KnBvcykNCiB7DQogCWludCBpcnEsIHBvczAsIGk7DQotCXN0cnVjdCBwY2llX3BvcnQgKnBwID0g
c3lzX3RvX3BjaWUoZGVzYy0+ZGV2LT5idXMtPnN5c2RhdGEpOw0KKwlzdHJ1Y3QgcGNpZV9wb3J0
ICpwcCA9IGRlc2MtPmRldi0+YnVzLT5zeXNkYXRhOw0KIA0KIAlwb3MwID0gYml0bWFwX2ZpbmRf
ZnJlZV9yZWdpb24ocHAtPm1zaV9pcnFfaW5fdXNlLCBNQVhfTVNJX0lSUVMsDQogCQkJCSAgICAg
ICBvcmRlcl9iYXNlXzIobm9faXJxcykpOw0KQEAgLTI5OCw3ICsyOTIsNyBAQCBzdGF0aWMgaW50
IGR3X21zaV9zZXR1cF9pcnEoc3RydWN0IG1zaV9jb250cm9sbGVyICpjaGlwLCBzdHJ1Y3QgcGNp
X2RldiAqcGRldiwNCiB7DQogCWludCBpcnEsIHBvczsNCiAJc3RydWN0IG1zaV9tc2cgbXNnOw0K
LQlzdHJ1Y3QgcGNpZV9wb3J0ICpwcCA9IHN5c190b19wY2llKHBkZXYtPmJ1cy0+c3lzZGF0YSk7
DQorCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gcGRldi0+YnVzLT5zeXNkYXRhOw0KIA0KIAlpZiAo
ZGVzYy0+bXNpX2F0dHJpYi5pc19tc2l4KQ0KIAkJcmV0dXJuIC1FSU5WQUw7DQpAQCAtMzI3LDcg
KzMyMSw3IEBAIHN0YXRpYyB2b2lkIGR3X21zaV90ZWFyZG93bl9pcnEoc3RydWN0IG1zaV9jb250
cm9sbGVyICpjaGlwLCB1bnNpZ25lZCBpbnQgaXJxKQ0KIHsNCiAJc3RydWN0IGlycV9kYXRhICpk
YXRhID0gaXJxX2dldF9pcnFfZGF0YShpcnEpOw0KIAlzdHJ1Y3QgbXNpX2Rlc2MgKm1zaSA9IGly
cV9kYXRhX2dldF9tc2koZGF0YSk7DQotCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gc3lzX3RvX3Bj
aWUobXNpLT5kZXYtPmJ1cy0+c3lzZGF0YSk7DQorCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gbXNp
LT5kZXYtPmJ1cy0+c3lzZGF0YTsNCiANCiAJY2xlYXJfaXJxX3JhbmdlKHBwLCBpcnEsIDEsIGRh
dGEtPmh3aXJxKTsNCiB9DQpAQCAtMzU5LDIyICszNTMsMTcgQEAgc3RhdGljIGNvbnN0IHN0cnVj
dCBpcnFfZG9tYWluX29wcyBtc2lfZG9tYWluX29wcyA9IHsNCiAJLm1hcCA9IGR3X3BjaWVfbXNp
X21hcCwNCiB9Ow0KIA0KLWludCBkd19wY2llX2hvc3RfaW5pdChzdHJ1Y3QgcGNpZV9wb3J0ICpw
cCkNCitpbnQgX19pbml0IGR3X3BjaWVfaG9zdF9pbml0KHN0cnVjdCBwY2llX3BvcnQgKnBwKQ0K
IHsNCiAJc3RydWN0IGRldmljZV9ub2RlICpucCA9IHBwLT5kZXYtPm9mX25vZGU7DQogCXN0cnVj
dCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYgPSB0b19wbGF0Zm9ybV9kZXZpY2UocHAtPmRldik7DQot
CXN0cnVjdCBvZl9wY2lfcmFuZ2UgcmFuZ2U7DQotCXN0cnVjdCBvZl9wY2lfcmFuZ2VfcGFyc2Vy
IHBhcnNlcjsNCisJc3RydWN0IHBjaV9idXMgKmJ1czsNCiAJc3RydWN0IHJlc291cmNlICpjZmdf
cmVzOw0KLQl1MzIgdmFsLCBuYSwgbnM7DQotCWNvbnN0IF9fYmUzMiAqYWRkcnA7DQotCWludCBp
LCBpbmRleCwgcmV0Ow0KLQ0KLQkvKiBGaW5kIHRoZSBhZGRyZXNzIGNlbGwgc2l6ZSBhbmQgdGhl
IG51bWJlciBvZiBjZWxscyBpbiBvcmRlciB0byBnZXQNCi0JICogdGhlIHVudHJhbnNsYXRlZCBh
ZGRyZXNzLg0KLQkgKi8NCi0Jb2ZfcHJvcGVydHlfcmVhZF91MzIobnAsICIjYWRkcmVzcy1jZWxs
cyIsICZuYSk7DQotCW5zID0gb2Zfbl9zaXplX2NlbGxzKG5wKTsNCisJTElTVF9IRUFEKHJlcyk7
DQorCXUzMiB2YWw7DQorCWludCBpLCByZXQ7DQorCXN0cnVjdCByZXNvdXJjZV9lbnRyeSAqd2lu
Ow0KKwlzdGF0aWMgaW50IHJvb3RfYnVzX25yID0gMDsNCiANCiAJY2ZnX3JlcyA9IHBsYXRmb3Jt
X2dldF9yZXNvdXJjZV9ieW5hbWUocGRldiwgSU9SRVNPVVJDRV9NRU0sICJjb25maWciKTsNCiAJ
aWYgKGNmZ19yZXMpIHsNCkBAIC0zODIsODUgKzM3MSw2MCBAQCBpbnQgZHdfcGNpZV9ob3N0X2lu
aXQoc3RydWN0IHBjaWVfcG9ydCAqcHApDQogCQlwcC0+Y2ZnMV9zaXplID0gcmVzb3VyY2Vfc2l6
ZShjZmdfcmVzKS8yOw0KIAkJcHAtPmNmZzBfYmFzZSA9IGNmZ19yZXMtPnN0YXJ0Ow0KIAkJcHAt
PmNmZzFfYmFzZSA9IGNmZ19yZXMtPnN0YXJ0ICsgcHAtPmNmZzBfc2l6ZTsNCi0NCi0JCS8qIEZp
bmQgdGhlIHVudHJhbnNsYXRlZCBjb25maWd1cmF0aW9uIHNwYWNlIGFkZHJlc3MgKi8NCi0JCWlu
ZGV4ID0gb2ZfcHJvcGVydHlfbWF0Y2hfc3RyaW5nKG5wLCAicmVnLW5hbWVzIiwgImNvbmZpZyIp
Ow0KLQkJYWRkcnAgPSBvZl9nZXRfYWRkcmVzcyhucCwgaW5kZXgsIE5VTEwsIE5VTEwpOw0KLQkJ
cHAtPmNmZzBfbW9kX2Jhc2UgPSBvZl9yZWFkX251bWJlcihhZGRycCwgbnMpOw0KLQkJcHAtPmNm
ZzFfbW9kX2Jhc2UgPSBwcC0+Y2ZnMF9tb2RfYmFzZSArIHBwLT5jZmcwX3NpemU7DQogCX0gZWxz
ZSB7DQogCQlkZXZfZXJyKHBwLT5kZXYsICJtaXNzaW5nICpjb25maWcqIHJlZyBzcGFjZVxuIik7
DQogCX0NCiANCi0JaWYgKG9mX3BjaV9yYW5nZV9wYXJzZXJfaW5pdCgmcGFyc2VyLCBucCkpIHsN
Ci0JCWRldl9lcnIocHAtPmRldiwgIm1pc3NpbmcgcmFuZ2VzIHByb3BlcnR5XG4iKTsNCi0JCXJl
dHVybiAtRUlOVkFMOw0KLQl9DQorCXJldCA9IG9mX3BjaV9nZXRfaG9zdF9icmlkZ2VfcmVzb3Vy
Y2VzKG5wLCAwLCAweGZmLCAmcmVzLCAmcHAtPmlvX2Jhc2UpOw0KKwlpZiAocmV0KQ0KKwkJcmV0
dXJuIHJldDsNCiANCiAJLyogR2V0IHRoZSBJL08gYW5kIG1lbW9yeSByYW5nZXMgZnJvbSBEVCAq
Lw0KLQlmb3JfZWFjaF9vZl9wY2lfcmFuZ2UoJnBhcnNlciwgJnJhbmdlKSB7DQotCQl1bnNpZ25l
ZCBsb25nIHJlc3R5cGUgPSByYW5nZS5mbGFncyAmIElPUkVTT1VSQ0VfVFlQRV9CSVRTOw0KLQ0K
LQkJaWYgKHJlc3R5cGUgPT0gSU9SRVNPVVJDRV9JTykgew0KLQkJCW9mX3BjaV9yYW5nZV90b19y
ZXNvdXJjZSgmcmFuZ2UsIG5wLCAmcHAtPmlvKTsNCi0JCQlwcC0+aW8ubmFtZSA9ICJJL08iOw0K
LQkJCXBwLT5pby5zdGFydCA9IG1heF90KHJlc291cmNlX3NpemVfdCwNCi0JCQkJCSAgICAgUENJ
QklPU19NSU5fSU8sDQotCQkJCQkgICAgIHJhbmdlLnBjaV9hZGRyICsgZ2xvYmFsX2lvX29mZnNl
dCk7DQotCQkJcHAtPmlvLmVuZCA9IG1pbl90KHJlc291cmNlX3NpemVfdCwNCi0JCQkJCSAgIElP
X1NQQUNFX0xJTUlULA0KLQkJCQkJICAgcmFuZ2UucGNpX2FkZHIgKyByYW5nZS5zaXplDQotCQkJ
CQkgICArIGdsb2JhbF9pb19vZmZzZXQgLSAxKTsNCi0JCQlwcC0+aW9fc2l6ZSA9IHJlc291cmNl
X3NpemUoJnBwLT5pbyk7DQotCQkJcHAtPmlvX2J1c19hZGRyID0gcmFuZ2UucGNpX2FkZHI7DQot
CQkJcHAtPmlvX2Jhc2UgPSByYW5nZS5jcHVfYWRkcjsNCi0NCi0JCQkvKiBGaW5kIHRoZSB1bnRy
YW5zbGF0ZWQgSU8gc3BhY2UgYWRkcmVzcyAqLw0KLQkJCXBwLT5pb19tb2RfYmFzZSA9IHJhbmdl
LmNwdV9hZGRyOw0KLQkJfQ0KLQkJaWYgKHJlc3R5cGUgPT0gSU9SRVNPVVJDRV9NRU0pIHsNCi0J
CQlvZl9wY2lfcmFuZ2VfdG9fcmVzb3VyY2UoJnJhbmdlLCBucCwgJnBwLT5tZW0pOw0KLQkJCXBw
LT5tZW0ubmFtZSA9ICJNRU0iOw0KLQkJCXBwLT5tZW1fc2l6ZSA9IHJlc291cmNlX3NpemUoJnBw
LT5tZW0pOw0KLQkJCXBwLT5tZW1fYnVzX2FkZHIgPSByYW5nZS5wY2lfYWRkcjsNCi0NCi0JCQkv
KiBGaW5kIHRoZSB1bnRyYW5zbGF0ZWQgTUVNIHNwYWNlIGFkZHJlc3MgKi8NCi0JCQlwcC0+bWVt
X21vZF9iYXNlID0gcmFuZ2UuY3B1X2FkZHI7DQotCQl9DQotCQlpZiAocmVzdHlwZSA9PSAwKSB7
DQotCQkJb2ZfcGNpX3JhbmdlX3RvX3Jlc291cmNlKCZyYW5nZSwgbnAsICZwcC0+Y2ZnKTsNCi0J
CQlwcC0+Y2ZnMF9zaXplID0gcmVzb3VyY2Vfc2l6ZSgmcHAtPmNmZykvMjsNCi0JCQlwcC0+Y2Zn
MV9zaXplID0gcmVzb3VyY2Vfc2l6ZSgmcHAtPmNmZykvMjsNCi0JCQlwcC0+Y2ZnMF9iYXNlID0g
cHAtPmNmZy5zdGFydDsNCi0JCQlwcC0+Y2ZnMV9iYXNlID0gcHAtPmNmZy5zdGFydCArIHBwLT5j
ZmcwX3NpemU7DQotDQotCQkJLyogRmluZCB0aGUgdW50cmFuc2xhdGVkIGNvbmZpZ3VyYXRpb24g
c3BhY2UgYWRkcmVzcyAqLw0KLQkJCXBwLT5jZmcwX21vZF9iYXNlID0gcmFuZ2UuY3B1X2FkZHI7
DQotCQkJcHAtPmNmZzFfbW9kX2Jhc2UgPSBwcC0+Y2ZnMF9tb2RfYmFzZSArDQotCQkJCQkgICAg
cHAtPmNmZzBfc2l6ZTsNCisJcmVzb3VyY2VfbGlzdF9mb3JfZWFjaF9lbnRyeSh3aW4sICZyZXMp
IHsNCisJCXN3aXRjaCAocmVzb3VyY2VfdHlwZSh3aW4tPnJlcykpIHsNCisJCWNhc2UgSU9SRVNP
VVJDRV9JTzoNCisJCQlwcC0+aW8gPSB3aW4tPnJlczsNCisJCQlwcC0+aW8tPm5hbWUgPSAiSS9P
IjsNCisJCQlwcC0+aW9fc2l6ZSA9IHJlc291cmNlX3NpemUocHAtPmlvKTsNCisJCQlwcC0+aW9f
YnVzX2FkZHIgPSBwcC0+aW8tPnN0YXJ0IC0gd2luLT5vZmZzZXQ7DQorCQkJcmV0ID0gcGNpX3Jl
bWFwX2lvc3BhY2UocHAtPmlvLCBwcC0+aW9fYmFzZSk7DQorCQkJaWYgKHJldCkgew0KKwkJCQlk
ZXZfd2FybihwcC0+ZGV2LCAiZXJyb3IgJWQ6IGZhaWxlZCB0byBtYXAgcmVzb3VyY2UgJXBSXG4i
LA0KKwkJCQkJIHJldCwgcHAtPmlvKTsNCisJCQkJY29udGludWU7DQorCQkJfQ0KKwkJCWJyZWFr
Ow0KKwkJY2FzZSBJT1JFU09VUkNFX01FTToNCisJCQlwcC0+bWVtID0gd2luLT5yZXM7DQorCQkJ
cHAtPm1lbS0+bmFtZSA9ICJNRU0iOw0KKwkJCXBwLT5tZW1fc2l6ZSA9IHJlc291cmNlX3NpemUo
cHAtPm1lbSk7DQorCQkJcHAtPm1lbV9idXNfYWRkciA9IHBwLT5tZW0tPnN0YXJ0IC0gd2luLT5v
ZmZzZXQ7DQorCQkJYnJlYWs7DQorCQljYXNlIDA6DQorCQkJcHAtPmNmZyA9IHdpbi0+cmVzOw0K
KwkJCXBwLT5jZmcwX3NpemUgPSByZXNvdXJjZV9zaXplKHBwLT5jZmcpLzI7DQorCQkJcHAtPmNm
ZzFfc2l6ZSA9IHJlc291cmNlX3NpemUocHAtPmNmZykvMjsNCisJCQlwcC0+Y2ZnMF9iYXNlID0g
cHAtPmNmZy0+c3RhcnQ7DQorCQkJcHAtPmNmZzFfYmFzZSA9IHBwLT5jZmctPnN0YXJ0ICsgcHAt
PmNmZzBfc2l6ZTsNCisJCQlicmVhazsNCisJCWNhc2UgSU9SRVNPVVJDRV9CVVM6DQorCQkJcHAt
PmJ1c24gPSB3aW4tPnJlczsNCisJCQlicmVhazsNCisJCWRlZmF1bHQ6DQorCQkJY29udGludWU7
DQogCQl9DQogCX0NCiANCi0JcmV0ID0gb2ZfcGNpX3BhcnNlX2J1c19yYW5nZShucCwgJnBwLT5i
dXNuKTsNCi0JaWYgKHJldCA8IDApIHsNCi0JCXBwLT5idXNuLm5hbWUgPSBucC0+bmFtZTsNCi0J
CXBwLT5idXNuLnN0YXJ0ID0gMDsNCi0JCXBwLT5idXNuLmVuZCA9IDB4ZmY7DQotCQlwcC0+YnVz
bi5mbGFncyA9IElPUkVTT1VSQ0VfQlVTOw0KLQkJZGV2X2RiZyhwcC0+ZGV2LCAiZmFpbGVkIHRv
IHBhcnNlIGJ1cy1yYW5nZSBwcm9wZXJ0eTogJWQsIHVzaW5nIGRlZmF1bHQgJXBSXG4iLA0KLQkJ
CXJldCwgJnBwLT5idXNuKTsNCi0JfQ0KLQ0KIAlpZiAoIXBwLT5kYmlfYmFzZSkgew0KLQkJcHAt
PmRiaV9iYXNlID0gZGV2bV9pb3JlbWFwKHBwLT5kZXYsIHBwLT5jZmcuc3RhcnQsDQotCQkJCQly
ZXNvdXJjZV9zaXplKCZwcC0+Y2ZnKSk7DQorCQlwcC0+ZGJpX2Jhc2UgPSBkZXZtX2lvcmVtYXAo
cHAtPmRldiwgcHAtPmNmZy0+c3RhcnQsDQorCQkJCQlyZXNvdXJjZV9zaXplKHBwLT5jZmcpKTsN
CiAJCWlmICghcHAtPmRiaV9iYXNlKSB7DQogCQkJZGV2X2VycihwcC0+ZGV2LCAiZXJyb3Igd2l0
aCBpb3JlbWFwXG4iKTsNCiAJCQlyZXR1cm4gLUVOT01FTTsNCiAJCX0NCiAJfQ0KIA0KLQlwcC0+
bWVtX2Jhc2UgPSBwcC0+bWVtLnN0YXJ0Ow0KKwlwcC0+bWVtX2Jhc2UgPSBwcC0+bWVtLT5zdGFy
dDsNCiANCiAJaWYgKCFwcC0+dmFfY2ZnMF9iYXNlKSB7DQogCQlwcC0+dmFfY2ZnMF9iYXNlID0g
ZGV2bV9pb3JlbWFwKHBwLT5kZXYsIHBwLT5jZmcwX2Jhc2UsDQpAQCAtNTA5LDcgKzQ3Myw3IEBA
IGludCBkd19wY2llX2hvc3RfaW5pdChzdHJ1Y3QgcGNpZV9wb3J0ICpwcCkNCiANCiAJaWYgKCFw
cC0+b3BzLT5yZF9vdGhlcl9jb25mKQ0KIAkJZHdfcGNpZV9wcm9nX291dGJvdW5kX2F0dShwcCwg
UENJRV9BVFVfUkVHSU9OX0lOREVYMSwNCi0JCQkJCSAgUENJRV9BVFVfVFlQRV9NRU0sIHBwLT5t
ZW1fbW9kX2Jhc2UsDQorCQkJCQkgIFBDSUVfQVRVX1RZUEVfTUVNLCBwcC0+bWVtX2Jhc2UsDQog
CQkJCQkgIHBwLT5tZW1fYnVzX2FkZHIsIHBwLT5tZW1fc2l6ZSk7DQogDQogCWR3X3BjaWVfd3Jf
b3duX2NvbmYocHAsIFBDSV9CQVNFX0FERFJFU1NfMCwgNCwgMCk7DQpAQCAtNTIxLDE1ICs0ODUs
NDAgQEAgaW50IGR3X3BjaWVfaG9zdF9pbml0KHN0cnVjdCBwY2llX3BvcnQgKnBwKQ0KIAl2YWwg
fD0gUE9SVF9MT0dJQ19TUEVFRF9DSEFOR0U7DQogCWR3X3BjaWVfd3Jfb3duX2NvbmYocHAsIFBD
SUVfTElOS19XSURUSF9TUEVFRF9DT05UUk9MLCA0LCB2YWwpOw0KIA0KLSNpZmRlZiBDT05GSUdf
UENJX01TSQ0KIAlkd19wY2llX21zaV9jaGlwLmRldiA9IHBwLT5kZXY7DQotCWR3X3BjaS5tc2lf
Y3RybCA9ICZkd19wY2llX21zaV9jaGlwOw0KKw0KKwltdXRleF9sb2NrKCZyb290X2J1c19ucl9t
dXgpOw0KKw0KKwlpZiAocHAtPnJvb3RfYnVzX25yICE9IERXX1JPT1RfTlJfVU5ERUZJTkVEKQ0K
KwkJcm9vdF9idXNfbnIgPSBwcC0+cm9vdF9idXNfbnI7DQorDQorCWJ1cyA9IHBjaV9jcmVhdGVf
cm9vdF9idXMocHAtPmRldiwgcm9vdF9idXNfbnIsICZkd19wY2llX29wcywNCisJCQkgICAgICBw
cCwgJnJlcyk7DQorCWlmICghYnVzKSB7DQorCQltdXRleF91bmxvY2soJnJvb3RfYnVzX25yX211
eCk7DQorCQlyZXR1cm4gLUVOT01FTTsNCisJfQ0KKw0KKwlyb290X2J1c19uciArPSBidXMtPmJ1
c25fcmVzLmVuZCArIDE7DQorCW11dGV4X3VubG9jaygmcm9vdF9idXNfbnJfbXV4KTsNCisNCisj
aWZkZWYgQ09ORklHX0dFTkVSSUNfTVNJX0lSUV9ET01BSU4NCisJYnVzLT5tc2kgPSBjb250YWlu
ZXJfb2YoJnBwLT5pcnFfZG9tYWluLCBzdHJ1Y3QgbXNpX2NvbnRyb2xsZXIsIGRvbWFpbik7DQor
I2Vsc2UNCisJYnVzLT5tc2kgPSAmZHdfcGNpZV9tc2lfY2hpcDsNCiAjZW5kaWYNCiANCi0JZHdf
cGNpLm5yX2NvbnRyb2xsZXJzID0gMTsNCi0JZHdfcGNpLnByaXZhdGVfZGF0YSA9ICh2b2lkICoq
KSZwcDsNCisJcGNpX3NjYW5fY2hpbGRfYnVzKGJ1cyk7DQorCWlmIChwcC0+b3BzLT5zY2FuX2J1
cykNCisJCXBwLT5vcHMtPnNjYW5fYnVzKHBwKTsNCisNCisjaWZkZWYgQ09ORklHX0FSTQ0KKwkv
KiBzdXBwb3J0IG9sZCBkdGJzIHRoYXQgaW5jb3JyZWN0bHkgZGVzY3JpYmUgSVJRcyAqLw0KKwlw
Y2lfZml4dXBfaXJxcyhwY2lfY29tbW9uX3N3aXp6bGUsIG9mX2lycV9wYXJzZV9hbmRfbWFwX3Bj
aSk7DQorI2VuZGlmDQogDQotCXBjaV9jb21tb25faW5pdF9kZXYocHAtPmRldiwgJmR3X3BjaSk7
DQorCXBjaV9hc3NpZ25fdW5hc3NpZ25lZF9idXNfcmVzb3VyY2VzKGJ1cyk7DQorCXBjaV9idXNf
YWRkX2RldmljZXMoYnVzKTsNCiANCiAJcmV0dXJuIDA7DQogfQ0KQEAgLTU0OCwxMiArNTM3LDEy
IEBAIHN0YXRpYyBpbnQgZHdfcGNpZV9yZF9vdGhlcl9jb25mKHN0cnVjdCBwY2llX3BvcnQgKnBw
LCBzdHJ1Y3QgcGNpX2J1cyAqYnVzLA0KIA0KIAlpZiAoYnVzLT5wYXJlbnQtPm51bWJlciA9PSBw
cC0+cm9vdF9idXNfbnIpIHsNCiAJCXR5cGUgPSBQQ0lFX0FUVV9UWVBFX0NGRzA7DQotCQljcHVf
YWRkciA9IHBwLT5jZmcwX21vZF9iYXNlOw0KKwkJY3B1X2FkZHIgPSBwcC0+Y2ZnMF9iYXNlOw0K
IAkJY2ZnX3NpemUgPSBwcC0+Y2ZnMF9zaXplOw0KIAkJdmFfY2ZnX2Jhc2UgPSBwcC0+dmFfY2Zn
MF9iYXNlOw0KIAl9IGVsc2Ugew0KIAkJdHlwZSA9IFBDSUVfQVRVX1RZUEVfQ0ZHMTsNCi0JCWNw
dV9hZGRyID0gcHAtPmNmZzFfbW9kX2Jhc2U7DQorCQljcHVfYWRkciA9IHBwLT5jZmcxX2Jhc2U7
DQogCQljZmdfc2l6ZSA9IHBwLT5jZmcxX3NpemU7DQogCQl2YV9jZmdfYmFzZSA9IHBwLT52YV9j
ZmcxX2Jhc2U7DQogCX0NCkBAIC01NjMsNyArNTUyLDcgQEAgc3RhdGljIGludCBkd19wY2llX3Jk
X290aGVyX2NvbmYoc3RydWN0IHBjaWVfcG9ydCAqcHAsIHN0cnVjdCBwY2lfYnVzICpidXMsDQog
CQkJCSAgYnVzZGV2LCBjZmdfc2l6ZSk7DQogCXJldCA9IGR3X3BjaWVfY2ZnX3JlYWQodmFfY2Zn
X2Jhc2UgKyBhZGRyZXNzLCB3aGVyZSwgc2l6ZSwgdmFsKTsNCiAJZHdfcGNpZV9wcm9nX291dGJv
dW5kX2F0dShwcCwgUENJRV9BVFVfUkVHSU9OX0lOREVYMCwNCi0JCQkJICBQQ0lFX0FUVV9UWVBF
X0lPLCBwcC0+aW9fbW9kX2Jhc2UsDQorCQkJCSAgUENJRV9BVFVfVFlQRV9JTywgcHAtPmlvX2Jh
c2UsDQogCQkJCSAgcHAtPmlvX2J1c19hZGRyLCBwcC0+aW9fc2l6ZSk7DQogDQogCXJldHVybiBy
ZXQ7DQpAQCAtNTgzLDEyICs1NzIsMTIgQEAgc3RhdGljIGludCBkd19wY2llX3dyX290aGVyX2Nv
bmYoc3RydWN0IHBjaWVfcG9ydCAqcHAsIHN0cnVjdCBwY2lfYnVzICpidXMsDQogDQogCWlmIChi
dXMtPnBhcmVudC0+bnVtYmVyID09IHBwLT5yb290X2J1c19ucikgew0KIAkJdHlwZSA9IFBDSUVf
QVRVX1RZUEVfQ0ZHMDsNCi0JCWNwdV9hZGRyID0gcHAtPmNmZzBfbW9kX2Jhc2U7DQorCQljcHVf
YWRkciA9IHBwLT5jZmcwX2Jhc2U7DQogCQljZmdfc2l6ZSA9IHBwLT5jZmcwX3NpemU7DQogCQl2
YV9jZmdfYmFzZSA9IHBwLT52YV9jZmcwX2Jhc2U7DQogCX0gZWxzZSB7DQogCQl0eXBlID0gUENJ
RV9BVFVfVFlQRV9DRkcxOw0KLQkJY3B1X2FkZHIgPSBwcC0+Y2ZnMV9tb2RfYmFzZTsNCisJCWNw
dV9hZGRyID0gcHAtPmNmZzFfYmFzZTsNCiAJCWNmZ19zaXplID0gcHAtPmNmZzFfc2l6ZTsNCiAJ
CXZhX2NmZ19iYXNlID0gcHAtPnZhX2NmZzFfYmFzZTsNCiAJfQ0KQEAgLTU5OCw3ICs1ODcsNyBA
QCBzdGF0aWMgaW50IGR3X3BjaWVfd3Jfb3RoZXJfY29uZihzdHJ1Y3QgcGNpZV9wb3J0ICpwcCwg
c3RydWN0IHBjaV9idXMgKmJ1cywNCiAJCQkJICBidXNkZXYsIGNmZ19zaXplKTsNCiAJcmV0ID0g
ZHdfcGNpZV9jZmdfd3JpdGUodmFfY2ZnX2Jhc2UgKyBhZGRyZXNzLCB3aGVyZSwgc2l6ZSwgdmFs
KTsNCiAJZHdfcGNpZV9wcm9nX291dGJvdW5kX2F0dShwcCwgUENJRV9BVFVfUkVHSU9OX0lOREVY
MCwNCi0JCQkJICBQQ0lFX0FUVV9UWVBFX0lPLCBwcC0+aW9fbW9kX2Jhc2UsDQorCQkJCSAgUENJ
RV9BVFVfVFlQRV9JTywgcHAtPmlvX2Jhc2UsDQogCQkJCSAgcHAtPmlvX2J1c19hZGRyLCBwcC0+
aW9fc2l6ZSk7DQogDQogCXJldHVybiByZXQ7DQpAQCAtNjMwLDcgKzYxOSw3IEBAIHN0YXRpYyBp
bnQgZHdfcGNpZV92YWxpZF9jb25maWcoc3RydWN0IHBjaWVfcG9ydCAqcHAsDQogc3RhdGljIGlu
dCBkd19wY2llX3JkX2NvbmYoc3RydWN0IHBjaV9idXMgKmJ1cywgdTMyIGRldmZuLCBpbnQgd2hl
cmUsDQogCQkJaW50IHNpemUsIHUzMiAqdmFsKQ0KIHsNCi0Jc3RydWN0IHBjaWVfcG9ydCAqcHAg
PSBzeXNfdG9fcGNpZShidXMtPnN5c2RhdGEpOw0KKwlzdHJ1Y3QgcGNpZV9wb3J0ICpwcCA9IGJ1
cy0+c3lzZGF0YTsNCiAJaW50IHJldDsNCiANCiAJaWYgKGR3X3BjaWVfdmFsaWRfY29uZmlnKHBw
LCBidXMsIFBDSV9TTE9UKGRldmZuKSkgPT0gMCkgew0KQEAgLTY1NCw3ICs2NDMsNyBAQCBzdGF0
aWMgaW50IGR3X3BjaWVfcmRfY29uZihzdHJ1Y3QgcGNpX2J1cyAqYnVzLCB1MzIgZGV2Zm4sIGlu
dCB3aGVyZSwNCiBzdGF0aWMgaW50IGR3X3BjaWVfd3JfY29uZihzdHJ1Y3QgcGNpX2J1cyAqYnVz
LCB1MzIgZGV2Zm4sDQogCQkJaW50IHdoZXJlLCBpbnQgc2l6ZSwgdTMyIHZhbCkNCiB7DQotCXN0
cnVjdCBwY2llX3BvcnQgKnBwID0gc3lzX3RvX3BjaWUoYnVzLT5zeXNkYXRhKTsNCisJc3RydWN0
IHBjaWVfcG9ydCAqcHAgPSBidXMtPnN5c2RhdGE7DQogCWludCByZXQ7DQogDQogCWlmIChkd19w
Y2llX3ZhbGlkX2NvbmZpZyhwcCwgYnVzLCBQQ0lfU0xPVChkZXZmbikpID09IDApDQpAQCAtNjc4
LDYyICs2NjcsNiBAQCBzdGF0aWMgc3RydWN0IHBjaV9vcHMgZHdfcGNpZV9vcHMgPSB7DQogCS53
cml0ZSA9IGR3X3BjaWVfd3JfY29uZiwNCiB9Ow0KIA0KLXN0YXRpYyBpbnQgZHdfcGNpZV9zZXR1
cChpbnQgbnIsIHN0cnVjdCBwY2lfc3lzX2RhdGEgKnN5cykNCi17DQotCXN0cnVjdCBwY2llX3Bv
cnQgKnBwOw0KLQ0KLQlwcCA9IHN5c190b19wY2llKHN5cyk7DQotDQotCWlmIChnbG9iYWxfaW9f
b2Zmc2V0IDwgU1pfMU0gJiYgcHAtPmlvX3NpemUgPiAwKSB7DQotCQlzeXMtPmlvX29mZnNldCA9
IGdsb2JhbF9pb19vZmZzZXQgLSBwcC0+aW9fYnVzX2FkZHI7DQotCQlwY2lfaW9yZW1hcF9pbyhn
bG9iYWxfaW9fb2Zmc2V0LCBwcC0+aW9fYmFzZSk7DQotCQlnbG9iYWxfaW9fb2Zmc2V0ICs9IFNa
XzY0SzsNCi0JCXBjaV9hZGRfcmVzb3VyY2Vfb2Zmc2V0KCZzeXMtPnJlc291cmNlcywgJnBwLT5p
bywNCi0JCQkJCXN5cy0+aW9fb2Zmc2V0KTsNCi0JfQ0KLQ0KLQlzeXMtPm1lbV9vZmZzZXQgPSBw
cC0+bWVtLnN0YXJ0IC0gcHAtPm1lbV9idXNfYWRkcjsNCi0JcGNpX2FkZF9yZXNvdXJjZV9vZmZz
ZXQoJnN5cy0+cmVzb3VyY2VzLCAmcHAtPm1lbSwgc3lzLT5tZW1fb2Zmc2V0KTsNCi0JcGNpX2Fk
ZF9yZXNvdXJjZSgmc3lzLT5yZXNvdXJjZXMsICZwcC0+YnVzbik7DQotDQotCXJldHVybiAxOw0K
LX0NCi0NCi1zdGF0aWMgc3RydWN0IHBjaV9idXMgKmR3X3BjaWVfc2Nhbl9idXMoaW50IG5yLCBz
dHJ1Y3QgcGNpX3N5c19kYXRhICpzeXMpDQotew0KLQlzdHJ1Y3QgcGNpX2J1cyAqYnVzOw0KLQlz
dHJ1Y3QgcGNpZV9wb3J0ICpwcCA9IHN5c190b19wY2llKHN5cyk7DQotDQotCXBwLT5yb290X2J1
c19uciA9IHN5cy0+YnVzbnI7DQotCWJ1cyA9IHBjaV9zY2FuX3Jvb3RfYnVzKHBwLT5kZXYsIHN5
cy0+YnVzbnIsDQotCQkJCSAgJmR3X3BjaWVfb3BzLCBzeXMsICZzeXMtPnJlc291cmNlcyk7DQot
CWlmICghYnVzKQ0KLQkJcmV0dXJuIE5VTEw7DQotDQotCWlmIChidXMgJiYgcHAtPm9wcy0+c2Nh
bl9idXMpDQotCQlwcC0+b3BzLT5zY2FuX2J1cyhwcCk7DQotDQotCXJldHVybiBidXM7DQotfQ0K
LQ0KLXN0YXRpYyBpbnQgZHdfcGNpZV9tYXBfaXJxKGNvbnN0IHN0cnVjdCBwY2lfZGV2ICpkZXYs
IHU4IHNsb3QsIHU4IHBpbikNCi17DQotCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gc3lzX3RvX3Bj
aWUoZGV2LT5idXMtPnN5c2RhdGEpOw0KLQlpbnQgaXJxOw0KLQ0KLQlpcnEgPSBvZl9pcnFfcGFy
c2VfYW5kX21hcF9wY2koZGV2LCBzbG90LCBwaW4pOw0KLQlpZiAoIWlycSkNCi0JCWlycSA9IHBw
LT5pcnE7DQotDQotCXJldHVybiBpcnE7DQotfQ0KLQ0KLXN0YXRpYyBzdHJ1Y3QgaHdfcGNpIGR3
X3BjaSA9IHsNCi0JLnNldHVwCQk9IGR3X3BjaWVfc2V0dXAsDQotCS5zY2FuCQk9IGR3X3BjaWVf
c2Nhbl9idXMsDQotCS5tYXBfaXJxCT0gZHdfcGNpZV9tYXBfaXJxLA0KLX07DQotDQogdm9pZCBk
d19wY2llX3NldHVwX3JjKHN0cnVjdCBwY2llX3BvcnQgKnBwKQ0KIHsNCiAJdTMyIHZhbDsNCmRp
ZmYgLS1naXQgYS9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtZGVzaWdud2FyZS5oIGIvZHJpdmVycy9w
Y2kvaG9zdC9wY2llLWRlc2lnbndhcmUuaA0KaW5kZXggZDBiYmQyNy4uMGMyYTdlYiAxMDA2NDQN
Ci0tLSBhL2RyaXZlcnMvcGNpL2hvc3QvcGNpZS1kZXNpZ253YXJlLmgNCisrKyBiL2RyaXZlcnMv
cGNpL2hvc3QvcGNpZS1kZXNpZ253YXJlLmgNCkBAIC0yMSwzMSArMjEsMjggQEANCiAgKi8NCiAj
ZGVmaW5lIE1BWF9NU0lfSVJRUwkJCTMyDQogI2RlZmluZSBNQVhfTVNJX0NUUkxTCQkJKE1BWF9N
U0lfSVJRUyAvIDMyKQ0KKyNkZWZpbmUgRFdfUk9PVF9OUl9VTkRFRklORUQJLTENCiANCiBzdHJ1
Y3QgcGNpZV9wb3J0IHsNCiAJc3RydWN0IGRldmljZQkJKmRldjsNCiAJdTgJCQlyb290X2J1c19u
cjsNCiAJdm9pZCBfX2lvbWVtCQkqZGJpX2Jhc2U7DQogCXU2NAkJCWNmZzBfYmFzZTsNCi0JdTY0
CQkJY2ZnMF9tb2RfYmFzZTsNCiAJdm9pZCBfX2lvbWVtCQkqdmFfY2ZnMF9iYXNlOw0KIAl1MzIJ
CQljZmcwX3NpemU7DQogCXU2NAkJCWNmZzFfYmFzZTsNCi0JdTY0CQkJY2ZnMV9tb2RfYmFzZTsN
CiAJdm9pZCBfX2lvbWVtCQkqdmFfY2ZnMV9iYXNlOw0KIAl1MzIJCQljZmcxX3NpemU7DQotCXU2
NAkJCWlvX2Jhc2U7DQotCXU2NAkJCWlvX21vZF9iYXNlOw0KKwlyZXNvdXJjZV9zaXplX3QJCWlv
X2Jhc2U7DQogCXBoeXNfYWRkcl90CQlpb19idXNfYWRkcjsNCiAJdTMyCQkJaW9fc2l6ZTsNCiAJ
dTY0CQkJbWVtX2Jhc2U7DQotCXU2NAkJCW1lbV9tb2RfYmFzZTsNCiAJcGh5c19hZGRyX3QJCW1l
bV9idXNfYWRkcjsNCiAJdTMyCQkJbWVtX3NpemU7DQotCXN0cnVjdCByZXNvdXJjZQkJY2ZnOw0K
LQlzdHJ1Y3QgcmVzb3VyY2UJCWlvOw0KLQlzdHJ1Y3QgcmVzb3VyY2UJCW1lbTsNCi0Jc3RydWN0
IHJlc291cmNlCQlidXNuOw0KKwlzdHJ1Y3QgcmVzb3VyY2UJCSpjZmc7DQorCXN0cnVjdCByZXNv
dXJjZQkJKmlvOw0KKwlzdHJ1Y3QgcmVzb3VyY2UJCSptZW07DQorCXN0cnVjdCByZXNvdXJjZQkJ
KmJ1c247DQogCWludAkJCWlycTsNCiAJdTMyCQkJbGFuZXM7DQogCXN0cnVjdCBwY2llX2hvc3Rf
b3BzCSpvcHM7DQpkaWZmIC0tZ2l0IGEvZHJpdmVycy9wY2kvaG9zdC9wY2llLXNwZWFyMTN4eC5j
IGIvZHJpdmVycy9wY2kvaG9zdC9wY2llLXNwZWFyMTN4eC5jDQppbmRleCBjNDlmYmRjLi5iMmM1
OWI5IDEwMDY0NA0KLS0tIGEvZHJpdmVycy9wY2kvaG9zdC9wY2llLXNwZWFyMTN4eC5jDQorKysg
Yi9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtc3BlYXIxM3h4LmMNCkBAIC0yODYsNyArMjg2LDcgQEAg
c3RhdGljIGludCBzcGVhcjEzeHhfYWRkX3BjaWVfcG9ydChzdHJ1Y3QgcGNpZV9wb3J0ICpwcCwN
CiAJCXJldHVybiByZXQ7DQogCX0NCiANCi0JcHAtPnJvb3RfYnVzX25yID0gLTE7DQorCXBwLT5y
b290X2J1c19uciA9IERXX1JPT1RfTlJfVU5ERUZJTkVEOw0KIAlwcC0+b3BzID0gJnNwZWFyMTN4
eF9wY2llX2hvc3Rfb3BzOw0KIA0KIAlyZXQgPSBkd19wY2llX2hvc3RfaW5pdChwcCk7DQotLSAN
CjEuOS4xDQoNCg0KPiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9tOiBMdWNhcyBT
dGFjaCBbbWFpbHRvOmwuc3RhY2hAcGVuZ3V0cm9uaXguZGVdDQo+IFNlbnQ6IFdlZG5lc2RheSwg
QXVndXN0IDE5LCAyMDE1IDE6NTQgUE0NCj4gVG86IFdhbmd6aG91IChCKQ0KPiBDYzogQmpvcm4g
SGVsZ2FhczsgamluZ29vaGFuMUBnbWFpbC5jb207IFByYXR5dXNoIEFuYW5kOyBBcm5kIEJlcmdt
YW5uOw0KPiBsaW51eEBhcm0ubGludXgub3JnLnVrOyB0aG9tYXMucGV0YXp6b25pQGZyZWUtZWxl
Y3Ryb25zLmNvbTsgR2FicmllbGUNCj4gUGFvbG9uaTsgbG9yZW56by5waWVyYWxpc2lAYXJtLmNv
bTsgamFtZXMubW9yc2VAYXJtLmNvbTsNCj4gTGl2aXUuRHVkYXVAYXJtLmNvbTsgamFzb25AbGFr
ZWRhZW1vbi5uZXQ7IHJvYmhAa2VybmVsLm9yZzsgbGludXgtDQo+IHBjaUB2Z2VyLmtlcm5lbC5v
cmc7IGxpbnV4LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZzsNCj4gZGV2aWNldHJlZUB2
Z2VyLmtlcm5lbC5vcmc7IFl1YW56aGljaGFuZzsgWmh1ZGFjYWk7IHpoYW5nanVrdW87DQo+IHFp
dXpoZW5mYTsgbGl1ZG9uZ2RvbmcgKEMpOyBxaXVqaWFuZzsgeHV3ZWkgKE8pOyBMaWd1b3podSAo
S2VubmV0aCkNCj4gU3ViamVjdDogUmU6IFtQQVRDSCB2NyAzLzZdIFBDSTogZGVzaWdud2FyZTog
QWRkIEFSTTY0IHN1cHBvcnQNCj4gDQo+IEFtIE1vbnRhZywgZGVuIDE3LjA4LjIwMTUsIDE5OjU1
ICswODAwIHNjaHJpZWIgWmhvdSBXYW5nOg0KPiA+IFRoaXMgcGF0Y2ggdHJpZXMgdG8gdW5pZnkg
QVJNMzIgYW5kIEFSTTY0IFBDSWUgaW4gZGVzaWdud2FyZSBkcml2ZXIuDQo+IERlbGV0ZQ0KPiA+
IGZ1bmN0aW9uIGR3X3BjaWVfc2V0dXAsIGR3X3BjaWVfc2Nhbl9idXMsIGR3X3BjaWVfbWFwX2ly
cSBhbmQgc3RydWN0DQo+IGh3X3BjaSwNCj4gPiBtb3ZlIHJlbGF0ZWQgb3BlcmF0aW9ucyB0byBk
d19wY2llX2hvc3RfaW5pdC4NCj4gPg0KPiA+IEluIHBhc3QsIHdlIHVzZToNCj4gPiBwY2lfY29t
bW9uX2luaXRfZGV2DQo+ID4gCS0+IHBjaWJpb3NfaW5pdF9odw0KPiA+IAkJLT4gaHctPnNjYW4g
KGR3X3BjaWVfc2Nhbl9idXMpDQo+ID4gdG8gcGFzcyAwIHRvIHJvb3RfYnVzX25yIGluIHN0cnVj
dCBwY2llX3BvcnQuIFRoaXMgcGF0Y2ggc2V0IHBwLQ0KPiA+cm9vdF9idXNfbnIgPSAwDQo+ID4g
aW4gZWFjaCBQQ0llIGhvc3QgZHJpdmVyIHdoaWNoIGlzIGJhc2VkIG9uIHBjaWUtZGVzaWdud2Fy
ZS4NCj4gPg0KPiBUaGlzIGlzIGluY29ycmVjdCBhdCBsZWFzdCBpZiB0aGVyZSBhcmUgMiBpbnN0
YW5jZXMgb2YgRFcgUENJZSBob3N0IGluDQo+IHRoZSBzYW1lIFNvQyB3aXRob3V0IHVzaW5nIFBD
SSBkb21haW5zLiBJbiB0aGF0IHRoZSBjYXNlIHRoZSBidXMgcmFuZ2UNCj4gZGV0ZXJtaW5lcyB0
aGUgcmFuZ2Ugb2YgdmFsaWQgYnVzIG51bWJlcnMgcGVyIGluc3RhbmNlIGFuZCB0aGUgZmlyc3QN
Cj4gbnVtYmVyIGlzIHRoZSByb290IGJ1cy4gUGxlYXNlIGxvb2sgYXQgdGhlICJidXMtcmFuZ2Ui
IERUIHByb3BlcnR5IGluDQo+IHRoZSBEVyBQQ0llIGJpbmRpbmdzLg0KPiANCj4gQWxzbyB3ZSBz
aG91bGQgZmluYWxseSByZW1vdmUgdGhpcyByb290LWJ1cyBzZXR1cCBmcm9tIHRoZSBnbHVlIGRy
aXZlcnMNCj4gYWx0b2dldGhlci4gSXQncyBzb21ldGhpbmcgdGhhdCBlbnRpcmVseSBiZWxvbmdz
IGludG8gdGhlIERXIGNvcmUgY29kZS4NCj4gDQo+IFJlZ2FyZHMsDQo+IEx1Y2FzDQo+IA0KPiA+
IFRoaXMgcGF0Y2ggYWxzbyB0cnkgdG8gdXNlIG9mX3BjaV9nZXRfaG9zdF9icmlkZ2VfcmVzb3Vy
Y2VzIGZvciBBUk0zMg0KPiBhbmQgQVJNNjQNCj4gPiBhY2NvcmRpbmcgdG8gdGhlIHN1Z2dlc3Rp
b24gZm9yIEdhYnJpZWxlWzFdDQo+ID4NCj4gPiBGaW5hbGx5IHRoaXMgcGF0Y2ggcmV2ZXJ0cyBj
b21taXQgZjRjNTVjNWEzZjdmICJQQ0k6IGRlc2lnbndhcmU6DQo+IFByb2dyYW0gQVRVDQo+ID4g
d2l0aCB1bnRyYW5zbGF0ZWQgYWRkcmVzcyIgYmFzZWQgb24gMS82IGluIHRoaXMgc2VyaWVzLiB3
ZSBkZWxldGUNCj4gKl9tb2RfYmFzZSBpbg0KPiA+IHBjaWUtZGVzaWdud2FyZS4gVGhpcyB3YXMg
ZGlzY3Vzc2VkIGluIFsyXQ0KPiA+DQo+ID4gSSBoYXZlIGNvbXBpbGVkIHRoZSBkcml2ZXIgd2l0
aCBtdWx0aV92N19kZWZjb25maWcuIEhvd2V2ZXIsIEkgZG9uJ3QNCj4gaGF2ZQ0KPiA+IEFSTTMy
IFBDSWUgcmVsYXRlZCBib2FyZCB0byBkbyB0ZXN0LiBJdCB3aWxsIGJlIGFwcHJlY2lhdGVkIGlm
DQo+IHNvbWVvbmUgY291bGQNCj4gPiBoZWxwIHRvIHRlc3QgaXQuDQo+ID4NCj4gPiBTaWduZWQt
b2ZmLWJ5OiBaaG91IFdhbmcgPHdhbmd6aG91MUBoaXNpbGljb24uY29tPg0KPiA+IFNpZ25lZC1v
ZmYtYnk6IEdhYnJpZWxlIFBhb2xvbmkgPGdhYnJpZWxlLnBhb2xvbmlAaHVhd2VpLmNvbT4NCj4g
PiBTaWduZWQtb2ZmLWJ5OiBBcm5kIEJlcmdtYW5uIDxhcm5kQGFybmRiLmRlPg0KPiA+IFRlc3Rl
ZC1CeTogSmFtZXMgTW9yc2UgPGphbWVzLm1vcnNlQGFybS5jb20+DQo+ID4NCj4gPiBbMV0gaHR0
cDovL3d3dy5zcGluaWNzLm5ldC9saXN0cy9saW51eC1wY2kvbXNnNDIxOTQuaHRtbA0KPiA+IFsy
XSBodHRwOi8vd3d3LnNwaW5pY3MubmV0L2xpc3RzL2FybS1rZXJuZWwvbXNnNDM2Nzc5Lmh0bWwN
Cj4gPiAtLS0NCj4gPiAgZHJpdmVycy9wY2kvaG9zdC9wY2ktZHJhN3h4LmMgICAgICB8ICAxNSAr
LS0NCj4gPiAgZHJpdmVycy9wY2kvaG9zdC9wY2ktZXh5bm9zLmMgICAgICB8ICAgMiArLQ0KPiA+
ICBkcml2ZXJzL3BjaS9ob3N0L3BjaS1pbXg2LmMgICAgICAgIHwgICAyICstDQo+ID4gIGRyaXZl
cnMvcGNpL2hvc3QvcGNpLWtleXN0b25lLWR3LmMgfCAgIDIgKy0NCj4gPiAgZHJpdmVycy9wY2kv
aG9zdC9wY2kta2V5c3RvbmUuYyAgICB8ICAgMiArLQ0KPiA+ICBkcml2ZXJzL3BjaS9ob3N0L3Bj
aS1sYXllcnNjYXBlLmMgIHwgICAyICstDQo+ID4gIGRyaXZlcnMvcGNpL2hvc3QvcGNpZS1kZXNp
Z253YXJlLmMgfCAyMjkgKysrKysrKysrKysrLS0tLS0tLS0tLS0tLS0tDQo+IC0tLS0tLS0tLS0N
Cj4gPiAgZHJpdmVycy9wY2kvaG9zdC9wY2llLWRlc2lnbndhcmUuaCB8ICAxNCArLS0NCj4gPiAg
ZHJpdmVycy9wY2kvaG9zdC9wY2llLXNwZWFyMTN4eC5jICB8ICAgMiArLQ0KPiA+ICA5IGZpbGVz
IGNoYW5nZWQsIDk1IGluc2VydGlvbnMoKyksIDE3NSBkZWxldGlvbnMoLSkNCj4gPg0KPiA+IGRp
ZmYgLS1naXQgYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1kcmE3eHguYyBiL2RyaXZlcnMvcGNpL2hv
c3QvcGNpLQ0KPiBkcmE3eHguYw0KPiA+IGluZGV4IDE4YWU3ZmYuLjEyNjhjNjkgMTAwNjQ0DQo+
ID4gLS0tIGEvZHJpdmVycy9wY2kvaG9zdC9wY2ktZHJhN3h4LmMNCj4gPiArKysgYi9kcml2ZXJz
L3BjaS9ob3N0L3BjaS1kcmE3eHguYw0KPiA+IEBAIC0xNDEsMTUgKzE0MSwxNSBAQCBzdGF0aWMg
dm9pZCBkcmE3eHhfcGNpZV9ob3N0X2luaXQoc3RydWN0DQo+IHBjaWVfcG9ydCAqcHApDQo+ID4g
IHsNCj4gPiAgCWR3X3BjaWVfc2V0dXBfcmMocHApOw0KPiA+DQo+ID4gLQlpZiAocHAtPmlvX21v
ZF9iYXNlKQ0KPiA+IC0JCXBwLT5pb19tb2RfYmFzZSAmPSBDUFVfVE9fQlVTX0FERFI7DQo+ID4g
KwlpZiAocHAtPmlvX2Jhc2UpDQo+ID4gKwkJcHAtPmlvX2Jhc2UgJj0gQ1BVX1RPX0JVU19BRERS
Ow0KPiA+DQo+ID4gLQlpZiAocHAtPm1lbV9tb2RfYmFzZSkNCj4gPiAtCQlwcC0+bWVtX21vZF9i
YXNlICY9IENQVV9UT19CVVNfQUREUjsNCj4gPiArCWlmIChwcC0+bWVtX2Jhc2UpDQo+ID4gKwkJ
cHAtPm1lbV9iYXNlICY9IENQVV9UT19CVVNfQUREUjsNCj4gPg0KPiA+IC0JaWYgKHBwLT5jZmcw
X21vZF9iYXNlKSB7DQo+ID4gLQkJcHAtPmNmZzBfbW9kX2Jhc2UgJj0gQ1BVX1RPX0JVU19BRERS
Ow0KPiA+IC0JCXBwLT5jZmcxX21vZF9iYXNlICY9IENQVV9UT19CVVNfQUREUjsNCj4gPiArCWlm
IChwcC0+Y2ZnMF9iYXNlKSB7DQo+ID4gKwkJcHAtPmNmZzBfYmFzZSAmPSBDUFVfVE9fQlVTX0FE
RFI7DQo+ID4gKwkJcHAtPmNmZzFfYmFzZSAmPSBDUFVfVE9fQlVTX0FERFI7DQo+ID4gIAl9DQo+
ID4NCj4gPiAgCWRyYTd4eF9wY2llX2VzdGFibGlzaF9saW5rKHBwKTsNCj4gPiBAQCAtMjg4LDYg
KzI4OCw3IEBAIHN0YXRpYyBpbnQgX19pbml0IGRyYTd4eF9hZGRfcGNpZV9wb3J0KHN0cnVjdA0K
PiBkcmE3eHhfcGNpZSAqZHJhN3h4LA0KPiA+DQo+ID4gIAlwcCA9ICZkcmE3eHgtPnBwOw0KPiA+
ICAJcHAtPmRldiA9IGRldjsNCj4gPiArCXBwLT5yb290X2J1c19uciA9IDA7DQo+ID4gIAlwcC0+
b3BzID0gJmRyYTd4eF9wY2llX2hvc3Rfb3BzOw0KPiA+DQo+ID4gIAlwcC0+aXJxID0gcGxhdGZv
cm1fZ2V0X2lycShwZGV2LCAxKTsNCj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9wY2kvaG9zdC9w
Y2ktZXh5bm9zLmMgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaS0NCj4gZXh5bm9zLmMNCj4gPiBpbmRl
eCBmOWY0NjhkLi45NzcxYmIwIDEwMDY0NA0KPiA+IC0tLSBhL2RyaXZlcnMvcGNpL2hvc3QvcGNp
LWV4eW5vcy5jDQo+ID4gKysrIGIvZHJpdmVycy9wY2kvaG9zdC9wY2ktZXh5bm9zLmMNCj4gPiBA
QCAtNTMwLDcgKzUzMCw3IEBAIHN0YXRpYyBpbnQgX19pbml0IGV4eW5vc19hZGRfcGNpZV9wb3J0
KHN0cnVjdA0KPiBwY2llX3BvcnQgKnBwLA0KPiA+ICAJCX0NCj4gPiAgCX0NCj4gPg0KPiA+IC0J
cHAtPnJvb3RfYnVzX25yID0gLTE7DQo+ID4gKwlwcC0+cm9vdF9idXNfbnIgPSAwOw0KPiA+ICAJ
cHAtPm9wcyA9ICZleHlub3NfcGNpZV9ob3N0X29wczsNCj4gPg0KPiA+ICAJcmV0ID0gZHdfcGNp
ZV9ob3N0X2luaXQocHApOw0KPiA+IGRpZmYgLS1naXQgYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1p
bXg2LmMgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaS0NCj4gaW14Ni5jDQo+ID4gaW5kZXggMjMzYTE5
Ni4uYmVjMjU2YyAxMDA2NDQNCj4gPiAtLS0gYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1pbXg2LmMN
Cj4gPiArKysgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaS1pbXg2LmMNCj4gPiBAQCAtNTUxLDcgKzU1
MSw3IEBAIHN0YXRpYyBpbnQgX19pbml0IGlteDZfYWRkX3BjaWVfcG9ydChzdHJ1Y3QNCj4gcGNp
ZV9wb3J0ICpwcCwNCj4gPiAgCQl9DQo+ID4gIAl9DQo+ID4NCj4gPiAtCXBwLT5yb290X2J1c19u
ciA9IC0xOw0KPiA+ICsJcHAtPnJvb3RfYnVzX25yID0gMDsNCj4gPiAgCXBwLT5vcHMgPSAmaW14
Nl9wY2llX2hvc3Rfb3BzOw0KPiA+DQo+ID4gIAlyZXQgPSBkd19wY2llX2hvc3RfaW5pdChwcCk7
DQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvcGNpL2hvc3QvcGNpLWtleXN0b25lLWR3LmMNCj4g
Yi9kcml2ZXJzL3BjaS9ob3N0L3BjaS1rZXlzdG9uZS1kdy5jDQo+ID4gaW5kZXggZjM0ODkyZS4u
YjFlNDEzNSAxMDA2NDQNCj4gPiAtLS0gYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1rZXlzdG9uZS1k
dy5jDQo+ID4gKysrIGIvZHJpdmVycy9wY2kvaG9zdC9wY2kta2V5c3RvbmUtZHcuYw0KPiA+IEBA
IC0zMjcsNyArMzI3LDcgQEAgc3RhdGljIHZvaWQga3NfZHdfcGNpZV9jbGVhcl9kYmlfbW9kZSh2
b2lkDQo+IF9faW9tZW0gKnJlZ192aXJ0KQ0KPiA+ICB2b2lkIGtzX2R3X3BjaWVfc2V0dXBfcmNf
YXBwX3JlZ3Moc3RydWN0IGtleXN0b25lX3BjaWUgKmtzX3BjaWUpDQo+ID4gIHsNCj4gPiAgCXN0
cnVjdCBwY2llX3BvcnQgKnBwID0gJmtzX3BjaWUtPnBwOw0KPiA+IC0JdTMyIHN0YXJ0ID0gcHAt
Pm1lbS5zdGFydCwgZW5kID0gcHAtPm1lbS5lbmQ7DQo+ID4gKwl1MzIgc3RhcnQgPSBwcC0+bWVt
LT5zdGFydCwgZW5kID0gcHAtPm1lbS0+ZW5kOw0KPiA+ICAJaW50IGksIHRyX3NpemU7DQo+ID4N
Cj4gPiAgCS8qIERpc2FibGUgQkFScyBmb3IgaW5ib3VuZCBhY2Nlc3MgKi8NCj4gPiBkaWZmIC0t
Z2l0IGEvZHJpdmVycy9wY2kvaG9zdC9wY2kta2V5c3RvbmUuYyBiL2RyaXZlcnMvcGNpL2hvc3Qv
cGNpLQ0KPiBrZXlzdG9uZS5jDQo+ID4gaW5kZXggNzM0ZGE1OC4uODExMzgzMiAxMDA2NDQNCj4g
PiAtLS0gYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1rZXlzdG9uZS5jDQo+ID4gKysrIGIvZHJpdmVy
cy9wY2kvaG9zdC9wY2kta2V5c3RvbmUuYw0KPiA+IEBAIC0zMDksNyArMzA5LDcgQEAgc3RhdGlj
IGludCBfX2luaXQga3NfYWRkX3BjaWVfcG9ydChzdHJ1Y3QNCj4ga2V5c3RvbmVfcGNpZSAqa3Nf
cGNpZSwNCj4gPiAgCQkJcmV0dXJuIHJldDsNCj4gPiAgCX0NCj4gPg0KPiA+IC0JcHAtPnJvb3Rf
YnVzX25yID0gLTE7DQo+ID4gKwlwcC0+cm9vdF9idXNfbnIgPSAwOw0KPiA+ICAJcHAtPm9wcyA9
ICZrZXlzdG9uZV9wY2llX2hvc3Rfb3BzOw0KPiA+ICAJcmV0ID0ga3NfZHdfcGNpZV9ob3N0X2lu
aXQoa3NfcGNpZSwga3NfcGNpZS0+bXNpX2ludGNfbnApOw0KPiA+ICAJaWYgKHJldCkgew0KPiA+
IGRpZmYgLS1naXQgYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1sYXllcnNjYXBlLmMNCj4gYi9kcml2
ZXJzL3BjaS9ob3N0L3BjaS1sYXllcnNjYXBlLmMNCj4gPiBpbmRleCBiMjMyOGVhMS4uNzlmZjA4
YyAxMDA2NDQNCj4gPiAtLS0gYS9kcml2ZXJzL3BjaS9ob3N0L3BjaS1sYXllcnNjYXBlLmMNCj4g
PiArKysgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaS1sYXllcnNjYXBlLmMNCj4gPiBAQCAtMTA2LDcg
KzEwNiw3IEBAIHN0YXRpYyBpbnQgbHNfYWRkX3BjaWVfcG9ydChzdHJ1Y3QgbHNfcGNpZSAqcGNp
ZSkNCj4gPiAgCXBwID0gJnBjaWUtPnBwOw0KPiA+ICAJcHAtPmRldiA9IHBjaWUtPmRldjsNCj4g
PiAgCXBwLT5kYmlfYmFzZSA9IHBjaWUtPmRiaTsNCj4gPiAtCXBwLT5yb290X2J1c19uciA9IC0x
Ow0KPiA+ICsJcHAtPnJvb3RfYnVzX25yID0gMDsNCj4gPiAgCXBwLT5vcHMgPSAmbHNfcGNpZV9o
b3N0X29wczsNCj4gPg0KPiA+ICAJcmV0ID0gZHdfcGNpZV9ob3N0X2luaXQocHApOw0KPiA+IGRp
ZmYgLS1naXQgYS9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtZGVzaWdud2FyZS5jDQo+IGIvZHJpdmVy
cy9wY2kvaG9zdC9wY2llLWRlc2lnbndhcmUuYw0KPiA+IGluZGV4IGM1ZDQwN2MuLmU3MWE4OGUg
MTAwNjQ0DQo+ID4gLS0tIGEvZHJpdmVycy9wY2kvaG9zdC9wY2llLWRlc2lnbndhcmUuYw0KPiA+
ICsrKyBiL2RyaXZlcnMvcGNpL2hvc3QvcGNpZS1kZXNpZ253YXJlLmMNCj4gPiBAQCAtMTEsNiAr
MTEsNyBAQA0KPiA+ICAgKiBwdWJsaXNoZWQgYnkgdGhlIEZyZWUgU29mdHdhcmUgRm91bmRhdGlv
bi4NCj4gPiAgICovDQo+ID4NCj4gPiArI2luY2x1ZGUgPGxpbnV4L2hhcmRpcnEuaD4NCj4gPiAg
I2luY2x1ZGUgPGxpbnV4L2lycS5oPg0KPiA+ICAjaW5jbHVkZSA8bGludXgvaXJxZG9tYWluLmg+
DQo+ID4gICNpbmNsdWRlIDxsaW51eC9rZXJuZWwuaD4NCj4gPiBAQCAtNjksMTYgKzcwLDcgQEAN
Cj4gPiAgI2RlZmluZSBQQ0lFX0FUVV9GVU5DKHgpCQkoKCh4KSAmIDB4NykgPDwgMTYpDQo+ID4g
ICNkZWZpbmUgUENJRV9BVFVfVVBQRVJfVEFSR0VUCQkweDkxQw0KPiA+DQo+ID4gLXN0YXRpYyBz
dHJ1Y3QgaHdfcGNpIGR3X3BjaTsNCj4gPiAtDQo+ID4gLXN0YXRpYyB1bnNpZ25lZCBsb25nIGds
b2JhbF9pb19vZmZzZXQ7DQo+ID4gLQ0KPiA+IC1zdGF0aWMgaW5saW5lIHN0cnVjdCBwY2llX3Bv
cnQgKnN5c190b19wY2llKHN0cnVjdCBwY2lfc3lzX2RhdGEgKnN5cykNCj4gPiAtew0KPiA+IC0J
QlVHX09OKCFzeXMtPnByaXZhdGVfZGF0YSk7DQo+ID4gLQ0KPiA+IC0JcmV0dXJuIHN5cy0+cHJp
dmF0ZV9kYXRhOw0KPiA+IC19DQo+ID4gK3N0YXRpYyBzdHJ1Y3QgcGNpX29wcyBkd19wY2llX29w
czsNCj4gPg0KPiA+ICBpbnQgZHdfcGNpZV9jZmdfcmVhZCh2b2lkIF9faW9tZW0gKmFkZHIsIGlu
dCB3aGVyZSwgaW50IHNpemUsIHUzMg0KPiAqdmFsKQ0KPiA+ICB7DQo+ID4gQEAgLTI1NSw3ICsy
NDcsNyBAQCBzdGF0aWMgdm9pZCBkd19wY2llX21zaV9zZXRfaXJxKHN0cnVjdCBwY2llX3BvcnQN
Cj4gKnBwLCBpbnQgaXJxKQ0KPiA+ICBzdGF0aWMgaW50IGFzc2lnbl9pcnEoaW50IG5vX2lycXMs
IHN0cnVjdCBtc2lfZGVzYyAqZGVzYywgaW50ICpwb3MpDQo+ID4gIHsNCj4gPiAgCWludCBpcnEs
IHBvczAsIGk7DQo+ID4gLQlzdHJ1Y3QgcGNpZV9wb3J0ICpwcCA9IHN5c190b19wY2llKGRlc2Mt
PmRldi0+YnVzLT5zeXNkYXRhKTsNCj4gPiArCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gZGVzYy0+
ZGV2LT5idXMtPnN5c2RhdGE7DQo+ID4NCj4gPiAgCXBvczAgPSBiaXRtYXBfZmluZF9mcmVlX3Jl
Z2lvbihwcC0+bXNpX2lycV9pbl91c2UsIE1BWF9NU0lfSVJRUywNCj4gPiAgCQkJCSAgICAgICBv
cmRlcl9iYXNlXzIobm9faXJxcykpOw0KPiA+IEBAIC0yOTgsNyArMjkwLDcgQEAgc3RhdGljIGlu
dCBkd19tc2lfc2V0dXBfaXJxKHN0cnVjdCBtc2lfY29udHJvbGxlcg0KPiAqY2hpcCwgc3RydWN0
IHBjaV9kZXYgKnBkZXYsDQo+ID4gIHsNCj4gPiAgCWludCBpcnEsIHBvczsNCj4gPiAgCXN0cnVj
dCBtc2lfbXNnIG1zZzsNCj4gPiAtCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gc3lzX3RvX3BjaWUo
cGRldi0+YnVzLT5zeXNkYXRhKTsNCj4gPiArCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gcGRldi0+
YnVzLT5zeXNkYXRhOw0KPiA+DQo+ID4gIAlpZiAoZGVzYy0+bXNpX2F0dHJpYi5pc19tc2l4KQ0K
PiA+ICAJCXJldHVybiAtRUlOVkFMOw0KPiA+IEBAIC0zMjcsNyArMzE5LDcgQEAgc3RhdGljIHZv
aWQgZHdfbXNpX3RlYXJkb3duX2lycShzdHJ1Y3QNCj4gbXNpX2NvbnRyb2xsZXIgKmNoaXAsIHVu
c2lnbmVkIGludCBpcnEpDQo+ID4gIHsNCj4gPiAgCXN0cnVjdCBpcnFfZGF0YSAqZGF0YSA9IGly
cV9nZXRfaXJxX2RhdGEoaXJxKTsNCj4gPiAgCXN0cnVjdCBtc2lfZGVzYyAqbXNpID0gaXJxX2Rh
dGFfZ2V0X21zaShkYXRhKTsNCj4gPiAtCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gc3lzX3RvX3Bj
aWUobXNpLT5kZXYtPmJ1cy0+c3lzZGF0YSk7DQo+ID4gKwlzdHJ1Y3QgcGNpZV9wb3J0ICpwcCA9
IG1zaS0+ZGV2LT5idXMtPnN5c2RhdGE7DQo+ID4NCj4gPiAgCWNsZWFyX2lycV9yYW5nZShwcCwg
aXJxLCAxLCBkYXRhLT5od2lycSk7DQo+ID4gIH0NCj4gPiBAQCAtMzYzLDE0ICszNTUsMTIgQEAg
aW50IGR3X3BjaWVfaG9zdF9pbml0KHN0cnVjdCBwY2llX3BvcnQgKnBwKQ0KPiA+ICB7DQo+ID4g
IAlzdHJ1Y3QgZGV2aWNlX25vZGUgKm5wID0gcHAtPmRldi0+b2Zfbm9kZTsNCj4gPiAgCXN0cnVj
dCBwbGF0Zm9ybV9kZXZpY2UgKnBkZXYgPSB0b19wbGF0Zm9ybV9kZXZpY2UocHAtPmRldik7DQo+
ID4gLQlzdHJ1Y3Qgb2ZfcGNpX3JhbmdlIHJhbmdlOw0KPiA+IC0Jc3RydWN0IG9mX3BjaV9yYW5n
ZV9wYXJzZXIgcGFyc2VyOw0KPiA+ICsJc3RydWN0IHBjaV9idXMgKmJ1czsNCj4gPiAgCXN0cnVj
dCByZXNvdXJjZSAqY2ZnX3JlczsNCj4gPiAtCXUzMiB2YWwsIG5zOw0KPiA+IC0JY29uc3QgX19i
ZTMyICphZGRycDsNCj4gPiAtCWludCBpLCBpbmRleCwgcmV0Ow0KPiA+IC0NCj4gPiAtCW5zID0g
b2Zfbl9zaXplX2NlbGxzKG5wKTsNCj4gPiArCUxJU1RfSEVBRChyZXMpOw0KPiA+ICsJdTMyIHZh
bDsNCj4gPiArCWludCBpLCByZXQ7DQo+ID4gKwlzdHJ1Y3QgcmVzb3VyY2VfZW50cnkgKndpbjsN
Cj4gPg0KPiA+ICAJY2ZnX3JlcyA9IHBsYXRmb3JtX2dldF9yZXNvdXJjZV9ieW5hbWUocGRldiwg
SU9SRVNPVVJDRV9NRU0sDQo+ICJjb25maWciKTsNCj4gPiAgCWlmIChjZmdfcmVzKSB7DQo+ID4g
QEAgLTM3OCw4NSArMzY4LDYwIEBAIGludCBkd19wY2llX2hvc3RfaW5pdChzdHJ1Y3QgcGNpZV9w
b3J0ICpwcCkNCj4gPiAgCQlwcC0+Y2ZnMV9zaXplID0gcmVzb3VyY2Vfc2l6ZShjZmdfcmVzKS8y
Ow0KPiA+ICAJCXBwLT5jZmcwX2Jhc2UgPSBjZmdfcmVzLT5zdGFydDsNCj4gPiAgCQlwcC0+Y2Zn
MV9iYXNlID0gY2ZnX3Jlcy0+c3RhcnQgKyBwcC0+Y2ZnMF9zaXplOw0KPiA+IC0NCj4gPiAtCQkv
KiBGaW5kIHRoZSB1bnRyYW5zbGF0ZWQgY29uZmlndXJhdGlvbiBzcGFjZSBhZGRyZXNzICovDQo+
ID4gLQkJaW5kZXggPSBvZl9wcm9wZXJ0eV9tYXRjaF9zdHJpbmcobnAsICJyZWctbmFtZXMiLCAi
Y29uZmlnIik7DQo+ID4gLQkJYWRkcnAgPSBvZl9nZXRfYWRkcmVzcyhucCwgaW5kZXgsIE5VTEws
IE5VTEwpOw0KPiA+IC0JCXBwLT5jZmcwX21vZF9iYXNlID0gb2ZfcmVhZF9udW1iZXIoYWRkcnAs
IG5zKTsNCj4gPiAtCQlwcC0+Y2ZnMV9tb2RfYmFzZSA9IHBwLT5jZmcwX21vZF9iYXNlICsgcHAt
PmNmZzBfc2l6ZTsNCj4gPiAgCX0gZWxzZSB7DQo+ID4gIAkJZGV2X2VycihwcC0+ZGV2LCAibWlz
c2luZyAqY29uZmlnKiByZWcgc3BhY2VcbiIpOw0KPiA+ICAJfQ0KPiA+DQo+ID4gLQlpZiAob2Zf
cGNpX3JhbmdlX3BhcnNlcl9pbml0KCZwYXJzZXIsIG5wKSkgew0KPiA+IC0JCWRldl9lcnIocHAt
PmRldiwgIm1pc3NpbmcgcmFuZ2VzIHByb3BlcnR5XG4iKTsNCj4gPiAtCQlyZXR1cm4gLUVJTlZB
TDsNCj4gPiAtCX0NCj4gPiArCXJldCA9IG9mX3BjaV9nZXRfaG9zdF9icmlkZ2VfcmVzb3VyY2Vz
KG5wLCAwLCAweGZmLCAmcmVzLCAmcHAtDQo+ID5pb19iYXNlKTsNCj4gPiArCWlmIChyZXQpDQo+
ID4gKwkJcmV0dXJuIHJldDsNCj4gPg0KPiA+ICAJLyogR2V0IHRoZSBJL08gYW5kIG1lbW9yeSBy
YW5nZXMgZnJvbSBEVCAqLw0KPiA+IC0JZm9yX2VhY2hfb2ZfcGNpX3JhbmdlKCZwYXJzZXIsICZy
YW5nZSkgew0KPiA+IC0JCXVuc2lnbmVkIGxvbmcgcmVzdHlwZSA9IHJhbmdlLmZsYWdzICYgSU9S
RVNPVVJDRV9UWVBFX0JJVFM7DQo+ID4gLQ0KPiA+IC0JCWlmIChyZXN0eXBlID09IElPUkVTT1VS
Q0VfSU8pIHsNCj4gPiAtCQkJb2ZfcGNpX3JhbmdlX3RvX3Jlc291cmNlKCZyYW5nZSwgbnAsICZw
cC0+aW8pOw0KPiA+IC0JCQlwcC0+aW8ubmFtZSA9ICJJL08iOw0KPiA+IC0JCQlwcC0+aW8uc3Rh
cnQgPSBtYXhfdChyZXNvdXJjZV9zaXplX3QsDQo+ID4gLQkJCQkJICAgICBQQ0lCSU9TX01JTl9J
TywNCj4gPiAtCQkJCQkgICAgIHJhbmdlLnBjaV9hZGRyICsgZ2xvYmFsX2lvX29mZnNldCk7DQo+
ID4gLQkJCXBwLT5pby5lbmQgPSBtaW5fdChyZXNvdXJjZV9zaXplX3QsDQo+ID4gLQkJCQkJICAg
SU9fU1BBQ0VfTElNSVQsDQo+ID4gLQkJCQkJICAgcmFuZ2UucGNpX2FkZHIgKyByYW5nZS5zaXpl
DQo+ID4gLQkJCQkJICAgKyBnbG9iYWxfaW9fb2Zmc2V0IC0gMSk7DQo+ID4gLQkJCXBwLT5pb19z
aXplID0gcmVzb3VyY2Vfc2l6ZSgmcHAtPmlvKTsNCj4gPiAtCQkJcHAtPmlvX2J1c19hZGRyID0g
cmFuZ2UucGNpX2FkZHI7DQo+ID4gLQkJCXBwLT5pb19iYXNlID0gcmFuZ2UuY3B1X2FkZHI7DQo+
ID4gLQ0KPiA+IC0JCQkvKiBGaW5kIHRoZSB1bnRyYW5zbGF0ZWQgSU8gc3BhY2UgYWRkcmVzcyAq
Lw0KPiA+IC0JCQlwcC0+aW9fbW9kX2Jhc2UgPSByYW5nZS5jcHVfYWRkcjsNCj4gPiAtCQl9DQo+
ID4gLQkJaWYgKHJlc3R5cGUgPT0gSU9SRVNPVVJDRV9NRU0pIHsNCj4gPiAtCQkJb2ZfcGNpX3Jh
bmdlX3RvX3Jlc291cmNlKCZyYW5nZSwgbnAsICZwcC0+bWVtKTsNCj4gPiAtCQkJcHAtPm1lbS5u
YW1lID0gIk1FTSI7DQo+ID4gLQkJCXBwLT5tZW1fc2l6ZSA9IHJlc291cmNlX3NpemUoJnBwLT5t
ZW0pOw0KPiA+IC0JCQlwcC0+bWVtX2J1c19hZGRyID0gcmFuZ2UucGNpX2FkZHI7DQo+ID4gLQ0K
PiA+IC0JCQkvKiBGaW5kIHRoZSB1bnRyYW5zbGF0ZWQgTUVNIHNwYWNlIGFkZHJlc3MgKi8NCj4g
PiAtCQkJcHAtPm1lbV9tb2RfYmFzZSA9IHJhbmdlLmNwdV9hZGRyOw0KPiA+IC0JCX0NCj4gPiAt
CQlpZiAocmVzdHlwZSA9PSAwKSB7DQo+ID4gLQkJCW9mX3BjaV9yYW5nZV90b19yZXNvdXJjZSgm
cmFuZ2UsIG5wLCAmcHAtPmNmZyk7DQo+ID4gLQkJCXBwLT5jZmcwX3NpemUgPSByZXNvdXJjZV9z
aXplKCZwcC0+Y2ZnKS8yOw0KPiA+IC0JCQlwcC0+Y2ZnMV9zaXplID0gcmVzb3VyY2Vfc2l6ZSgm
cHAtPmNmZykvMjsNCj4gPiAtCQkJcHAtPmNmZzBfYmFzZSA9IHBwLT5jZmcuc3RhcnQ7DQo+ID4g
LQkJCXBwLT5jZmcxX2Jhc2UgPSBwcC0+Y2ZnLnN0YXJ0ICsgcHAtPmNmZzBfc2l6ZTsNCj4gPiAt
DQo+ID4gLQkJCS8qIEZpbmQgdGhlIHVudHJhbnNsYXRlZCBjb25maWd1cmF0aW9uIHNwYWNlIGFk
ZHJlc3MNCj4gKi8NCj4gPiAtCQkJcHAtPmNmZzBfbW9kX2Jhc2UgPSByYW5nZS5jcHVfYWRkcjsN
Cj4gPiAtCQkJcHAtPmNmZzFfbW9kX2Jhc2UgPSBwcC0+Y2ZnMF9tb2RfYmFzZSArDQo+ID4gLQkJ
CQkJICAgIHBwLT5jZmcwX3NpemU7DQo+ID4gKwlyZXNvdXJjZV9saXN0X2Zvcl9lYWNoX2VudHJ5
KHdpbiwgJnJlcykgew0KPiA+ICsJCXN3aXRjaCAocmVzb3VyY2VfdHlwZSh3aW4tPnJlcykpIHsN
Cj4gPiArCQljYXNlIElPUkVTT1VSQ0VfSU86DQo+ID4gKwkJCXBwLT5pbyA9IHdpbi0+cmVzOw0K
PiA+ICsJCQlwcC0+aW8tPm5hbWUgPSAiSS9PIjsNCj4gPiArCQkJcHAtPmlvX3NpemUgPSByZXNv
dXJjZV9zaXplKHBwLT5pbyk7DQo+ID4gKwkJCXBwLT5pb19idXNfYWRkciA9IHBwLT5pby0+c3Rh
cnQgLSB3aW4tPm9mZnNldDsNCj4gPiArCQkJcmV0ID0gcGNpX3JlbWFwX2lvc3BhY2UocHAtPmlv
LCBwcC0+aW9fYmFzZSk7DQo+ID4gKwkJCWlmIChyZXQpIHsNCj4gPiArCQkJCWRldl93YXJuKHBw
LT5kZXYsICJlcnJvciAlZDogZmFpbGVkIHRvIG1hcA0KPiByZXNvdXJjZSAlcFJcbiIsDQo+ID4g
KwkJCQkJIHJldCwgcHAtPmlvKTsNCj4gPiArCQkJCWNvbnRpbnVlOw0KPiA+ICsJCQl9DQo+ID4g
KwkJCWJyZWFrOw0KPiA+ICsJCWNhc2UgSU9SRVNPVVJDRV9NRU06DQo+ID4gKwkJCXBwLT5tZW0g
PSB3aW4tPnJlczsNCj4gPiArCQkJcHAtPm1lbS0+bmFtZSA9ICJNRU0iOw0KPiA+ICsJCQlwcC0+
bWVtX3NpemUgPSByZXNvdXJjZV9zaXplKHBwLT5tZW0pOw0KPiA+ICsJCQlwcC0+bWVtX2J1c19h
ZGRyID0gcHAtPm1lbS0+c3RhcnQgLSB3aW4tPm9mZnNldDsNCj4gPiArCQkJYnJlYWs7DQo+ID4g
KwkJY2FzZSAwOg0KPiA+ICsJCQlwcC0+Y2ZnID0gd2luLT5yZXM7DQo+ID4gKwkJCXBwLT5jZmcw
X3NpemUgPSByZXNvdXJjZV9zaXplKHBwLT5jZmcpLzI7DQo+ID4gKwkJCXBwLT5jZmcxX3NpemUg
PSByZXNvdXJjZV9zaXplKHBwLT5jZmcpLzI7DQo+ID4gKwkJCXBwLT5jZmcwX2Jhc2UgPSBwcC0+
Y2ZnLT5zdGFydDsNCj4gPiArCQkJcHAtPmNmZzFfYmFzZSA9IHBwLT5jZmctPnN0YXJ0ICsgcHAt
PmNmZzBfc2l6ZTsNCj4gPiArCQkJYnJlYWs7DQo+ID4gKwkJY2FzZSBJT1JFU09VUkNFX0JVUzoN
Cj4gPiArCQkJcHAtPmJ1c24gPSB3aW4tPnJlczsNCj4gPiArCQkJYnJlYWs7DQo+ID4gKwkJZGVm
YXVsdDoNCj4gPiArCQkJY29udGludWU7DQo+ID4gIAkJfQ0KPiA+ICAJfQ0KPiA+DQo+ID4gLQly
ZXQgPSBvZl9wY2lfcGFyc2VfYnVzX3JhbmdlKG5wLCAmcHAtPmJ1c24pOw0KPiA+IC0JaWYgKHJl
dCA8IDApIHsNCj4gPiAtCQlwcC0+YnVzbi5uYW1lID0gbnAtPm5hbWU7DQo+ID4gLQkJcHAtPmJ1
c24uc3RhcnQgPSAwOw0KPiA+IC0JCXBwLT5idXNuLmVuZCA9IDB4ZmY7DQo+ID4gLQkJcHAtPmJ1
c24uZmxhZ3MgPSBJT1JFU09VUkNFX0JVUzsNCj4gPiAtCQlkZXZfZGJnKHBwLT5kZXYsICJmYWls
ZWQgdG8gcGFyc2UgYnVzLXJhbmdlIHByb3BlcnR5OiAlZCwNCj4gdXNpbmcgZGVmYXVsdCAlcFJc
biIsDQo+ID4gLQkJCXJldCwgJnBwLT5idXNuKTsNCj4gPiAtCX0NCj4gPiAtDQo+ID4gIAlpZiAo
IXBwLT5kYmlfYmFzZSkgew0KPiA+IC0JCXBwLT5kYmlfYmFzZSA9IGRldm1faW9yZW1hcChwcC0+
ZGV2LCBwcC0+Y2ZnLnN0YXJ0LA0KPiA+IC0JCQkJCXJlc291cmNlX3NpemUoJnBwLT5jZmcpKTsN
Cj4gPiArCQlwcC0+ZGJpX2Jhc2UgPSBkZXZtX2lvcmVtYXAocHAtPmRldiwgcHAtPmNmZy0+c3Rh
cnQsDQo+ID4gKwkJCQkJcmVzb3VyY2Vfc2l6ZShwcC0+Y2ZnKSk7DQo+ID4gIAkJaWYgKCFwcC0+
ZGJpX2Jhc2UpIHsNCj4gPiAgCQkJZGV2X2VycihwcC0+ZGV2LCAiZXJyb3Igd2l0aCBpb3JlbWFw
XG4iKTsNCj4gPiAgCQkJcmV0dXJuIC1FTk9NRU07DQo+ID4gIAkJfQ0KPiA+ICAJfQ0KPiA+DQo+
ID4gLQlwcC0+bWVtX2Jhc2UgPSBwcC0+bWVtLnN0YXJ0Ow0KPiA+ICsJcHAtPm1lbV9iYXNlID0g
cHAtPm1lbS0+c3RhcnQ7DQo+ID4NCj4gPiAgCWlmICghcHAtPnZhX2NmZzBfYmFzZSkgew0KPiA+
ICAJCXBwLT52YV9jZmcwX2Jhc2UgPSBkZXZtX2lvcmVtYXAocHAtPmRldiwgcHAtPmNmZzBfYmFz
ZSwNCj4gPiBAQCAtNTA1LDcgKzQ3MCw3IEBAIGludCBkd19wY2llX2hvc3RfaW5pdChzdHJ1Y3Qg
cGNpZV9wb3J0ICpwcCkNCj4gPg0KPiA+ICAJaWYgKCFwcC0+b3BzLT5yZF9vdGhlcl9jb25mKQ0K
PiA+ICAJCWR3X3BjaWVfcHJvZ19vdXRib3VuZF9hdHUocHAsIFBDSUVfQVRVX1JFR0lPTl9JTkRF
WDEsDQo+ID4gLQkJCQkJICBQQ0lFX0FUVV9UWVBFX01FTSwgcHAtPm1lbV9tb2RfYmFzZSwNCj4g
PiArCQkJCQkgIFBDSUVfQVRVX1RZUEVfTUVNLCBwcC0+bWVtX2Jhc2UsDQo+ID4gIAkJCQkJICBw
cC0+bWVtX2J1c19hZGRyLCBwcC0+bWVtX3NpemUpOw0KPiA+DQo+ID4gIAlkd19wY2llX3dyX293
bl9jb25mKHBwLCBQQ0lfQkFTRV9BRERSRVNTXzAsIDQsIDApOw0KPiA+IEBAIC01MTcsMTUgKzQ4
MiwyOSBAQCBpbnQgZHdfcGNpZV9ob3N0X2luaXQoc3RydWN0IHBjaWVfcG9ydCAqcHApDQo+ID4g
IAl2YWwgfD0gUE9SVF9MT0dJQ19TUEVFRF9DSEFOR0U7DQo+ID4gIAlkd19wY2llX3dyX293bl9j
b25mKHBwLCBQQ0lFX0xJTktfV0lEVEhfU1BFRURfQ09OVFJPTCwgNCwgdmFsKTsNCj4gPg0KPiA+
IC0jaWZkZWYgQ09ORklHX1BDSV9NU0kNCj4gPiArCWJ1cyA9IHBjaV9jcmVhdGVfcm9vdF9idXMo
cHAtPmRldiwgcHAtPnJvb3RfYnVzX25yLCAmZHdfcGNpZV9vcHMsDQo+ID4gKwkJCQkgIHBwLCAm
cmVzKTsNCj4gPiArCWlmICghYnVzKQ0KPiA+ICsJCXJldHVybiAtRU5PTUVNOw0KPiA+ICsNCj4g
PiArI2lmZGVmIENPTkZJR19HRU5FUklDX01TSV9JUlFfRE9NQUlODQo+ID4gKwlidXMtPm1zaSA9
IGNvbnRhaW5lcl9vZigmcHAtPmlycV9kb21haW4sIHN0cnVjdCBtc2lfY29udHJvbGxlciwNCj4g
ZG9tYWluKTsNCj4gPiArI2Vsc2UNCj4gPiAgCWR3X3BjaWVfbXNpX2NoaXAuZGV2ID0gcHAtPmRl
djsNCj4gPiAtCWR3X3BjaS5tc2lfY3RybCA9ICZkd19wY2llX21zaV9jaGlwOw0KPiA+ICsJYnVz
LT5tc2kgPSAmZHdfcGNpZV9tc2lfY2hpcDsNCj4gPiAgI2VuZGlmDQo+ID4NCj4gPiAtCWR3X3Bj
aS5ucl9jb250cm9sbGVycyA9IDE7DQo+ID4gLQlkd19wY2kucHJpdmF0ZV9kYXRhID0gKHZvaWQg
KiopJnBwOw0KPiA+ICsJcGNpX3NjYW5fY2hpbGRfYnVzKGJ1cyk7DQo+ID4gKwlpZiAocHAtPm9w
cy0+c2Nhbl9idXMpDQo+ID4gKwkJcHAtPm9wcy0+c2Nhbl9idXMocHApOw0KPiA+ICsNCj4gPiAr
I2lmZGVmIENPTkZJR19BUk0NCj4gPiArCS8qIHN1cHBvcnQgb2xkIGR0YnMgdGhhdCBpbmNvcnJl
Y3RseSBkZXNjcmliZSBJUlFzICovDQo+ID4gKwlwY2lfZml4dXBfaXJxcyhwY2lfY29tbW9uX3N3
aXp6bGUsIG9mX2lycV9wYXJzZV9hbmRfbWFwX3BjaSk7DQo+ID4gKyNlbmRpZg0KPiA+DQo+ID4g
LQlwY2lfY29tbW9uX2luaXRfZGV2KHBwLT5kZXYsICZkd19wY2kpOw0KPiA+ICsJcGNpX2Fzc2ln
bl91bmFzc2lnbmVkX2J1c19yZXNvdXJjZXMoYnVzKTsNCj4gPiArCXBjaV9idXNfYWRkX2Rldmlj
ZXMoYnVzKTsNCj4gPg0KPiA+ICAJcmV0dXJuIDA7DQo+ID4gIH0NCj4gPiBAQCAtNTQ0LDEyICs1
MjMsMTIgQEAgc3RhdGljIGludCBkd19wY2llX3JkX290aGVyX2NvbmYoc3RydWN0DQo+IHBjaWVf
cG9ydCAqcHAsIHN0cnVjdCBwY2lfYnVzICpidXMsDQo+ID4NCj4gPiAgCWlmIChidXMtPnBhcmVu
dC0+bnVtYmVyID09IHBwLT5yb290X2J1c19ucikgew0KPiA+ICAJCXR5cGUgPSBQQ0lFX0FUVV9U
WVBFX0NGRzA7DQo+ID4gLQkJY3B1X2FkZHIgPSBwcC0+Y2ZnMF9tb2RfYmFzZTsNCj4gPiArCQlj
cHVfYWRkciA9IHBwLT5jZmcwX2Jhc2U7DQo+ID4gIAkJY2ZnX3NpemUgPSBwcC0+Y2ZnMF9zaXpl
Ow0KPiA+ICAJCXZhX2NmZ19iYXNlID0gcHAtPnZhX2NmZzBfYmFzZTsNCj4gPiAgCX0gZWxzZSB7
DQo+ID4gIAkJdHlwZSA9IFBDSUVfQVRVX1RZUEVfQ0ZHMTsNCj4gPiAtCQljcHVfYWRkciA9IHBw
LT5jZmcxX21vZF9iYXNlOw0KPiA+ICsJCWNwdV9hZGRyID0gcHAtPmNmZzFfYmFzZTsNCj4gPiAg
CQljZmdfc2l6ZSA9IHBwLT5jZmcxX3NpemU7DQo+ID4gIAkJdmFfY2ZnX2Jhc2UgPSBwcC0+dmFf
Y2ZnMV9iYXNlOw0KPiA+ICAJfQ0KPiA+IEBAIC01NTksNyArNTM4LDcgQEAgc3RhdGljIGludCBk
d19wY2llX3JkX290aGVyX2NvbmYoc3RydWN0IHBjaWVfcG9ydA0KPiAqcHAsIHN0cnVjdCBwY2lf
YnVzICpidXMsDQo+ID4gIAkJCQkgIGJ1c2RldiwgY2ZnX3NpemUpOw0KPiA+ICAJcmV0ID0gZHdf
cGNpZV9jZmdfcmVhZCh2YV9jZmdfYmFzZSArIGFkZHJlc3MsIHdoZXJlLCBzaXplLCB2YWwpOw0K
PiA+ICAJZHdfcGNpZV9wcm9nX291dGJvdW5kX2F0dShwcCwgUENJRV9BVFVfUkVHSU9OX0lOREVY
MCwNCj4gPiAtCQkJCSAgUENJRV9BVFVfVFlQRV9JTywgcHAtPmlvX21vZF9iYXNlLA0KPiA+ICsJ
CQkJICBQQ0lFX0FUVV9UWVBFX0lPLCBwcC0+aW9fYmFzZSwNCj4gPiAgCQkJCSAgcHAtPmlvX2J1
c19hZGRyLCBwcC0+aW9fc2l6ZSk7DQo+ID4NCj4gPiAgCXJldHVybiByZXQ7DQo+ID4gQEAgLTU3
OSwxMiArNTU4LDEyIEBAIHN0YXRpYyBpbnQgZHdfcGNpZV93cl9vdGhlcl9jb25mKHN0cnVjdA0K
PiBwY2llX3BvcnQgKnBwLCBzdHJ1Y3QgcGNpX2J1cyAqYnVzLA0KPiA+DQo+ID4gIAlpZiAoYnVz
LT5wYXJlbnQtPm51bWJlciA9PSBwcC0+cm9vdF9idXNfbnIpIHsNCj4gPiAgCQl0eXBlID0gUENJ
RV9BVFVfVFlQRV9DRkcwOw0KPiA+IC0JCWNwdV9hZGRyID0gcHAtPmNmZzBfbW9kX2Jhc2U7DQo+
ID4gKwkJY3B1X2FkZHIgPSBwcC0+Y2ZnMF9iYXNlOw0KPiA+ICAJCWNmZ19zaXplID0gcHAtPmNm
ZzBfc2l6ZTsNCj4gPiAgCQl2YV9jZmdfYmFzZSA9IHBwLT52YV9jZmcwX2Jhc2U7DQo+ID4gIAl9
IGVsc2Ugew0KPiA+ICAJCXR5cGUgPSBQQ0lFX0FUVV9UWVBFX0NGRzE7DQo+ID4gLQkJY3B1X2Fk
ZHIgPSBwcC0+Y2ZnMV9tb2RfYmFzZTsNCj4gPiArCQljcHVfYWRkciA9IHBwLT5jZmcxX2Jhc2U7
DQo+ID4gIAkJY2ZnX3NpemUgPSBwcC0+Y2ZnMV9zaXplOw0KPiA+ICAJCXZhX2NmZ19iYXNlID0g
cHAtPnZhX2NmZzFfYmFzZTsNCj4gPiAgCX0NCj4gPiBAQCAtNTk0LDcgKzU3Myw3IEBAIHN0YXRp
YyBpbnQgZHdfcGNpZV93cl9vdGhlcl9jb25mKHN0cnVjdCBwY2llX3BvcnQNCj4gKnBwLCBzdHJ1
Y3QgcGNpX2J1cyAqYnVzLA0KPiA+ICAJCQkJICBidXNkZXYsIGNmZ19zaXplKTsNCj4gPiAgCXJl
dCA9IGR3X3BjaWVfY2ZnX3dyaXRlKHZhX2NmZ19iYXNlICsgYWRkcmVzcywgd2hlcmUsIHNpemUs
IHZhbCk7DQo+ID4gIAlkd19wY2llX3Byb2dfb3V0Ym91bmRfYXR1KHBwLCBQQ0lFX0FUVV9SRUdJ
T05fSU5ERVgwLA0KPiA+IC0JCQkJICBQQ0lFX0FUVV9UWVBFX0lPLCBwcC0+aW9fbW9kX2Jhc2Us
DQo+ID4gKwkJCQkgIFBDSUVfQVRVX1RZUEVfSU8sIHBwLT5pb19iYXNlLA0KPiA+ICAJCQkJICBw
cC0+aW9fYnVzX2FkZHIsIHBwLT5pb19zaXplKTsNCj4gPg0KPiA+ICAJcmV0dXJuIHJldDsNCj4g
PiBAQCAtNjI2LDcgKzYwNSw3IEBAIHN0YXRpYyBpbnQgZHdfcGNpZV92YWxpZF9jb25maWcoc3Ry
dWN0IHBjaWVfcG9ydA0KPiAqcHAsDQo+ID4gIHN0YXRpYyBpbnQgZHdfcGNpZV9yZF9jb25mKHN0
cnVjdCBwY2lfYnVzICpidXMsIHUzMiBkZXZmbiwgaW50IHdoZXJlLA0KPiA+ICAJCQlpbnQgc2l6
ZSwgdTMyICp2YWwpDQo+ID4gIHsNCj4gPiAtCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gc3lzX3Rv
X3BjaWUoYnVzLT5zeXNkYXRhKTsNCj4gPiArCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gYnVzLT5z
eXNkYXRhOw0KPiA+ICAJaW50IHJldDsNCj4gPg0KPiA+ICAJaWYgKGR3X3BjaWVfdmFsaWRfY29u
ZmlnKHBwLCBidXMsIFBDSV9TTE9UKGRldmZuKSkgPT0gMCkgew0KPiA+IEBAIC02NTAsNyArNjI5
LDcgQEAgc3RhdGljIGludCBkd19wY2llX3JkX2NvbmYoc3RydWN0IHBjaV9idXMgKmJ1cywNCj4g
dTMyIGRldmZuLCBpbnQgd2hlcmUsDQo+ID4gIHN0YXRpYyBpbnQgZHdfcGNpZV93cl9jb25mKHN0
cnVjdCBwY2lfYnVzICpidXMsIHUzMiBkZXZmbiwNCj4gPiAgCQkJaW50IHdoZXJlLCBpbnQgc2l6
ZSwgdTMyIHZhbCkNCj4gPiAgew0KPiA+IC0Jc3RydWN0IHBjaWVfcG9ydCAqcHAgPSBzeXNfdG9f
cGNpZShidXMtPnN5c2RhdGEpOw0KPiA+ICsJc3RydWN0IHBjaWVfcG9ydCAqcHAgPSBidXMtPnN5
c2RhdGE7DQo+ID4gIAlpbnQgcmV0Ow0KPiA+DQo+ID4gIAlpZiAoZHdfcGNpZV92YWxpZF9jb25m
aWcocHAsIGJ1cywgUENJX1NMT1QoZGV2Zm4pKSA9PSAwKQ0KPiA+IEBAIC02NzQsNjIgKzY1Myw2
IEBAIHN0YXRpYyBzdHJ1Y3QgcGNpX29wcyBkd19wY2llX29wcyA9IHsNCj4gPiAgCS53cml0ZSA9
IGR3X3BjaWVfd3JfY29uZiwNCj4gPiAgfTsNCj4gPg0KPiA+IC1zdGF0aWMgaW50IGR3X3BjaWVf
c2V0dXAoaW50IG5yLCBzdHJ1Y3QgcGNpX3N5c19kYXRhICpzeXMpDQo+ID4gLXsNCj4gPiAtCXN0
cnVjdCBwY2llX3BvcnQgKnBwOw0KPiA+IC0NCj4gPiAtCXBwID0gc3lzX3RvX3BjaWUoc3lzKTsN
Cj4gPiAtDQo+ID4gLQlpZiAoZ2xvYmFsX2lvX29mZnNldCA8IFNaXzFNICYmIHBwLT5pb19zaXpl
ID4gMCkgew0KPiA+IC0JCXN5cy0+aW9fb2Zmc2V0ID0gZ2xvYmFsX2lvX29mZnNldCAtIHBwLT5p
b19idXNfYWRkcjsNCj4gPiAtCQlwY2lfaW9yZW1hcF9pbyhnbG9iYWxfaW9fb2Zmc2V0LCBwcC0+
aW9fYmFzZSk7DQo+ID4gLQkJZ2xvYmFsX2lvX29mZnNldCArPSBTWl82NEs7DQo+ID4gLQkJcGNp
X2FkZF9yZXNvdXJjZV9vZmZzZXQoJnN5cy0+cmVzb3VyY2VzLCAmcHAtPmlvLA0KPiA+IC0JCQkJ
CXN5cy0+aW9fb2Zmc2V0KTsNCj4gPiAtCX0NCj4gPiAtDQo+ID4gLQlzeXMtPm1lbV9vZmZzZXQg
PSBwcC0+bWVtLnN0YXJ0IC0gcHAtPm1lbV9idXNfYWRkcjsNCj4gPiAtCXBjaV9hZGRfcmVzb3Vy
Y2Vfb2Zmc2V0KCZzeXMtPnJlc291cmNlcywgJnBwLT5tZW0sIHN5cy0NCj4gPm1lbV9vZmZzZXQp
Ow0KPiA+IC0JcGNpX2FkZF9yZXNvdXJjZSgmc3lzLT5yZXNvdXJjZXMsICZwcC0+YnVzbik7DQo+
ID4gLQ0KPiA+IC0JcmV0dXJuIDE7DQo+ID4gLX0NCj4gPiAtDQo+ID4gLXN0YXRpYyBzdHJ1Y3Qg
cGNpX2J1cyAqZHdfcGNpZV9zY2FuX2J1cyhpbnQgbnIsIHN0cnVjdCBwY2lfc3lzX2RhdGENCj4g
KnN5cykNCj4gPiAtew0KPiA+IC0Jc3RydWN0IHBjaV9idXMgKmJ1czsNCj4gPiAtCXN0cnVjdCBw
Y2llX3BvcnQgKnBwID0gc3lzX3RvX3BjaWUoc3lzKTsNCj4gPiAtDQo+ID4gLQlwcC0+cm9vdF9i
dXNfbnIgPSBzeXMtPmJ1c25yOw0KPiA+IC0JYnVzID0gcGNpX3NjYW5fcm9vdF9idXMocHAtPmRl
diwgc3lzLT5idXNuciwNCj4gPiAtCQkJCSAgJmR3X3BjaWVfb3BzLCBzeXMsICZzeXMtPnJlc291
cmNlcyk7DQo+ID4gLQlpZiAoIWJ1cykNCj4gPiAtCQlyZXR1cm4gTlVMTDsNCj4gPiAtDQo+ID4g
LQlpZiAoYnVzICYmIHBwLT5vcHMtPnNjYW5fYnVzKQ0KPiA+IC0JCXBwLT5vcHMtPnNjYW5fYnVz
KHBwKTsNCj4gPiAtDQo+ID4gLQlyZXR1cm4gYnVzOw0KPiA+IC19DQo+ID4gLQ0KPiA+IC1zdGF0
aWMgaW50IGR3X3BjaWVfbWFwX2lycShjb25zdCBzdHJ1Y3QgcGNpX2RldiAqZGV2LCB1OCBzbG90
LCB1OA0KPiBwaW4pDQo+ID4gLXsNCj4gPiAtCXN0cnVjdCBwY2llX3BvcnQgKnBwID0gc3lzX3Rv
X3BjaWUoZGV2LT5idXMtPnN5c2RhdGEpOw0KPiA+IC0JaW50IGlycTsNCj4gPiAtDQo+ID4gLQlp
cnEgPSBvZl9pcnFfcGFyc2VfYW5kX21hcF9wY2koZGV2LCBzbG90LCBwaW4pOw0KPiA+IC0JaWYg
KCFpcnEpDQo+ID4gLQkJaXJxID0gcHAtPmlycTsNCj4gPiAtDQo+ID4gLQlyZXR1cm4gaXJxOw0K
PiA+IC19DQo+ID4gLQ0KPiA+IC1zdGF0aWMgc3RydWN0IGh3X3BjaSBkd19wY2kgPSB7DQo+ID4g
LQkuc2V0dXAJCT0gZHdfcGNpZV9zZXR1cCwNCj4gPiAtCS5zY2FuCQk9IGR3X3BjaWVfc2Nhbl9i
dXMsDQo+ID4gLQkubWFwX2lycQk9IGR3X3BjaWVfbWFwX2lycSwNCj4gPiAtfTsNCj4gPiAtDQo+
ID4gIHZvaWQgZHdfcGNpZV9zZXR1cF9yYyhzdHJ1Y3QgcGNpZV9wb3J0ICpwcCkNCj4gPiAgew0K
PiA+ICAJdTMyIHZhbDsNCj4gPiBkaWZmIC0tZ2l0IGEvZHJpdmVycy9wY2kvaG9zdC9wY2llLWRl
c2lnbndhcmUuaA0KPiBiL2RyaXZlcnMvcGNpL2hvc3QvcGNpZS1kZXNpZ253YXJlLmgNCj4gPiBp
bmRleCBkMGJiZDI3Li4yNjRjOTY5IDEwMDY0NA0KPiA+IC0tLSBhL2RyaXZlcnMvcGNpL2hvc3Qv
cGNpZS1kZXNpZ253YXJlLmgNCj4gPiArKysgYi9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtZGVzaWdu
d2FyZS5oDQo+ID4gQEAgLTI3LDI1ICsyNywyMSBAQCBzdHJ1Y3QgcGNpZV9wb3J0IHsNCj4gPiAg
CXU4CQkJcm9vdF9idXNfbnI7DQo+ID4gIAl2b2lkIF9faW9tZW0JCSpkYmlfYmFzZTsNCj4gPiAg
CXU2NAkJCWNmZzBfYmFzZTsNCj4gPiAtCXU2NAkJCWNmZzBfbW9kX2Jhc2U7DQo+ID4gIAl2b2lk
IF9faW9tZW0JCSp2YV9jZmcwX2Jhc2U7DQo+ID4gIAl1MzIJCQljZmcwX3NpemU7DQo+ID4gIAl1
NjQJCQljZmcxX2Jhc2U7DQo+ID4gLQl1NjQJCQljZmcxX21vZF9iYXNlOw0KPiA+ICAJdm9pZCBf
X2lvbWVtCQkqdmFfY2ZnMV9iYXNlOw0KPiA+ICAJdTMyCQkJY2ZnMV9zaXplOw0KPiA+IC0JdTY0
CQkJaW9fYmFzZTsNCj4gPiAtCXU2NAkJCWlvX21vZF9iYXNlOw0KPiA+ICsJcmVzb3VyY2Vfc2l6
ZV90CQlpb19iYXNlOw0KPiA+ICAJcGh5c19hZGRyX3QJCWlvX2J1c19hZGRyOw0KPiA+ICAJdTMy
CQkJaW9fc2l6ZTsNCj4gPiAgCXU2NAkJCW1lbV9iYXNlOw0KPiA+IC0JdTY0CQkJbWVtX21vZF9i
YXNlOw0KPiA+ICAJcGh5c19hZGRyX3QJCW1lbV9idXNfYWRkcjsNCj4gPiAgCXUzMgkJCW1lbV9z
aXplOw0KPiA+IC0Jc3RydWN0IHJlc291cmNlCQljZmc7DQo+ID4gLQlzdHJ1Y3QgcmVzb3VyY2UJ
CWlvOw0KPiA+IC0Jc3RydWN0IHJlc291cmNlCQltZW07DQo+ID4gLQlzdHJ1Y3QgcmVzb3VyY2UJ
CWJ1c247DQo+ID4gKwlzdHJ1Y3QgcmVzb3VyY2UJCSpjZmc7DQo+ID4gKwlzdHJ1Y3QgcmVzb3Vy
Y2UJCSppbzsNCj4gPiArCXN0cnVjdCByZXNvdXJjZQkJKm1lbTsNCj4gPiArCXN0cnVjdCByZXNv
dXJjZQkJKmJ1c247DQo+ID4gIAlpbnQJCQlpcnE7DQo+ID4gIAl1MzIJCQlsYW5lczsNCj4gPiAg
CXN0cnVjdCBwY2llX2hvc3Rfb3BzCSpvcHM7DQo+ID4gZGlmZiAtLWdpdCBhL2RyaXZlcnMvcGNp
L2hvc3QvcGNpZS1zcGVhcjEzeHguYw0KPiBiL2RyaXZlcnMvcGNpL2hvc3QvcGNpZS1zcGVhcjEz
eHguYw0KPiA+IGluZGV4IGM0OWZiZGMuLjAzZWIyMDQgMTAwNjQ0DQo+ID4gLS0tIGEvZHJpdmVy
cy9wY2kvaG9zdC9wY2llLXNwZWFyMTN4eC5jDQo+ID4gKysrIGIvZHJpdmVycy9wY2kvaG9zdC9w
Y2llLXNwZWFyMTN4eC5jDQo+ID4gQEAgLTI4Niw3ICsyODYsNyBAQCBzdGF0aWMgaW50IHNwZWFy
MTN4eF9hZGRfcGNpZV9wb3J0KHN0cnVjdA0KPiBwY2llX3BvcnQgKnBwLA0KPiA+ICAJCXJldHVy
biByZXQ7DQo+ID4gIAl9DQo+ID4NCj4gPiAtCXBwLT5yb290X2J1c19uciA9IC0xOw0KPiA+ICsJ
cHAtPnJvb3RfYnVzX25yID0gMDsNCj4gPiAgCXBwLT5vcHMgPSAmc3BlYXIxM3h4X3BjaWVfaG9z
dF9vcHM7DQo+ID4NCj4gPiAgCXJldCA9IGR3X3BjaWVfaG9zdF9pbml0KHBwKTsNCj4gDQo+IC0t
DQo+IFBlbmd1dHJvbml4IGUuSy4gICAgICAgICAgICAgfCBMdWNhcyBTdGFjaCAgICAgICAgICAg
ICAgICAgfA0KPiBJbmR1c3RyaWFsIExpbnV4IFNvbHV0aW9ucyAgIHwgaHR0cDovL3d3dy5wZW5n
dXRyb25peC5kZS8gIHwNCg0K
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Lucas Stach Aug. 19, 2015, 3:37 p.m. UTC | #4
Hi Gab,

Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele Paoloni:
> Hi Lucas
> 
> I have rewritten the patch to take into account multiple controllers.
> 
> As you can see now there is a static var in dw_pcie_host_init() that tracks
> the bus numbers used.

This is wrong. The DT specifies the valid bus number range. You can not
just assign the next free bus number to the root bus.

It is perfectly valid to have a bus range of 0x00-0x10 assigned to one
instance and 0x50-0xff to the next instance. Additional with PCIe
hotplug you may not use the full range of the bus numbers on one
instance at the first scan, but only later populate more buses when more
bridges are added to the tree.

> Drivers that do not specify the bus range in the DTB set pp->root_bus_nr = DW_ROOT_NR_UNDEFINED.
> Designware will check if the flag is set and will use the automatic bus range
> assignment.

No, please lets get rid of this assignment altogether. The glue drivers
have no business in assigning the bus range. Please remove the
pp->root_bus_nr assignment from all the glue drivers.

"bus range" is a generic DW PCIe property, so just parse the root bus
number from the DT, it is handled the same way for all the DW based PCIe
drivers. The bindings specifies that if the bus range property is
missing the range is 0x00-0xff, so you can default to 0 as the root bus
number in that case.

Also I would think this conversion warrants a patch on its own and
should not be mixed in the ARM64 support patch.

Regards,
Lucas

> Instead if the driver assigns pp->root_bus_nr according to the dtb, designwware
> will use the value passed in by the driver.
> Below the relevant section:
> 
> 
> +	static int root_bus_nr = 0;
> ...
> +	mutex_lock(&root_bus_nr_mux);
> +
> +	if (pp->root_bus_nr != DW_ROOT_NR_UNDEFINED)
> +		root_bus_nr = pp->root_bus_nr;
> +
> +	bus = pci_create_root_bus(pp->dev, root_bus_nr, &dw_pcie_ops,
> +			      pp, &res);
> +	if (!bus) {
> +		mutex_unlock(&root_bus_nr_mux);
> +		return -ENOMEM;
> +	}
> +
> +	root_bus_nr += bus->busn_res.end + 1;
> +	mutex_unlock(&root_bus_nr_mux);
> 
> Please let me know what you think...
> 
> Many Thanks
> 
> Gab
> ----------
> 
> From: gabriele paoloni <gabriele.paoloni@huawei.com>
> 
> This patch tries to unify ARM32 and ARM64 PCIe in designware driver. Delete
> function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct hw_pci,
> move related operations to dw_pcie_host_init.
> Also set pp->root_bus_nr = DW_ROOT_NR_UNDEFINED in all the drivers that
> are based on designware to flag that the drivers do not read the bus
> ranges from DT.
> This patch also adds handling of multiple PCI domains in designware.
> if the PCI host bridge driver does not specify a root bus number, in case
> of multiple domains, designware will automatillay set the next domain root
> bus number to the last bus number used in the last domain + 1.
> 
> This patch also try to use of_pci_get_host_bridge_resources for ARM32 and
> ARM64 according to the suggestion for Gabriele[1]
> 
> This patch is based on Gabriele's patch about of_pci_range fix[2]
> 
> Finally this patch reverts commit f4c55c5a3f7f "PCI: designware:
> Program ATU with untranslated address". This was discussed in [3]
> 
> I have compiled the driver with multi_v7_defconfig. However, I don't have
> ARM32 PCIe related board to do test. It will be appreciated if someone could
> help to test it.
> 
> Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
> Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> 
> [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> [2] https://patchwork.ozlabs.org/patch/495018/
> [3] http://www.spinics.net/lists/arm-kernel/msg436779.html
> ---
>  drivers/pci/host/pci-dra7xx.c      |  15 +--
>  drivers/pci/host/pci-exynos.c      |   2 +-
>  drivers/pci/host/pci-imx6.c        |   2 +-
>  drivers/pci/host/pci-keystone-dw.c |   2 +-
>  drivers/pci/host/pci-keystone.c    |   2 +-
>  drivers/pci/host/pci-layerscape.c  |   2 +-
>  drivers/pci/host/pcie-designware.c | 247 ++++++++++++++-----------------------
>  drivers/pci/host/pcie-designware.h |  15 +--
>  drivers/pci/host/pcie-spear13xx.c  |   2 +-
>  9 files changed, 110 insertions(+), 179 deletions(-)
> 
> diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
> index 5678b57..8d598fb 100644
> --- a/drivers/pci/host/pci-dra7xx.c
> +++ b/drivers/pci/host/pci-dra7xx.c
> @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct pcie_port *pp)
>  {
>  	dw_pcie_setup_rc(pp);
>  
> -	if (pp->io_mod_base)
> -		pp->io_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->io_base)
> +		pp->io_base &= CPU_TO_BUS_ADDR;
>  
> -	if (pp->mem_mod_base)
> -		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->mem_base)
> +		pp->mem_base &= CPU_TO_BUS_ADDR;
>  
> -	if (pp->cfg0_mod_base) {
> -		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> -		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> +	if (pp->cfg0_base) {
> +		pp->cfg0_base &= CPU_TO_BUS_ADDR;
> +		pp->cfg1_base &= CPU_TO_BUS_ADDR;
>  	}
>  
>  	dra7xx_pcie_establish_link(pp);
> @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
>  
>  	pp = &dra7xx->pp;
>  	pp->dev = dev;
> +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
>  	pp->ops = &dra7xx_pcie_host_ops;
>  
>  	pp->irq = platform_get_irq(pdev, 1);
> diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
> index f9f468d..ed03a8f 100644
> --- a/drivers/pci/host/pci-exynos.c
> +++ b/drivers/pci/host/pci-exynos.c
> @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct pcie_port *pp,
>  		}
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
>  	pp->ops = &exynos_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
> index 233a196..0efac85 100644
> --- a/drivers/pci/host/pci-imx6.c
> +++ b/drivers/pci/host/pci-imx6.c
> @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct pcie_port *pp,
>  		}
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
>  	pp->ops = &imx6_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
> index f34892e..b1e4135 100644
> --- a/drivers/pci/host/pci-keystone-dw.c
> +++ b/drivers/pci/host/pci-keystone-dw.c
> @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt)
>  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
>  {
>  	struct pcie_port *pp = &ks_pcie->pp;
> -	u32 start = pp->mem.start, end = pp->mem.end;
> +	u32 start = pp->mem->start, end = pp->mem->end;
>  	int i, tr_size;
>  
>  	/* Disable BARs for inbound access */
> diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c
> index 734da58..b522956 100644
> --- a/drivers/pci/host/pci-keystone.c
> +++ b/drivers/pci/host/pci-keystone.c
> @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie,
>  			return ret;
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
>  	pp->ops = &keystone_pcie_host_ops;
>  	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
>  	if (ret) {
> diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
> index b2328ea1..dd92ffa 100644
> --- a/drivers/pci/host/pci-layerscape.c
> +++ b/drivers/pci/host/pci-layerscape.c
> @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)
>  	pp = &pcie->pp;
>  	pp->dev = pcie->dev;
>  	pp->dbi_base = pcie->dbi;
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
>  	pp->ops = &ls_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
> index 5307b35..bd2606b 100644
> --- a/drivers/pci/host/pcie-designware.c
> +++ b/drivers/pci/host/pcie-designware.c
> @@ -11,6 +11,7 @@
>   * published by the Free Software Foundation.
>   */
>  
> +#include <linux/hardirq.h>
>  #include <linux/irq.h>
>  #include <linux/irqdomain.h>
>  #include <linux/kernel.h>
> @@ -69,16 +70,9 @@
>  #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
>  #define PCIE_ATU_UPPER_TARGET		0x91C
>  
> -static struct hw_pci dw_pci;
> +static struct pci_ops dw_pcie_ops;
>  
> -static unsigned long global_io_offset;
> -
> -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
> -{
> -	BUG_ON(!sys->private_data);
> -
> -	return sys->private_data;
> -}
> +DEFINE_MUTEX(root_bus_nr_mux);
>  
>  int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
>  {
> @@ -255,7 +249,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
>  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
>  {
>  	int irq, pos0, i;
> -	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
> +	struct pcie_port *pp = desc->dev->bus->sysdata;
>  
>  	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
>  				       order_base_2(no_irqs));
> @@ -298,7 +292,7 @@ static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
>  {
>  	int irq, pos;
>  	struct msi_msg msg;
> -	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
> +	struct pcie_port *pp = pdev->bus->sysdata;
>  
>  	if (desc->msi_attrib.is_msix)
>  		return -EINVAL;
> @@ -327,7 +321,7 @@ static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
>  {
>  	struct irq_data *data = irq_get_irq_data(irq);
>  	struct msi_desc *msi = irq_data_get_msi(data);
> -	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
> +	struct pcie_port *pp = msi->dev->bus->sysdata;
>  
>  	clear_irq_range(pp, irq, 1, data->hwirq);
>  }
> @@ -359,22 +353,17 @@ static const struct irq_domain_ops msi_domain_ops = {
>  	.map = dw_pcie_msi_map,
>  };
>  
> -int dw_pcie_host_init(struct pcie_port *pp)
> +int __init dw_pcie_host_init(struct pcie_port *pp)
>  {
>  	struct device_node *np = pp->dev->of_node;
>  	struct platform_device *pdev = to_platform_device(pp->dev);
> -	struct of_pci_range range;
> -	struct of_pci_range_parser parser;
> +	struct pci_bus *bus;
>  	struct resource *cfg_res;
> -	u32 val, na, ns;
> -	const __be32 *addrp;
> -	int i, index, ret;
> -
> -	/* Find the address cell size and the number of cells in order to get
> -	 * the untranslated address.
> -	 */
> -	of_property_read_u32(np, "#address-cells", &na);
> -	ns = of_n_size_cells(np);
> +	LIST_HEAD(res);
> +	u32 val;
> +	int i, ret;
> +	struct resource_entry *win;
> +	static int root_bus_nr = 0;
>  
>  	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
>  	if (cfg_res) {
> @@ -382,85 +371,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  		pp->cfg1_size = resource_size(cfg_res)/2;
>  		pp->cfg0_base = cfg_res->start;
>  		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> -
> -		/* Find the untranslated configuration space address */
> -		index = of_property_match_string(np, "reg-names", "config");
> -		addrp = of_get_address(np, index, NULL, NULL);
> -		pp->cfg0_mod_base = of_read_number(addrp, ns);
> -		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
>  	} else {
>  		dev_err(pp->dev, "missing *config* reg space\n");
>  	}
>  
> -	if (of_pci_range_parser_init(&parser, np)) {
> -		dev_err(pp->dev, "missing ranges property\n");
> -		return -EINVAL;
> -	}
> +	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base);
> +	if (ret)
> +		return ret;
>  
>  	/* Get the I/O and memory ranges from DT */
> -	for_each_of_pci_range(&parser, &range) {
> -		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
> -
> -		if (restype == IORESOURCE_IO) {
> -			of_pci_range_to_resource(&range, np, &pp->io);
> -			pp->io.name = "I/O";
> -			pp->io.start = max_t(resource_size_t,
> -					     PCIBIOS_MIN_IO,
> -					     range.pci_addr + global_io_offset);
> -			pp->io.end = min_t(resource_size_t,
> -					   IO_SPACE_LIMIT,
> -					   range.pci_addr + range.size
> -					   + global_io_offset - 1);
> -			pp->io_size = resource_size(&pp->io);
> -			pp->io_bus_addr = range.pci_addr;
> -			pp->io_base = range.cpu_addr;
> -
> -			/* Find the untranslated IO space address */
> -			pp->io_mod_base = range.cpu_addr;
> -		}
> -		if (restype == IORESOURCE_MEM) {
> -			of_pci_range_to_resource(&range, np, &pp->mem);
> -			pp->mem.name = "MEM";
> -			pp->mem_size = resource_size(&pp->mem);
> -			pp->mem_bus_addr = range.pci_addr;
> -
> -			/* Find the untranslated MEM space address */
> -			pp->mem_mod_base = range.cpu_addr;
> -		}
> -		if (restype == 0) {
> -			of_pci_range_to_resource(&range, np, &pp->cfg);
> -			pp->cfg0_size = resource_size(&pp->cfg)/2;
> -			pp->cfg1_size = resource_size(&pp->cfg)/2;
> -			pp->cfg0_base = pp->cfg.start;
> -			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> -
> -			/* Find the untranslated configuration space address */
> -			pp->cfg0_mod_base = range.cpu_addr;
> -			pp->cfg1_mod_base = pp->cfg0_mod_base +
> -					    pp->cfg0_size;
> +	resource_list_for_each_entry(win, &res) {
> +		switch (resource_type(win->res)) {
> +		case IORESOURCE_IO:
> +			pp->io = win->res;
> +			pp->io->name = "I/O";
> +			pp->io_size = resource_size(pp->io);
> +			pp->io_bus_addr = pp->io->start - win->offset;
> +			ret = pci_remap_iospace(pp->io, pp->io_base);
> +			if (ret) {
> +				dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
> +					 ret, pp->io);
> +				continue;
> +			}
> +			break;
> +		case IORESOURCE_MEM:
> +			pp->mem = win->res;
> +			pp->mem->name = "MEM";
> +			pp->mem_size = resource_size(pp->mem);
> +			pp->mem_bus_addr = pp->mem->start - win->offset;
> +			break;
> +		case 0:
> +			pp->cfg = win->res;
> +			pp->cfg0_size = resource_size(pp->cfg)/2;
> +			pp->cfg1_size = resource_size(pp->cfg)/2;
> +			pp->cfg0_base = pp->cfg->start;
> +			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
> +			break;
> +		case IORESOURCE_BUS:
> +			pp->busn = win->res;
> +			break;
> +		default:
> +			continue;
>  		}
>  	}
>  
> -	ret = of_pci_parse_bus_range(np, &pp->busn);
> -	if (ret < 0) {
> -		pp->busn.name = np->name;
> -		pp->busn.start = 0;
> -		pp->busn.end = 0xff;
> -		pp->busn.flags = IORESOURCE_BUS;
> -		dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n",
> -			ret, &pp->busn);
> -	}
> -
>  	if (!pp->dbi_base) {
> -		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
> -					resource_size(&pp->cfg));
> +		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
> +					resource_size(pp->cfg));
>  		if (!pp->dbi_base) {
>  			dev_err(pp->dev, "error with ioremap\n");
>  			return -ENOMEM;
>  		}
>  	}
>  
> -	pp->mem_base = pp->mem.start;
> +	pp->mem_base = pp->mem->start;
>  
>  	if (!pp->va_cfg0_base) {
>  		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
> @@ -509,7 +473,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  
>  	if (!pp->ops->rd_other_conf)
>  		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> -					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
> +					  PCIE_ATU_TYPE_MEM, pp->mem_base,
>  					  pp->mem_bus_addr, pp->mem_size);
>  
>  	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> @@ -521,15 +485,40 @@ int dw_pcie_host_init(struct pcie_port *pp)
>  	val |= PORT_LOGIC_SPEED_CHANGE;
>  	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
>  
> -#ifdef CONFIG_PCI_MSI
>  	dw_pcie_msi_chip.dev = pp->dev;
> -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> +
> +	mutex_lock(&root_bus_nr_mux);
> +
> +	if (pp->root_bus_nr != DW_ROOT_NR_UNDEFINED)
> +		root_bus_nr = pp->root_bus_nr;
> +
> +	bus = pci_create_root_bus(pp->dev, root_bus_nr, &dw_pcie_ops,
> +			      pp, &res);
> +	if (!bus) {
> +		mutex_unlock(&root_bus_nr_mux);
> +		return -ENOMEM;
> +	}
> +
> +	root_bus_nr += bus->busn_res.end + 1;
> +	mutex_unlock(&root_bus_nr_mux);
> +
> +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> +	bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain);
> +#else
> +	bus->msi = &dw_pcie_msi_chip;
>  #endif
>  
> -	dw_pci.nr_controllers = 1;
> -	dw_pci.private_data = (void **)&pp;
> +	pci_scan_child_bus(bus);
> +	if (pp->ops->scan_bus)
> +		pp->ops->scan_bus(pp);
> +
> +#ifdef CONFIG_ARM
> +	/* support old dtbs that incorrectly describe IRQs */
> +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> +#endif
>  
> -	pci_common_init_dev(pp->dev, &dw_pci);
> +	pci_assign_unassigned_bus_resources(bus);
> +	pci_bus_add_devices(bus);
>  
>  	return 0;
>  }
> @@ -548,12 +537,12 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  
>  	if (bus->parent->number == pp->root_bus_nr) {
>  		type = PCIE_ATU_TYPE_CFG0;
> -		cpu_addr = pp->cfg0_mod_base;
> +		cpu_addr = pp->cfg0_base;
>  		cfg_size = pp->cfg0_size;
>  		va_cfg_base = pp->va_cfg0_base;
>  	} else {
>  		type = PCIE_ATU_TYPE_CFG1;
> -		cpu_addr = pp->cfg1_mod_base;
> +		cpu_addr = pp->cfg1_base;
>  		cfg_size = pp->cfg1_size;
>  		va_cfg_base = pp->va_cfg1_base;
>  	}
> @@ -563,7 +552,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  				  busdev, cfg_size);
>  	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
>  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +				  PCIE_ATU_TYPE_IO, pp->io_base,
>  				  pp->io_bus_addr, pp->io_size);
>  
>  	return ret;
> @@ -583,12 +572,12 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  
>  	if (bus->parent->number == pp->root_bus_nr) {
>  		type = PCIE_ATU_TYPE_CFG0;
> -		cpu_addr = pp->cfg0_mod_base;
> +		cpu_addr = pp->cfg0_base;
>  		cfg_size = pp->cfg0_size;
>  		va_cfg_base = pp->va_cfg0_base;
>  	} else {
>  		type = PCIE_ATU_TYPE_CFG1;
> -		cpu_addr = pp->cfg1_mod_base;
> +		cpu_addr = pp->cfg1_base;
>  		cfg_size = pp->cfg1_size;
>  		va_cfg_base = pp->va_cfg1_base;
>  	}
> @@ -598,7 +587,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
>  				  busdev, cfg_size);
>  	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
>  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> +				  PCIE_ATU_TYPE_IO, pp->io_base,
>  				  pp->io_bus_addr, pp->io_size);
>  
>  	return ret;
> @@ -630,7 +619,7 @@ static int dw_pcie_valid_config(struct pcie_port *pp,
>  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>  			int size, u32 *val)
>  {
> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +	struct pcie_port *pp = bus->sysdata;
>  	int ret;
>  
>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
> @@ -654,7 +643,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
>  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
>  			int where, int size, u32 val)
>  {
> -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> +	struct pcie_port *pp = bus->sysdata;
>  	int ret;
>  
>  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
> @@ -678,62 +667,6 @@ static struct pci_ops dw_pcie_ops = {
>  	.write = dw_pcie_wr_conf,
>  };
>  
> -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
> -{
> -	struct pcie_port *pp;
> -
> -	pp = sys_to_pcie(sys);
> -
> -	if (global_io_offset < SZ_1M && pp->io_size > 0) {
> -		sys->io_offset = global_io_offset - pp->io_bus_addr;
> -		pci_ioremap_io(global_io_offset, pp->io_base);
> -		global_io_offset += SZ_64K;
> -		pci_add_resource_offset(&sys->resources, &pp->io,
> -					sys->io_offset);
> -	}
> -
> -	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
> -	pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
> -	pci_add_resource(&sys->resources, &pp->busn);
> -
> -	return 1;
> -}
> -
> -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
> -{
> -	struct pci_bus *bus;
> -	struct pcie_port *pp = sys_to_pcie(sys);
> -
> -	pp->root_bus_nr = sys->busnr;
> -	bus = pci_scan_root_bus(pp->dev, sys->busnr,
> -				  &dw_pcie_ops, sys, &sys->resources);
> -	if (!bus)
> -		return NULL;
> -
> -	if (bus && pp->ops->scan_bus)
> -		pp->ops->scan_bus(pp);
> -
> -	return bus;
> -}
> -
> -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
> -{
> -	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
> -	int irq;
> -
> -	irq = of_irq_parse_and_map_pci(dev, slot, pin);
> -	if (!irq)
> -		irq = pp->irq;
> -
> -	return irq;
> -}
> -
> -static struct hw_pci dw_pci = {
> -	.setup		= dw_pcie_setup,
> -	.scan		= dw_pcie_scan_bus,
> -	.map_irq	= dw_pcie_map_irq,
> -};
> -
>  void dw_pcie_setup_rc(struct pcie_port *pp)
>  {
>  	u32 val;
> diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
> index d0bbd27..0c2a7eb 100644
> --- a/drivers/pci/host/pcie-designware.h
> +++ b/drivers/pci/host/pcie-designware.h
> @@ -21,31 +21,28 @@
>   */
>  #define MAX_MSI_IRQS			32
>  #define MAX_MSI_CTRLS			(MAX_MSI_IRQS / 32)
> +#define DW_ROOT_NR_UNDEFINED	-1
>  
>  struct pcie_port {
>  	struct device		*dev;
>  	u8			root_bus_nr;
>  	void __iomem		*dbi_base;
>  	u64			cfg0_base;
> -	u64			cfg0_mod_base;
>  	void __iomem		*va_cfg0_base;
>  	u32			cfg0_size;
>  	u64			cfg1_base;
> -	u64			cfg1_mod_base;
>  	void __iomem		*va_cfg1_base;
>  	u32			cfg1_size;
> -	u64			io_base;
> -	u64			io_mod_base;
> +	resource_size_t		io_base;
>  	phys_addr_t		io_bus_addr;
>  	u32			io_size;
>  	u64			mem_base;
> -	u64			mem_mod_base;
>  	phys_addr_t		mem_bus_addr;
>  	u32			mem_size;
> -	struct resource		cfg;
> -	struct resource		io;
> -	struct resource		mem;
> -	struct resource		busn;
> +	struct resource		*cfg;
> +	struct resource		*io;
> +	struct resource		*mem;
> +	struct resource		*busn;
>  	int			irq;
>  	u32			lanes;
>  	struct pcie_host_ops	*ops;
> diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
> index c49fbdc..b2c59b9 100644
> --- a/drivers/pci/host/pcie-spear13xx.c
> +++ b/drivers/pci/host/pcie-spear13xx.c
> @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct pcie_port *pp,
>  		return ret;
>  	}
>  
> -	pp->root_bus_nr = -1;
> +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;
>  	pp->ops = &spear13xx_pcie_host_ops;
>  
>  	ret = dw_pcie_host_init(pp);
> -- 
> 1.9.1
> 
> 
> > -----Original Message-----
> > From: Lucas Stach [mailto:l.stach@pengutronix.de]
> > Sent: Wednesday, August 19, 2015 1:54 PM
> > To: Wangzhou (B)
> > Cc: Bjorn Helgaas; jingoohan1@gmail.com; Pratyush Anand; Arnd Bergmann;
> > linux@arm.linux.org.uk; thomas.petazzoni@free-electrons.com; Gabriele
> > Paoloni; lorenzo.pieralisi@arm.com; james.morse@arm.com;
> > Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; linux-
> > pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> > devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)
> > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> > 
> > Am Montag, den 17.08.2015, 19:55 +0800 schrieb Zhou Wang:
> > > This patch tries to unify ARM32 and ARM64 PCIe in designware driver.
> > Delete
> > > function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct
> > hw_pci,
> > > move related operations to dw_pcie_host_init.
> > >
> > > In past, we use:
> > > pci_common_init_dev
> > > 	-> pcibios_init_hw
> > > 		-> hw->scan (dw_pcie_scan_bus)
> > > to pass 0 to root_bus_nr in struct pcie_port. This patch set pp-
> > >root_bus_nr = 0
> > > in each PCIe host driver which is based on pcie-designware.
> > >
> > This is incorrect at least if there are 2 instances of DW PCIe host in
> > the same SoC without using PCI domains. In that the case the bus range
> > determines the range of valid bus numbers per instance and the first
> > number is the root bus. Please look at the "bus-range" DT property in
> > the DW PCIe bindings.
> > 
> > Also we should finally remove this root-bus setup from the glue drivers
> > altogether. It's something that entirely belongs into the DW core code.
> > 
> > Regards,
> > Lucas
> > 
> > > This patch also try to use of_pci_get_host_bridge_resources for ARM32
> > and ARM64
> > > according to the suggestion for Gabriele[1]
> > >
> > > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware:
> > Program ATU
> > > with untranslated address" based on 1/6 in this series. we delete
> > *_mod_base in
> > > pcie-designware. This was discussed in [2]
> > >
> > > I have compiled the driver with multi_v7_defconfig. However, I don't
> > have
> > > ARM32 PCIe related board to do test. It will be appreciated if
> > someone could
> > > help to test it.
> > >
> > > Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>
> > > Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>
> > > Signed-off-by: Arnd Bergmann <arnd@arndb.de>
> > > Tested-By: James Morse <james.morse@arm.com>
> > >
> > > [1] http://www.spinics.net/lists/linux-pci/msg42194.html
> > > [2] http://www.spinics.net/lists/arm-kernel/msg436779.html
> > > ---
> > >  drivers/pci/host/pci-dra7xx.c      |  15 +--
> > >  drivers/pci/host/pci-exynos.c      |   2 +-
> > >  drivers/pci/host/pci-imx6.c        |   2 +-
> > >  drivers/pci/host/pci-keystone-dw.c |   2 +-
> > >  drivers/pci/host/pci-keystone.c    |   2 +-
> > >  drivers/pci/host/pci-layerscape.c  |   2 +-
> > >  drivers/pci/host/pcie-designware.c | 229 ++++++++++++---------------
> > ----------
> > >  drivers/pci/host/pcie-designware.h |  14 +--
> > >  drivers/pci/host/pcie-spear13xx.c  |   2 +-
> > >  9 files changed, 95 insertions(+), 175 deletions(-)
> > >
> > > diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-
> > dra7xx.c
> > > index 18ae7ff..1268c69 100644
> > > --- a/drivers/pci/host/pci-dra7xx.c
> > > +++ b/drivers/pci/host/pci-dra7xx.c
> > > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct
> > pcie_port *pp)
> > >  {
> > >  	dw_pcie_setup_rc(pp);
> > >
> > > -	if (pp->io_mod_base)
> > > -		pp->io_mod_base &= CPU_TO_BUS_ADDR;
> > > +	if (pp->io_base)
> > > +		pp->io_base &= CPU_TO_BUS_ADDR;
> > >
> > > -	if (pp->mem_mod_base)
> > > -		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
> > > +	if (pp->mem_base)
> > > +		pp->mem_base &= CPU_TO_BUS_ADDR;
> > >
> > > -	if (pp->cfg0_mod_base) {
> > > -		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
> > > -		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
> > > +	if (pp->cfg0_base) {
> > > +		pp->cfg0_base &= CPU_TO_BUS_ADDR;
> > > +		pp->cfg1_base &= CPU_TO_BUS_ADDR;
> > >  	}
> > >
> > >  	dra7xx_pcie_establish_link(pp);
> > > @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct
> > dra7xx_pcie *dra7xx,
> > >
> > >  	pp = &dra7xx->pp;
> > >  	pp->dev = dev;
> > > +	pp->root_bus_nr = 0;
> > >  	pp->ops = &dra7xx_pcie_host_ops;
> > >
> > >  	pp->irq = platform_get_irq(pdev, 1);
> > > diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-
> > exynos.c
> > > index f9f468d..9771bb0 100644
> > > --- a/drivers/pci/host/pci-exynos.c
> > > +++ b/drivers/pci/host/pci-exynos.c
> > > @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct
> > pcie_port *pp,
> > >  		}
> > >  	}
> > >
> > > -	pp->root_bus_nr = -1;
> > > +	pp->root_bus_nr = 0;
> > >  	pp->ops = &exynos_pcie_host_ops;
> > >
> > >  	ret = dw_pcie_host_init(pp);
> > > diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-
> > imx6.c
> > > index 233a196..bec256c 100644
> > > --- a/drivers/pci/host/pci-imx6.c
> > > +++ b/drivers/pci/host/pci-imx6.c
> > > @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct
> > pcie_port *pp,
> > >  		}
> > >  	}
> > >
> > > -	pp->root_bus_nr = -1;
> > > +	pp->root_bus_nr = 0;
> > >  	pp->ops = &imx6_pcie_host_ops;
> > >
> > >  	ret = dw_pcie_host_init(pp);
> > > diff --git a/drivers/pci/host/pci-keystone-dw.c
> > b/drivers/pci/host/pci-keystone-dw.c
> > > index f34892e..b1e4135 100644
> > > --- a/drivers/pci/host/pci-keystone-dw.c
> > > +++ b/drivers/pci/host/pci-keystone-dw.c
> > > @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void
> > __iomem *reg_virt)
> > >  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
> > >  {
> > >  	struct pcie_port *pp = &ks_pcie->pp;
> > > -	u32 start = pp->mem.start, end = pp->mem.end;
> > > +	u32 start = pp->mem->start, end = pp->mem->end;
> > >  	int i, tr_size;
> > >
> > >  	/* Disable BARs for inbound access */
> > > diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-
> > keystone.c
> > > index 734da58..8113832 100644
> > > --- a/drivers/pci/host/pci-keystone.c
> > > +++ b/drivers/pci/host/pci-keystone.c
> > > @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct
> > keystone_pcie *ks_pcie,
> > >  			return ret;
> > >  	}
> > >
> > > -	pp->root_bus_nr = -1;
> > > +	pp->root_bus_nr = 0;
> > >  	pp->ops = &keystone_pcie_host_ops;
> > >  	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
> > >  	if (ret) {
> > > diff --git a/drivers/pci/host/pci-layerscape.c
> > b/drivers/pci/host/pci-layerscape.c
> > > index b2328ea1..79ff08c 100644
> > > --- a/drivers/pci/host/pci-layerscape.c
> > > +++ b/drivers/pci/host/pci-layerscape.c
> > > @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)
> > >  	pp = &pcie->pp;
> > >  	pp->dev = pcie->dev;
> > >  	pp->dbi_base = pcie->dbi;
> > > -	pp->root_bus_nr = -1;
> > > +	pp->root_bus_nr = 0;
> > >  	pp->ops = &ls_pcie_host_ops;
> > >
> > >  	ret = dw_pcie_host_init(pp);
> > > diff --git a/drivers/pci/host/pcie-designware.c
> > b/drivers/pci/host/pcie-designware.c
> > > index c5d407c..e71a88e 100644
> > > --- a/drivers/pci/host/pcie-designware.c
> > > +++ b/drivers/pci/host/pcie-designware.c
> > > @@ -11,6 +11,7 @@
> > >   * published by the Free Software Foundation.
> > >   */
> > >
> > > +#include <linux/hardirq.h>
> > >  #include <linux/irq.h>
> > >  #include <linux/irqdomain.h>
> > >  #include <linux/kernel.h>
> > > @@ -69,16 +70,7 @@
> > >  #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
> > >  #define PCIE_ATU_UPPER_TARGET		0x91C
> > >
> > > -static struct hw_pci dw_pci;
> > > -
> > > -static unsigned long global_io_offset;
> > > -
> > > -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
> > > -{
> > > -	BUG_ON(!sys->private_data);
> > > -
> > > -	return sys->private_data;
> > > -}
> > > +static struct pci_ops dw_pcie_ops;
> > >
> > >  int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32
> > *val)
> > >  {
> > > @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port
> > *pp, int irq)
> > >  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
> > >  {
> > >  	int irq, pos0, i;
> > > -	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
> > > +	struct pcie_port *pp = desc->dev->bus->sysdata;
> > >
> > >  	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
> > >  				       order_base_2(no_irqs));
> > > @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct msi_controller
> > *chip, struct pci_dev *pdev,
> > >  {
> > >  	int irq, pos;
> > >  	struct msi_msg msg;
> > > -	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
> > > +	struct pcie_port *pp = pdev->bus->sysdata;
> > >
> > >  	if (desc->msi_attrib.is_msix)
> > >  		return -EINVAL;
> > > @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct
> > msi_controller *chip, unsigned int irq)
> > >  {
> > >  	struct irq_data *data = irq_get_irq_data(irq);
> > >  	struct msi_desc *msi = irq_data_get_msi(data);
> > > -	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
> > > +	struct pcie_port *pp = msi->dev->bus->sysdata;
> > >
> > >  	clear_irq_range(pp, irq, 1, data->hwirq);
> > >  }
> > > @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > >  {
> > >  	struct device_node *np = pp->dev->of_node;
> > >  	struct platform_device *pdev = to_platform_device(pp->dev);
> > > -	struct of_pci_range range;
> > > -	struct of_pci_range_parser parser;
> > > +	struct pci_bus *bus;
> > >  	struct resource *cfg_res;
> > > -	u32 val, ns;
> > > -	const __be32 *addrp;
> > > -	int i, index, ret;
> > > -
> > > -	ns = of_n_size_cells(np);
> > > +	LIST_HEAD(res);
> > > +	u32 val;
> > > +	int i, ret;
> > > +	struct resource_entry *win;
> > >
> > >  	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,
> > "config");
> > >  	if (cfg_res) {
> > > @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > >  		pp->cfg1_size = resource_size(cfg_res)/2;
> > >  		pp->cfg0_base = cfg_res->start;
> > >  		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
> > > -
> > > -		/* Find the untranslated configuration space address */
> > > -		index = of_property_match_string(np, "reg-names", "config");
> > > -		addrp = of_get_address(np, index, NULL, NULL);
> > > -		pp->cfg0_mod_base = of_read_number(addrp, ns);
> > > -		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
> > >  	} else {
> > >  		dev_err(pp->dev, "missing *config* reg space\n");
> > >  	}
> > >
> > > -	if (of_pci_range_parser_init(&parser, np)) {
> > > -		dev_err(pp->dev, "missing ranges property\n");
> > > -		return -EINVAL;
> > > -	}
> > > +	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp-
> > >io_base);
> > > +	if (ret)
> > > +		return ret;
> > >
> > >  	/* Get the I/O and memory ranges from DT */
> > > -	for_each_of_pci_range(&parser, &range) {
> > > -		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
> > > -
> > > -		if (restype == IORESOURCE_IO) {
> > > -			of_pci_range_to_resource(&range, np, &pp->io);
> > > -			pp->io.name = "I/O";
> > > -			pp->io.start = max_t(resource_size_t,
> > > -					     PCIBIOS_MIN_IO,
> > > -					     range.pci_addr + global_io_offset);
> > > -			pp->io.end = min_t(resource_size_t,
> > > -					   IO_SPACE_LIMIT,
> > > -					   range.pci_addr + range.size
> > > -					   + global_io_offset - 1);
> > > -			pp->io_size = resource_size(&pp->io);
> > > -			pp->io_bus_addr = range.pci_addr;
> > > -			pp->io_base = range.cpu_addr;
> > > -
> > > -			/* Find the untranslated IO space address */
> > > -			pp->io_mod_base = range.cpu_addr;
> > > -		}
> > > -		if (restype == IORESOURCE_MEM) {
> > > -			of_pci_range_to_resource(&range, np, &pp->mem);
> > > -			pp->mem.name = "MEM";
> > > -			pp->mem_size = resource_size(&pp->mem);
> > > -			pp->mem_bus_addr = range.pci_addr;
> > > -
> > > -			/* Find the untranslated MEM space address */
> > > -			pp->mem_mod_base = range.cpu_addr;
> > > -		}
> > > -		if (restype == 0) {
> > > -			of_pci_range_to_resource(&range, np, &pp->cfg);
> > > -			pp->cfg0_size = resource_size(&pp->cfg)/2;
> > > -			pp->cfg1_size = resource_size(&pp->cfg)/2;
> > > -			pp->cfg0_base = pp->cfg.start;
> > > -			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
> > > -
> > > -			/* Find the untranslated configuration space address
> > */
> > > -			pp->cfg0_mod_base = range.cpu_addr;
> > > -			pp->cfg1_mod_base = pp->cfg0_mod_base +
> > > -					    pp->cfg0_size;
> > > +	resource_list_for_each_entry(win, &res) {
> > > +		switch (resource_type(win->res)) {
> > > +		case IORESOURCE_IO:
> > > +			pp->io = win->res;
> > > +			pp->io->name = "I/O";
> > > +			pp->io_size = resource_size(pp->io);
> > > +			pp->io_bus_addr = pp->io->start - win->offset;
> > > +			ret = pci_remap_iospace(pp->io, pp->io_base);
> > > +			if (ret) {
> > > +				dev_warn(pp->dev, "error %d: failed to map
> > resource %pR\n",
> > > +					 ret, pp->io);
> > > +				continue;
> > > +			}
> > > +			break;
> > > +		case IORESOURCE_MEM:
> > > +			pp->mem = win->res;
> > > +			pp->mem->name = "MEM";
> > > +			pp->mem_size = resource_size(pp->mem);
> > > +			pp->mem_bus_addr = pp->mem->start - win->offset;
> > > +			break;
> > > +		case 0:
> > > +			pp->cfg = win->res;
> > > +			pp->cfg0_size = resource_size(pp->cfg)/2;
> > > +			pp->cfg1_size = resource_size(pp->cfg)/2;
> > > +			pp->cfg0_base = pp->cfg->start;
> > > +			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
> > > +			break;
> > > +		case IORESOURCE_BUS:
> > > +			pp->busn = win->res;
> > > +			break;
> > > +		default:
> > > +			continue;
> > >  		}
> > >  	}
> > >
> > > -	ret = of_pci_parse_bus_range(np, &pp->busn);
> > > -	if (ret < 0) {
> > > -		pp->busn.name = np->name;
> > > -		pp->busn.start = 0;
> > > -		pp->busn.end = 0xff;
> > > -		pp->busn.flags = IORESOURCE_BUS;
> > > -		dev_dbg(pp->dev, "failed to parse bus-range property: %d,
> > using default %pR\n",
> > > -			ret, &pp->busn);
> > > -	}
> > > -
> > >  	if (!pp->dbi_base) {
> > > -		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
> > > -					resource_size(&pp->cfg));
> > > +		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
> > > +					resource_size(pp->cfg));
> > >  		if (!pp->dbi_base) {
> > >  			dev_err(pp->dev, "error with ioremap\n");
> > >  			return -ENOMEM;
> > >  		}
> > >  	}
> > >
> > > -	pp->mem_base = pp->mem.start;
> > > +	pp->mem_base = pp->mem->start;
> > >
> > >  	if (!pp->va_cfg0_base) {
> > >  		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
> > > @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > >
> > >  	if (!pp->ops->rd_other_conf)
> > >  		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
> > > -					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
> > > +					  PCIE_ATU_TYPE_MEM, pp->mem_base,
> > >  					  pp->mem_bus_addr, pp->mem_size);
> > >
> > >  	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
> > > @@ -517,15 +482,29 @@ int dw_pcie_host_init(struct pcie_port *pp)
> > >  	val |= PORT_LOGIC_SPEED_CHANGE;
> > >  	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
> > >
> > > -#ifdef CONFIG_PCI_MSI
> > > +	bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
> > > +				  pp, &res);
> > > +	if (!bus)
> > > +		return -ENOMEM;
> > > +
> > > +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
> > > +	bus->msi = container_of(&pp->irq_domain, struct msi_controller,
> > domain);
> > > +#else
> > >  	dw_pcie_msi_chip.dev = pp->dev;
> > > -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
> > > +	bus->msi = &dw_pcie_msi_chip;
> > >  #endif
> > >
> > > -	dw_pci.nr_controllers = 1;
> > > -	dw_pci.private_data = (void **)&pp;
> > > +	pci_scan_child_bus(bus);
> > > +	if (pp->ops->scan_bus)
> > > +		pp->ops->scan_bus(pp);
> > > +
> > > +#ifdef CONFIG_ARM
> > > +	/* support old dtbs that incorrectly describe IRQs */
> > > +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
> > > +#endif
> > >
> > > -	pci_common_init_dev(pp->dev, &dw_pci);
> > > +	pci_assign_unassigned_bus_resources(bus);
> > > +	pci_bus_add_devices(bus);
> > >
> > >  	return 0;
> > >  }
> > > @@ -544,12 +523,12 @@ static int dw_pcie_rd_other_conf(struct
> > pcie_port *pp, struct pci_bus *bus,
> > >
> > >  	if (bus->parent->number == pp->root_bus_nr) {
> > >  		type = PCIE_ATU_TYPE_CFG0;
> > > -		cpu_addr = pp->cfg0_mod_base;
> > > +		cpu_addr = pp->cfg0_base;
> > >  		cfg_size = pp->cfg0_size;
> > >  		va_cfg_base = pp->va_cfg0_base;
> > >  	} else {
> > >  		type = PCIE_ATU_TYPE_CFG1;
> > > -		cpu_addr = pp->cfg1_mod_base;
> > > +		cpu_addr = pp->cfg1_base;
> > >  		cfg_size = pp->cfg1_size;
> > >  		va_cfg_base = pp->va_cfg1_base;
> > >  	}
> > > @@ -559,7 +538,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port
> > *pp, struct pci_bus *bus,
> > >  				  busdev, cfg_size);
> > >  	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
> > >  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > > -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> > > +				  PCIE_ATU_TYPE_IO, pp->io_base,
> > >  				  pp->io_bus_addr, pp->io_size);
> > >
> > >  	return ret;
> > > @@ -579,12 +558,12 @@ static int dw_pcie_wr_other_conf(struct
> > pcie_port *pp, struct pci_bus *bus,
> > >
> > >  	if (bus->parent->number == pp->root_bus_nr) {
> > >  		type = PCIE_ATU_TYPE_CFG0;
> > > -		cpu_addr = pp->cfg0_mod_base;
> > > +		cpu_addr = pp->cfg0_base;
> > >  		cfg_size = pp->cfg0_size;
> > >  		va_cfg_base = pp->va_cfg0_base;
> > >  	} else {
> > >  		type = PCIE_ATU_TYPE_CFG1;
> > > -		cpu_addr = pp->cfg1_mod_base;
> > > +		cpu_addr = pp->cfg1_base;
> > >  		cfg_size = pp->cfg1_size;
> > >  		va_cfg_base = pp->va_cfg1_base;
> > >  	}
> > > @@ -594,7 +573,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port
> > *pp, struct pci_bus *bus,
> > >  				  busdev, cfg_size);
> > >  	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
> > >  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
> > > -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
> > > +				  PCIE_ATU_TYPE_IO, pp->io_base,
> > >  				  pp->io_bus_addr, pp->io_size);
> > >
> > >  	return ret;
> > > @@ -626,7 +605,7 @@ static int dw_pcie_valid_config(struct pcie_port
> > *pp,
> > >  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
> > >  			int size, u32 *val)
> > >  {
> > > -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> > > +	struct pcie_port *pp = bus->sysdata;
> > >  	int ret;
> > >
> > >  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
> > > @@ -650,7 +629,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus,
> > u32 devfn, int where,
> > >  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
> > >  			int where, int size, u32 val)
> > >  {
> > > -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
> > > +	struct pcie_port *pp = bus->sysdata;
> > >  	int ret;
> > >
> > >  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
> > > @@ -674,62 +653,6 @@ static struct pci_ops dw_pcie_ops = {
> > >  	.write = dw_pcie_wr_conf,
> > >  };
> > >
> > > -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
> > > -{
> > > -	struct pcie_port *pp;
> > > -
> > > -	pp = sys_to_pcie(sys);
> > > -
> > > -	if (global_io_offset < SZ_1M && pp->io_size > 0) {
> > > -		sys->io_offset = global_io_offset - pp->io_bus_addr;
> > > -		pci_ioremap_io(global_io_offset, pp->io_base);
> > > -		global_io_offset += SZ_64K;
> > > -		pci_add_resource_offset(&sys->resources, &pp->io,
> > > -					sys->io_offset);
> > > -	}
> > > -
> > > -	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
> > > -	pci_add_resource_offset(&sys->resources, &pp->mem, sys-
> > >mem_offset);
> > > -	pci_add_resource(&sys->resources, &pp->busn);
> > > -
> > > -	return 1;
> > > -}
> > > -
> > > -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data
> > *sys)
> > > -{
> > > -	struct pci_bus *bus;
> > > -	struct pcie_port *pp = sys_to_pcie(sys);
> > > -
> > > -	pp->root_bus_nr = sys->busnr;
> > > -	bus = pci_scan_root_bus(pp->dev, sys->busnr,
> > > -				  &dw_pcie_ops, sys, &sys->resources);
> > > -	if (!bus)
> > > -		return NULL;
> > > -
> > > -	if (bus && pp->ops->scan_bus)
> > > -		pp->ops->scan_bus(pp);
> > > -
> > > -	return bus;
> > > -}
> > > -
> > > -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8
> > pin)
> > > -{
> > > -	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
> > > -	int irq;
> > > -
> > > -	irq = of_irq_parse_and_map_pci(dev, slot, pin);
> > > -	if (!irq)
> > > -		irq = pp->irq;
> > > -
> > > -	return irq;
> > > -}
> > > -
> > > -static struct hw_pci dw_pci = {
> > > -	.setup		= dw_pcie_setup,
> > > -	.scan		= dw_pcie_scan_bus,
> > > -	.map_irq	= dw_pcie_map_irq,
> > > -};
> > > -
> > >  void dw_pcie_setup_rc(struct pcie_port *pp)
> > >  {
> > >  	u32 val;
> > > diff --git a/drivers/pci/host/pcie-designware.h
> > b/drivers/pci/host/pcie-designware.h
> > > index d0bbd27..264c969 100644
> > > --- a/drivers/pci/host/pcie-designware.h
> > > +++ b/drivers/pci/host/pcie-designware.h
> > > @@ -27,25 +27,21 @@ struct pcie_port {
> > >  	u8			root_bus_nr;
> > >  	void __iomem		*dbi_base;
> > >  	u64			cfg0_base;
> > > -	u64			cfg0_mod_base;
> > >  	void __iomem		*va_cfg0_base;
> > >  	u32			cfg0_size;
> > >  	u64			cfg1_base;
> > > -	u64			cfg1_mod_base;
> > >  	void __iomem		*va_cfg1_base;
> > >  	u32			cfg1_size;
> > > -	u64			io_base;
> > > -	u64			io_mod_base;
> > > +	resource_size_t		io_base;
> > >  	phys_addr_t		io_bus_addr;
> > >  	u32			io_size;
> > >  	u64			mem_base;
> > > -	u64			mem_mod_base;
> > >  	phys_addr_t		mem_bus_addr;
> > >  	u32			mem_size;
> > > -	struct resource		cfg;
> > > -	struct resource		io;
> > > -	struct resource		mem;
> > > -	struct resource		busn;
> > > +	struct resource		*cfg;
> > > +	struct resource		*io;
> > > +	struct resource		*mem;
> > > +	struct resource		*busn;
> > >  	int			irq;
> > >  	u32			lanes;
> > >  	struct pcie_host_ops	*ops;
> > > diff --git a/drivers/pci/host/pcie-spear13xx.c
> > b/drivers/pci/host/pcie-spear13xx.c
> > > index c49fbdc..03eb204 100644
> > > --- a/drivers/pci/host/pcie-spear13xx.c
> > > +++ b/drivers/pci/host/pcie-spear13xx.c
> > > @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct
> > pcie_port *pp,
> > >  		return ret;
> > >  	}
> > >
> > > -	pp->root_bus_nr = -1;
> > > +	pp->root_bus_nr = 0;
> > >  	pp->ops = &spear13xx_pcie_host_ops;
> > >
> > >  	ret = dw_pcie_host_init(pp);
> > 
> > --
> > Pengutronix e.K.             | Lucas Stach                 |
> > Industrial Linux Solutions   | http://www.pengutronix.de/  |
>
Gabriele Paoloni Aug. 19, 2015, 4:34 p.m. UTC | #5
Hi Lucas

First of all many thanks for the quick reply, really appreciated

> -----Original Message-----

> From: Lucas Stach [mailto:l.stach@pengutronix.de]

> Sent: Wednesday, August 19, 2015 4:37 PM

> To: Gabriele Paoloni

> Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; Pratyush Anand;

> Arnd Bergmann; linux@arm.linux.org.uk; thomas.petazzoni@free-

> electrons.com; lorenzo.pieralisi@arm.com; james.morse@arm.com;

> Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; linux-

> pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;

> devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;

> qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)

> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support

> 

> Hi Gab,

> 

> Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele Paoloni:

> > Hi Lucas

> >

> > I have rewritten the patch to take into account multiple controllers.

> >

> > As you can see now there is a static var in dw_pcie_host_init() that

> tracks

> > the bus numbers used.

> 

> This is wrong. The DT specifies the valid bus number range. You can not

> just assign the next free bus number to the root bus.


I think this is what is being done in
http://lxr.free-electrons.com/source/arch/arm/kernel/bios32.c#L495
and currently designware assigns the root bus number in
http://lxr.free-electrons.com/source/drivers/pci/host/pcie-designware.c#L730


In general I agree with you but if you look at all the current drivers 
based on designware none of them define the "bus-range" dtb property.
Therefore doing as you say would break the current driver when we have
multiple controllers...am I right?

If that is the case in order to fix this in the way you say I would need
to assign "bus-range" for all the PCIe drivers with multiple controllers:
in this case I would split the default range evenly (that is, if we have 
two controllers I would define "bus-range"  0-127 and 128-255)

If you think this solution is ok I can go for it. My only doubt was about
touching other vendors DTBs....


> 

> It is perfectly valid to have a bus range of 0x00-0x10 assigned to one

> instance and 0x50-0xff to the next instance. Additional with PCIe

> hotplug you may not use the full range of the bus numbers on one

> instance at the first scan, but only later populate more buses when

> more

> bridges are added to the tree.

> 

> > Drivers that do not specify the bus range in the DTB set pp-

> >root_bus_nr = DW_ROOT_NR_UNDEFINED.

> > Designware will check if the flag is set and will use the automatic

> bus range

> > assignment.

> 

> No, please lets get rid of this assignment altogether. The glue drivers

> have no business in assigning the bus range. Please remove the

> pp->root_bus_nr assignment from all the glue drivers.

> 

> "bus range" is a generic DW PCIe property, so just parse the root bus

> number from the DT, it is handled the same way for all the DW based

> PCIe

> drivers. The bindings specifies that if the bus range property is

> missing the range is 0x00-0xff, so you can default to 0 as the root bus

> number in that case.

> 

> Also I would think this conversion warrants a patch on its own and

> should not be mixed in the ARM64 support patch.

> 

> Regards,

> Lucas

> 

> > Instead if the driver assigns pp->root_bus_nr according to the dtb,

> designwware

> > will use the value passed in by the driver.

> > Below the relevant section:

> >

> >

> > +	static int root_bus_nr = 0;

> > ...

> > +	mutex_lock(&root_bus_nr_mux);

> > +

> > +	if (pp->root_bus_nr != DW_ROOT_NR_UNDEFINED)

> > +		root_bus_nr = pp->root_bus_nr;

> > +

> > +	bus = pci_create_root_bus(pp->dev, root_bus_nr, &dw_pcie_ops,

> > +			      pp, &res);

> > +	if (!bus) {

> > +		mutex_unlock(&root_bus_nr_mux);

> > +		return -ENOMEM;

> > +	}

> > +

> > +	root_bus_nr += bus->busn_res.end + 1;

> > +	mutex_unlock(&root_bus_nr_mux);

> >

> > Please let me know what you think...

> >

> > Many Thanks

> >

> > Gab

> > ----------

> >

> > From: gabriele paoloni <gabriele.paoloni@huawei.com>

> >

> > This patch tries to unify ARM32 and ARM64 PCIe in designware driver.

> Delete

> > function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and struct

> hw_pci,

> > move related operations to dw_pcie_host_init.

> > Also set pp->root_bus_nr = DW_ROOT_NR_UNDEFINED in all the drivers

> that

> > are based on designware to flag that the drivers do not read the bus

> > ranges from DT.

> > This patch also adds handling of multiple PCI domains in designware.

> > if the PCI host bridge driver does not specify a root bus number, in

> case

> > of multiple domains, designware will automatillay set the next domain

> root

> > bus number to the last bus number used in the last domain + 1.

> >

> > This patch also try to use of_pci_get_host_bridge_resources for ARM32

> and

> > ARM64 according to the suggestion for Gabriele[1]

> >

> > This patch is based on Gabriele's patch about of_pci_range fix[2]

> >

> > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware:

> > Program ATU with untranslated address". This was discussed in [3]

> >

> > I have compiled the driver with multi_v7_defconfig. However, I don't

> have

> > ARM32 PCIe related board to do test. It will be appreciated if

> someone could

> > help to test it.

> >

> > Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>

> > Signed-off-by: Arnd Bergmann <arnd@arndb.de>

> > Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>

> >

> > [1] http://www.spinics.net/lists/linux-pci/msg42194.html

> > [2] https://patchwork.ozlabs.org/patch/495018/

> > [3] http://www.spinics.net/lists/arm-kernel/msg436779.html

> > ---

> >  drivers/pci/host/pci-dra7xx.c      |  15 +--

> >  drivers/pci/host/pci-exynos.c      |   2 +-

> >  drivers/pci/host/pci-imx6.c        |   2 +-

> >  drivers/pci/host/pci-keystone-dw.c |   2 +-

> >  drivers/pci/host/pci-keystone.c    |   2 +-

> >  drivers/pci/host/pci-layerscape.c  |   2 +-

> >  drivers/pci/host/pcie-designware.c | 247 ++++++++++++++-------------

> ----------

> >  drivers/pci/host/pcie-designware.h |  15 +--

> >  drivers/pci/host/pcie-spear13xx.c  |   2 +-

> >  9 files changed, 110 insertions(+), 179 deletions(-)

> >

> > diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-

> dra7xx.c

> > index 5678b57..8d598fb 100644

> > --- a/drivers/pci/host/pci-dra7xx.c

> > +++ b/drivers/pci/host/pci-dra7xx.c

> > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct

> pcie_port *pp)

> >  {

> >  	dw_pcie_setup_rc(pp);

> >

> > -	if (pp->io_mod_base)

> > -		pp->io_mod_base &= CPU_TO_BUS_ADDR;

> > +	if (pp->io_base)

> > +		pp->io_base &= CPU_TO_BUS_ADDR;

> >

> > -	if (pp->mem_mod_base)

> > -		pp->mem_mod_base &= CPU_TO_BUS_ADDR;

> > +	if (pp->mem_base)

> > +		pp->mem_base &= CPU_TO_BUS_ADDR;

> >

> > -	if (pp->cfg0_mod_base) {

> > -		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;

> > -		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;

> > +	if (pp->cfg0_base) {

> > +		pp->cfg0_base &= CPU_TO_BUS_ADDR;

> > +		pp->cfg1_base &= CPU_TO_BUS_ADDR;

> >  	}

> >

> >  	dra7xx_pcie_establish_link(pp);

> > @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct

> dra7xx_pcie *dra7xx,

> >

> >  	pp = &dra7xx->pp;

> >  	pp->dev = dev;

> > +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;

> >  	pp->ops = &dra7xx_pcie_host_ops;

> >

> >  	pp->irq = platform_get_irq(pdev, 1);

> > diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-

> exynos.c

> > index f9f468d..ed03a8f 100644

> > --- a/drivers/pci/host/pci-exynos.c

> > +++ b/drivers/pci/host/pci-exynos.c

> > @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct

> pcie_port *pp,

> >  		}

> >  	}

> >

> > -	pp->root_bus_nr = -1;

> > +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;

> >  	pp->ops = &exynos_pcie_host_ops;

> >

> >  	ret = dw_pcie_host_init(pp);

> > diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-

> imx6.c

> > index 233a196..0efac85 100644

> > --- a/drivers/pci/host/pci-imx6.c

> > +++ b/drivers/pci/host/pci-imx6.c

> > @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct

> pcie_port *pp,

> >  		}

> >  	}

> >

> > -	pp->root_bus_nr = -1;

> > +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;

> >  	pp->ops = &imx6_pcie_host_ops;

> >

> >  	ret = dw_pcie_host_init(pp);

> > diff --git a/drivers/pci/host/pci-keystone-dw.c

> b/drivers/pci/host/pci-keystone-dw.c

> > index f34892e..b1e4135 100644

> > --- a/drivers/pci/host/pci-keystone-dw.c

> > +++ b/drivers/pci/host/pci-keystone-dw.c

> > @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void

> __iomem *reg_virt)

> >  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)

> >  {

> >  	struct pcie_port *pp = &ks_pcie->pp;

> > -	u32 start = pp->mem.start, end = pp->mem.end;

> > +	u32 start = pp->mem->start, end = pp->mem->end;

> >  	int i, tr_size;

> >

> >  	/* Disable BARs for inbound access */

> > diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-

> keystone.c

> > index 734da58..b522956 100644

> > --- a/drivers/pci/host/pci-keystone.c

> > +++ b/drivers/pci/host/pci-keystone.c

> > @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct

> keystone_pcie *ks_pcie,

> >  			return ret;

> >  	}

> >

> > -	pp->root_bus_nr = -1;

> > +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;

> >  	pp->ops = &keystone_pcie_host_ops;

> >  	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);

> >  	if (ret) {

> > diff --git a/drivers/pci/host/pci-layerscape.c

> b/drivers/pci/host/pci-layerscape.c

> > index b2328ea1..dd92ffa 100644

> > --- a/drivers/pci/host/pci-layerscape.c

> > +++ b/drivers/pci/host/pci-layerscape.c

> > @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie *pcie)

> >  	pp = &pcie->pp;

> >  	pp->dev = pcie->dev;

> >  	pp->dbi_base = pcie->dbi;

> > -	pp->root_bus_nr = -1;

> > +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;

> >  	pp->ops = &ls_pcie_host_ops;

> >

> >  	ret = dw_pcie_host_init(pp);

> > diff --git a/drivers/pci/host/pcie-designware.c

> b/drivers/pci/host/pcie-designware.c

> > index 5307b35..bd2606b 100644

> > --- a/drivers/pci/host/pcie-designware.c

> > +++ b/drivers/pci/host/pcie-designware.c

> > @@ -11,6 +11,7 @@

> >   * published by the Free Software Foundation.

> >   */

> >

> > +#include <linux/hardirq.h>

> >  #include <linux/irq.h>

> >  #include <linux/irqdomain.h>

> >  #include <linux/kernel.h>

> > @@ -69,16 +70,9 @@

> >  #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)

> >  #define PCIE_ATU_UPPER_TARGET		0x91C

> >

> > -static struct hw_pci dw_pci;

> > +static struct pci_ops dw_pcie_ops;

> >

> > -static unsigned long global_io_offset;

> > -

> > -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)

> > -{

> > -	BUG_ON(!sys->private_data);

> > -

> > -	return sys->private_data;

> > -}

> > +DEFINE_MUTEX(root_bus_nr_mux);

> >

> >  int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32

> *val)

> >  {

> > @@ -255,7 +249,7 @@ static void dw_pcie_msi_set_irq(struct pcie_port

> *pp, int irq)

> >  static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)

> >  {

> >  	int irq, pos0, i;

> > -	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);

> > +	struct pcie_port *pp = desc->dev->bus->sysdata;

> >

> >  	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,

> >  				       order_base_2(no_irqs));

> > @@ -298,7 +292,7 @@ static int dw_msi_setup_irq(struct msi_controller

> *chip, struct pci_dev *pdev,

> >  {

> >  	int irq, pos;

> >  	struct msi_msg msg;

> > -	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);

> > +	struct pcie_port *pp = pdev->bus->sysdata;

> >

> >  	if (desc->msi_attrib.is_msix)

> >  		return -EINVAL;

> > @@ -327,7 +321,7 @@ static void dw_msi_teardown_irq(struct

> msi_controller *chip, unsigned int irq)

> >  {

> >  	struct irq_data *data = irq_get_irq_data(irq);

> >  	struct msi_desc *msi = irq_data_get_msi(data);

> > -	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);

> > +	struct pcie_port *pp = msi->dev->bus->sysdata;

> >

> >  	clear_irq_range(pp, irq, 1, data->hwirq);

> >  }

> > @@ -359,22 +353,17 @@ static const struct irq_domain_ops

> msi_domain_ops = {

> >  	.map = dw_pcie_msi_map,

> >  };

> >

> > -int dw_pcie_host_init(struct pcie_port *pp)

> > +int __init dw_pcie_host_init(struct pcie_port *pp)

> >  {

> >  	struct device_node *np = pp->dev->of_node;

> >  	struct platform_device *pdev = to_platform_device(pp->dev);

> > -	struct of_pci_range range;

> > -	struct of_pci_range_parser parser;

> > +	struct pci_bus *bus;

> >  	struct resource *cfg_res;

> > -	u32 val, na, ns;

> > -	const __be32 *addrp;

> > -	int i, index, ret;

> > -

> > -	/* Find the address cell size and the number of cells in order to

> get

> > -	 * the untranslated address.

> > -	 */

> > -	of_property_read_u32(np, "#address-cells", &na);

> > -	ns = of_n_size_cells(np);

> > +	LIST_HEAD(res);

> > +	u32 val;

> > +	int i, ret;

> > +	struct resource_entry *win;

> > +	static int root_bus_nr = 0;

> >

> >  	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,

> "config");

> >  	if (cfg_res) {

> > @@ -382,85 +371,60 @@ int dw_pcie_host_init(struct pcie_port *pp)

> >  		pp->cfg1_size = resource_size(cfg_res)/2;

> >  		pp->cfg0_base = cfg_res->start;

> >  		pp->cfg1_base = cfg_res->start + pp->cfg0_size;

> > -

> > -		/* Find the untranslated configuration space address */

> > -		index = of_property_match_string(np, "reg-names", "config");

> > -		addrp = of_get_address(np, index, NULL, NULL);

> > -		pp->cfg0_mod_base = of_read_number(addrp, ns);

> > -		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;

> >  	} else {

> >  		dev_err(pp->dev, "missing *config* reg space\n");

> >  	}

> >

> > -	if (of_pci_range_parser_init(&parser, np)) {

> > -		dev_err(pp->dev, "missing ranges property\n");

> > -		return -EINVAL;

> > -	}

> > +	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp-

> >io_base);

> > +	if (ret)

> > +		return ret;

> >

> >  	/* Get the I/O and memory ranges from DT */

> > -	for_each_of_pci_range(&parser, &range) {

> > -		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;

> > -

> > -		if (restype == IORESOURCE_IO) {

> > -			of_pci_range_to_resource(&range, np, &pp->io);

> > -			pp->io.name = "I/O";

> > -			pp->io.start = max_t(resource_size_t,

> > -					     PCIBIOS_MIN_IO,

> > -					     range.pci_addr + global_io_offset);

> > -			pp->io.end = min_t(resource_size_t,

> > -					   IO_SPACE_LIMIT,

> > -					   range.pci_addr + range.size

> > -					   + global_io_offset - 1);

> > -			pp->io_size = resource_size(&pp->io);

> > -			pp->io_bus_addr = range.pci_addr;

> > -			pp->io_base = range.cpu_addr;

> > -

> > -			/* Find the untranslated IO space address */

> > -			pp->io_mod_base = range.cpu_addr;

> > -		}

> > -		if (restype == IORESOURCE_MEM) {

> > -			of_pci_range_to_resource(&range, np, &pp->mem);

> > -			pp->mem.name = "MEM";

> > -			pp->mem_size = resource_size(&pp->mem);

> > -			pp->mem_bus_addr = range.pci_addr;

> > -

> > -			/* Find the untranslated MEM space address */

> > -			pp->mem_mod_base = range.cpu_addr;

> > -		}

> > -		if (restype == 0) {

> > -			of_pci_range_to_resource(&range, np, &pp->cfg);

> > -			pp->cfg0_size = resource_size(&pp->cfg)/2;

> > -			pp->cfg1_size = resource_size(&pp->cfg)/2;

> > -			pp->cfg0_base = pp->cfg.start;

> > -			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;

> > -

> > -			/* Find the untranslated configuration space address

> */

> > -			pp->cfg0_mod_base = range.cpu_addr;

> > -			pp->cfg1_mod_base = pp->cfg0_mod_base +

> > -					    pp->cfg0_size;

> > +	resource_list_for_each_entry(win, &res) {

> > +		switch (resource_type(win->res)) {

> > +		case IORESOURCE_IO:

> > +			pp->io = win->res;

> > +			pp->io->name = "I/O";

> > +			pp->io_size = resource_size(pp->io);

> > +			pp->io_bus_addr = pp->io->start - win->offset;

> > +			ret = pci_remap_iospace(pp->io, pp->io_base);

> > +			if (ret) {

> > +				dev_warn(pp->dev, "error %d: failed to map

> resource %pR\n",

> > +					 ret, pp->io);

> > +				continue;

> > +			}

> > +			break;

> > +		case IORESOURCE_MEM:

> > +			pp->mem = win->res;

> > +			pp->mem->name = "MEM";

> > +			pp->mem_size = resource_size(pp->mem);

> > +			pp->mem_bus_addr = pp->mem->start - win->offset;

> > +			break;

> > +		case 0:

> > +			pp->cfg = win->res;

> > +			pp->cfg0_size = resource_size(pp->cfg)/2;

> > +			pp->cfg1_size = resource_size(pp->cfg)/2;

> > +			pp->cfg0_base = pp->cfg->start;

> > +			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;

> > +			break;

> > +		case IORESOURCE_BUS:

> > +			pp->busn = win->res;

> > +			break;

> > +		default:

> > +			continue;

> >  		}

> >  	}

> >

> > -	ret = of_pci_parse_bus_range(np, &pp->busn);

> > -	if (ret < 0) {

> > -		pp->busn.name = np->name;

> > -		pp->busn.start = 0;

> > -		pp->busn.end = 0xff;

> > -		pp->busn.flags = IORESOURCE_BUS;

> > -		dev_dbg(pp->dev, "failed to parse bus-range property: %d,

> using default %pR\n",

> > -			ret, &pp->busn);

> > -	}

> > -

> >  	if (!pp->dbi_base) {

> > -		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,

> > -					resource_size(&pp->cfg));

> > +		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,

> > +					resource_size(pp->cfg));

> >  		if (!pp->dbi_base) {

> >  			dev_err(pp->dev, "error with ioremap\n");

> >  			return -ENOMEM;

> >  		}

> >  	}

> >

> > -	pp->mem_base = pp->mem.start;

> > +	pp->mem_base = pp->mem->start;

> >

> >  	if (!pp->va_cfg0_base) {

> >  		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,

> > @@ -509,7 +473,7 @@ int dw_pcie_host_init(struct pcie_port *pp)

> >

> >  	if (!pp->ops->rd_other_conf)

> >  		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,

> > -					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,

> > +					  PCIE_ATU_TYPE_MEM, pp->mem_base,

> >  					  pp->mem_bus_addr, pp->mem_size);

> >

> >  	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);

> > @@ -521,15 +485,40 @@ int dw_pcie_host_init(struct pcie_port *pp)

> >  	val |= PORT_LOGIC_SPEED_CHANGE;

> >  	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);

> >

> > -#ifdef CONFIG_PCI_MSI

> >  	dw_pcie_msi_chip.dev = pp->dev;

> > -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;

> > +

> > +	mutex_lock(&root_bus_nr_mux);

> > +

> > +	if (pp->root_bus_nr != DW_ROOT_NR_UNDEFINED)

> > +		root_bus_nr = pp->root_bus_nr;

> > +

> > +	bus = pci_create_root_bus(pp->dev, root_bus_nr, &dw_pcie_ops,

> > +			      pp, &res);

> > +	if (!bus) {

> > +		mutex_unlock(&root_bus_nr_mux);

> > +		return -ENOMEM;

> > +	}

> > +

> > +	root_bus_nr += bus->busn_res.end + 1;

> > +	mutex_unlock(&root_bus_nr_mux);

> > +

> > +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN

> > +	bus->msi = container_of(&pp->irq_domain, struct msi_controller,

> domain);

> > +#else

> > +	bus->msi = &dw_pcie_msi_chip;

> >  #endif

> >

> > -	dw_pci.nr_controllers = 1;

> > -	dw_pci.private_data = (void **)&pp;

> > +	pci_scan_child_bus(bus);

> > +	if (pp->ops->scan_bus)

> > +		pp->ops->scan_bus(pp);

> > +

> > +#ifdef CONFIG_ARM

> > +	/* support old dtbs that incorrectly describe IRQs */

> > +	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);

> > +#endif

> >

> > -	pci_common_init_dev(pp->dev, &dw_pci);

> > +	pci_assign_unassigned_bus_resources(bus);

> > +	pci_bus_add_devices(bus);

> >

> >  	return 0;

> >  }

> > @@ -548,12 +537,12 @@ static int dw_pcie_rd_other_conf(struct

> pcie_port *pp, struct pci_bus *bus,

> >

> >  	if (bus->parent->number == pp->root_bus_nr) {

> >  		type = PCIE_ATU_TYPE_CFG0;

> > -		cpu_addr = pp->cfg0_mod_base;

> > +		cpu_addr = pp->cfg0_base;

> >  		cfg_size = pp->cfg0_size;

> >  		va_cfg_base = pp->va_cfg0_base;

> >  	} else {

> >  		type = PCIE_ATU_TYPE_CFG1;

> > -		cpu_addr = pp->cfg1_mod_base;

> > +		cpu_addr = pp->cfg1_base;

> >  		cfg_size = pp->cfg1_size;

> >  		va_cfg_base = pp->va_cfg1_base;

> >  	}

> > @@ -563,7 +552,7 @@ static int dw_pcie_rd_other_conf(struct pcie_port

> *pp, struct pci_bus *bus,

> >  				  busdev, cfg_size);

> >  	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);

> >  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,

> > -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,

> > +				  PCIE_ATU_TYPE_IO, pp->io_base,

> >  				  pp->io_bus_addr, pp->io_size);

> >

> >  	return ret;

> > @@ -583,12 +572,12 @@ static int dw_pcie_wr_other_conf(struct

> pcie_port *pp, struct pci_bus *bus,

> >

> >  	if (bus->parent->number == pp->root_bus_nr) {

> >  		type = PCIE_ATU_TYPE_CFG0;

> > -		cpu_addr = pp->cfg0_mod_base;

> > +		cpu_addr = pp->cfg0_base;

> >  		cfg_size = pp->cfg0_size;

> >  		va_cfg_base = pp->va_cfg0_base;

> >  	} else {

> >  		type = PCIE_ATU_TYPE_CFG1;

> > -		cpu_addr = pp->cfg1_mod_base;

> > +		cpu_addr = pp->cfg1_base;

> >  		cfg_size = pp->cfg1_size;

> >  		va_cfg_base = pp->va_cfg1_base;

> >  	}

> > @@ -598,7 +587,7 @@ static int dw_pcie_wr_other_conf(struct pcie_port

> *pp, struct pci_bus *bus,

> >  				  busdev, cfg_size);

> >  	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);

> >  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,

> > -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,

> > +				  PCIE_ATU_TYPE_IO, pp->io_base,

> >  				  pp->io_bus_addr, pp->io_size);

> >

> >  	return ret;

> > @@ -630,7 +619,7 @@ static int dw_pcie_valid_config(struct pcie_port

> *pp,

> >  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,

> >  			int size, u32 *val)

> >  {

> > -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);

> > +	struct pcie_port *pp = bus->sysdata;

> >  	int ret;

> >

> >  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {

> > @@ -654,7 +643,7 @@ static int dw_pcie_rd_conf(struct pci_bus *bus,

> u32 devfn, int where,

> >  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,

> >  			int where, int size, u32 val)

> >  {

> > -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);

> > +	struct pcie_port *pp = bus->sysdata;

> >  	int ret;

> >

> >  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)

> > @@ -678,62 +667,6 @@ static struct pci_ops dw_pcie_ops = {

> >  	.write = dw_pcie_wr_conf,

> >  };

> >

> > -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)

> > -{

> > -	struct pcie_port *pp;

> > -

> > -	pp = sys_to_pcie(sys);

> > -

> > -	if (global_io_offset < SZ_1M && pp->io_size > 0) {

> > -		sys->io_offset = global_io_offset - pp->io_bus_addr;

> > -		pci_ioremap_io(global_io_offset, pp->io_base);

> > -		global_io_offset += SZ_64K;

> > -		pci_add_resource_offset(&sys->resources, &pp->io,

> > -					sys->io_offset);

> > -	}

> > -

> > -	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;

> > -	pci_add_resource_offset(&sys->resources, &pp->mem, sys-

> >mem_offset);

> > -	pci_add_resource(&sys->resources, &pp->busn);

> > -

> > -	return 1;

> > -}

> > -

> > -static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data

> *sys)

> > -{

> > -	struct pci_bus *bus;

> > -	struct pcie_port *pp = sys_to_pcie(sys);

> > -

> > -	pp->root_bus_nr = sys->busnr;

> > -	bus = pci_scan_root_bus(pp->dev, sys->busnr,

> > -				  &dw_pcie_ops, sys, &sys->resources);

> > -	if (!bus)

> > -		return NULL;

> > -

> > -	if (bus && pp->ops->scan_bus)

> > -		pp->ops->scan_bus(pp);

> > -

> > -	return bus;

> > -}

> > -

> > -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8

> pin)

> > -{

> > -	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);

> > -	int irq;

> > -

> > -	irq = of_irq_parse_and_map_pci(dev, slot, pin);

> > -	if (!irq)

> > -		irq = pp->irq;

> > -

> > -	return irq;

> > -}

> > -

> > -static struct hw_pci dw_pci = {

> > -	.setup		= dw_pcie_setup,

> > -	.scan		= dw_pcie_scan_bus,

> > -	.map_irq	= dw_pcie_map_irq,

> > -};

> > -

> >  void dw_pcie_setup_rc(struct pcie_port *pp)

> >  {

> >  	u32 val;

> > diff --git a/drivers/pci/host/pcie-designware.h

> b/drivers/pci/host/pcie-designware.h

> > index d0bbd27..0c2a7eb 100644

> > --- a/drivers/pci/host/pcie-designware.h

> > +++ b/drivers/pci/host/pcie-designware.h

> > @@ -21,31 +21,28 @@

> >   */

> >  #define MAX_MSI_IRQS			32

> >  #define MAX_MSI_CTRLS			(MAX_MSI_IRQS / 32)

> > +#define DW_ROOT_NR_UNDEFINED	-1

> >

> >  struct pcie_port {

> >  	struct device		*dev;

> >  	u8			root_bus_nr;

> >  	void __iomem		*dbi_base;

> >  	u64			cfg0_base;

> > -	u64			cfg0_mod_base;

> >  	void __iomem		*va_cfg0_base;

> >  	u32			cfg0_size;

> >  	u64			cfg1_base;

> > -	u64			cfg1_mod_base;

> >  	void __iomem		*va_cfg1_base;

> >  	u32			cfg1_size;

> > -	u64			io_base;

> > -	u64			io_mod_base;

> > +	resource_size_t		io_base;

> >  	phys_addr_t		io_bus_addr;

> >  	u32			io_size;

> >  	u64			mem_base;

> > -	u64			mem_mod_base;

> >  	phys_addr_t		mem_bus_addr;

> >  	u32			mem_size;

> > -	struct resource		cfg;

> > -	struct resource		io;

> > -	struct resource		mem;

> > -	struct resource		busn;

> > +	struct resource		*cfg;

> > +	struct resource		*io;

> > +	struct resource		*mem;

> > +	struct resource		*busn;

> >  	int			irq;

> >  	u32			lanes;

> >  	struct pcie_host_ops	*ops;

> > diff --git a/drivers/pci/host/pcie-spear13xx.c

> b/drivers/pci/host/pcie-spear13xx.c

> > index c49fbdc..b2c59b9 100644

> > --- a/drivers/pci/host/pcie-spear13xx.c

> > +++ b/drivers/pci/host/pcie-spear13xx.c

> > @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct

> pcie_port *pp,

> >  		return ret;

> >  	}

> >

> > -	pp->root_bus_nr = -1;

> > +	pp->root_bus_nr = DW_ROOT_NR_UNDEFINED;

> >  	pp->ops = &spear13xx_pcie_host_ops;

> >

> >  	ret = dw_pcie_host_init(pp);

> > --

> > 1.9.1

> >

> >

> > > -----Original Message-----

> > > From: Lucas Stach [mailto:l.stach@pengutronix.de]

> > > Sent: Wednesday, August 19, 2015 1:54 PM

> > > To: Wangzhou (B)

> > > Cc: Bjorn Helgaas; jingoohan1@gmail.com; Pratyush Anand; Arnd

> Bergmann;

> > > linux@arm.linux.org.uk; thomas.petazzoni@free-electrons.com;

> Gabriele

> > > Paoloni; lorenzo.pieralisi@arm.com; james.morse@arm.com;

> > > Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; linux-

> > > pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;

> > > devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;

> > > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)

> > > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support

> > >

> > > Am Montag, den 17.08.2015, 19:55 +0800 schrieb Zhou Wang:

> > > > This patch tries to unify ARM32 and ARM64 PCIe in designware

> driver.

> > > Delete

> > > > function dw_pcie_setup, dw_pcie_scan_bus, dw_pcie_map_irq and

> struct

> > > hw_pci,

> > > > move related operations to dw_pcie_host_init.

> > > >

> > > > In past, we use:

> > > > pci_common_init_dev

> > > > 	-> pcibios_init_hw

> > > > 		-> hw->scan (dw_pcie_scan_bus)

> > > > to pass 0 to root_bus_nr in struct pcie_port. This patch set pp-

> > > >root_bus_nr = 0

> > > > in each PCIe host driver which is based on pcie-designware.

> > > >

> > > This is incorrect at least if there are 2 instances of DW PCIe host

> in

> > > the same SoC without using PCI domains. In that the case the bus

> range

> > > determines the range of valid bus numbers per instance and the

> first

> > > number is the root bus. Please look at the "bus-range" DT property

> in

> > > the DW PCIe bindings.

> > >

> > > Also we should finally remove this root-bus setup from the glue

> drivers

> > > altogether. It's something that entirely belongs into the DW core

> code.

> > >

> > > Regards,

> > > Lucas

> > >

> > > > This patch also try to use of_pci_get_host_bridge_resources for

> ARM32

> > > and ARM64

> > > > according to the suggestion for Gabriele[1]

> > > >

> > > > Finally this patch reverts commit f4c55c5a3f7f "PCI: designware:

> > > Program ATU

> > > > with untranslated address" based on 1/6 in this series. we delete

> > > *_mod_base in

> > > > pcie-designware. This was discussed in [2]

> > > >

> > > > I have compiled the driver with multi_v7_defconfig. However, I

> don't

> > > have

> > > > ARM32 PCIe related board to do test. It will be appreciated if

> > > someone could

> > > > help to test it.

> > > >

> > > > Signed-off-by: Zhou Wang <wangzhou1@hisilicon.com>

> > > > Signed-off-by: Gabriele Paoloni <gabriele.paoloni@huawei.com>

> > > > Signed-off-by: Arnd Bergmann <arnd@arndb.de>

> > > > Tested-By: James Morse <james.morse@arm.com>

> > > >

> > > > [1] http://www.spinics.net/lists/linux-pci/msg42194.html

> > > > [2] http://www.spinics.net/lists/arm-kernel/msg436779.html

> > > > ---

> > > >  drivers/pci/host/pci-dra7xx.c      |  15 +--

> > > >  drivers/pci/host/pci-exynos.c      |   2 +-

> > > >  drivers/pci/host/pci-imx6.c        |   2 +-

> > > >  drivers/pci/host/pci-keystone-dw.c |   2 +-

> > > >  drivers/pci/host/pci-keystone.c    |   2 +-

> > > >  drivers/pci/host/pci-layerscape.c  |   2 +-

> > > >  drivers/pci/host/pcie-designware.c | 229 ++++++++++++-----------

> ----

> > > ----------

> > > >  drivers/pci/host/pcie-designware.h |  14 +--

> > > >  drivers/pci/host/pcie-spear13xx.c  |   2 +-

> > > >  9 files changed, 95 insertions(+), 175 deletions(-)

> > > >

> > > > diff --git a/drivers/pci/host/pci-dra7xx.c

> b/drivers/pci/host/pci-

> > > dra7xx.c

> > > > index 18ae7ff..1268c69 100644

> > > > --- a/drivers/pci/host/pci-dra7xx.c

> > > > +++ b/drivers/pci/host/pci-dra7xx.c

> > > > @@ -141,15 +141,15 @@ static void dra7xx_pcie_host_init(struct

> > > pcie_port *pp)

> > > >  {

> > > >  	dw_pcie_setup_rc(pp);

> > > >

> > > > -	if (pp->io_mod_base)

> > > > -		pp->io_mod_base &= CPU_TO_BUS_ADDR;

> > > > +	if (pp->io_base)

> > > > +		pp->io_base &= CPU_TO_BUS_ADDR;

> > > >

> > > > -	if (pp->mem_mod_base)

> > > > -		pp->mem_mod_base &= CPU_TO_BUS_ADDR;

> > > > +	if (pp->mem_base)

> > > > +		pp->mem_base &= CPU_TO_BUS_ADDR;

> > > >

> > > > -	if (pp->cfg0_mod_base) {

> > > > -		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;

> > > > -		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;

> > > > +	if (pp->cfg0_base) {

> > > > +		pp->cfg0_base &= CPU_TO_BUS_ADDR;

> > > > +		pp->cfg1_base &= CPU_TO_BUS_ADDR;

> > > >  	}

> > > >

> > > >  	dra7xx_pcie_establish_link(pp);

> > > > @@ -288,6 +288,7 @@ static int __init dra7xx_add_pcie_port(struct

> > > dra7xx_pcie *dra7xx,

> > > >

> > > >  	pp = &dra7xx->pp;

> > > >  	pp->dev = dev;

> > > > +	pp->root_bus_nr = 0;

> > > >  	pp->ops = &dra7xx_pcie_host_ops;

> > > >

> > > >  	pp->irq = platform_get_irq(pdev, 1);

> > > > diff --git a/drivers/pci/host/pci-exynos.c

> b/drivers/pci/host/pci-

> > > exynos.c

> > > > index f9f468d..9771bb0 100644

> > > > --- a/drivers/pci/host/pci-exynos.c

> > > > +++ b/drivers/pci/host/pci-exynos.c

> > > > @@ -530,7 +530,7 @@ static int __init exynos_add_pcie_port(struct

> > > pcie_port *pp,

> > > >  		}

> > > >  	}

> > > >

> > > > -	pp->root_bus_nr = -1;

> > > > +	pp->root_bus_nr = 0;

> > > >  	pp->ops = &exynos_pcie_host_ops;

> > > >

> > > >  	ret = dw_pcie_host_init(pp);

> > > > diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-

> > > imx6.c

> > > > index 233a196..bec256c 100644

> > > > --- a/drivers/pci/host/pci-imx6.c

> > > > +++ b/drivers/pci/host/pci-imx6.c

> > > > @@ -551,7 +551,7 @@ static int __init imx6_add_pcie_port(struct

> > > pcie_port *pp,

> > > >  		}

> > > >  	}

> > > >

> > > > -	pp->root_bus_nr = -1;

> > > > +	pp->root_bus_nr = 0;

> > > >  	pp->ops = &imx6_pcie_host_ops;

> > > >

> > > >  	ret = dw_pcie_host_init(pp);

> > > > diff --git a/drivers/pci/host/pci-keystone-dw.c

> > > b/drivers/pci/host/pci-keystone-dw.c

> > > > index f34892e..b1e4135 100644

> > > > --- a/drivers/pci/host/pci-keystone-dw.c

> > > > +++ b/drivers/pci/host/pci-keystone-dw.c

> > > > @@ -327,7 +327,7 @@ static void ks_dw_pcie_clear_dbi_mode(void

> > > __iomem *reg_virt)

> > > >  void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)

> > > >  {

> > > >  	struct pcie_port *pp = &ks_pcie->pp;

> > > > -	u32 start = pp->mem.start, end = pp->mem.end;

> > > > +	u32 start = pp->mem->start, end = pp->mem->end;

> > > >  	int i, tr_size;

> > > >

> > > >  	/* Disable BARs for inbound access */

> > > > diff --git a/drivers/pci/host/pci-keystone.c

> b/drivers/pci/host/pci-

> > > keystone.c

> > > > index 734da58..8113832 100644

> > > > --- a/drivers/pci/host/pci-keystone.c

> > > > +++ b/drivers/pci/host/pci-keystone.c

> > > > @@ -309,7 +309,7 @@ static int __init ks_add_pcie_port(struct

> > > keystone_pcie *ks_pcie,

> > > >  			return ret;

> > > >  	}

> > > >

> > > > -	pp->root_bus_nr = -1;

> > > > +	pp->root_bus_nr = 0;

> > > >  	pp->ops = &keystone_pcie_host_ops;

> > > >  	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);

> > > >  	if (ret) {

> > > > diff --git a/drivers/pci/host/pci-layerscape.c

> > > b/drivers/pci/host/pci-layerscape.c

> > > > index b2328ea1..79ff08c 100644

> > > > --- a/drivers/pci/host/pci-layerscape.c

> > > > +++ b/drivers/pci/host/pci-layerscape.c

> > > > @@ -106,7 +106,7 @@ static int ls_add_pcie_port(struct ls_pcie

> *pcie)

> > > >  	pp = &pcie->pp;

> > > >  	pp->dev = pcie->dev;

> > > >  	pp->dbi_base = pcie->dbi;

> > > > -	pp->root_bus_nr = -1;

> > > > +	pp->root_bus_nr = 0;

> > > >  	pp->ops = &ls_pcie_host_ops;

> > > >

> > > >  	ret = dw_pcie_host_init(pp);

> > > > diff --git a/drivers/pci/host/pcie-designware.c

> > > b/drivers/pci/host/pcie-designware.c

> > > > index c5d407c..e71a88e 100644

> > > > --- a/drivers/pci/host/pcie-designware.c

> > > > +++ b/drivers/pci/host/pcie-designware.c

> > > > @@ -11,6 +11,7 @@

> > > >   * published by the Free Software Foundation.

> > > >   */

> > > >

> > > > +#include <linux/hardirq.h>

> > > >  #include <linux/irq.h>

> > > >  #include <linux/irqdomain.h>

> > > >  #include <linux/kernel.h>

> > > > @@ -69,16 +70,7 @@

> > > >  #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)

> > > >  #define PCIE_ATU_UPPER_TARGET		0x91C

> > > >

> > > > -static struct hw_pci dw_pci;

> > > > -

> > > > -static unsigned long global_io_offset;

> > > > -

> > > > -static inline struct pcie_port *sys_to_pcie(struct pci_sys_data

> *sys)

> > > > -{

> > > > -	BUG_ON(!sys->private_data);

> > > > -

> > > > -	return sys->private_data;

> > > > -}

> > > > +static struct pci_ops dw_pcie_ops;

> > > >

> > > >  int dw_pcie_cfg_read(void __iomem *addr, int where, int size,

> u32

> > > *val)

> > > >  {

> > > > @@ -255,7 +247,7 @@ static void dw_pcie_msi_set_irq(struct

> pcie_port

> > > *pp, int irq)

> > > >  static int assign_irq(int no_irqs, struct msi_desc *desc, int

> *pos)

> > > >  {

> > > >  	int irq, pos0, i;

> > > > -	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);

> > > > +	struct pcie_port *pp = desc->dev->bus->sysdata;

> > > >

> > > >  	pos0 = bitmap_find_free_region(pp->msi_irq_in_use,

> MAX_MSI_IRQS,

> > > >  				       order_base_2(no_irqs));

> > > > @@ -298,7 +290,7 @@ static int dw_msi_setup_irq(struct

> msi_controller

> > > *chip, struct pci_dev *pdev,

> > > >  {

> > > >  	int irq, pos;

> > > >  	struct msi_msg msg;

> > > > -	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);

> > > > +	struct pcie_port *pp = pdev->bus->sysdata;

> > > >

> > > >  	if (desc->msi_attrib.is_msix)

> > > >  		return -EINVAL;

> > > > @@ -327,7 +319,7 @@ static void dw_msi_teardown_irq(struct

> > > msi_controller *chip, unsigned int irq)

> > > >  {

> > > >  	struct irq_data *data = irq_get_irq_data(irq);

> > > >  	struct msi_desc *msi = irq_data_get_msi(data);

> > > > -	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);

> > > > +	struct pcie_port *pp = msi->dev->bus->sysdata;

> > > >

> > > >  	clear_irq_range(pp, irq, 1, data->hwirq);

> > > >  }

> > > > @@ -363,14 +355,12 @@ int dw_pcie_host_init(struct pcie_port *pp)

> > > >  {

> > > >  	struct device_node *np = pp->dev->of_node;

> > > >  	struct platform_device *pdev = to_platform_device(pp->dev);

> > > > -	struct of_pci_range range;

> > > > -	struct of_pci_range_parser parser;

> > > > +	struct pci_bus *bus;

> > > >  	struct resource *cfg_res;

> > > > -	u32 val, ns;

> > > > -	const __be32 *addrp;

> > > > -	int i, index, ret;

> > > > -

> > > > -	ns = of_n_size_cells(np);

> > > > +	LIST_HEAD(res);

> > > > +	u32 val;

> > > > +	int i, ret;

> > > > +	struct resource_entry *win;

> > > >

> > > >  	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM,

> > > "config");

> > > >  	if (cfg_res) {

> > > > @@ -378,85 +368,60 @@ int dw_pcie_host_init(struct pcie_port *pp)

> > > >  		pp->cfg1_size = resource_size(cfg_res)/2;

> > > >  		pp->cfg0_base = cfg_res->start;

> > > >  		pp->cfg1_base = cfg_res->start + pp->cfg0_size;

> > > > -

> > > > -		/* Find the untranslated configuration space address

> */

> > > > -		index = of_property_match_string(np, "reg-names",

> "config");

> > > > -		addrp = of_get_address(np, index, NULL, NULL);

> > > > -		pp->cfg0_mod_base = of_read_number(addrp, ns);

> > > > -		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;

> > > >  	} else {

> > > >  		dev_err(pp->dev, "missing *config* reg space\n");

> > > >  	}

> > > >

> > > > -	if (of_pci_range_parser_init(&parser, np)) {

> > > > -		dev_err(pp->dev, "missing ranges property\n");

> > > > -		return -EINVAL;

> > > > -	}

> > > > +	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res,

> &pp-

> > > >io_base);

> > > > +	if (ret)

> > > > +		return ret;

> > > >

> > > >  	/* Get the I/O and memory ranges from DT */

> > > > -	for_each_of_pci_range(&parser, &range) {

> > > > -		unsigned long restype = range.flags &

> IORESOURCE_TYPE_BITS;

> > > > -

> > > > -		if (restype == IORESOURCE_IO) {

> > > > -			of_pci_range_to_resource(&range, np, &pp->io);

> > > > -			pp->io.name = "I/O";

> > > > -			pp->io.start = max_t(resource_size_t,

> > > > -					     PCIBIOS_MIN_IO,

> > > > -					     range.pci_addr +

> global_io_offset);

> > > > -			pp->io.end = min_t(resource_size_t,

> > > > -					   IO_SPACE_LIMIT,

> > > > -					   range.pci_addr + range.size

> > > > -					   + global_io_offset - 1);

> > > > -			pp->io_size = resource_size(&pp->io);

> > > > -			pp->io_bus_addr = range.pci_addr;

> > > > -			pp->io_base = range.cpu_addr;

> > > > -

> > > > -			/* Find the untranslated IO space address */

> > > > -			pp->io_mod_base = range.cpu_addr;

> > > > -		}

> > > > -		if (restype == IORESOURCE_MEM) {

> > > > -			of_pci_range_to_resource(&range, np, &pp->mem);

> > > > -			pp->mem.name = "MEM";

> > > > -			pp->mem_size = resource_size(&pp->mem);

> > > > -			pp->mem_bus_addr = range.pci_addr;

> > > > -

> > > > -			/* Find the untranslated MEM space address */

> > > > -			pp->mem_mod_base = range.cpu_addr;

> > > > -		}

> > > > -		if (restype == 0) {

> > > > -			of_pci_range_to_resource(&range, np, &pp->cfg);

> > > > -			pp->cfg0_size = resource_size(&pp->cfg)/2;

> > > > -			pp->cfg1_size = resource_size(&pp->cfg)/2;

> > > > -			pp->cfg0_base = pp->cfg.start;

> > > > -			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;

> > > > -

> > > > -			/* Find the untranslated configuration space

> address

> > > */

> > > > -			pp->cfg0_mod_base = range.cpu_addr;

> > > > -			pp->cfg1_mod_base = pp->cfg0_mod_base +

> > > > -					    pp->cfg0_size;

> > > > +	resource_list_for_each_entry(win, &res) {

> > > > +		switch (resource_type(win->res)) {

> > > > +		case IORESOURCE_IO:

> > > > +			pp->io = win->res;

> > > > +			pp->io->name = "I/O";

> > > > +			pp->io_size = resource_size(pp->io);

> > > > +			pp->io_bus_addr = pp->io->start - win->offset;

> > > > +			ret = pci_remap_iospace(pp->io, pp->io_base);

> > > > +			if (ret) {

> > > > +				dev_warn(pp->dev, "error %d: failed to

> map

> > > resource %pR\n",

> > > > +					 ret, pp->io);

> > > > +				continue;

> > > > +			}

> > > > +			break;

> > > > +		case IORESOURCE_MEM:

> > > > +			pp->mem = win->res;

> > > > +			pp->mem->name = "MEM";

> > > > +			pp->mem_size = resource_size(pp->mem);

> > > > +			pp->mem_bus_addr = pp->mem->start - win->offset;

> > > > +			break;

> > > > +		case 0:

> > > > +			pp->cfg = win->res;

> > > > +			pp->cfg0_size = resource_size(pp->cfg)/2;

> > > > +			pp->cfg1_size = resource_size(pp->cfg)/2;

> > > > +			pp->cfg0_base = pp->cfg->start;

> > > > +			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;

> > > > +			break;

> > > > +		case IORESOURCE_BUS:

> > > > +			pp->busn = win->res;

> > > > +			break;

> > > > +		default:

> > > > +			continue;

> > > >  		}

> > > >  	}

> > > >

> > > > -	ret = of_pci_parse_bus_range(np, &pp->busn);

> > > > -	if (ret < 0) {

> > > > -		pp->busn.name = np->name;

> > > > -		pp->busn.start = 0;

> > > > -		pp->busn.end = 0xff;

> > > > -		pp->busn.flags = IORESOURCE_BUS;

> > > > -		dev_dbg(pp->dev, "failed to parse bus-range

> property: %d,

> > > using default %pR\n",

> > > > -			ret, &pp->busn);

> > > > -	}

> > > > -

> > > >  	if (!pp->dbi_base) {

> > > > -		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,

> > > > -					resource_size(&pp->cfg));

> > > > +		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,

> > > > +					resource_size(pp->cfg));

> > > >  		if (!pp->dbi_base) {

> > > >  			dev_err(pp->dev, "error with ioremap\n");

> > > >  			return -ENOMEM;

> > > >  		}

> > > >  	}

> > > >

> > > > -	pp->mem_base = pp->mem.start;

> > > > +	pp->mem_base = pp->mem->start;

> > > >

> > > >  	if (!pp->va_cfg0_base) {

> > > >  		pp->va_cfg0_base = devm_ioremap(pp->dev, pp-

> >cfg0_base,

> > > > @@ -505,7 +470,7 @@ int dw_pcie_host_init(struct pcie_port *pp)

> > > >

> > > >  	if (!pp->ops->rd_other_conf)

> > > >  		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,

> > > > -					  PCIE_ATU_TYPE_MEM, pp-

> >mem_mod_base,

> > > > +					  PCIE_ATU_TYPE_MEM, pp->mem_base,

> > > >  					  pp->mem_bus_addr, pp->mem_size);

> > > >

> > > >  	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);

> > > > @@ -517,15 +482,29 @@ int dw_pcie_host_init(struct pcie_port *pp)

> > > >  	val |= PORT_LOGIC_SPEED_CHANGE;

> > > >  	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4,

> val);

> > > >

> > > > -#ifdef CONFIG_PCI_MSI

> > > > +	bus = pci_create_root_bus(pp->dev, pp->root_bus_nr,

> &dw_pcie_ops,

> > > > +				  pp, &res);

> > > > +	if (!bus)

> > > > +		return -ENOMEM;

> > > > +

> > > > +#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN

> > > > +	bus->msi = container_of(&pp->irq_domain, struct

> msi_controller,

> > > domain);

> > > > +#else

> > > >  	dw_pcie_msi_chip.dev = pp->dev;

> > > > -	dw_pci.msi_ctrl = &dw_pcie_msi_chip;

> > > > +	bus->msi = &dw_pcie_msi_chip;

> > > >  #endif

> > > >

> > > > -	dw_pci.nr_controllers = 1;

> > > > -	dw_pci.private_data = (void **)&pp;

> > > > +	pci_scan_child_bus(bus);

> > > > +	if (pp->ops->scan_bus)

> > > > +		pp->ops->scan_bus(pp);

> > > > +

> > > > +#ifdef CONFIG_ARM

> > > > +	/* support old dtbs that incorrectly describe IRQs */

> > > > +	pci_fixup_irqs(pci_common_swizzle,

> of_irq_parse_and_map_pci);

> > > > +#endif

> > > >

> > > > -	pci_common_init_dev(pp->dev, &dw_pci);

> > > > +	pci_assign_unassigned_bus_resources(bus);

> > > > +	pci_bus_add_devices(bus);

> > > >

> > > >  	return 0;

> > > >  }

> > > > @@ -544,12 +523,12 @@ static int dw_pcie_rd_other_conf(struct

> > > pcie_port *pp, struct pci_bus *bus,

> > > >

> > > >  	if (bus->parent->number == pp->root_bus_nr) {

> > > >  		type = PCIE_ATU_TYPE_CFG0;

> > > > -		cpu_addr = pp->cfg0_mod_base;

> > > > +		cpu_addr = pp->cfg0_base;

> > > >  		cfg_size = pp->cfg0_size;

> > > >  		va_cfg_base = pp->va_cfg0_base;

> > > >  	} else {

> > > >  		type = PCIE_ATU_TYPE_CFG1;

> > > > -		cpu_addr = pp->cfg1_mod_base;

> > > > +		cpu_addr = pp->cfg1_base;

> > > >  		cfg_size = pp->cfg1_size;

> > > >  		va_cfg_base = pp->va_cfg1_base;

> > > >  	}

> > > > @@ -559,7 +538,7 @@ static int dw_pcie_rd_other_conf(struct

> pcie_port

> > > *pp, struct pci_bus *bus,

> > > >  				  busdev, cfg_size);

> > > >  	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size,

> val);

> > > >  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,

> > > > -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,

> > > > +				  PCIE_ATU_TYPE_IO, pp->io_base,

> > > >  				  pp->io_bus_addr, pp->io_size);

> > > >

> > > >  	return ret;

> > > > @@ -579,12 +558,12 @@ static int dw_pcie_wr_other_conf(struct

> > > pcie_port *pp, struct pci_bus *bus,

> > > >

> > > >  	if (bus->parent->number == pp->root_bus_nr) {

> > > >  		type = PCIE_ATU_TYPE_CFG0;

> > > > -		cpu_addr = pp->cfg0_mod_base;

> > > > +		cpu_addr = pp->cfg0_base;

> > > >  		cfg_size = pp->cfg0_size;

> > > >  		va_cfg_base = pp->va_cfg0_base;

> > > >  	} else {

> > > >  		type = PCIE_ATU_TYPE_CFG1;

> > > > -		cpu_addr = pp->cfg1_mod_base;

> > > > +		cpu_addr = pp->cfg1_base;

> > > >  		cfg_size = pp->cfg1_size;

> > > >  		va_cfg_base = pp->va_cfg1_base;

> > > >  	}

> > > > @@ -594,7 +573,7 @@ static int dw_pcie_wr_other_conf(struct

> pcie_port

> > > *pp, struct pci_bus *bus,

> > > >  				  busdev, cfg_size);

> > > >  	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size,

> val);

> > > >  	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,

> > > > -				  PCIE_ATU_TYPE_IO, pp->io_mod_base,

> > > > +				  PCIE_ATU_TYPE_IO, pp->io_base,

> > > >  				  pp->io_bus_addr, pp->io_size);

> > > >

> > > >  	return ret;

> > > > @@ -626,7 +605,7 @@ static int dw_pcie_valid_config(struct

> pcie_port

> > > *pp,

> > > >  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int

> where,

> > > >  			int size, u32 *val)

> > > >  {

> > > > -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);

> > > > +	struct pcie_port *pp = bus->sysdata;

> > > >  	int ret;

> > > >

> > > >  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {

> > > > @@ -650,7 +629,7 @@ static int dw_pcie_rd_conf(struct pci_bus

> *bus,

> > > u32 devfn, int where,

> > > >  static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,

> > > >  			int where, int size, u32 val)

> > > >  {

> > > > -	struct pcie_port *pp = sys_to_pcie(bus->sysdata);

> > > > +	struct pcie_port *pp = bus->sysdata;

> > > >  	int ret;

> > > >

> > > >  	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)

> > > > @@ -674,62 +653,6 @@ static struct pci_ops dw_pcie_ops = {

> > > >  	.write = dw_pcie_wr_conf,

> > > >  };

> > > >

> > > > -static int dw_pcie_setup(int nr, struct pci_sys_data *sys)

> > > > -{

> > > > -	struct pcie_port *pp;

> > > > -

> > > > -	pp = sys_to_pcie(sys);

> > > > -

> > > > -	if (global_io_offset < SZ_1M && pp->io_size > 0) {

> > > > -		sys->io_offset = global_io_offset - pp->io_bus_addr;

> > > > -		pci_ioremap_io(global_io_offset, pp->io_base);

> > > > -		global_io_offset += SZ_64K;

> > > > -		pci_add_resource_offset(&sys->resources, &pp->io,

> > > > -					sys->io_offset);

> > > > -	}

> > > > -

> > > > -	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;

> > > > -	pci_add_resource_offset(&sys->resources, &pp->mem, sys-

> > > >mem_offset);

> > > > -	pci_add_resource(&sys->resources, &pp->busn);

> > > > -

> > > > -	return 1;

> > > > -}

> > > > -

> > > > -static struct pci_bus *dw_pcie_scan_bus(int nr, struct

> pci_sys_data

> > > *sys)

> > > > -{

> > > > -	struct pci_bus *bus;

> > > > -	struct pcie_port *pp = sys_to_pcie(sys);

> > > > -

> > > > -	pp->root_bus_nr = sys->busnr;

> > > > -	bus = pci_scan_root_bus(pp->dev, sys->busnr,

> > > > -				  &dw_pcie_ops, sys, &sys->resources);

> > > > -	if (!bus)

> > > > -		return NULL;

> > > > -

> > > > -	if (bus && pp->ops->scan_bus)

> > > > -		pp->ops->scan_bus(pp);

> > > > -

> > > > -	return bus;

> > > > -}

> > > > -

> > > > -static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot,

> u8

> > > pin)

> > > > -{

> > > > -	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);

> > > > -	int irq;

> > > > -

> > > > -	irq = of_irq_parse_and_map_pci(dev, slot, pin);

> > > > -	if (!irq)

> > > > -		irq = pp->irq;

> > > > -

> > > > -	return irq;

> > > > -}

> > > > -

> > > > -static struct hw_pci dw_pci = {

> > > > -	.setup		= dw_pcie_setup,

> > > > -	.scan		= dw_pcie_scan_bus,

> > > > -	.map_irq	= dw_pcie_map_irq,

> > > > -};

> > > > -

> > > >  void dw_pcie_setup_rc(struct pcie_port *pp)

> > > >  {

> > > >  	u32 val;

> > > > diff --git a/drivers/pci/host/pcie-designware.h

> > > b/drivers/pci/host/pcie-designware.h

> > > > index d0bbd27..264c969 100644

> > > > --- a/drivers/pci/host/pcie-designware.h

> > > > +++ b/drivers/pci/host/pcie-designware.h

> > > > @@ -27,25 +27,21 @@ struct pcie_port {

> > > >  	u8			root_bus_nr;

> > > >  	void __iomem		*dbi_base;

> > > >  	u64			cfg0_base;

> > > > -	u64			cfg0_mod_base;

> > > >  	void __iomem		*va_cfg0_base;

> > > >  	u32			cfg0_size;

> > > >  	u64			cfg1_base;

> > > > -	u64			cfg1_mod_base;

> > > >  	void __iomem		*va_cfg1_base;

> > > >  	u32			cfg1_size;

> > > > -	u64			io_base;

> > > > -	u64			io_mod_base;

> > > > +	resource_size_t		io_base;

> > > >  	phys_addr_t		io_bus_addr;

> > > >  	u32			io_size;

> > > >  	u64			mem_base;

> > > > -	u64			mem_mod_base;

> > > >  	phys_addr_t		mem_bus_addr;

> > > >  	u32			mem_size;

> > > > -	struct resource		cfg;

> > > > -	struct resource		io;

> > > > -	struct resource		mem;

> > > > -	struct resource		busn;

> > > > +	struct resource		*cfg;

> > > > +	struct resource		*io;

> > > > +	struct resource		*mem;

> > > > +	struct resource		*busn;

> > > >  	int			irq;

> > > >  	u32			lanes;

> > > >  	struct pcie_host_ops	*ops;

> > > > diff --git a/drivers/pci/host/pcie-spear13xx.c

> > > b/drivers/pci/host/pcie-spear13xx.c

> > > > index c49fbdc..03eb204 100644

> > > > --- a/drivers/pci/host/pcie-spear13xx.c

> > > > +++ b/drivers/pci/host/pcie-spear13xx.c

> > > > @@ -286,7 +286,7 @@ static int spear13xx_add_pcie_port(struct

> > > pcie_port *pp,

> > > >  		return ret;

> > > >  	}

> > > >

> > > > -	pp->root_bus_nr = -1;

> > > > +	pp->root_bus_nr = 0;

> > > >  	pp->ops = &spear13xx_pcie_host_ops;

> > > >

> > > >  	ret = dw_pcie_host_init(pp);

> > >

> > > --

> > > Pengutronix e.K.             | Lucas Stach                 |

> > > Industrial Linux Solutions   | http://www.pengutronix.de/  |

> >

> 

> --

> Pengutronix e.K.             | Lucas Stach                 |

> Industrial Linux Solutions   | http://www.pengutronix.de/  |
Lucas Stach Aug. 20, 2015, 8:27 a.m. UTC | #6
Hi Gab,

Am Mittwoch, den 19.08.2015, 16:34 +0000 schrieb Gabriele Paoloni:
> Hi Lucas
> 
> First of all many thanks for the quick reply, really appreciated
> 
> > -----Original Message-----
> > From: Lucas Stach [mailto:l.stach@pengutronix.de]
> > Sent: Wednesday, August 19, 2015 4:37 PM
> > To: Gabriele Paoloni
> > Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; Pratyush Anand;
> > Arnd Bergmann; linux@arm.linux.org.uk; thomas.petazzoni@free-
> > electrons.com; lorenzo.pieralisi@arm.com; james.morse@arm.com;
> > Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; linux-
> > pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> > devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)
> > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> > 
> > Hi Gab,
> > 
> > Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele Paoloni:
> > > Hi Lucas
> > >
> > > I have rewritten the patch to take into account multiple controllers.
> > >
> > > As you can see now there is a static var in dw_pcie_host_init() that
> > tracks
> > > the bus numbers used.
> > 
> > This is wrong. The DT specifies the valid bus number range. You can not
> > just assign the next free bus number to the root bus.
> 
> I think this is what is being done in
> http://lxr.free-electrons.com/source/arch/arm/kernel/bios32.c#L495
> and currently designware assigns the root bus number in
> http://lxr.free-electrons.com/source/drivers/pci/host/pcie-designware.c#L730
> 
You found the right spot. It works a bit different than I remember, but
is less broken than your current code. :)

It actually assigns the next instance a root bus number behind the
current instances bus range. Please note the difference to your code
which assigns the next free bus number, which may still lay within the
current instances bus range.

> 
> In general I agree with you but if you look at all the current drivers 
> based on designware none of them define the "bus-range" dtb property.
> Therefore doing as you say would break the current driver when we have
> multiple controllers...am I right?
> 
The current _code_ works fine for multiple controllers. It's just that
you must define the bus range property in the DTB if you want to enable
multiple instances of one controller and support a kernel without PCI
domains support. As all current implementations have only a single
instance of the controller per SoC, or depend on PCI domain support,
it's totally fine for them to not define the bus ranges property, as
it's an optional property and it is well defined how things behave if it
is absent. We absolutely need to keep that specified behavior.

> If that is the case in order to fix this in the way you say I would need
> to assign "bus-range" for all the PCIe drivers with multiple controllers:
> in this case I would split the default range evenly (that is, if we have 
> two controllers I would define "bus-range"  0-127 and 128-255)
> 
> If you think this solution is ok I can go for it. My only doubt was about
> touching other vendors DTBs....
> 
You don't need to touch any of the current DTBs, as they are fine with
the default bus range behavior. You need to keep the specified behavior
of the bus range property with the new code.

Regards,
Lucas
> 
> > 
> > It is perfectly valid to have a bus range of 0x00-0x10 assigned to one
> > instance and 0x50-0xff to the next instance. Additional with PCIe
> > hotplug you may not use the full range of the bus numbers on one
> > instance at the first scan, but only later populate more buses when
> > more
> > bridges are added to the tree.
> > 
> > > Drivers that do not specify the bus range in the DTB set pp-
> > >root_bus_nr = DW_ROOT_NR_UNDEFINED.
> > > Designware will check if the flag is set and will use the automatic
> > bus range
> > > assignment.
> > 
> > No, please lets get rid of this assignment altogether. The glue drivers
> > have no business in assigning the bus range. Please remove the
> > pp->root_bus_nr assignment from all the glue drivers.
> > 
> > "bus range" is a generic DW PCIe property, so just parse the root bus
> > number from the DT, it is handled the same way for all the DW based
> > PCIe
> > drivers. The bindings specifies that if the bus range property is
> > missing the range is 0x00-0xff, so you can default to 0 as the root bus
> > number in that case.
> > 
> > Also I would think this conversion warrants a patch on its own and
> > should not be mixed in the ARM64 support patch.
> > 
> > Regards,
> > Lucas
> >
Gabriele Paoloni Aug. 20, 2015, 11:10 a.m. UTC | #7
SGkgTHVjYXMNCg0KQWdhaW4gbWFueSB0aGFua3MgZm9yIGV4cGxhaW5pbmcgYW5kIGZvciB5b3Vy
IHRpbWUuDQoNCkkgZ290IHlvdXIgcG9pbnQgbm93IGFuZCBJIGhhdmUgZHVnIGEgYml0IGJldHRl
ciBpbiB0aGUgUENJX0RPTUFJTlMgY29kZS4NCg0KSG93ZXZlciBJIGhhdmUgYSBxdWVzdGlvbi4u
LnNlZSBpbmxpbmUgYmVsb3cNCg0KPiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiBGcm9t
OiBMdWNhcyBTdGFjaCBbbWFpbHRvOmwuc3RhY2hAcGVuZ3V0cm9uaXguZGVdDQo+IFNlbnQ6IFRo
dXJzZGF5LCBBdWd1c3QgMjAsIDIwMTUgOToyNyBBTQ0KPiBUbzogR2FicmllbGUgUGFvbG9uaQ0K
PiBDYzogV2FuZ3pob3UgKEIpOyBCam9ybiBIZWxnYWFzOyBqaW5nb29oYW4xQGdtYWlsLmNvbTsg
UHJhdHl1c2ggQW5hbmQ7DQo+IEFybmQgQmVyZ21hbm47IGxpbnV4QGFybS5saW51eC5vcmcudWs7
IHRob21hcy5wZXRhenpvbmlAZnJlZS0NCj4gZWxlY3Ryb25zLmNvbTsgbG9yZW56by5waWVyYWxp
c2lAYXJtLmNvbTsgamFtZXMubW9yc2VAYXJtLmNvbTsNCj4gTGl2aXUuRHVkYXVAYXJtLmNvbTsg
amFzb25AbGFrZWRhZW1vbi5uZXQ7IHJvYmhAa2VybmVsLm9yZzsgbGludXgtDQo+IHBjaUB2Z2Vy
Lmtlcm5lbC5vcmc7IGxpbnV4LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZzsNCj4gZGV2
aWNldHJlZUB2Z2VyLmtlcm5lbC5vcmc7IFl1YW56aGljaGFuZzsgWmh1ZGFjYWk7IHpoYW5nanVr
dW87DQo+IHFpdXpoZW5mYTsgbGl1ZG9uZ2RvbmcgKEMpOyBxaXVqaWFuZzsgeHV3ZWkgKE8pOyBM
aWd1b3podSAoS2VubmV0aCkNCj4gU3ViamVjdDogUmU6IFtQQVRDSCB2NyAzLzZdIFBDSTogZGVz
aWdud2FyZTogQWRkIEFSTTY0IHN1cHBvcnQNCj4gDQo+IEhpIEdhYiwNCj4gDQo+IEFtIE1pdHR3
b2NoLCBkZW4gMTkuMDguMjAxNSwgMTY6MzQgKzAwMDAgc2NocmllYiBHYWJyaWVsZSBQYW9sb25p
Og0KPiA+IEhpIEx1Y2FzDQo+ID4NCj4gPiBGaXJzdCBvZiBhbGwgbWFueSB0aGFua3MgZm9yIHRo
ZSBxdWljayByZXBseSwgcmVhbGx5IGFwcHJlY2lhdGVkDQo+ID4NCj4gPiA+IC0tLS0tT3JpZ2lu
YWwgTWVzc2FnZS0tLS0tDQo+ID4gPiBGcm9tOiBMdWNhcyBTdGFjaCBbbWFpbHRvOmwuc3RhY2hA
cGVuZ3V0cm9uaXguZGVdDQo+ID4gPiBTZW50OiBXZWRuZXNkYXksIEF1Z3VzdCAxOSwgMjAxNSA0
OjM3IFBNDQo+ID4gPiBUbzogR2FicmllbGUgUGFvbG9uaQ0KPiA+ID4gQ2M6IFdhbmd6aG91IChC
KTsgQmpvcm4gSGVsZ2FhczsgamluZ29vaGFuMUBnbWFpbC5jb207IFByYXR5dXNoDQo+IEFuYW5k
Ow0KPiA+ID4gQXJuZCBCZXJnbWFubjsgbGludXhAYXJtLmxpbnV4Lm9yZy51azsgdGhvbWFzLnBl
dGF6em9uaUBmcmVlLQ0KPiA+ID4gZWxlY3Ryb25zLmNvbTsgbG9yZW56by5waWVyYWxpc2lAYXJt
LmNvbTsgamFtZXMubW9yc2VAYXJtLmNvbTsNCj4gPiA+IExpdml1LkR1ZGF1QGFybS5jb207IGph
c29uQGxha2VkYWVtb24ubmV0OyByb2JoQGtlcm5lbC5vcmc7IGxpbnV4LQ0KPiA+ID4gcGNpQHZn
ZXIua2VybmVsLm9yZzsgbGludXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnOw0KPiA+
ID4gZGV2aWNldHJlZUB2Z2VyLmtlcm5lbC5vcmc7IFl1YW56aGljaGFuZzsgWmh1ZGFjYWk7IHpo
YW5nanVrdW87DQo+ID4gPiBxaXV6aGVuZmE7IGxpdWRvbmdkb25nIChDKTsgcWl1amlhbmc7IHh1
d2VpIChPKTsgTGlndW96aHUgKEtlbm5ldGgpDQo+ID4gPiBTdWJqZWN0OiBSZTogW1BBVENIIHY3
IDMvNl0gUENJOiBkZXNpZ253YXJlOiBBZGQgQVJNNjQgc3VwcG9ydA0KPiA+ID4NCj4gPiA+IEhp
IEdhYiwNCj4gPiA+DQo+ID4gPiBBbSBNaXR0d29jaCwgZGVuIDE5LjA4LjIwMTUsIDE1OjE2ICsw
MDAwIHNjaHJpZWIgR2FicmllbGUgUGFvbG9uaToNCj4gPiA+ID4gSGkgTHVjYXMNCj4gPiA+ID4N
Cj4gPiA+ID4gSSBoYXZlIHJld3JpdHRlbiB0aGUgcGF0Y2ggdG8gdGFrZSBpbnRvIGFjY291bnQg
bXVsdGlwbGUNCj4gY29udHJvbGxlcnMuDQo+ID4gPiA+DQo+ID4gPiA+IEFzIHlvdSBjYW4gc2Vl
IG5vdyB0aGVyZSBpcyBhIHN0YXRpYyB2YXIgaW4gZHdfcGNpZV9ob3N0X2luaXQoKQ0KPiB0aGF0
DQo+ID4gPiB0cmFja3MNCj4gPiA+ID4gdGhlIGJ1cyBudW1iZXJzIHVzZWQuDQo+ID4gPg0KPiA+
ID4gVGhpcyBpcyB3cm9uZy4gVGhlIERUIHNwZWNpZmllcyB0aGUgdmFsaWQgYnVzIG51bWJlciBy
YW5nZS4gWW91IGNhbg0KPiBub3QNCj4gPiA+IGp1c3QgYXNzaWduIHRoZSBuZXh0IGZyZWUgYnVz
IG51bWJlciB0byB0aGUgcm9vdCBidXMuDQo+ID4NCj4gPiBJIHRoaW5rIHRoaXMgaXMgd2hhdCBp
cyBiZWluZyBkb25lIGluDQo+ID4gaHR0cDovL2x4ci5mcmVlLWVsZWN0cm9ucy5jb20vc291cmNl
L2FyY2gvYXJtL2tlcm5lbC9iaW9zMzIuYyNMNDk1DQo+ID4gYW5kIGN1cnJlbnRseSBkZXNpZ253
YXJlIGFzc2lnbnMgdGhlIHJvb3QgYnVzIG51bWJlciBpbg0KPiA+IGh0dHA6Ly9seHIuZnJlZS1l
bGVjdHJvbnMuY29tL3NvdXJjZS9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtDQo+IGRlc2lnbndhcmUu
YyNMNzMwDQo+ID4NCj4gWW91IGZvdW5kIHRoZSByaWdodCBzcG90LiBJdCB3b3JrcyBhIGJpdCBk
aWZmZXJlbnQgdGhhbiBJIHJlbWVtYmVyLCBidXQNCj4gaXMgbGVzcyBicm9rZW4gdGhhbiB5b3Vy
IGN1cnJlbnQgY29kZS4gOikNCj4gDQo+IEl0IGFjdHVhbGx5IGFzc2lnbnMgdGhlIG5leHQgaW5z
dGFuY2UgYSByb290IGJ1cyBudW1iZXIgYmVoaW5kIHRoZQ0KPiBjdXJyZW50IGluc3RhbmNlcyBi
dXMgcmFuZ2UuIFBsZWFzZSBub3RlIHRoZSBkaWZmZXJlbmNlIHRvIHlvdXIgY29kZQ0KPiB3aGlj
aCBhc3NpZ25zIHRoZSBuZXh0IGZyZWUgYnVzIG51bWJlciwgd2hpY2ggbWF5IHN0aWxsIGxheSB3
aXRoaW4gdGhlDQo+IGN1cnJlbnQgaW5zdGFuY2VzIGJ1cyByYW5nZS4NCg0KTW1tbSBoZXJlIEkg
aGF2ZSBkb25lIGEgbWlzdGFrZTogaW4gdGhlIGN1cnJlbnQgZGVzaWdud2FyZSB0aGUgbnVtYmVy
IG9mIGh3DQpjb250cm9sbGVycyBpcyBhbHdheXMgMQ0KaHR0cDovL2x4ci5mcmVlLWVsZWN0cm9u
cy5jb20vc291cmNlL2RyaXZlcnMvcGNpL2hvc3QvcGNpZS1kZXNpZ253YXJlLmMjTDUxMA0KU28g
dGhlIGxvb3AgaW4gYmlvczMyLmMgZG9lcyBub3Qgd29yayBvbiBtdWx0aXBsZSBQQ0llIHBvcnRz
Li4uDQpIb3dldmVyIHlvdXIgY29tbWVudCBhYm91dCBQQ0lfRE9NQUlOUyBlbmxpZ2h0ZW5lZCBt
eSBtaW5kIGFuZCBub3cgSSBzZWUNCnRoYXQgd2hlbiBDT05GSUdfUENJX0RPTUFJTlMgaXMgZGVm
aW5lZCB3ZSBoYXZlIHRoZSBkb21haW5zIG51bWJlcnMNCih0cmFja2VkIGJ5IF9fZG9tYWluX25y
KS4NClNvIChjb3JyZWN0IG1lIGlmIEkgYW0gd3JvbmcpIGlmIHdlIGhhdmUgMiBQQ0llIHBvcnRz
IHRoYXQgZG8gbm90IHNwZWNpZnkNCnRoZSAiYnVzLXJhbmdlIiBwcm9wZXJ0eSwgYm90aCByb290
IHBvcnRzIHdpbGwgZW51bWVyYXRlIHN0YXJ0aW5nIGZyb20gDQpyb290X2J1c19uciA9IDAgYW5k
IGV2ZXJ5dGhpbmcgd2lsbCBzdGlsbCB3b3JrIG9rLg0KDQpTbyBpZiBteSBhc3N1bXB0aW9uIGlz
IGNvcnJlY3QsIEkgZG8gbm90IHNlZSB3aHkgdGhlIG9yZ2luYWwgcGF0Y2ggZnJvbSBXYW5nIA0K
WmhvdSBpcyB3cm9uZy4gDQpUaGUgb25seSBwb2ludCBjYW4gYmUgdGhhdCBhc3NpZ25pbmcgcHAt
PnJvb3RfYnVzX25yID0gMCBpcyBub3QgcmVxdWlyZWQgDQphcyBwcCBtZW1vcnkgaXMga3phbGxv
YydlZCAoYW4gdGhlcmVmb3JlIGluaXQgdG8gemVybykuDQoNCg0KPiANCj4gPg0KPiA+IEluIGdl
bmVyYWwgSSBhZ3JlZSB3aXRoIHlvdSBidXQgaWYgeW91IGxvb2sgYXQgYWxsIHRoZSBjdXJyZW50
DQo+IGRyaXZlcnMNCj4gPiBiYXNlZCBvbiBkZXNpZ253YXJlIG5vbmUgb2YgdGhlbSBkZWZpbmUg
dGhlICJidXMtcmFuZ2UiIGR0YiBwcm9wZXJ0eS4NCj4gPiBUaGVyZWZvcmUgZG9pbmcgYXMgeW91
IHNheSB3b3VsZCBicmVhayB0aGUgY3VycmVudCBkcml2ZXIgd2hlbiB3ZQ0KPiBoYXZlDQo+ID4g
bXVsdGlwbGUgY29udHJvbGxlcnMuLi5hbSBJIHJpZ2h0Pw0KPiA+DQo+IFRoZSBjdXJyZW50IF9j
b2RlXyB3b3JrcyBmaW5lIGZvciBtdWx0aXBsZSBjb250cm9sbGVycy4gSXQncyBqdXN0IHRoYXQN
Cj4geW91IG11c3QgZGVmaW5lIHRoZSBidXMgcmFuZ2UgcHJvcGVydHkgaW4gdGhlIERUQiBpZiB5
b3Ugd2FudCB0byBlbmFibGUNCj4gbXVsdGlwbGUgaW5zdGFuY2VzIG9mIG9uZSBjb250cm9sbGVy
IGFuZCBzdXBwb3J0IGEga2VybmVsIHdpdGhvdXQgUENJDQo+IGRvbWFpbnMgc3VwcG9ydC4gQXMg
YWxsIGN1cnJlbnQgaW1wbGVtZW50YXRpb25zIGhhdmUgb25seSBhIHNpbmdsZQ0KPiBpbnN0YW5j
ZSBvZiB0aGUgY29udHJvbGxlciBwZXIgU29DLCBvciBkZXBlbmQgb24gUENJIGRvbWFpbiBzdXBw
b3J0LA0KPiBpdCdzIHRvdGFsbHkgZmluZSBmb3IgdGhlbSB0byBub3QgZGVmaW5lIHRoZSBidXMg
cmFuZ2VzIHByb3BlcnR5LCBhcw0KPiBpdCdzIGFuIG9wdGlvbmFsIHByb3BlcnR5IGFuZCBpdCBp
cyB3ZWxsIGRlZmluZWQgaG93IHRoaW5ncyBiZWhhdmUgaWYNCj4gaXQNCj4gaXMgYWJzZW50LiBX
ZSBhYnNvbHV0ZWx5IG5lZWQgdG8ga2VlcCB0aGF0IHNwZWNpZmllZCBiZWhhdmlvci4NCj4gDQo+
ID4gSWYgdGhhdCBpcyB0aGUgY2FzZSBpbiBvcmRlciB0byBmaXggdGhpcyBpbiB0aGUgd2F5IHlv
dSBzYXkgSSB3b3VsZA0KPiBuZWVkDQo+ID4gdG8gYXNzaWduICJidXMtcmFuZ2UiIGZvciBhbGwg
dGhlIFBDSWUgZHJpdmVycyB3aXRoIG11bHRpcGxlDQo+IGNvbnRyb2xsZXJzOg0KPiA+IGluIHRo
aXMgY2FzZSBJIHdvdWxkIHNwbGl0IHRoZSBkZWZhdWx0IHJhbmdlIGV2ZW5seSAodGhhdCBpcywg
aWYgd2UNCj4gaGF2ZQ0KPiA+IHR3byBjb250cm9sbGVycyBJIHdvdWxkIGRlZmluZSAiYnVzLXJh
bmdlIiAgMC0xMjcgYW5kIDEyOC0yNTUpDQo+ID4NCj4gPiBJZiB5b3UgdGhpbmsgdGhpcyBzb2x1
dGlvbiBpcyBvayBJIGNhbiBnbyBmb3IgaXQuIE15IG9ubHkgZG91YnQgd2FzDQo+IGFib3V0DQo+
ID4gdG91Y2hpbmcgb3RoZXIgdmVuZG9ycyBEVEJzLi4uLg0KPiA+DQo+IFlvdSBkb24ndCBuZWVk
IHRvIHRvdWNoIGFueSBvZiB0aGUgY3VycmVudCBEVEJzLCBhcyB0aGV5IGFyZSBmaW5lIHdpdGgN
Cj4gdGhlIGRlZmF1bHQgYnVzIHJhbmdlIGJlaGF2aW9yLiBZb3UgbmVlZCB0byBrZWVwIHRoZSBz
cGVjaWZpZWQgYmVoYXZpb3INCj4gb2YgdGhlIGJ1cyByYW5nZSBwcm9wZXJ0eSB3aXRoIHRoZSBu
ZXcgY29kZS4NCj4gDQo+IFJlZ2FyZHMsDQo+IEx1Y2FzDQo+ID4NCj4gPiA+DQo+ID4gPiBJdCBp
cyBwZXJmZWN0bHkgdmFsaWQgdG8gaGF2ZSBhIGJ1cyByYW5nZSBvZiAweDAwLTB4MTAgYXNzaWdu
ZWQgdG8NCj4gb25lDQo+ID4gPiBpbnN0YW5jZSBhbmQgMHg1MC0weGZmIHRvIHRoZSBuZXh0IGlu
c3RhbmNlLiBBZGRpdGlvbmFsIHdpdGggUENJZQ0KPiA+ID4gaG90cGx1ZyB5b3UgbWF5IG5vdCB1
c2UgdGhlIGZ1bGwgcmFuZ2Ugb2YgdGhlIGJ1cyBudW1iZXJzIG9uIG9uZQ0KPiA+ID4gaW5zdGFu
Y2UgYXQgdGhlIGZpcnN0IHNjYW4sIGJ1dCBvbmx5IGxhdGVyIHBvcHVsYXRlIG1vcmUgYnVzZXMg
d2hlbg0KPiA+ID4gbW9yZQ0KPiA+ID4gYnJpZGdlcyBhcmUgYWRkZWQgdG8gdGhlIHRyZWUuDQo+
ID4gPg0KPiA+ID4gPiBEcml2ZXJzIHRoYXQgZG8gbm90IHNwZWNpZnkgdGhlIGJ1cyByYW5nZSBp
biB0aGUgRFRCIHNldCBwcC0NCj4gPiA+ID5yb290X2J1c19uciA9IERXX1JPT1RfTlJfVU5ERUZJ
TkVELg0KPiA+ID4gPiBEZXNpZ253YXJlIHdpbGwgY2hlY2sgaWYgdGhlIGZsYWcgaXMgc2V0IGFu
ZCB3aWxsIHVzZSB0aGUNCj4gYXV0b21hdGljDQo+ID4gPiBidXMgcmFuZ2UNCj4gPiA+ID4gYXNz
aWdubWVudC4NCj4gPiA+DQo+ID4gPiBObywgcGxlYXNlIGxldHMgZ2V0IHJpZCBvZiB0aGlzIGFz
c2lnbm1lbnQgYWx0b2dldGhlci4gVGhlIGdsdWUNCj4gZHJpdmVycw0KPiA+ID4gaGF2ZSBubyBi
dXNpbmVzcyBpbiBhc3NpZ25pbmcgdGhlIGJ1cyByYW5nZS4gUGxlYXNlIHJlbW92ZSB0aGUNCj4g
PiA+IHBwLT5yb290X2J1c19uciBhc3NpZ25tZW50IGZyb20gYWxsIHRoZSBnbHVlIGRyaXZlcnMu
DQo+ID4gPg0KPiA+ID4gImJ1cyByYW5nZSIgaXMgYSBnZW5lcmljIERXIFBDSWUgcHJvcGVydHks
IHNvIGp1c3QgcGFyc2UgdGhlIHJvb3QNCj4gYnVzDQo+ID4gPiBudW1iZXIgZnJvbSB0aGUgRFQs
IGl0IGlzIGhhbmRsZWQgdGhlIHNhbWUgd2F5IGZvciBhbGwgdGhlIERXIGJhc2VkDQo+ID4gPiBQ
Q0llDQo+ID4gPiBkcml2ZXJzLiBUaGUgYmluZGluZ3Mgc3BlY2lmaWVzIHRoYXQgaWYgdGhlIGJ1
cyByYW5nZSBwcm9wZXJ0eSBpcw0KPiA+ID4gbWlzc2luZyB0aGUgcmFuZ2UgaXMgMHgwMC0weGZm
LCBzbyB5b3UgY2FuIGRlZmF1bHQgdG8gMCBhcyB0aGUgcm9vdA0KPiBidXMNCj4gPiA+IG51bWJl
ciBpbiB0aGF0IGNhc2UuDQo+ID4gPg0KPiA+ID4gQWxzbyBJIHdvdWxkIHRoaW5rIHRoaXMgY29u
dmVyc2lvbiB3YXJyYW50cyBhIHBhdGNoIG9uIGl0cyBvd24gYW5kDQo+ID4gPiBzaG91bGQgbm90
IGJlIG1peGVkIGluIHRoZSBBUk02NCBzdXBwb3J0IHBhdGNoLg0KPiA+ID4NCj4gPiA+IFJlZ2Fy
ZHMsDQo+ID4gPiBMdWNhcw0KPiA+ID4NCj4gDQo+IC0tDQo+IFBlbmd1dHJvbml4IGUuSy4gICAg
ICAgICAgICAgfCBMdWNhcyBTdGFjaCAgICAgICAgICAgICAgICAgfA0KPiBJbmR1c3RyaWFsIExp
bnV4IFNvbHV0aW9ucyAgIHwgaHR0cDovL3d3dy5wZW5ndXRyb25peC5kZS8gIHwNCg0K
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Liviu Dudau Aug. 21, 2015, 1:42 p.m. UTC | #8
On Thu, Aug 20, 2015 at 12:10:24PM +0100, Gabriele Paoloni wrote:
> Hi Lucas
> 
> Again many thanks for explaining and for your time.
> 
> I got your point now and I have dug a bit better in the PCI_DOMAINS code.
> 
> However I have a question...see inline below
> 
> > -----Original Message-----
> > From: Lucas Stach [mailto:l.stach@pengutronix.de]
> > Sent: Thursday, August 20, 2015 9:27 AM
> > To: Gabriele Paoloni
> > Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; Pratyush Anand;
> > Arnd Bergmann; linux@arm.linux.org.uk; thomas.petazzoni@free-
> > electrons.com; lorenzo.pieralisi@arm.com; james.morse@arm.com;
> > Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; linux-
> > pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> > devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)
> > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> > 
> > Hi Gab,
> > 
> > Am Mittwoch, den 19.08.2015, 16:34 +0000 schrieb Gabriele Paoloni:
> > > Hi Lucas
> > >
> > > First of all many thanks for the quick reply, really appreciated
> > >
> > > > -----Original Message-----
> > > > From: Lucas Stach [mailto:l.stach@pengutronix.de]
> > > > Sent: Wednesday, August 19, 2015 4:37 PM
> > > > To: Gabriele Paoloni
> > > > Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; Pratyush
> > Anand;
> > > > Arnd Bergmann; linux@arm.linux.org.uk; thomas.petazzoni@free-
> > > > electrons.com; lorenzo.pieralisi@arm.com; james.morse@arm.com;
> > > > Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; linux-
> > > > pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
> > > > devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
> > > > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)
> > > > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
> > > >
> > > > Hi Gab,
> > > >
> > > > Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele Paoloni:
> > > > > Hi Lucas
> > > > >
> > > > > I have rewritten the patch to take into account multiple
> > controllers.
> > > > >
> > > > > As you can see now there is a static var in dw_pcie_host_init()
> > that
> > > > tracks
> > > > > the bus numbers used.
> > > >
> > > > This is wrong. The DT specifies the valid bus number range. You can
> > not
> > > > just assign the next free bus number to the root bus.
> > >
> > > I think this is what is being done in
> > > http://lxr.free-electrons.com/source/arch/arm/kernel/bios32.c#L495
> > > and currently designware assigns the root bus number in
> > > http://lxr.free-electrons.com/source/drivers/pci/host/pcie-
> > designware.c#L730
> > >
> > You found the right spot. It works a bit different than I remember, but
> > is less broken than your current code. :)
> > 
> > It actually assigns the next instance a root bus number behind the
> > current instances bus range. Please note the difference to your code
> > which assigns the next free bus number, which may still lay within the
> > current instances bus range.

Hi Gabriele,

> 
> Mmmm here I have done a mistake: in the current designware the number of hw
> controllers is always 1
> http://lxr.free-electrons.com/source/drivers/pci/host/pcie-designware.c#L510
> So the loop in bios32.c does not work on multiple PCIe ports...

Bios32.c is broken for multiple PCIe hosts for multiple reasons, this is just
one of them. Hence the effort to get rid of it for maintained drivers.

> However your comment about PCI_DOMAINS enlightened my mind and now I see
> that when CONFIG_PCI_DOMAINS is defined we have the domains numbers
> (tracked by __domain_nr).

CONFIG_PCI_DOMAINS in itself doesn't do much without adding code to your driver.
You could request a new domain for each controller with a special property to
disable that behaviour in the dts, or you could enable CONFIG_PCI_DOMAINS_GENERIC
which will give you a new domain automatically.

> So (correct me if I am wrong) if we have 2 PCIe ports that do not specify
> the "bus-range" property, both root ports will enumerate starting from 
> root_bus_nr = 0 and everything will still work ok.

Correct.

Best regards,
Liviu

> 
> So if my assumption is correct, I do not see why the orginal patch from Wang 
> Zhou is wrong. 
> The only point can be that assigning pp->root_bus_nr = 0 is not required 
> as pp memory is kzalloc'ed (an therefore init to zero).
> 
> 
> > 
> > >
> > > In general I agree with you but if you look at all the current
> > drivers
> > > based on designware none of them define the "bus-range" dtb property.
> > > Therefore doing as you say would break the current driver when we
> > have
> > > multiple controllers...am I right?
> > >
> > The current _code_ works fine for multiple controllers. It's just that
> > you must define the bus range property in the DTB if you want to enable
> > multiple instances of one controller and support a kernel without PCI
> > domains support. As all current implementations have only a single
> > instance of the controller per SoC, or depend on PCI domain support,
> > it's totally fine for them to not define the bus ranges property, as
> > it's an optional property and it is well defined how things behave if
> > it
> > is absent. We absolutely need to keep that specified behavior.
> > 
> > > If that is the case in order to fix this in the way you say I would
> > need
> > > to assign "bus-range" for all the PCIe drivers with multiple
> > controllers:
> > > in this case I would split the default range evenly (that is, if we
> > have
> > > two controllers I would define "bus-range"  0-127 and 128-255)
> > >
> > > If you think this solution is ok I can go for it. My only doubt was
> > about
> > > touching other vendors DTBs....
> > >
> > You don't need to touch any of the current DTBs, as they are fine with
> > the default bus range behavior. You need to keep the specified behavior
> > of the bus range property with the new code.
> > 
> > Regards,
> > Lucas
> > >
> > > >
> > > > It is perfectly valid to have a bus range of 0x00-0x10 assigned to
> > one
> > > > instance and 0x50-0xff to the next instance. Additional with PCIe
> > > > hotplug you may not use the full range of the bus numbers on one
> > > > instance at the first scan, but only later populate more buses when
> > > > more
> > > > bridges are added to the tree.
> > > >
> > > > > Drivers that do not specify the bus range in the DTB set pp-
> > > > >root_bus_nr = DW_ROOT_NR_UNDEFINED.
> > > > > Designware will check if the flag is set and will use the
> > automatic
> > > > bus range
> > > > > assignment.
> > > >
> > > > No, please lets get rid of this assignment altogether. The glue
> > drivers
> > > > have no business in assigning the bus range. Please remove the
> > > > pp->root_bus_nr assignment from all the glue drivers.
> > > >
> > > > "bus range" is a generic DW PCIe property, so just parse the root
> > bus
> > > > number from the DT, it is handled the same way for all the DW based
> > > > PCIe
> > > > drivers. The bindings specifies that if the bus range property is
> > > > missing the range is 0x00-0xff, so you can default to 0 as the root
> > bus
> > > > number in that case.
> > > >
> > > > Also I would think this conversion warrants a patch on its own and
> > > > should not be mixed in the ARM64 support patch.
> > > >
> > > > Regards,
> > > > Lucas
> > > >
> > 
> > --
> > Pengutronix e.K.             | Lucas Stach                 |
> > Industrial Linux Solutions   | http://www.pengutronix.de/  |
>
Gabriele Paoloni Aug. 21, 2015, 2:19 p.m. UTC | #9
Hi Liviu

Many Thanks for reviewing

> -----Original Message-----

> From: linux-pci-owner@vger.kernel.org [mailto:linux-pci-

> owner@vger.kernel.org] On Behalf Of Liviu Dudau

> Sent: Friday, August 21, 2015 2:43 PM

> To: Gabriele Paoloni

> Cc: Lucas Stach; Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com;

> Pratyush Anand; Arnd Bergmann; linux@arm.linux.org.uk;

> thomas.petazzoni@free-electrons.com; Lorenzo Pieralisi; James Morse;

> jason@lakedaemon.net; robh@kernel.org; linux-pci@vger.kernel.org;

> linux-arm-kernel@lists.infradead.org; devicetree@vger.kernel.org;

> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; liudongdong (C);

> qiujiang; xuwei (O); Liguozhu (Kenneth)

> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support

> 

> On Thu, Aug 20, 2015 at 12:10:24PM +0100, Gabriele Paoloni wrote:

> > Hi Lucas

> >

> > Again many thanks for explaining and for your time.

> >

> > I got your point now and I have dug a bit better in the PCI_DOMAINS

> code.

> >

> > However I have a question...see inline below

> >

> > > -----Original Message-----

> > > From: Lucas Stach [mailto:l.stach@pengutronix.de]

> > > Sent: Thursday, August 20, 2015 9:27 AM

> > > To: Gabriele Paoloni

> > > Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; Pratyush

> Anand;

> > > Arnd Bergmann; linux@arm.linux.org.uk; thomas.petazzoni@free-

> > > electrons.com; lorenzo.pieralisi@arm.com; james.morse@arm.com;

> > > Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; linux-

> > > pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;

> > > devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;

> > > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)

> > > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support

> > >

> > > Hi Gab,

> > >

> > > Am Mittwoch, den 19.08.2015, 16:34 +0000 schrieb Gabriele Paoloni:

> > > > Hi Lucas

> > > >

> > > > First of all many thanks for the quick reply, really appreciated

> > > >

> > > > > -----Original Message-----

> > > > > From: Lucas Stach [mailto:l.stach@pengutronix.de]

> > > > > Sent: Wednesday, August 19, 2015 4:37 PM

> > > > > To: Gabriele Paoloni

> > > > > Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; Pratyush

> > > Anand;

> > > > > Arnd Bergmann; linux@arm.linux.org.uk; thomas.petazzoni@free-

> > > > > electrons.com; lorenzo.pieralisi@arm.com; james.morse@arm.com;

> > > > > Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org;

> linux-

> > > > > pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;

> > > > > devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;

> > > > > qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu

> (Kenneth)

> > > > > Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support

> > > > >

> > > > > Hi Gab,

> > > > >

> > > > > Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele

> Paoloni:

> > > > > > Hi Lucas

> > > > > >

> > > > > > I have rewritten the patch to take into account multiple

> > > controllers.

> > > > > >

> > > > > > As you can see now there is a static var in

> dw_pcie_host_init()

> > > that

> > > > > tracks

> > > > > > the bus numbers used.

> > > > >

> > > > > This is wrong. The DT specifies the valid bus number range. You

> can

> > > not

> > > > > just assign the next free bus number to the root bus.

> > > >

> > > > I think this is what is being done in

> > > > http://lxr.free-

> electrons.com/source/arch/arm/kernel/bios32.c#L495

> > > > and currently designware assigns the root bus number in

> > > > http://lxr.free-electrons.com/source/drivers/pci/host/pcie-

> > > designware.c#L730

> > > >

> > > You found the right spot. It works a bit different than I remember,

> but

> > > is less broken than your current code. :)

> > >

> > > It actually assigns the next instance a root bus number behind the

> > > current instances bus range. Please note the difference to your

> code

> > > which assigns the next free bus number, which may still lay within

> the

> > > current instances bus range.

> 

> Hi Gabriele,

> 

> >

> > Mmmm here I have done a mistake: in the current designware the number

> of hw

> > controllers is always 1

> > http://lxr.free-electrons.com/source/drivers/pci/host/pcie-

> designware.c#L510

> > So the loop in bios32.c does not work on multiple PCIe ports...

> 

> Bios32.c is broken for multiple PCIe hosts for multiple reasons, this

> is just

> one of them. Hence the effort to get rid of it for maintained drivers.


As you can see we're pushing hard for this :)

> 

> > However your comment about PCI_DOMAINS enlightened my mind and now I

> see

> > that when CONFIG_PCI_DOMAINS is defined we have the domains numbers

> > (tracked by __domain_nr).

> 

> CONFIG_PCI_DOMAINS in itself doesn't do much without adding code to

> your driver.

> You could request a new domain for each controller with a special

> property to

> disable that behaviour in the dts, or you could enable

> CONFIG_PCI_DOMAINS_GENERIC

> which will give you a new domain automatically.


So far I see that for ARM and ARM64 CONFIG_PCI_DOMAINS_GENERIC defaults to 
the same value as CONFIG_PCI_DOMAINS (see arch/arm/Kconfig, arch/arm64/Kconfig). 
So I think this is how current designware based drivers get multiple PCIe 
controller to work (they just enable CONFIG_PCI_DOMAINS)...

 

> 

> > So (correct me if I am wrong) if we have 2 PCIe ports that do not

> specify

> > the "bus-range" property, both root ports will enumerate starting

> from

> > root_bus_nr = 0 and everything will still work ok.

> 

> Correct.

> 

> Best regards,

> Liviu

> 

> >

> > So if my assumption is correct, I do not see why the orginal patch

> from Wang

> > Zhou is wrong.

> > The only point can be that assigning pp->root_bus_nr = 0 is not

> required

> > as pp memory is kzalloc'ed (an therefore init to zero).

> >

> >

> > >

> > > >

> > > > In general I agree with you but if you look at all the current

> > > drivers

> > > > based on designware none of them define the "bus-range" dtb

> property.

> > > > Therefore doing as you say would break the current driver when we

> > > have

> > > > multiple controllers...am I right?

> > > >

> > > The current _code_ works fine for multiple controllers. It's just

> that

> > > you must define the bus range property in the DTB if you want to

> enable

> > > multiple instances of one controller and support a kernel without

> PCI

> > > domains support. As all current implementations have only a single

> > > instance of the controller per SoC, or depend on PCI domain support,

> > > it's totally fine for them to not define the bus ranges property,

> as

> > > it's an optional property and it is well defined how things behave

> if

> > > it

> > > is absent. We absolutely need to keep that specified behavior.

> > >

> > > > If that is the case in order to fix this in the way you say I

> would

> > > need

> > > > to assign "bus-range" for all the PCIe drivers with multiple

> > > controllers:

> > > > in this case I would split the default range evenly (that is, if

> we

> > > have

> > > > two controllers I would define "bus-range"  0-127 and 128-255)

> > > >

> > > > If you think this solution is ok I can go for it. My only doubt

> was

> > > about

> > > > touching other vendors DTBs....

> > > >

> > > You don't need to touch any of the current DTBs, as they are fine

> with

> > > the default bus range behavior. You need to keep the specified

> behavior

> > > of the bus range property with the new code.

> > >

> > > Regards,

> > > Lucas

> > > >

> > > > >

> > > > > It is perfectly valid to have a bus range of 0x00-0x10 assigned

> to

> > > one

> > > > > instance and 0x50-0xff to the next instance. Additional with

> PCIe

> > > > > hotplug you may not use the full range of the bus numbers on

> one

> > > > > instance at the first scan, but only later populate more buses

> when

> > > > > more

> > > > > bridges are added to the tree.

> > > > >

> > > > > > Drivers that do not specify the bus range in the DTB set pp-

> > > > > >root_bus_nr = DW_ROOT_NR_UNDEFINED.

> > > > > > Designware will check if the flag is set and will use the

> > > automatic

> > > > > bus range

> > > > > > assignment.

> > > > >

> > > > > No, please lets get rid of this assignment altogether. The glue

> > > drivers

> > > > > have no business in assigning the bus range. Please remove the

> > > > > pp->root_bus_nr assignment from all the glue drivers.

> > > > >

> > > > > "bus range" is a generic DW PCIe property, so just parse the

> root

> > > bus

> > > > > number from the DT, it is handled the same way for all the DW

> based

> > > > > PCIe

> > > > > drivers. The bindings specifies that if the bus range property

> is

> > > > > missing the range is 0x00-0xff, so you can default to 0 as the

> root

> > > bus

> > > > > number in that case.

> > > > >

> > > > > Also I would think this conversion warrants a patch on its own

> and

> > > > > should not be mixed in the ARM64 support patch.

> > > > >

> > > > > Regards,

> > > > > Lucas

> > > > >

> > >

> > > --

> > > Pengutronix e.K.             | Lucas Stach                 |

> > > Industrial Linux Solutions   | http://www.pengutronix.de/  |

> >

> 

> --

> ====================

> | I would like to |

> | fix the world,  |

> | but they're not |

> | giving me the   |

>  \ source code!  /

>   ---------------

>     ¯\_(?)_/¯

> 

> --

> To unsubscribe from this list: send the line "unsubscribe linux-pci" in

> the body of a message to majordomo@vger.kernel.org

> More majordomo info at  http://vger.kernel.org/majordomo-info.html
Zhou Wang Aug. 24, 2015, 6:26 a.m. UTC | #10
On 2015/8/21 22:19, Gabriele Paoloni wrote:
> Hi Liviu
> 
> Many Thanks for reviewing
> 
>> -----Original Message-----
>> From: linux-pci-owner@vger.kernel.org [mailto:linux-pci-
>> owner@vger.kernel.org] On Behalf Of Liviu Dudau
>> Sent: Friday, August 21, 2015 2:43 PM
>> To: Gabriele Paoloni
>> Cc: Lucas Stach; Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com;
>> Pratyush Anand; Arnd Bergmann; linux@arm.linux.org.uk;
>> thomas.petazzoni@free-electrons.com; Lorenzo Pieralisi; James Morse;
>> jason@lakedaemon.net; robh@kernel.org; linux-pci@vger.kernel.org;
>> linux-arm-kernel@lists.infradead.org; devicetree@vger.kernel.org;
>> Yuanzhichang; Zhudacai; zhangjukuo; qiuzhenfa; liudongdong (C);
>> qiujiang; xuwei (O); Liguozhu (Kenneth)
>> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
>>
>> On Thu, Aug 20, 2015 at 12:10:24PM +0100, Gabriele Paoloni wrote:
>>> Hi Lucas
>>>
>>> Again many thanks for explaining and for your time.
>>>
>>> I got your point now and I have dug a bit better in the PCI_DOMAINS
>> code.
>>>
>>> However I have a question...see inline below
>>>
>>>> -----Original Message-----
>>>> From: Lucas Stach [mailto:l.stach@pengutronix.de]
>>>> Sent: Thursday, August 20, 2015 9:27 AM
>>>> To: Gabriele Paoloni
>>>> Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; Pratyush
>> Anand;
>>>> Arnd Bergmann; linux@arm.linux.org.uk; thomas.petazzoni@free-
>>>> electrons.com; lorenzo.pieralisi@arm.com; james.morse@arm.com;
>>>> Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org; linux-
>>>> pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
>>>> devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
>>>> qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu (Kenneth)
>>>> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
>>>>
>>>> Hi Gab,
>>>>
>>>> Am Mittwoch, den 19.08.2015, 16:34 +0000 schrieb Gabriele Paoloni:
>>>>> Hi Lucas
>>>>>
>>>>> First of all many thanks for the quick reply, really appreciated
>>>>>
>>>>>> -----Original Message-----
>>>>>> From: Lucas Stach [mailto:l.stach@pengutronix.de]
>>>>>> Sent: Wednesday, August 19, 2015 4:37 PM
>>>>>> To: Gabriele Paoloni
>>>>>> Cc: Wangzhou (B); Bjorn Helgaas; jingoohan1@gmail.com; Pratyush
>>>> Anand;
>>>>>> Arnd Bergmann; linux@arm.linux.org.uk; thomas.petazzoni@free-
>>>>>> electrons.com; lorenzo.pieralisi@arm.com; james.morse@arm.com;
>>>>>> Liviu.Dudau@arm.com; jason@lakedaemon.net; robh@kernel.org;
>> linux-
>>>>>> pci@vger.kernel.org; linux-arm-kernel@lists.infradead.org;
>>>>>> devicetree@vger.kernel.org; Yuanzhichang; Zhudacai; zhangjukuo;
>>>>>> qiuzhenfa; liudongdong (C); qiujiang; xuwei (O); Liguozhu
>> (Kenneth)
>>>>>> Subject: Re: [PATCH v7 3/6] PCI: designware: Add ARM64 support
>>>>>>
>>>>>> Hi Gab,
>>>>>>
>>>>>> Am Mittwoch, den 19.08.2015, 15:16 +0000 schrieb Gabriele
>> Paoloni:
>>>>>>> Hi Lucas
>>>>>>>
>>>>>>> I have rewritten the patch to take into account multiple
>>>> controllers.
>>>>>>>
>>>>>>> As you can see now there is a static var in
>> dw_pcie_host_init()
>>>> that
>>>>>> tracks
>>>>>>> the bus numbers used.
>>>>>>
>>>>>> This is wrong. The DT specifies the valid bus number range. You
>> can
>>>> not
>>>>>> just assign the next free bus number to the root bus.
>>>>>
>>>>> I think this is what is being done in
>>>>> http://lxr.free-
>> electrons.com/source/arch/arm/kernel/bios32.c#L495
>>>>> and currently designware assigns the root bus number in
>>>>> http://lxr.free-electrons.com/source/drivers/pci/host/pcie-
>>>> designware.c#L730
>>>>>
>>>> You found the right spot. It works a bit different than I remember,
>> but
>>>> is less broken than your current code. :)
>>>>
>>>> It actually assigns the next instance a root bus number behind the
>>>> current instances bus range. Please note the difference to your
>> code
>>>> which assigns the next free bus number, which may still lay within
>> the
>>>> current instances bus range.
>>
>> Hi Gabriele,
>>
>>>
>>> Mmmm here I have done a mistake: in the current designware the number
>> of hw
>>> controllers is always 1
>>> http://lxr.free-electrons.com/source/drivers/pci/host/pcie-
>> designware.c#L510
>>> So the loop in bios32.c does not work on multiple PCIe ports...
>>
>> Bios32.c is broken for multiple PCIe hosts for multiple reasons, this
>> is just
>> one of them. Hence the effort to get rid of it for maintained drivers.
> 
> As you can see we're pushing hard for this :)
>

How about we pass pp->busn->start to pci_create_root_bus as root bus number?
We get pp->busn->start from resource list(res) whose elements come from
of_pci_get_host_bridge_resources.

If there is a bus-range item in dts, root bus number will get from it.
Oppositely, root bus number will be default value(0x0).

Thanks,
Zhou

>>
>>> However your comment about PCI_DOMAINS enlightened my mind and now I
>> see
>>> that when CONFIG_PCI_DOMAINS is defined we have the domains numbers
>>> (tracked by __domain_nr).
>>
>> CONFIG_PCI_DOMAINS in itself doesn't do much without adding code to
>> your driver.
>> You could request a new domain for each controller with a special
>> property to
>> disable that behaviour in the dts, or you could enable
>> CONFIG_PCI_DOMAINS_GENERIC
>> which will give you a new domain automatically.
> 
> So far I see that for ARM and ARM64 CONFIG_PCI_DOMAINS_GENERIC defaults to 
> the same value as CONFIG_PCI_DOMAINS (see arch/arm/Kconfig, arch/arm64/Kconfig). 
> So I think this is how current designware based drivers get multiple PCIe 
> controller to work (they just enable CONFIG_PCI_DOMAINS)...
> 
>  
> 
>>
>>> So (correct me if I am wrong) if we have 2 PCIe ports that do not
>> specify
>>> the "bus-range" property, both root ports will enumerate starting
>> from
>>> root_bus_nr = 0 and everything will still work ok.
>>
>> Correct.
>>
>> Best regards,
>> Liviu
>>
>>>
>>> So if my assumption is correct, I do not see why the orginal patch
>> from Wang
>>> Zhou is wrong.
>>> The only point can be that assigning pp->root_bus_nr = 0 is not
>> required
>>> as pp memory is kzalloc'ed (an therefore init to zero).
>>>
>>>
>>>>
>>>>>
>>>>> In general I agree with you but if you look at all the current
>>>> drivers
>>>>> based on designware none of them define the "bus-range" dtb
>> property.
>>>>> Therefore doing as you say would break the current driver when we
>>>> have
>>>>> multiple controllers...am I right?
>>>>>
>>>> The current _code_ works fine for multiple controllers. It's just
>> that
>>>> you must define the bus range property in the DTB if you want to
>> enable
>>>> multiple instances of one controller and support a kernel without
>> PCI
>>>> domains support. As all current implementations have only a single
>>>> instance of the controller per SoC, or depend on PCI domain support,
>>>> it's totally fine for them to not define the bus ranges property,
>> as
>>>> it's an optional property and it is well defined how things behave
>> if
>>>> it
>>>> is absent. We absolutely need to keep that specified behavior.
>>>>
>>>>> If that is the case in order to fix this in the way you say I
>> would
>>>> need
>>>>> to assign "bus-range" for all the PCIe drivers with multiple
>>>> controllers:
>>>>> in this case I would split the default range evenly (that is, if
>> we
>>>> have
>>>>> two controllers I would define "bus-range"  0-127 and 128-255)
>>>>>
>>>>> If you think this solution is ok I can go for it. My only doubt
>> was
>>>> about
>>>>> touching other vendors DTBs....
>>>>>
>>>> You don't need to touch any of the current DTBs, as they are fine
>> with
>>>> the default bus range behavior. You need to keep the specified
>> behavior
>>>> of the bus range property with the new code.
>>>>
>>>> Regards,
>>>> Lucas
>>>>>
>>>>>>
>>>>>> It is perfectly valid to have a bus range of 0x00-0x10 assigned
>> to
>>>> one
>>>>>> instance and 0x50-0xff to the next instance. Additional with
>> PCIe
>>>>>> hotplug you may not use the full range of the bus numbers on
>> one
>>>>>> instance at the first scan, but only later populate more buses
>> when
>>>>>> more
>>>>>> bridges are added to the tree.
>>>>>>
>>>>>>> Drivers that do not specify the bus range in the DTB set pp-
>>>>>>> root_bus_nr = DW_ROOT_NR_UNDEFINED.
>>>>>>> Designware will check if the flag is set and will use the
>>>> automatic
>>>>>> bus range
>>>>>>> assignment.
>>>>>>
>>>>>> No, please lets get rid of this assignment altogether. The glue
>>>> drivers
>>>>>> have no business in assigning the bus range. Please remove the
>>>>>> pp->root_bus_nr assignment from all the glue drivers.
>>>>>>
>>>>>> "bus range" is a generic DW PCIe property, so just parse the
>> root
>>>> bus
>>>>>> number from the DT, it is handled the same way for all the DW
>> based
>>>>>> PCIe
>>>>>> drivers. The bindings specifies that if the bus range property
>> is
>>>>>> missing the range is 0x00-0xff, so you can default to 0 as the
>> root
>>>> bus
>>>>>> number in that case.
>>>>>>
>>>>>> Also I would think this conversion warrants a patch on its own
>> and
>>>>>> should not be mixed in the ARM64 support patch.
>>>>>>
>>>>>> Regards,
>>>>>> Lucas
>>>>>>
>>>>
>>>> --
>>>> Pengutronix e.K.             | Lucas Stach                 |
>>>> Industrial Linux Solutions   | http://www.pengutronix.de/  |
>>>
>>
>> --
>> ====================
>> | I would like to |
>> | fix the world,  |
>> | but they're not |
>> | giving me the   |
>>  \ source code!  /
>>   ---------------
>>     ¯\_(?)_/¯
>>
>> --
>> To unsubscribe from this list: send the line "unsubscribe linux-pci" in
>> the body of a message to majordomo@vger.kernel.org
>> More majordomo info at  http://vger.kernel.org/majordomo-info.html


--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
Gabriele Paoloni Aug. 24, 2015, 8:28 a.m. UTC | #11
DQoNCj4gLS0tLS1PcmlnaW5hbCBNZXNzYWdlLS0tLS0NCj4gRnJvbTogV2FuZ3pob3UgKEIpDQo+
IFNlbnQ6IE1vbmRheSwgQXVndXN0IDI0LCAyMDE1IDc6MjYgQU0NCj4gVG86IEdhYnJpZWxlIFBh
b2xvbmkNCj4gQ2M6IExpdml1IER1ZGF1OyBMdWNhcyBTdGFjaDsgQmpvcm4gSGVsZ2Fhczsgamlu
Z29vaGFuMUBnbWFpbC5jb207DQo+IFByYXR5dXNoIEFuYW5kOyBBcm5kIEJlcmdtYW5uOyBsaW51
eEBhcm0ubGludXgub3JnLnVrOw0KPiB0aG9tYXMucGV0YXp6b25pQGZyZWUtZWxlY3Ryb25zLmNv
bTsgTG9yZW56byBQaWVyYWxpc2k7IEphbWVzIE1vcnNlOw0KPiBqYXNvbkBsYWtlZGFlbW9uLm5l
dDsgcm9iaEBrZXJuZWwub3JnOyBsaW51eC1wY2lAdmdlci5rZXJuZWwub3JnOw0KPiBsaW51eC1h
cm0ta2VybmVsQGxpc3RzLmluZnJhZGVhZC5vcmc7IGRldmljZXRyZWVAdmdlci5rZXJuZWwub3Jn
Ow0KPiBZdWFuemhpY2hhbmc7IFpodWRhY2FpOyB6aGFuZ2p1a3VvOyBxaXV6aGVuZmE7IGxpdWRv
bmdkb25nIChDKTsNCj4gcWl1amlhbmc7IHh1d2VpIChPKTsgTGlndW96aHUgKEtlbm5ldGgpDQo+
IFN1YmplY3Q6IFJlOiBbUEFUQ0ggdjcgMy82XSBQQ0k6IGRlc2lnbndhcmU6IEFkZCBBUk02NCBz
dXBwb3J0DQo+IA0KPiBPbiAyMDE1LzgvMjEgMjI6MTksIEdhYnJpZWxlIFBhb2xvbmkgd3JvdGU6
DQo+ID4gSGkgTGl2aXUNCj4gPg0KPiA+IE1hbnkgVGhhbmtzIGZvciByZXZpZXdpbmcNCj4gPg0K
PiA+PiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiA+PiBGcm9tOiBsaW51eC1wY2ktb3du
ZXJAdmdlci5rZXJuZWwub3JnIFttYWlsdG86bGludXgtcGNpLQ0KPiA+PiBvd25lckB2Z2VyLmtl
cm5lbC5vcmddIE9uIEJlaGFsZiBPZiBMaXZpdSBEdWRhdQ0KPiA+PiBTZW50OiBGcmlkYXksIEF1
Z3VzdCAyMSwgMjAxNSAyOjQzIFBNDQo+ID4+IFRvOiBHYWJyaWVsZSBQYW9sb25pDQo+ID4+IENj
OiBMdWNhcyBTdGFjaDsgV2FuZ3pob3UgKEIpOyBCam9ybiBIZWxnYWFzOyBqaW5nb29oYW4xQGdt
YWlsLmNvbTsNCj4gPj4gUHJhdHl1c2ggQW5hbmQ7IEFybmQgQmVyZ21hbm47IGxpbnV4QGFybS5s
aW51eC5vcmcudWs7DQo+ID4+IHRob21hcy5wZXRhenpvbmlAZnJlZS1lbGVjdHJvbnMuY29tOyBM
b3JlbnpvIFBpZXJhbGlzaTsgSmFtZXMgTW9yc2U7DQo+ID4+IGphc29uQGxha2VkYWVtb24ubmV0
OyByb2JoQGtlcm5lbC5vcmc7IGxpbnV4LXBjaUB2Z2VyLmtlcm5lbC5vcmc7DQo+ID4+IGxpbnV4
LWFybS1rZXJuZWxAbGlzdHMuaW5mcmFkZWFkLm9yZzsgZGV2aWNldHJlZUB2Z2VyLmtlcm5lbC5v
cmc7DQo+ID4+IFl1YW56aGljaGFuZzsgWmh1ZGFjYWk7IHpoYW5nanVrdW87IHFpdXpoZW5mYTsg
bGl1ZG9uZ2RvbmcgKEMpOw0KPiA+PiBxaXVqaWFuZzsgeHV3ZWkgKE8pOyBMaWd1b3podSAoS2Vu
bmV0aCkNCj4gPj4gU3ViamVjdDogUmU6IFtQQVRDSCB2NyAzLzZdIFBDSTogZGVzaWdud2FyZTog
QWRkIEFSTTY0IHN1cHBvcnQNCj4gPj4NCj4gPj4gT24gVGh1LCBBdWcgMjAsIDIwMTUgYXQgMTI6
MTA6MjRQTSArMDEwMCwgR2FicmllbGUgUGFvbG9uaSB3cm90ZToNCj4gPj4+IEhpIEx1Y2FzDQo+
ID4+Pg0KPiA+Pj4gQWdhaW4gbWFueSB0aGFua3MgZm9yIGV4cGxhaW5pbmcgYW5kIGZvciB5b3Vy
IHRpbWUuDQo+ID4+Pg0KPiA+Pj4gSSBnb3QgeW91ciBwb2ludCBub3cgYW5kIEkgaGF2ZSBkdWcg
YSBiaXQgYmV0dGVyIGluIHRoZSBQQ0lfRE9NQUlOUw0KPiA+PiBjb2RlLg0KPiA+Pj4NCj4gPj4+
IEhvd2V2ZXIgSSBoYXZlIGEgcXVlc3Rpb24uLi5zZWUgaW5saW5lIGJlbG93DQo+ID4+Pg0KPiA+
Pj4+IC0tLS0tT3JpZ2luYWwgTWVzc2FnZS0tLS0tDQo+ID4+Pj4gRnJvbTogTHVjYXMgU3RhY2gg
W21haWx0bzpsLnN0YWNoQHBlbmd1dHJvbml4LmRlXQ0KPiA+Pj4+IFNlbnQ6IFRodXJzZGF5LCBB
dWd1c3QgMjAsIDIwMTUgOToyNyBBTQ0KPiA+Pj4+IFRvOiBHYWJyaWVsZSBQYW9sb25pDQo+ID4+
Pj4gQ2M6IFdhbmd6aG91IChCKTsgQmpvcm4gSGVsZ2FhczsgamluZ29vaGFuMUBnbWFpbC5jb207
IFByYXR5dXNoDQo+ID4+IEFuYW5kOw0KPiA+Pj4+IEFybmQgQmVyZ21hbm47IGxpbnV4QGFybS5s
aW51eC5vcmcudWs7IHRob21hcy5wZXRhenpvbmlAZnJlZS0NCj4gPj4+PiBlbGVjdHJvbnMuY29t
OyBsb3JlbnpvLnBpZXJhbGlzaUBhcm0uY29tOyBqYW1lcy5tb3JzZUBhcm0uY29tOw0KPiA+Pj4+
IExpdml1LkR1ZGF1QGFybS5jb207IGphc29uQGxha2VkYWVtb24ubmV0OyByb2JoQGtlcm5lbC5v
cmc7IGxpbnV4LQ0KPiA+Pj4+IHBjaUB2Z2VyLmtlcm5lbC5vcmc7IGxpbnV4LWFybS1rZXJuZWxA
bGlzdHMuaW5mcmFkZWFkLm9yZzsNCj4gPj4+PiBkZXZpY2V0cmVlQHZnZXIua2VybmVsLm9yZzsg
WXVhbnpoaWNoYW5nOyBaaHVkYWNhaTsgemhhbmdqdWt1bzsNCj4gPj4+PiBxaXV6aGVuZmE7IGxp
dWRvbmdkb25nIChDKTsgcWl1amlhbmc7IHh1d2VpIChPKTsgTGlndW96aHUgKEtlbm5ldGgpDQo+
ID4+Pj4gU3ViamVjdDogUmU6IFtQQVRDSCB2NyAzLzZdIFBDSTogZGVzaWdud2FyZTogQWRkIEFS
TTY0IHN1cHBvcnQNCj4gPj4+Pg0KPiA+Pj4+IEhpIEdhYiwNCj4gPj4+Pg0KPiA+Pj4+IEFtIE1p
dHR3b2NoLCBkZW4gMTkuMDguMjAxNSwgMTY6MzQgKzAwMDAgc2NocmllYiBHYWJyaWVsZSBQYW9s
b25pOg0KPiA+Pj4+PiBIaSBMdWNhcw0KPiA+Pj4+Pg0KPiA+Pj4+PiBGaXJzdCBvZiBhbGwgbWFu
eSB0aGFua3MgZm9yIHRoZSBxdWljayByZXBseSwgcmVhbGx5IGFwcHJlY2lhdGVkDQo+ID4+Pj4+
DQo+ID4+Pj4+PiAtLS0tLU9yaWdpbmFsIE1lc3NhZ2UtLS0tLQ0KPiA+Pj4+Pj4gRnJvbTogTHVj
YXMgU3RhY2ggW21haWx0bzpsLnN0YWNoQHBlbmd1dHJvbml4LmRlXQ0KPiA+Pj4+Pj4gU2VudDog
V2VkbmVzZGF5LCBBdWd1c3QgMTksIDIwMTUgNDozNyBQTQ0KPiA+Pj4+Pj4gVG86IEdhYnJpZWxl
IFBhb2xvbmkNCj4gPj4+Pj4+IENjOiBXYW5nemhvdSAoQik7IEJqb3JuIEhlbGdhYXM7IGppbmdv
b2hhbjFAZ21haWwuY29tOyBQcmF0eXVzaA0KPiA+Pj4+IEFuYW5kOw0KPiA+Pj4+Pj4gQXJuZCBC
ZXJnbWFubjsgbGludXhAYXJtLmxpbnV4Lm9yZy51azsgdGhvbWFzLnBldGF6em9uaUBmcmVlLQ0K
PiA+Pj4+Pj4gZWxlY3Ryb25zLmNvbTsgbG9yZW56by5waWVyYWxpc2lAYXJtLmNvbTsgamFtZXMu
bW9yc2VAYXJtLmNvbTsNCj4gPj4+Pj4+IExpdml1LkR1ZGF1QGFybS5jb207IGphc29uQGxha2Vk
YWVtb24ubmV0OyByb2JoQGtlcm5lbC5vcmc7DQo+ID4+IGxpbnV4LQ0KPiA+Pj4+Pj4gcGNpQHZn
ZXIua2VybmVsLm9yZzsgbGludXgtYXJtLWtlcm5lbEBsaXN0cy5pbmZyYWRlYWQub3JnOw0KPiA+
Pj4+Pj4gZGV2aWNldHJlZUB2Z2VyLmtlcm5lbC5vcmc7IFl1YW56aGljaGFuZzsgWmh1ZGFjYWk7
IHpoYW5nanVrdW87DQo+ID4+Pj4+PiBxaXV6aGVuZmE7IGxpdWRvbmdkb25nIChDKTsgcWl1amlh
bmc7IHh1d2VpIChPKTsgTGlndW96aHUNCj4gPj4gKEtlbm5ldGgpDQo+ID4+Pj4+PiBTdWJqZWN0
OiBSZTogW1BBVENIIHY3IDMvNl0gUENJOiBkZXNpZ253YXJlOiBBZGQgQVJNNjQgc3VwcG9ydA0K
PiA+Pj4+Pj4NCj4gPj4+Pj4+IEhpIEdhYiwNCj4gPj4+Pj4+DQo+ID4+Pj4+PiBBbSBNaXR0d29j
aCwgZGVuIDE5LjA4LjIwMTUsIDE1OjE2ICswMDAwIHNjaHJpZWIgR2FicmllbGUNCj4gPj4gUGFv
bG9uaToNCj4gPj4+Pj4+PiBIaSBMdWNhcw0KPiA+Pj4+Pj4+DQo+ID4+Pj4+Pj4gSSBoYXZlIHJl
d3JpdHRlbiB0aGUgcGF0Y2ggdG8gdGFrZSBpbnRvIGFjY291bnQgbXVsdGlwbGUNCj4gPj4+PiBj
b250cm9sbGVycy4NCj4gPj4+Pj4+Pg0KPiA+Pj4+Pj4+IEFzIHlvdSBjYW4gc2VlIG5vdyB0aGVy
ZSBpcyBhIHN0YXRpYyB2YXIgaW4NCj4gPj4gZHdfcGNpZV9ob3N0X2luaXQoKQ0KPiA+Pj4+IHRo
YXQNCj4gPj4+Pj4+IHRyYWNrcw0KPiA+Pj4+Pj4+IHRoZSBidXMgbnVtYmVycyB1c2VkLg0KPiA+
Pj4+Pj4NCj4gPj4+Pj4+IFRoaXMgaXMgd3JvbmcuIFRoZSBEVCBzcGVjaWZpZXMgdGhlIHZhbGlk
IGJ1cyBudW1iZXIgcmFuZ2UuIFlvdQ0KPiA+PiBjYW4NCj4gPj4+PiBub3QNCj4gPj4+Pj4+IGp1
c3QgYXNzaWduIHRoZSBuZXh0IGZyZWUgYnVzIG51bWJlciB0byB0aGUgcm9vdCBidXMuDQo+ID4+
Pj4+DQo+ID4+Pj4+IEkgdGhpbmsgdGhpcyBpcyB3aGF0IGlzIGJlaW5nIGRvbmUgaW4NCj4gPj4+
Pj4gaHR0cDovL2x4ci5mcmVlLQ0KPiA+PiBlbGVjdHJvbnMuY29tL3NvdXJjZS9hcmNoL2FybS9r
ZXJuZWwvYmlvczMyLmMjTDQ5NQ0KPiA+Pj4+PiBhbmQgY3VycmVudGx5IGRlc2lnbndhcmUgYXNz
aWducyB0aGUgcm9vdCBidXMgbnVtYmVyIGluDQo+ID4+Pj4+IGh0dHA6Ly9seHIuZnJlZS1lbGVj
dHJvbnMuY29tL3NvdXJjZS9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtDQo+ID4+Pj4gZGVzaWdud2Fy
ZS5jI0w3MzANCj4gPj4+Pj4NCj4gPj4+PiBZb3UgZm91bmQgdGhlIHJpZ2h0IHNwb3QuIEl0IHdv
cmtzIGEgYml0IGRpZmZlcmVudCB0aGFuIEkgcmVtZW1iZXIsDQo+ID4+IGJ1dA0KPiA+Pj4+IGlz
IGxlc3MgYnJva2VuIHRoYW4geW91ciBjdXJyZW50IGNvZGUuIDopDQo+ID4+Pj4NCj4gPj4+PiBJ
dCBhY3R1YWxseSBhc3NpZ25zIHRoZSBuZXh0IGluc3RhbmNlIGEgcm9vdCBidXMgbnVtYmVyIGJl
aGluZCB0aGUNCj4gPj4+PiBjdXJyZW50IGluc3RhbmNlcyBidXMgcmFuZ2UuIFBsZWFzZSBub3Rl
IHRoZSBkaWZmZXJlbmNlIHRvIHlvdXINCj4gPj4gY29kZQ0KPiA+Pj4+IHdoaWNoIGFzc2lnbnMg
dGhlIG5leHQgZnJlZSBidXMgbnVtYmVyLCB3aGljaCBtYXkgc3RpbGwgbGF5IHdpdGhpbg0KPiA+
PiB0aGUNCj4gPj4+PiBjdXJyZW50IGluc3RhbmNlcyBidXMgcmFuZ2UuDQo+ID4+DQo+ID4+IEhp
IEdhYnJpZWxlLA0KPiA+Pg0KPiA+Pj4NCj4gPj4+IE1tbW0gaGVyZSBJIGhhdmUgZG9uZSBhIG1p
c3Rha2U6IGluIHRoZSBjdXJyZW50IGRlc2lnbndhcmUgdGhlDQo+IG51bWJlcg0KPiA+PiBvZiBo
dw0KPiA+Pj4gY29udHJvbGxlcnMgaXMgYWx3YXlzIDENCj4gPj4+IGh0dHA6Ly9seHIuZnJlZS1l
bGVjdHJvbnMuY29tL3NvdXJjZS9kcml2ZXJzL3BjaS9ob3N0L3BjaWUtDQo+ID4+IGRlc2lnbndh
cmUuYyNMNTEwDQo+ID4+PiBTbyB0aGUgbG9vcCBpbiBiaW9zMzIuYyBkb2VzIG5vdCB3b3JrIG9u
IG11bHRpcGxlIFBDSWUgcG9ydHMuLi4NCj4gPj4NCj4gPj4gQmlvczMyLmMgaXMgYnJva2VuIGZv
ciBtdWx0aXBsZSBQQ0llIGhvc3RzIGZvciBtdWx0aXBsZSByZWFzb25zLA0KPiB0aGlzDQo+ID4+
IGlzIGp1c3QNCj4gPj4gb25lIG9mIHRoZW0uIEhlbmNlIHRoZSBlZmZvcnQgdG8gZ2V0IHJpZCBv
ZiBpdCBmb3IgbWFpbnRhaW5lZA0KPiBkcml2ZXJzLg0KPiA+DQo+ID4gQXMgeW91IGNhbiBzZWUg
d2UncmUgcHVzaGluZyBoYXJkIGZvciB0aGlzIDopDQo+ID4NCj4gDQo+IEhvdyBhYm91dCB3ZSBw
YXNzIHBwLT5idXNuLT5zdGFydCB0byBwY2lfY3JlYXRlX3Jvb3RfYnVzIGFzIHJvb3QgYnVzDQo+
IG51bWJlcj8NCj4gV2UgZ2V0IHBwLT5idXNuLT5zdGFydCBmcm9tIHJlc291cmNlIGxpc3QocmVz
KSB3aG9zZSBlbGVtZW50cyBjb21lIGZyb20NCj4gb2ZfcGNpX2dldF9ob3N0X2JyaWRnZV9yZXNv
dXJjZXMuDQo+IA0KPiBJZiB0aGVyZSBpcyBhIGJ1cy1yYW5nZSBpdGVtIGluIGR0cywgcm9vdCBi
dXMgbnVtYmVyIHdpbGwgZ2V0IGZyb20gaXQuDQo+IE9wcG9zaXRlbHksIHJvb3QgYnVzIG51bWJl
ciB3aWxsIGJlIGRlZmF1bHQgdmFsdWUoMHgwKS4NCj4gDQo+IFRoYW5rcywNCj4gWmhvdQ0KDQpT
b3VuZHMgZ29vZCB0byBtZS4gU28gd2UgY2FuIHJlbW92ZSByb290X2J1c19ucg0KDQo+IA0KPiA+
Pg0KPiA+Pj4gSG93ZXZlciB5b3VyIGNvbW1lbnQgYWJvdXQgUENJX0RPTUFJTlMgZW5saWdodGVu
ZWQgbXkgbWluZCBhbmQgbm93DQo+IEkNCj4gPj4gc2VlDQo+ID4+PiB0aGF0IHdoZW4gQ09ORklH
X1BDSV9ET01BSU5TIGlzIGRlZmluZWQgd2UgaGF2ZSB0aGUgZG9tYWlucyBudW1iZXJzDQo+ID4+
PiAodHJhY2tlZCBieSBfX2RvbWFpbl9ucikuDQo+ID4+DQo+ID4+IENPTkZJR19QQ0lfRE9NQUlO
UyBpbiBpdHNlbGYgZG9lc24ndCBkbyBtdWNoIHdpdGhvdXQgYWRkaW5nIGNvZGUgdG8NCj4gPj4g
eW91ciBkcml2ZXIuDQo+ID4+IFlvdSBjb3VsZCByZXF1ZXN0IGEgbmV3IGRvbWFpbiBmb3IgZWFj
aCBjb250cm9sbGVyIHdpdGggYSBzcGVjaWFsDQo+ID4+IHByb3BlcnR5IHRvDQo+ID4+IGRpc2Fi
bGUgdGhhdCBiZWhhdmlvdXIgaW4gdGhlIGR0cywgb3IgeW91IGNvdWxkIGVuYWJsZQ0KPiA+PiBD
T05GSUdfUENJX0RPTUFJTlNfR0VORVJJQw0KPiA+PiB3aGljaCB3aWxsIGdpdmUgeW91IGEgbmV3
IGRvbWFpbiBhdXRvbWF0aWNhbGx5Lg0KPiA+DQo+ID4gU28gZmFyIEkgc2VlIHRoYXQgZm9yIEFS
TSBhbmQgQVJNNjQgQ09ORklHX1BDSV9ET01BSU5TX0dFTkVSSUMNCj4gZGVmYXVsdHMgdG8NCj4g
PiB0aGUgc2FtZSB2YWx1ZSBhcyBDT05GSUdfUENJX0RPTUFJTlMgKHNlZSBhcmNoL2FybS9LY29u
ZmlnLA0KPiBhcmNoL2FybTY0L0tjb25maWcpLg0KPiA+IFNvIEkgdGhpbmsgdGhpcyBpcyBob3cg
Y3VycmVudCBkZXNpZ253YXJlIGJhc2VkIGRyaXZlcnMgZ2V0IG11bHRpcGxlDQo+IFBDSWUNCj4g
PiBjb250cm9sbGVyIHRvIHdvcmsgKHRoZXkganVzdCBlbmFibGUgQ09ORklHX1BDSV9ET01BSU5T
KS4uLg0KPiA+DQo+ID4NCj4gPg0KPiA+Pg0KPiA+Pj4gU28gKGNvcnJlY3QgbWUgaWYgSSBhbSB3
cm9uZykgaWYgd2UgaGF2ZSAyIFBDSWUgcG9ydHMgdGhhdCBkbyBub3QNCj4gPj4gc3BlY2lmeQ0K
PiA+Pj4gdGhlICJidXMtcmFuZ2UiIHByb3BlcnR5LCBib3RoIHJvb3QgcG9ydHMgd2lsbCBlbnVt
ZXJhdGUgc3RhcnRpbmcNCj4gPj4gZnJvbQ0KPiA+Pj4gcm9vdF9idXNfbnIgPSAwIGFuZCBldmVy
eXRoaW5nIHdpbGwgc3RpbGwgd29yayBvay4NCj4gPj4NCj4gPj4gQ29ycmVjdC4NCj4gPj4NCj4g
Pj4gQmVzdCByZWdhcmRzLA0KPiA+PiBMaXZpdQ0KPiA+Pg0KPiA+Pj4NCj4gPj4+IFNvIGlmIG15
IGFzc3VtcHRpb24gaXMgY29ycmVjdCwgSSBkbyBub3Qgc2VlIHdoeSB0aGUgb3JnaW5hbCBwYXRj
aA0KPiA+PiBmcm9tIFdhbmcNCj4gPj4+IFpob3UgaXMgd3JvbmcuDQo+ID4+PiBUaGUgb25seSBw
b2ludCBjYW4gYmUgdGhhdCBhc3NpZ25pbmcgcHAtPnJvb3RfYnVzX25yID0gMCBpcyBub3QNCj4g
Pj4gcmVxdWlyZWQNCj4gPj4+IGFzIHBwIG1lbW9yeSBpcyBremFsbG9jJ2VkIChhbiB0aGVyZWZv
cmUgaW5pdCB0byB6ZXJvKS4NCj4gPj4+DQo+ID4+Pg0KPiA+Pj4+DQo+ID4+Pj4+DQo+ID4+Pj4+
IEluIGdlbmVyYWwgSSBhZ3JlZSB3aXRoIHlvdSBidXQgaWYgeW91IGxvb2sgYXQgYWxsIHRoZSBj
dXJyZW50DQo+ID4+Pj4gZHJpdmVycw0KPiA+Pj4+PiBiYXNlZCBvbiBkZXNpZ253YXJlIG5vbmUg
b2YgdGhlbSBkZWZpbmUgdGhlICJidXMtcmFuZ2UiIGR0Yg0KPiA+PiBwcm9wZXJ0eS4NCj4gPj4+
Pj4gVGhlcmVmb3JlIGRvaW5nIGFzIHlvdSBzYXkgd291bGQgYnJlYWsgdGhlIGN1cnJlbnQgZHJp
dmVyIHdoZW4gd2UNCj4gPj4+PiBoYXZlDQo+ID4+Pj4+IG11bHRpcGxlIGNvbnRyb2xsZXJzLi4u
YW0gSSByaWdodD8NCj4gPj4+Pj4NCj4gPj4+PiBUaGUgY3VycmVudCBfY29kZV8gd29ya3MgZmlu
ZSBmb3IgbXVsdGlwbGUgY29udHJvbGxlcnMuIEl0J3MganVzdA0KPiA+PiB0aGF0DQo+ID4+Pj4g
eW91IG11c3QgZGVmaW5lIHRoZSBidXMgcmFuZ2UgcHJvcGVydHkgaW4gdGhlIERUQiBpZiB5b3Ug
d2FudCB0bw0KPiA+PiBlbmFibGUNCj4gPj4+PiBtdWx0aXBsZSBpbnN0YW5jZXMgb2Ygb25lIGNv
bnRyb2xsZXIgYW5kIHN1cHBvcnQgYSBrZXJuZWwgd2l0aG91dA0KPiA+PiBQQ0kNCj4gPj4+PiBk
b21haW5zIHN1cHBvcnQuIEFzIGFsbCBjdXJyZW50IGltcGxlbWVudGF0aW9ucyBoYXZlIG9ubHkg
YSBzaW5nbGUNCj4gPj4+PiBpbnN0YW5jZSBvZiB0aGUgY29udHJvbGxlciBwZXIgU29DLCBvciBk
ZXBlbmQgb24gUENJIGRvbWFpbg0KPiBzdXBwb3J0LA0KPiA+Pj4+IGl0J3MgdG90YWxseSBmaW5l
IGZvciB0aGVtIHRvIG5vdCBkZWZpbmUgdGhlIGJ1cyByYW5nZXMgcHJvcGVydHksDQo+ID4+IGFz
DQo+ID4+Pj4gaXQncyBhbiBvcHRpb25hbCBwcm9wZXJ0eSBhbmQgaXQgaXMgd2VsbCBkZWZpbmVk
IGhvdyB0aGluZ3MgYmVoYXZlDQo+ID4+IGlmDQo+ID4+Pj4gaXQNCj4gPj4+PiBpcyBhYnNlbnQu
IFdlIGFic29sdXRlbHkgbmVlZCB0byBrZWVwIHRoYXQgc3BlY2lmaWVkIGJlaGF2aW9yLg0KPiA+
Pj4+DQo+ID4+Pj4+IElmIHRoYXQgaXMgdGhlIGNhc2UgaW4gb3JkZXIgdG8gZml4IHRoaXMgaW4g
dGhlIHdheSB5b3Ugc2F5IEkNCj4gPj4gd291bGQNCj4gPj4+PiBuZWVkDQo+ID4+Pj4+IHRvIGFz
c2lnbiAiYnVzLXJhbmdlIiBmb3IgYWxsIHRoZSBQQ0llIGRyaXZlcnMgd2l0aCBtdWx0aXBsZQ0K
PiA+Pj4+IGNvbnRyb2xsZXJzOg0KPiA+Pj4+PiBpbiB0aGlzIGNhc2UgSSB3b3VsZCBzcGxpdCB0
aGUgZGVmYXVsdCByYW5nZSBldmVubHkgKHRoYXQgaXMsIGlmDQo+ID4+IHdlDQo+ID4+Pj4gaGF2
ZQ0KPiA+Pj4+PiB0d28gY29udHJvbGxlcnMgSSB3b3VsZCBkZWZpbmUgImJ1cy1yYW5nZSIgIDAt
MTI3IGFuZCAxMjgtMjU1KQ0KPiA+Pj4+Pg0KPiA+Pj4+PiBJZiB5b3UgdGhpbmsgdGhpcyBzb2x1
dGlvbiBpcyBvayBJIGNhbiBnbyBmb3IgaXQuIE15IG9ubHkgZG91YnQNCj4gPj4gd2FzDQo+ID4+
Pj4gYWJvdXQNCj4gPj4+Pj4gdG91Y2hpbmcgb3RoZXIgdmVuZG9ycyBEVEJzLi4uLg0KPiA+Pj4+
Pg0KPiA+Pj4+IFlvdSBkb24ndCBuZWVkIHRvIHRvdWNoIGFueSBvZiB0aGUgY3VycmVudCBEVEJz
LCBhcyB0aGV5IGFyZSBmaW5lDQo+ID4+IHdpdGgNCj4gPj4+PiB0aGUgZGVmYXVsdCBidXMgcmFu
Z2UgYmVoYXZpb3IuIFlvdSBuZWVkIHRvIGtlZXAgdGhlIHNwZWNpZmllZA0KPiA+PiBiZWhhdmlv
cg0KPiA+Pj4+IG9mIHRoZSBidXMgcmFuZ2UgcHJvcGVydHkgd2l0aCB0aGUgbmV3IGNvZGUuDQo+
ID4+Pj4NCj4gPj4+PiBSZWdhcmRzLA0KPiA+Pj4+IEx1Y2FzDQo+ID4+Pj4+DQo+ID4+Pj4+Pg0K
PiA+Pj4+Pj4gSXQgaXMgcGVyZmVjdGx5IHZhbGlkIHRvIGhhdmUgYSBidXMgcmFuZ2Ugb2YgMHgw
MC0weDEwIGFzc2lnbmVkDQo+ID4+IHRvDQo+ID4+Pj4gb25lDQo+ID4+Pj4+PiBpbnN0YW5jZSBh
bmQgMHg1MC0weGZmIHRvIHRoZSBuZXh0IGluc3RhbmNlLiBBZGRpdGlvbmFsIHdpdGgNCj4gPj4g
UENJZQ0KPiA+Pj4+Pj4gaG90cGx1ZyB5b3UgbWF5IG5vdCB1c2UgdGhlIGZ1bGwgcmFuZ2Ugb2Yg
dGhlIGJ1cyBudW1iZXJzIG9uDQo+ID4+IG9uZQ0KPiA+Pj4+Pj4gaW5zdGFuY2UgYXQgdGhlIGZp
cnN0IHNjYW4sIGJ1dCBvbmx5IGxhdGVyIHBvcHVsYXRlIG1vcmUgYnVzZXMNCj4gPj4gd2hlbg0K
PiA+Pj4+Pj4gbW9yZQ0KPiA+Pj4+Pj4gYnJpZGdlcyBhcmUgYWRkZWQgdG8gdGhlIHRyZWUuDQo+
ID4+Pj4+Pg0KPiA+Pj4+Pj4+IERyaXZlcnMgdGhhdCBkbyBub3Qgc3BlY2lmeSB0aGUgYnVzIHJh
bmdlIGluIHRoZSBEVEIgc2V0IHBwLQ0KPiA+Pj4+Pj4+IHJvb3RfYnVzX25yID0gRFdfUk9PVF9O
Ul9VTkRFRklORUQuDQo+ID4+Pj4+Pj4gRGVzaWdud2FyZSB3aWxsIGNoZWNrIGlmIHRoZSBmbGFn
IGlzIHNldCBhbmQgd2lsbCB1c2UgdGhlDQo+ID4+Pj4gYXV0b21hdGljDQo+ID4+Pj4+PiBidXMg
cmFuZ2UNCj4gPj4+Pj4+PiBhc3NpZ25tZW50Lg0KPiA+Pj4+Pj4NCj4gPj4+Pj4+IE5vLCBwbGVh
c2UgbGV0cyBnZXQgcmlkIG9mIHRoaXMgYXNzaWdubWVudCBhbHRvZ2V0aGVyLiBUaGUgZ2x1ZQ0K
PiA+Pj4+IGRyaXZlcnMNCj4gPj4+Pj4+IGhhdmUgbm8gYnVzaW5lc3MgaW4gYXNzaWduaW5nIHRo
ZSBidXMgcmFuZ2UuIFBsZWFzZSByZW1vdmUgdGhlDQo+ID4+Pj4+PiBwcC0+cm9vdF9idXNfbnIg
YXNzaWdubWVudCBmcm9tIGFsbCB0aGUgZ2x1ZSBkcml2ZXJzLg0KPiA+Pj4+Pj4NCj4gPj4+Pj4+
ICJidXMgcmFuZ2UiIGlzIGEgZ2VuZXJpYyBEVyBQQ0llIHByb3BlcnR5LCBzbyBqdXN0IHBhcnNl
IHRoZQ0KPiA+PiByb290DQo+ID4+Pj4gYnVzDQo+ID4+Pj4+PiBudW1iZXIgZnJvbSB0aGUgRFQs
IGl0IGlzIGhhbmRsZWQgdGhlIHNhbWUgd2F5IGZvciBhbGwgdGhlIERXDQo+ID4+IGJhc2VkDQo+
ID4+Pj4+PiBQQ0llDQo+ID4+Pj4+PiBkcml2ZXJzLiBUaGUgYmluZGluZ3Mgc3BlY2lmaWVzIHRo
YXQgaWYgdGhlIGJ1cyByYW5nZSBwcm9wZXJ0eQ0KPiA+PiBpcw0KPiA+Pj4+Pj4gbWlzc2luZyB0
aGUgcmFuZ2UgaXMgMHgwMC0weGZmLCBzbyB5b3UgY2FuIGRlZmF1bHQgdG8gMCBhcyB0aGUNCj4g
Pj4gcm9vdA0KPiA+Pj4+IGJ1cw0KPiA+Pj4+Pj4gbnVtYmVyIGluIHRoYXQgY2FzZS4NCj4gPj4+
Pj4+DQo+ID4+Pj4+PiBBbHNvIEkgd291bGQgdGhpbmsgdGhpcyBjb252ZXJzaW9uIHdhcnJhbnRz
IGEgcGF0Y2ggb24gaXRzIG93bg0KPiA+PiBhbmQNCj4gPj4+Pj4+IHNob3VsZCBub3QgYmUgbWl4
ZWQgaW4gdGhlIEFSTTY0IHN1cHBvcnQgcGF0Y2guDQo+ID4+Pj4+Pg0KPiA+Pj4+Pj4gUmVnYXJk
cywNCj4gPj4+Pj4+IEx1Y2FzDQo+ID4+Pj4+Pg0KPiA+Pj4+DQo+ID4+Pj4gLS0NCj4gPj4+PiBQ
ZW5ndXRyb25peCBlLksuICAgICAgICAgICAgIHwgTHVjYXMgU3RhY2ggICAgICAgICAgICAgICAg
IHwNCj4gPj4+PiBJbmR1c3RyaWFsIExpbnV4IFNvbHV0aW9ucyAgIHwgaHR0cDovL3d3dy5wZW5n
dXRyb25peC5kZS8gIHwNCj4gPj4+DQo+ID4+DQo+ID4+IC0tDQo+ID4+ID09PT09PT09PT09PT09
PT09PT09DQo+ID4+IHwgSSB3b3VsZCBsaWtlIHRvIHwNCj4gPj4gfCBmaXggdGhlIHdvcmxkLCAg
fA0KPiA+PiB8IGJ1dCB0aGV5J3JlIG5vdCB8DQo+ID4+IHwgZ2l2aW5nIG1lIHRoZSAgIHwNCj4g
Pj4gIFwgc291cmNlIGNvZGUhICAvDQo+ID4+ICAgLS0tLS0tLS0tLS0tLS0tDQo+ID4+ICAgICDC
r1xfKOODhClfL8KvDQo+ID4+DQo+ID4+IC0tDQo+ID4+IFRvIHVuc3Vic2NyaWJlIGZyb20gdGhp
cyBsaXN0OiBzZW5kIHRoZSBsaW5lICJ1bnN1YnNjcmliZSBsaW51eC1wY2kiDQo+IGluDQo+ID4+
IHRoZSBib2R5IG9mIGEgbWVzc2FnZSB0byBtYWpvcmRvbW9Admdlci5rZXJuZWwub3JnDQo+ID4+
IE1vcmUgbWFqb3Jkb21vIGluZm8gYXQgIGh0dHA6Ly92Z2VyLmtlcm5lbC5vcmcvbWFqb3Jkb21v
LWluZm8uaHRtbA0KPiANCg0K
--
To unsubscribe from this list: send the line "unsubscribe linux-pci" in
the body of a message to majordomo@vger.kernel.org
More majordomo info at  http://vger.kernel.org/majordomo-info.html
diff mbox

Patch

diff --git a/drivers/pci/host/pci-dra7xx.c b/drivers/pci/host/pci-dra7xx.c
index 18ae7ff..1268c69 100644
--- a/drivers/pci/host/pci-dra7xx.c
+++ b/drivers/pci/host/pci-dra7xx.c
@@ -141,15 +141,15 @@  static void dra7xx_pcie_host_init(struct pcie_port *pp)
 {
 	dw_pcie_setup_rc(pp);
 
-	if (pp->io_mod_base)
-		pp->io_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->io_base)
+		pp->io_base &= CPU_TO_BUS_ADDR;
 
-	if (pp->mem_mod_base)
-		pp->mem_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->mem_base)
+		pp->mem_base &= CPU_TO_BUS_ADDR;
 
-	if (pp->cfg0_mod_base) {
-		pp->cfg0_mod_base &= CPU_TO_BUS_ADDR;
-		pp->cfg1_mod_base &= CPU_TO_BUS_ADDR;
+	if (pp->cfg0_base) {
+		pp->cfg0_base &= CPU_TO_BUS_ADDR;
+		pp->cfg1_base &= CPU_TO_BUS_ADDR;
 	}
 
 	dra7xx_pcie_establish_link(pp);
@@ -288,6 +288,7 @@  static int __init dra7xx_add_pcie_port(struct dra7xx_pcie *dra7xx,
 
 	pp = &dra7xx->pp;
 	pp->dev = dev;
+	pp->root_bus_nr = 0;
 	pp->ops = &dra7xx_pcie_host_ops;
 
 	pp->irq = platform_get_irq(pdev, 1);
diff --git a/drivers/pci/host/pci-exynos.c b/drivers/pci/host/pci-exynos.c
index f9f468d..9771bb0 100644
--- a/drivers/pci/host/pci-exynos.c
+++ b/drivers/pci/host/pci-exynos.c
@@ -530,7 +530,7 @@  static int __init exynos_add_pcie_port(struct pcie_port *pp,
 		}
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &exynos_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/host/pci-imx6.c b/drivers/pci/host/pci-imx6.c
index 233a196..bec256c 100644
--- a/drivers/pci/host/pci-imx6.c
+++ b/drivers/pci/host/pci-imx6.c
@@ -551,7 +551,7 @@  static int __init imx6_add_pcie_port(struct pcie_port *pp,
 		}
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &imx6_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/host/pci-keystone-dw.c b/drivers/pci/host/pci-keystone-dw.c
index f34892e..b1e4135 100644
--- a/drivers/pci/host/pci-keystone-dw.c
+++ b/drivers/pci/host/pci-keystone-dw.c
@@ -327,7 +327,7 @@  static void ks_dw_pcie_clear_dbi_mode(void __iomem *reg_virt)
 void ks_dw_pcie_setup_rc_app_regs(struct keystone_pcie *ks_pcie)
 {
 	struct pcie_port *pp = &ks_pcie->pp;
-	u32 start = pp->mem.start, end = pp->mem.end;
+	u32 start = pp->mem->start, end = pp->mem->end;
 	int i, tr_size;
 
 	/* Disable BARs for inbound access */
diff --git a/drivers/pci/host/pci-keystone.c b/drivers/pci/host/pci-keystone.c
index 734da58..8113832 100644
--- a/drivers/pci/host/pci-keystone.c
+++ b/drivers/pci/host/pci-keystone.c
@@ -309,7 +309,7 @@  static int __init ks_add_pcie_port(struct keystone_pcie *ks_pcie,
 			return ret;
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &keystone_pcie_host_ops;
 	ret = ks_dw_pcie_host_init(ks_pcie, ks_pcie->msi_intc_np);
 	if (ret) {
diff --git a/drivers/pci/host/pci-layerscape.c b/drivers/pci/host/pci-layerscape.c
index b2328ea1..79ff08c 100644
--- a/drivers/pci/host/pci-layerscape.c
+++ b/drivers/pci/host/pci-layerscape.c
@@ -106,7 +106,7 @@  static int ls_add_pcie_port(struct ls_pcie *pcie)
 	pp = &pcie->pp;
 	pp->dev = pcie->dev;
 	pp->dbi_base = pcie->dbi;
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &ls_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);
diff --git a/drivers/pci/host/pcie-designware.c b/drivers/pci/host/pcie-designware.c
index c5d407c..e71a88e 100644
--- a/drivers/pci/host/pcie-designware.c
+++ b/drivers/pci/host/pcie-designware.c
@@ -11,6 +11,7 @@ 
  * published by the Free Software Foundation.
  */
 
+#include <linux/hardirq.h>
 #include <linux/irq.h>
 #include <linux/irqdomain.h>
 #include <linux/kernel.h>
@@ -69,16 +70,7 @@ 
 #define PCIE_ATU_FUNC(x)		(((x) & 0x7) << 16)
 #define PCIE_ATU_UPPER_TARGET		0x91C
 
-static struct hw_pci dw_pci;
-
-static unsigned long global_io_offset;
-
-static inline struct pcie_port *sys_to_pcie(struct pci_sys_data *sys)
-{
-	BUG_ON(!sys->private_data);
-
-	return sys->private_data;
-}
+static struct pci_ops dw_pcie_ops;
 
 int dw_pcie_cfg_read(void __iomem *addr, int where, int size, u32 *val)
 {
@@ -255,7 +247,7 @@  static void dw_pcie_msi_set_irq(struct pcie_port *pp, int irq)
 static int assign_irq(int no_irqs, struct msi_desc *desc, int *pos)
 {
 	int irq, pos0, i;
-	struct pcie_port *pp = sys_to_pcie(desc->dev->bus->sysdata);
+	struct pcie_port *pp = desc->dev->bus->sysdata;
 
 	pos0 = bitmap_find_free_region(pp->msi_irq_in_use, MAX_MSI_IRQS,
 				       order_base_2(no_irqs));
@@ -298,7 +290,7 @@  static int dw_msi_setup_irq(struct msi_controller *chip, struct pci_dev *pdev,
 {
 	int irq, pos;
 	struct msi_msg msg;
-	struct pcie_port *pp = sys_to_pcie(pdev->bus->sysdata);
+	struct pcie_port *pp = pdev->bus->sysdata;
 
 	if (desc->msi_attrib.is_msix)
 		return -EINVAL;
@@ -327,7 +319,7 @@  static void dw_msi_teardown_irq(struct msi_controller *chip, unsigned int irq)
 {
 	struct irq_data *data = irq_get_irq_data(irq);
 	struct msi_desc *msi = irq_data_get_msi(data);
-	struct pcie_port *pp = sys_to_pcie(msi->dev->bus->sysdata);
+	struct pcie_port *pp = msi->dev->bus->sysdata;
 
 	clear_irq_range(pp, irq, 1, data->hwirq);
 }
@@ -363,14 +355,12 @@  int dw_pcie_host_init(struct pcie_port *pp)
 {
 	struct device_node *np = pp->dev->of_node;
 	struct platform_device *pdev = to_platform_device(pp->dev);
-	struct of_pci_range range;
-	struct of_pci_range_parser parser;
+	struct pci_bus *bus;
 	struct resource *cfg_res;
-	u32 val, ns;
-	const __be32 *addrp;
-	int i, index, ret;
-
-	ns = of_n_size_cells(np);
+	LIST_HEAD(res);
+	u32 val;
+	int i, ret;
+	struct resource_entry *win;
 
 	cfg_res = platform_get_resource_byname(pdev, IORESOURCE_MEM, "config");
 	if (cfg_res) {
@@ -378,85 +368,60 @@  int dw_pcie_host_init(struct pcie_port *pp)
 		pp->cfg1_size = resource_size(cfg_res)/2;
 		pp->cfg0_base = cfg_res->start;
 		pp->cfg1_base = cfg_res->start + pp->cfg0_size;
-
-		/* Find the untranslated configuration space address */
-		index = of_property_match_string(np, "reg-names", "config");
-		addrp = of_get_address(np, index, NULL, NULL);
-		pp->cfg0_mod_base = of_read_number(addrp, ns);
-		pp->cfg1_mod_base = pp->cfg0_mod_base + pp->cfg0_size;
 	} else {
 		dev_err(pp->dev, "missing *config* reg space\n");
 	}
 
-	if (of_pci_range_parser_init(&parser, np)) {
-		dev_err(pp->dev, "missing ranges property\n");
-		return -EINVAL;
-	}
+	ret = of_pci_get_host_bridge_resources(np, 0, 0xff, &res, &pp->io_base);
+	if (ret)
+		return ret;
 
 	/* Get the I/O and memory ranges from DT */
-	for_each_of_pci_range(&parser, &range) {
-		unsigned long restype = range.flags & IORESOURCE_TYPE_BITS;
-
-		if (restype == IORESOURCE_IO) {
-			of_pci_range_to_resource(&range, np, &pp->io);
-			pp->io.name = "I/O";
-			pp->io.start = max_t(resource_size_t,
-					     PCIBIOS_MIN_IO,
-					     range.pci_addr + global_io_offset);
-			pp->io.end = min_t(resource_size_t,
-					   IO_SPACE_LIMIT,
-					   range.pci_addr + range.size
-					   + global_io_offset - 1);
-			pp->io_size = resource_size(&pp->io);
-			pp->io_bus_addr = range.pci_addr;
-			pp->io_base = range.cpu_addr;
-
-			/* Find the untranslated IO space address */
-			pp->io_mod_base = range.cpu_addr;
-		}
-		if (restype == IORESOURCE_MEM) {
-			of_pci_range_to_resource(&range, np, &pp->mem);
-			pp->mem.name = "MEM";
-			pp->mem_size = resource_size(&pp->mem);
-			pp->mem_bus_addr = range.pci_addr;
-
-			/* Find the untranslated MEM space address */
-			pp->mem_mod_base = range.cpu_addr;
-		}
-		if (restype == 0) {
-			of_pci_range_to_resource(&range, np, &pp->cfg);
-			pp->cfg0_size = resource_size(&pp->cfg)/2;
-			pp->cfg1_size = resource_size(&pp->cfg)/2;
-			pp->cfg0_base = pp->cfg.start;
-			pp->cfg1_base = pp->cfg.start + pp->cfg0_size;
-
-			/* Find the untranslated configuration space address */
-			pp->cfg0_mod_base = range.cpu_addr;
-			pp->cfg1_mod_base = pp->cfg0_mod_base +
-					    pp->cfg0_size;
+	resource_list_for_each_entry(win, &res) {
+		switch (resource_type(win->res)) {
+		case IORESOURCE_IO:
+			pp->io = win->res;
+			pp->io->name = "I/O";
+			pp->io_size = resource_size(pp->io);
+			pp->io_bus_addr = pp->io->start - win->offset;
+			ret = pci_remap_iospace(pp->io, pp->io_base);
+			if (ret) {
+				dev_warn(pp->dev, "error %d: failed to map resource %pR\n",
+					 ret, pp->io);
+				continue;
+			}
+			break;
+		case IORESOURCE_MEM:
+			pp->mem = win->res;
+			pp->mem->name = "MEM";
+			pp->mem_size = resource_size(pp->mem);
+			pp->mem_bus_addr = pp->mem->start - win->offset;
+			break;
+		case 0:
+			pp->cfg = win->res;
+			pp->cfg0_size = resource_size(pp->cfg)/2;
+			pp->cfg1_size = resource_size(pp->cfg)/2;
+			pp->cfg0_base = pp->cfg->start;
+			pp->cfg1_base = pp->cfg->start + pp->cfg0_size;
+			break;
+		case IORESOURCE_BUS:
+			pp->busn = win->res;
+			break;
+		default:
+			continue;
 		}
 	}
 
-	ret = of_pci_parse_bus_range(np, &pp->busn);
-	if (ret < 0) {
-		pp->busn.name = np->name;
-		pp->busn.start = 0;
-		pp->busn.end = 0xff;
-		pp->busn.flags = IORESOURCE_BUS;
-		dev_dbg(pp->dev, "failed to parse bus-range property: %d, using default %pR\n",
-			ret, &pp->busn);
-	}
-
 	if (!pp->dbi_base) {
-		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg.start,
-					resource_size(&pp->cfg));
+		pp->dbi_base = devm_ioremap(pp->dev, pp->cfg->start,
+					resource_size(pp->cfg));
 		if (!pp->dbi_base) {
 			dev_err(pp->dev, "error with ioremap\n");
 			return -ENOMEM;
 		}
 	}
 
-	pp->mem_base = pp->mem.start;
+	pp->mem_base = pp->mem->start;
 
 	if (!pp->va_cfg0_base) {
 		pp->va_cfg0_base = devm_ioremap(pp->dev, pp->cfg0_base,
@@ -505,7 +470,7 @@  int dw_pcie_host_init(struct pcie_port *pp)
 
 	if (!pp->ops->rd_other_conf)
 		dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX1,
-					  PCIE_ATU_TYPE_MEM, pp->mem_mod_base,
+					  PCIE_ATU_TYPE_MEM, pp->mem_base,
 					  pp->mem_bus_addr, pp->mem_size);
 
 	dw_pcie_wr_own_conf(pp, PCI_BASE_ADDRESS_0, 4, 0);
@@ -517,15 +482,29 @@  int dw_pcie_host_init(struct pcie_port *pp)
 	val |= PORT_LOGIC_SPEED_CHANGE;
 	dw_pcie_wr_own_conf(pp, PCIE_LINK_WIDTH_SPEED_CONTROL, 4, val);
 
-#ifdef CONFIG_PCI_MSI
+	bus = pci_create_root_bus(pp->dev, pp->root_bus_nr, &dw_pcie_ops,
+				  pp, &res);
+	if (!bus)
+		return -ENOMEM;
+
+#ifdef CONFIG_GENERIC_MSI_IRQ_DOMAIN
+	bus->msi = container_of(&pp->irq_domain, struct msi_controller, domain);
+#else
 	dw_pcie_msi_chip.dev = pp->dev;
-	dw_pci.msi_ctrl = &dw_pcie_msi_chip;
+	bus->msi = &dw_pcie_msi_chip;
 #endif
 
-	dw_pci.nr_controllers = 1;
-	dw_pci.private_data = (void **)&pp;
+	pci_scan_child_bus(bus);
+	if (pp->ops->scan_bus)
+		pp->ops->scan_bus(pp);
+
+#ifdef CONFIG_ARM
+	/* support old dtbs that incorrectly describe IRQs */
+	pci_fixup_irqs(pci_common_swizzle, of_irq_parse_and_map_pci);
+#endif
 
-	pci_common_init_dev(pp->dev, &dw_pci);
+	pci_assign_unassigned_bus_resources(bus);
+	pci_bus_add_devices(bus);
 
 	return 0;
 }
@@ -544,12 +523,12 @@  static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 
 	if (bus->parent->number == pp->root_bus_nr) {
 		type = PCIE_ATU_TYPE_CFG0;
-		cpu_addr = pp->cfg0_mod_base;
+		cpu_addr = pp->cfg0_base;
 		cfg_size = pp->cfg0_size;
 		va_cfg_base = pp->va_cfg0_base;
 	} else {
 		type = PCIE_ATU_TYPE_CFG1;
-		cpu_addr = pp->cfg1_mod_base;
+		cpu_addr = pp->cfg1_base;
 		cfg_size = pp->cfg1_size;
 		va_cfg_base = pp->va_cfg1_base;
 	}
@@ -559,7 +538,7 @@  static int dw_pcie_rd_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 				  busdev, cfg_size);
 	ret = dw_pcie_cfg_read(va_cfg_base + address, where, size, val);
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
-				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
+				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
 
 	return ret;
@@ -579,12 +558,12 @@  static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 
 	if (bus->parent->number == pp->root_bus_nr) {
 		type = PCIE_ATU_TYPE_CFG0;
-		cpu_addr = pp->cfg0_mod_base;
+		cpu_addr = pp->cfg0_base;
 		cfg_size = pp->cfg0_size;
 		va_cfg_base = pp->va_cfg0_base;
 	} else {
 		type = PCIE_ATU_TYPE_CFG1;
-		cpu_addr = pp->cfg1_mod_base;
+		cpu_addr = pp->cfg1_base;
 		cfg_size = pp->cfg1_size;
 		va_cfg_base = pp->va_cfg1_base;
 	}
@@ -594,7 +573,7 @@  static int dw_pcie_wr_other_conf(struct pcie_port *pp, struct pci_bus *bus,
 				  busdev, cfg_size);
 	ret = dw_pcie_cfg_write(va_cfg_base + address, where, size, val);
 	dw_pcie_prog_outbound_atu(pp, PCIE_ATU_REGION_INDEX0,
-				  PCIE_ATU_TYPE_IO, pp->io_mod_base,
+				  PCIE_ATU_TYPE_IO, pp->io_base,
 				  pp->io_bus_addr, pp->io_size);
 
 	return ret;
@@ -626,7 +605,7 @@  static int dw_pcie_valid_config(struct pcie_port *pp,
 static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 			int size, u32 *val)
 {
-	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
+	struct pcie_port *pp = bus->sysdata;
 	int ret;
 
 	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0) {
@@ -650,7 +629,7 @@  static int dw_pcie_rd_conf(struct pci_bus *bus, u32 devfn, int where,
 static int dw_pcie_wr_conf(struct pci_bus *bus, u32 devfn,
 			int where, int size, u32 val)
 {
-	struct pcie_port *pp = sys_to_pcie(bus->sysdata);
+	struct pcie_port *pp = bus->sysdata;
 	int ret;
 
 	if (dw_pcie_valid_config(pp, bus, PCI_SLOT(devfn)) == 0)
@@ -674,62 +653,6 @@  static struct pci_ops dw_pcie_ops = {
 	.write = dw_pcie_wr_conf,
 };
 
-static int dw_pcie_setup(int nr, struct pci_sys_data *sys)
-{
-	struct pcie_port *pp;
-
-	pp = sys_to_pcie(sys);
-
-	if (global_io_offset < SZ_1M && pp->io_size > 0) {
-		sys->io_offset = global_io_offset - pp->io_bus_addr;
-		pci_ioremap_io(global_io_offset, pp->io_base);
-		global_io_offset += SZ_64K;
-		pci_add_resource_offset(&sys->resources, &pp->io,
-					sys->io_offset);
-	}
-
-	sys->mem_offset = pp->mem.start - pp->mem_bus_addr;
-	pci_add_resource_offset(&sys->resources, &pp->mem, sys->mem_offset);
-	pci_add_resource(&sys->resources, &pp->busn);
-
-	return 1;
-}
-
-static struct pci_bus *dw_pcie_scan_bus(int nr, struct pci_sys_data *sys)
-{
-	struct pci_bus *bus;
-	struct pcie_port *pp = sys_to_pcie(sys);
-
-	pp->root_bus_nr = sys->busnr;
-	bus = pci_scan_root_bus(pp->dev, sys->busnr,
-				  &dw_pcie_ops, sys, &sys->resources);
-	if (!bus)
-		return NULL;
-
-	if (bus && pp->ops->scan_bus)
-		pp->ops->scan_bus(pp);
-
-	return bus;
-}
-
-static int dw_pcie_map_irq(const struct pci_dev *dev, u8 slot, u8 pin)
-{
-	struct pcie_port *pp = sys_to_pcie(dev->bus->sysdata);
-	int irq;
-
-	irq = of_irq_parse_and_map_pci(dev, slot, pin);
-	if (!irq)
-		irq = pp->irq;
-
-	return irq;
-}
-
-static struct hw_pci dw_pci = {
-	.setup		= dw_pcie_setup,
-	.scan		= dw_pcie_scan_bus,
-	.map_irq	= dw_pcie_map_irq,
-};
-
 void dw_pcie_setup_rc(struct pcie_port *pp)
 {
 	u32 val;
diff --git a/drivers/pci/host/pcie-designware.h b/drivers/pci/host/pcie-designware.h
index d0bbd27..264c969 100644
--- a/drivers/pci/host/pcie-designware.h
+++ b/drivers/pci/host/pcie-designware.h
@@ -27,25 +27,21 @@  struct pcie_port {
 	u8			root_bus_nr;
 	void __iomem		*dbi_base;
 	u64			cfg0_base;
-	u64			cfg0_mod_base;
 	void __iomem		*va_cfg0_base;
 	u32			cfg0_size;
 	u64			cfg1_base;
-	u64			cfg1_mod_base;
 	void __iomem		*va_cfg1_base;
 	u32			cfg1_size;
-	u64			io_base;
-	u64			io_mod_base;
+	resource_size_t		io_base;
 	phys_addr_t		io_bus_addr;
 	u32			io_size;
 	u64			mem_base;
-	u64			mem_mod_base;
 	phys_addr_t		mem_bus_addr;
 	u32			mem_size;
-	struct resource		cfg;
-	struct resource		io;
-	struct resource		mem;
-	struct resource		busn;
+	struct resource		*cfg;
+	struct resource		*io;
+	struct resource		*mem;
+	struct resource		*busn;
 	int			irq;
 	u32			lanes;
 	struct pcie_host_ops	*ops;
diff --git a/drivers/pci/host/pcie-spear13xx.c b/drivers/pci/host/pcie-spear13xx.c
index c49fbdc..03eb204 100644
--- a/drivers/pci/host/pcie-spear13xx.c
+++ b/drivers/pci/host/pcie-spear13xx.c
@@ -286,7 +286,7 @@  static int spear13xx_add_pcie_port(struct pcie_port *pp,
 		return ret;
 	}
 
-	pp->root_bus_nr = -1;
+	pp->root_bus_nr = 0;
 	pp->ops = &spear13xx_pcie_host_ops;
 
 	ret = dw_pcie_host_init(pp);